@fluidframework/driver-definitions 2.114.0 → 2.115.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 +13 -0
- package/dist/serviceClient.d.ts +20 -0
- package/dist/serviceClient.d.ts.map +1 -1
- package/dist/serviceClient.js.map +1 -1
- package/lib/serviceClient.d.ts +20 -0
- package/lib/serviceClient.d.ts.map +1 -1
- package/lib/serviceClient.js.map +1 -1
- package/package.json +2 -2
- package/src/serviceClient.ts +25 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @fluidframework/driver-definitions
|
|
2
2
|
|
|
3
|
+
## 2.115.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Simplify creating attached Fluid containers with ServiceClient ([#27789](https://github.com/microsoft/FluidFramework/pull/27789)) [1671447b57](https://github.com/microsoft/FluidFramework/commit/1671447b57852875ec90a9d1c16b3817ce25e004)
|
|
8
|
+
|
|
9
|
+
Added `ServiceClient.createAttachedContainer` which creates and attaches a Fluid container in one operation.
|
|
10
|
+
It is a convenient shorthand for calling `createContainer` followed by `attach` when detached-container access is not needed.
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
const container = await client.createAttachedContainer(dataStoreKind);
|
|
14
|
+
```
|
|
15
|
+
|
|
3
16
|
## 2.114.0
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
package/dist/serviceClient.d.ts
CHANGED
|
@@ -324,6 +324,26 @@ export interface ServiceClient {
|
|
|
324
324
|
* or when the container needs a registry for creating additional data stores beyond the root.
|
|
325
325
|
*/
|
|
326
326
|
createContainer<T>(root: DataStoreKey<T>, registry: DataStoreRegistry): Promise<FluidContainerWithService<T>>;
|
|
327
|
+
/**
|
|
328
|
+
* A shorthand for {@link ServiceClient.(createContainer:1)} followed by {@link FluidContainerWithService.attach}.
|
|
329
|
+
* @remarks
|
|
330
|
+
* Due to current implementation limitations making container creation async and service specific,
|
|
331
|
+
* creating then attaching one is a bit verbose with two awaits that are messy to include inline.
|
|
332
|
+
* This provides a convenient way to create and attach a container in a single step.
|
|
333
|
+
* @privateRemarks
|
|
334
|
+
* TODO: We should fix ergonomics issues that make this helpful,
|
|
335
|
+
* then remove (or deprecate) this method in favor of `service.attach(createContainer(root))` as a better orthogonalized API.
|
|
336
|
+
* See private remarks on {@link ServiceClient.(createContainer:1)}.
|
|
337
|
+
*/
|
|
338
|
+
createAttachedContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerAttached<T>>;
|
|
339
|
+
/**
|
|
340
|
+
* A shorthand for {@link ServiceClient.(createContainer:2)} followed by {@link FluidContainerWithService.attach}.
|
|
341
|
+
* @remarks
|
|
342
|
+
* Due to current implementation limitations making container creation async and service specific,
|
|
343
|
+
* creating then attaching one is a bit verbose with two awaits that are messy to include inline.
|
|
344
|
+
* This provides a convenient way to create and attach a container in a single step.
|
|
345
|
+
*/
|
|
346
|
+
createAttachedContainer<T>(root: DataStoreKey<T>, registry: DataStoreRegistry): Promise<FluidContainerAttached<T>>;
|
|
327
347
|
/**
|
|
328
348
|
* Loads an existing container from the service.
|
|
329
349
|
* @typeParam T - The type of the container's root data store.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceClient.d.ts","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO;IAC/C;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;OAUG;IACH,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EACzC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EACvB,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,GACzB,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAKzE;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,8BAA8B,GAAG,KAAK,MAAM,IAAI,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,SAAS,GAAG,MAAM,EAAE,EAAE,KAAK,SAAS,GAAG,MAAM,EAAE,EAClF,OAAO,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,GAC9E,GAAG,KAAK,IAAI,KAAK,IAAI,CAMvB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,0BAA0B,EAAE,8BAA8B,CAAC;CACpE;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,IAAI,WAAW,CACxD,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAC5B,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;;;;OAOG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,cAAc,CAAC,KAAK,GAAG,OAAO,CAC9C,SAAQ,gBAAgB,EACvB,cAAc,CAAC,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACnD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAErB;;;;;;;;;;;OAWG;IACH,KAAK,IAAI,IAAI,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,cAAc,CAAC,KAAK,CAAC;IACxF;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;CAGjD;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,cAAc,CAAC,KAAK,CAAC;IACrF;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAC7C,SAAQ,YAAY,CAAC,CAAC,CAAC,EACtB,cAAc,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;CAAG;AAElD;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAErF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;IAElF;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EAChB,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EACrB,QAAQ,EAAE,iBAAiB,GACzB,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzC;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,CAAC,EACd,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAC3C,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC"}
|
|
1
|
+
{"version":3,"file":"serviceClient.d.ts","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO;IAC/C;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;OAUG;IACH,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EACzC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EACvB,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,GACzB,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAKzE;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,8BAA8B,GAAG,KAAK,MAAM,IAAI,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,SAAS,GAAG,MAAM,EAAE,EAAE,KAAK,SAAS,GAAG,MAAM,EAAE,EAClF,OAAO,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,EAAE,GAAG,GAAG,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,GAC9E,GAAG,KAAK,IAAI,KAAK,IAAI,CAMvB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,0BAA0B,EAAE,8BAA8B,CAAC;CACpE;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,IAAI,WAAW,CACxD,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAC5B,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;;;;OAOG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,cAAc,CAAC,KAAK,GAAG,OAAO,CAC9C,SAAQ,gBAAgB,EACvB,cAAc,CAAC,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACnD;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAErB;;;;;;;;;;;OAWG;IACH,KAAK,IAAI,IAAI,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,cAAc,CAAC,KAAK,CAAC;IACxF;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;CAGjD;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,cAAc,CAAC,KAAK,CAAC;IACrF;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAC7C,SAAQ,YAAY,CAAC,CAAC,CAAC,EACtB,cAAc,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;CAAG;AAElD;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAErF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;IAElF;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EAChB,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EACrB,QAAQ,EAAE,iBAAiB,GACzB,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzC;;;;;;;;;;OAUG;IACH,uBAAuB,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvF;;;;;;OAMG;IACH,uBAAuB,CAAC,CAAC,EACxB,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,EACrB,QAAQ,EAAE,iBAAiB,GACzB,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtC;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,CAAC,EACd,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAC3C,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceClient.js","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAsFH;;;;;GAKG;AACH,SAAgB,gBAAgB,CAC/B,QAAuB,EACvB,GAA2B;IAE3B,OAAO,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AALD,4CAKC;AAED;;;;GAIG;AACH,SAAgB,sBAAsB,CAAI,IAAY;IACrD,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;KACvB,CAAC;AACH,CAAC;AALD,wDAKC;AAgCD;;;;;;;;;;;GAWG;AACH,SAAgB,cAAc,CAC7B,OAAgF;IAEhF,6KAA6K;IAC7K,2JAA2J;IAC3J,6KAA6K;IAC7K,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAU,IAAI,MAAM,CAAC,CAAC,CAAU,IAAI,CAAC;AACxD,CAAC;AARD,wCAQC;AAiPD,aAAa","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ErasedBaseType } from \"@fluidframework/core-interfaces/internal\";\n\n/**\n * This file defines the external facing API for the {@link ServiceClient} and related types.\n *\n * It provides an API surface at a similar abstraction level to aqueduct and fluid-static, but is intended to be a replacement for those which solves several problems with them.\n * Mainly it strives to have the encapsulation of implementation details (including all legacy APIs from aqueduct and lower level internals) like fluid-static\n * while being both more flexible and simpler.\n *\n * This aims to be the cleanest practical way to build applications on the Fluid Framework Client.\n * There are however several known cases where the API quality was sacrificed to ease initial implementation,\n * since some of the unification desired in this API's design are not yet implemented in the underlying Fluid Framework Client code or require additional work to implement.\n * These cases are called out with TODOs in this file.\n * These should be considered and addressed before stabilizing this API past alpha.\n *\n * All code interacting through this API surface within a single client must avoid using multiple copies of any Fluid Framework client package (at the same or different versions).\n * This mirrors the `@public` \"declarative model\" APIs and is a deliberate simplification of what is allowed in the legacy API surface.\n * It is enforced best-effort only: `@sealed` nominal erased types catch many mismatches at compile time, and factory identity checks throw a UsageError (\"Conflicting ... with same type\") at run time, but the checking is not exhaustive.\n * See `LayerCompatibilityUnified.md` for the full policy, rationale, and failure signatures.\n *\n * TODO:\n * Before stabilizing any of this past beta, evaluate whether this single-copy requirement must be relaxed, and if so how.\n * Whatever rule is chosen (relaxed or not) should be enforced at both compile time and run time as much as possible.\n *\n * TODO:\n * Fault isolation should be considered in this API design.\n * When are exceptions recoverable and how?\n * Likely we can fault isolate exceptions to containers in most cases,\n * and containers can indicate their status by being closed or disposed.\n * Non fatal errors should not be exceptions.\n */\n\n// #region Registry types\n\n/**\n * A collection of entries looked up by a `type` string.\n * @remarks\n * Use of a function for this allows a few things that most collections would not:\n * 1. It's possible to generate placeholder / error values on demand.\n * 2. It makes loading from some external registry on demand practical.\n * 3. The lookup can throw an exception if appropriate (this would typically indicate a bug and produce a fatal error).\n * 4. Generation of values can be lazy, and even asynchronous if `T` allows for a promise.\n *\n * This flexibility lets the implementer decide how to handle requests for unknown types.\n * They can produce placeholders, assert, fall back to a generic implementation etc.\n * @typeParam T - The type of entry produced for any given `type` string.\n * @input\n * @alpha\n */\nexport type Registry<T> = (type: string) => T;\n\n/**\n * A strongly typed key for a {@link Registry}.\n * Use with {@link lookupInRegistry}.\n * @remarks\n * Used to look up a `TIn` in a `Registry<TIn>`, and produce a `TOut` from it.\n * @typeParam TOut - The type produced by {@link RegistryKey.adapt} from a looked-up entry.\n * @typeParam TIn - The type of the entries in the {@link Registry} this key is used with.\n * @privateRemarks\n * This is currently input and sealed, meaning effectively type erased since the design might change.\n * @input\n * @sealed\n * @alpha\n */\nexport interface RegistryKey<TOut, TIn = unknown> {\n\t/**\n\t * Identifier to provide to the {@link Registry}.\n\t */\n\treadonly type: string;\n\n\t/**\n\t * Convert a value from the registry to the desired output type.\n\t * @remarks\n\t * How this is done is up to the implementation.\n\t *\n\t * This might be a type guard which throws if the input is not valid.\n\t * Or it could be a conversion, an identity function, or something else.\n\t *\n\t * @param value - The value from the registry.\n\t * @returns The converted value.\n\t */\n\tadapt(value: TIn): TOut;\n}\n\n/**\n * Lookup an entry in a {@link Registry} using a {@link RegistryKey}.\n * @typeParam TOut - The type produced from the looked-up entry.\n * @typeParam TIn - The type of the entries in `registry`.\n * @alpha\n */\nexport function lookupInRegistry<TOut, TIn>(\n\tregistry: Registry<TIn>,\n\tkey: RegistryKey<TOut, TIn>,\n): TOut {\n\treturn key.adapt(registry(key.type));\n}\n\n/**\n * Creates a simple {@link RegistryKey} which does no type conversion.\n * @typeParam T - The type of the registry entry, which is returned unchanged by the key.\n * @alpha\n */\nexport function createBasicRegistryKey<T>(type: string): RegistryKey<T, T> {\n\treturn {\n\t\ttype,\n\t\tadapt: (value) => value,\n\t};\n}\n\n// #endregion\n\n// #region ServiceClient types\n\n/**\n * Oldest version of Fluid Framework client packages to support collaborating with.\n * @remarks\n * A string in SemVer format indicating a specific version of the Fluid Framework client package, or the special case of {@link @fluidframework/runtime-utils#defaultMinVersionForCollab}.\n *\n * Collaboration with other clients is only supported when all Fluid Framework client packages used by the client have a version that is greater than or equal\n * to the specified `MinimumVersionForCollaboration`.\n *\n * Cannot exceed the version of any Fluid Framework client package in use by the local client.\n *\n * The higher the version specified, the more features and optimizations will be enabled. *\n * @privateRemarks\n * This is similar to, and a subset of, the `MinimumVersionForCollab` type in `@fluidframework/runtime-definitions`.\n * This differs in that:\n * - This avoids the shorthand \"collab\" to instead align with our preferred whole word naming convention.\n * - This is `alpha` instead of `public`.\n * - This is available to drivers due to its location in `driver-definitions` instead of `runtime-definitions`.\n * - This does not allow requesting collaboration with pre-2.0.0 versions, including the special case of `2.0.0-defaults`.\n * - Patch versions cannot be set: a given minor release is not guaranteed to be greater or equal compat wise to all patches of the previous release, so we do not enable features based on patch versions (instead fall back to the next minor if needed).\n * Therefore allowing patch versions here could be misleading and could lead to bugs.\n *\n * @input\n * @alpha\n */\nexport type MinimumVersionForCollaboration = `2.${bigint}.0`;\n\n/**\n * Strips patch and prerelease from a SemVer string, returning only the major and minor version.\n * @remarks\n * This formats a version in the same style used by {@link MinimumVersionForCollaboration}, specifying only the major and minor versions,\n * which are the portions used for feature selection.\n * @typeParam major - The major version number of `version` as a string, preserved in the result type.\n * @typeParam minor - The minor version number of `version` as a string, preserved in the result type.\n * @privateRemarks\n * This fills a similar role as cleanedPackageVersion in `@fluidframework/runtime-utils`.\n * It can be used to workaround our generated pkgVersion values being invalid `MinimumVersionForCollaboration` on CI (due to prerelease) or patched release branches.\n * @alpha\n */\nexport function featureVersion<major extends `${bigint}`, minor extends `${bigint}`>(\n\tversion: `${major}.${minor}.${bigint}-${string}` | `${major}.${minor}.${bigint}`,\n): `${major}.${minor}.0` {\n\t// The SemVer package could be used to parse this version, but it wouldn't gain us anything, and would just make it harder to determine that the down casting below is valid.\n\t// Since we have a strongly typed string input, we know exactly which formats are allowed, so we don't need its more general parsing and validation either.\n\t// If we wanted to preserve the patch or prerelease version, that would require more complex parsing and would justify using the SemVer package, but we don't need that here.\n\tconst parsed = version.split(\".\");\n\treturn `${parsed[0] as major}.${parsed[1] as minor}.0`;\n}\n\n/**\n * Options for configuring a {@link ServiceClient}.\n * @remarks\n * These are the options which apply to all services.\n *\n * Individual services will extend with additional options.\n *\n * @input\n * @alpha\n */\nexport interface ServiceOptions {\n\treadonly minVersionForCollaboration: MinimumVersionForCollaboration;\n}\n\n/**\n * A {@link RegistryKey} for a {@link DataStoreKind}.\n * @remarks\n * This is implemented by {@link DataStoreKind}, but alternative implementations can be used if needed.\n *\n * If you want lazy loading and need a key that does not eagerly load the {@link DataStoreKind}, an alternative {@link DataStoreKey} can be implemented.\n * @typeParam T - The type to expose from the {@link DataStoreKind} this key resolves to.\n * @typeParam TAll - The type covering all {@link DataStoreKind}s in the {@link Registry} this key is used with.\n * @privateRemarks\n * TODO: A built in common pattern for the lazy key case should be provided.\n * TODO: things probably break if \"adapt\" does anything except throw or return the result from the input promise.\n * @input\n * @alpha\n */\nexport type DataStoreKey<T, TAll = unknown> = RegistryKey<\n\tPromise<DataStoreKind<T>>,\n\tPromise<DataStoreKind<TAll>>\n>;\n\n/**\n * A context which has a registry and can create data stores using it.\n * @sealed\n * @alpha\n */\nexport interface DataStoreCreator {\n\t/**\n\t * Create a new detached data store `T` which can be attached to the {@link FluidContainer}.\n\t * by adding a handle to a data store or shared object which is already attached to the {@link FluidContainer}.\n\t * @remarks\n\t * `kind` will be looked up in the {@link Registry} used to create or load this {@link DataStoreCreator}.\n\t * It is up to that registry to decide how it handles unknown types, for example by throwing an exception or returning a placeholder.\n\t * @typeParam T - type implemented by the data store to expose in the result, as defined by `kind`.\n\t */\n\tcreateDataStore<T>(kind: DataStoreKey<T>): Promise<T>;\n}\n\n/**\n * A Fluid container.\n * @remarks\n * A document which can be stored to or loaded from a Fluid service using a {@link ServiceClient}.\n *\n * @typeParam TData - The type of the container's root data store, exposed via {@link FluidContainer.data}.\n * @privateRemarks\n * This will likely end up needing many of IFluidContainer's APIs, like disconnect, connectionState, events etc.\n * Before adding them though, care should be taken to consider if they can be improved or simplified.\n * For example maybe a single status enum for `detached -> attaching -> dirty -> saved -> closed` would be good.\n * Or maybe `detached -> attaching -> attached -> closed` and a timer for how long since the last unsaved change was created.\n *\n * The underlying IContainer has a lifecycle which includes both a closed and disposed state.\n * This should be avoidable: the closed but not disposed state exists so its possible to read out some state at that time.\n * We have made the close remove all the timers, so the the dispose step should be unnecessary and we can just have a single closed state.\n *\n * @sealed\n * @alpha\n */\nexport interface FluidContainer<TData = unknown>\n\textends DataStoreCreator,\n\t\tErasedBaseType<readonly [\"FluidContainer\", TData]> {\n\t/**\n\t * The unique identifier for this container within its service.\n\t * @remarks\n\t * `undefined` if the container has not yet been attached to a service.\n\t * This can be used to load another instance of this container from the service using {@link ServiceClient.loadContainer}.\n\t */\n\treadonly id?: string | undefined;\n\n\t/**\n\t * The root data store of the container.\n\t * @remarks\n\t * The type of the root data store is defined by the {@link DataStoreKind} used to create the container.\n\t */\n\treadonly data: TData;\n\n\t/**\n\t * Close the container, stopping all networking and cancelling runtime timers.\n\t *\n\t * @remarks\n\t * After calling `close()`, the container's data can still be read but no further operations can be sent.\n\t * @privateRemarks\n\t * TODO: we should document the what the expected behavior is if one tries to modify the data after close, or tries to call close multiple times.\n\t * TODO: we also likely want to have a way to detect if closed and events for on close.\n\t * TODO: ensure this truly closes all timers: it seems like we might still leak some related to the summarizer.\n\t * TODO: we should clarify how this interacts with unsaved content including inprogress summaries,\n\t * and likely also provide an async API with some options for how to handle that.\n\t */\n\tclose(): void;\n}\n\n/**\n * A Fluid container with an associated {@link ServiceClient} it can attach to.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerWithService<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * Attaches this container to the associated service client.\n\t *\n\t * The returned promise resolves once the container is attached: the container from the promise is the same one passed in as the argument.\n\t */\n\tattach(): Promise<FluidContainerAttached<TData>>;\n\n\t// This could expose access to the ServiceClient if needed.\n}\n\n/**\n * A Fluid container that has been attached to a service.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerAttached<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * {@inheritdoc FluidContainer.id}\n\t */\n\treadonly id: string;\n}\n\n/**\n * Defines a {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind} of data store, allowing creating and loading instances of it.\n * @remarks\n * A `DataStoreKind` acts as the factory and type descriptor for a category of data store:\n * it defines the `type` used to identify the data store in a {@link DataStoreRegistry},\n * and the `T` API surface that instances of that data store expose.\n *\n * Provide a `DataStoreKind` to {@link ServiceClient.(createContainer:1)} or {@link DataStoreCreator.createDataStore}\n * to create new instances, and to {@link ServiceClient.loadContainer} to load existing ones.\n *\n * A `DataStoreKind` is not constructed directly.\n * Instead, obtain one from a framework-provided factory:\n * use {@link @fluidframework/shared-object-base#defineDataStore} to define a data store which wraps a root shared object,\n * or use a more specific wrapper around that,\n * such as {@link @fluidframework/tree#defineTreeDataStore} for a {@link @fluidframework/tree#TreeView}-backed data store.\n *\n * Since it implements {@link DataStoreKey}, a `DataStoreKind` can also be used directly as the key to look\n * itself up in a {@link Registry}.\n * @typeParam T - The API surface that instances of this data store kind expose.\n * @privateRemarks\n * TODO:\n * SharedObjects should be usable as these (though putting shared objects directly in the container might need special logic).\n * Type erased {@link IFluidDataStoreFactory}.\n * @sealed\n * @alpha\n */\nexport interface DataStoreKind<out T = unknown>\n\textends DataStoreKey<T>,\n\t\tErasedBaseType<readonly [\"DataStoreKind\", T]> {}\n\n/**\n * A registry of {@link DataStoreKind}s.\n * @privateRemarks\n * TODO: unify this with SharedObjectRegistry.\n *\n * @typeParam T - The type covering all {@link DataStoreKind}s in the registry.\n * @input\n * @alpha\n */\nexport type DataStoreRegistry<out T = unknown> = Registry<Promise<DataStoreKind<T>>>;\n\n/**\n * A connection to a Fluid storage service.\n * @sealed\n * @alpha\n */\nexport interface ServiceClient {\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKind} to use for the root.\n\t * @remarks\n\t * This overload is a shorthand for a simple case of {@link ServiceClient.(createContainer:2)}\n\t * where a single item registry is produced which contains only the root.\n\t * This is usable only when the root {@link DataStoreKind} is available eagerly (e.g. not lazy loaded),\n\t * and when the container does not need a registry for creating additional data stores beyond the root.\n\t * @privateRemarks\n\t * TODO: As this is a detached container, it should be able to be created synchronously.\n\t *\n\t * TODO: Provide more general alternative to this in the form of a service-independent `createContainer` free function.\n\t * It would work with a `ServiceClient.attachContainer<T>(detached: FluidContainer<T>): Promise<FluidContainerAttached<T>>`\n\t * which returns a promise that resolves once the detached container has been attached\n\t * (pointing to the same container object, but with the new type).\n\t *\n\t * Challenges:\n\t *\n\t * Currently the service must be provided at creation time because `IContainer.attach` does not accept a service client,\n\t * making it unclear whether a truly service-independent path is feasible in the near term.\n\t */\n\tcreateContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKey} used to look up the root's {@link DataStoreKind} from `registry`.\n\t * @param registry - The {@link DataStoreRegistry} supplying the {@link DataStoreKind} for the root and any other data stores the container may need to create.\n\t * @remarks\n\t * Use this overload when the root {@link DataStoreKind} is not available eagerly (e.g. for lazy loading),\n\t * or when the container needs a registry for creating additional data stores beyond the root.\n\t */\n\tcreateContainer<T>(\n\t\troot: DataStoreKey<T>,\n\t\tregistry: DataStoreRegistry,\n\t): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * Loads an existing container from the service.\n\t * @typeParam T - The type of the container's root data store.\n\t * @param id - The unique identifier of the container to load.\n\t * @param root - The {@link DataStoreKind} for the root, or a registry which will be used to look up the root based on its type.\n\t *\n\t * @throws a {@link @fluidframework/telemetry-utils#UsageError} if the DataStoreKind's type (either the root directly or looked up from the registry) does not match the type of the root data store in the container.\n\t *\n\t * @privateRemarks\n\t * The ability to provide a registry here means that it's possible to:\n\t * 1. Load a container which might have a few different possible roots, for example because of versioning.\n\t * 2. Generate the DataStoreKind on demand based on the type: this approach could be used for things like debug tools which can load any possible container.\n\t * 3. Generating the DataStoreKind if the type is unrecognized, for example to provide a placeholder which might support some minimal functionality (like debug inspection, and summary).\n\t *\n\t * The ability to provide just a single DataStoreKind<T> is purely a convenience to make it cleaner to use this in simple cases.\n\t */\n\tloadContainer<T>(\n\t\tid: string,\n\t\troot: DataStoreKind<T> | DataStoreRegistry<T>,\n\t): Promise<FluidContainerAttached<T>>;\n}\n\n// #endregion\n"]}
|
|
1
|
+
{"version":3,"file":"serviceClient.js","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAsFH;;;;;GAKG;AACH,SAAgB,gBAAgB,CAC/B,QAAuB,EACvB,GAA2B;IAE3B,OAAO,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AALD,4CAKC;AAED;;;;GAIG;AACH,SAAgB,sBAAsB,CAAI,IAAY;IACrD,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;KACvB,CAAC;AACH,CAAC;AALD,wDAKC;AAgCD;;;;;;;;;;;GAWG;AACH,SAAgB,cAAc,CAC7B,OAAgF;IAEhF,6KAA6K;IAC7K,2JAA2J;IAC3J,6KAA6K;IAC7K,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAU,IAAI,MAAM,CAAC,CAAC,CAAU,IAAI,CAAC;AACxD,CAAC;AARD,wCAQC;AA0QD,aAAa","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ErasedBaseType } from \"@fluidframework/core-interfaces/internal\";\n\n/**\n * This file defines the external facing API for the {@link ServiceClient} and related types.\n *\n * It provides an API surface at a similar abstraction level to aqueduct and fluid-static, but is intended to be a replacement for those which solves several problems with them.\n * Mainly it strives to have the encapsulation of implementation details (including all legacy APIs from aqueduct and lower level internals) like fluid-static\n * while being both more flexible and simpler.\n *\n * This aims to be the cleanest practical way to build applications on the Fluid Framework Client.\n * There are however several known cases where the API quality was sacrificed to ease initial implementation,\n * since some of the unification desired in this API's design are not yet implemented in the underlying Fluid Framework Client code or require additional work to implement.\n * These cases are called out with TODOs in this file.\n * These should be considered and addressed before stabilizing this API past alpha.\n *\n * All code interacting through this API surface within a single client must avoid using multiple copies of any Fluid Framework client package (at the same or different versions).\n * This mirrors the `@public` \"declarative model\" APIs and is a deliberate simplification of what is allowed in the legacy API surface.\n * It is enforced best-effort only: `@sealed` nominal erased types catch many mismatches at compile time, and factory identity checks throw a UsageError (\"Conflicting ... with same type\") at run time, but the checking is not exhaustive.\n * See `LayerCompatibilityUnified.md` for the full policy, rationale, and failure signatures.\n *\n * TODO:\n * Before stabilizing any of this past beta, evaluate whether this single-copy requirement must be relaxed, and if so how.\n * Whatever rule is chosen (relaxed or not) should be enforced at both compile time and run time as much as possible.\n *\n * TODO:\n * Fault isolation should be considered in this API design.\n * When are exceptions recoverable and how?\n * Likely we can fault isolate exceptions to containers in most cases,\n * and containers can indicate their status by being closed or disposed.\n * Non fatal errors should not be exceptions.\n */\n\n// #region Registry types\n\n/**\n * A collection of entries looked up by a `type` string.\n * @remarks\n * Use of a function for this allows a few things that most collections would not:\n * 1. It's possible to generate placeholder / error values on demand.\n * 2. It makes loading from some external registry on demand practical.\n * 3. The lookup can throw an exception if appropriate (this would typically indicate a bug and produce a fatal error).\n * 4. Generation of values can be lazy, and even asynchronous if `T` allows for a promise.\n *\n * This flexibility lets the implementer decide how to handle requests for unknown types.\n * They can produce placeholders, assert, fall back to a generic implementation etc.\n * @typeParam T - The type of entry produced for any given `type` string.\n * @input\n * @alpha\n */\nexport type Registry<T> = (type: string) => T;\n\n/**\n * A strongly typed key for a {@link Registry}.\n * Use with {@link lookupInRegistry}.\n * @remarks\n * Used to look up a `TIn` in a `Registry<TIn>`, and produce a `TOut` from it.\n * @typeParam TOut - The type produced by {@link RegistryKey.adapt} from a looked-up entry.\n * @typeParam TIn - The type of the entries in the {@link Registry} this key is used with.\n * @privateRemarks\n * This is currently input and sealed, meaning effectively type erased since the design might change.\n * @input\n * @sealed\n * @alpha\n */\nexport interface RegistryKey<TOut, TIn = unknown> {\n\t/**\n\t * Identifier to provide to the {@link Registry}.\n\t */\n\treadonly type: string;\n\n\t/**\n\t * Convert a value from the registry to the desired output type.\n\t * @remarks\n\t * How this is done is up to the implementation.\n\t *\n\t * This might be a type guard which throws if the input is not valid.\n\t * Or it could be a conversion, an identity function, or something else.\n\t *\n\t * @param value - The value from the registry.\n\t * @returns The converted value.\n\t */\n\tadapt(value: TIn): TOut;\n}\n\n/**\n * Lookup an entry in a {@link Registry} using a {@link RegistryKey}.\n * @typeParam TOut - The type produced from the looked-up entry.\n * @typeParam TIn - The type of the entries in `registry`.\n * @alpha\n */\nexport function lookupInRegistry<TOut, TIn>(\n\tregistry: Registry<TIn>,\n\tkey: RegistryKey<TOut, TIn>,\n): TOut {\n\treturn key.adapt(registry(key.type));\n}\n\n/**\n * Creates a simple {@link RegistryKey} which does no type conversion.\n * @typeParam T - The type of the registry entry, which is returned unchanged by the key.\n * @alpha\n */\nexport function createBasicRegistryKey<T>(type: string): RegistryKey<T, T> {\n\treturn {\n\t\ttype,\n\t\tadapt: (value) => value,\n\t};\n}\n\n// #endregion\n\n// #region ServiceClient types\n\n/**\n * Oldest version of Fluid Framework client packages to support collaborating with.\n * @remarks\n * A string in SemVer format indicating a specific version of the Fluid Framework client package, or the special case of {@link @fluidframework/runtime-utils#defaultMinVersionForCollab}.\n *\n * Collaboration with other clients is only supported when all Fluid Framework client packages used by the client have a version that is greater than or equal\n * to the specified `MinimumVersionForCollaboration`.\n *\n * Cannot exceed the version of any Fluid Framework client package in use by the local client.\n *\n * The higher the version specified, the more features and optimizations will be enabled. *\n * @privateRemarks\n * This is similar to, and a subset of, the `MinimumVersionForCollab` type in `@fluidframework/runtime-definitions`.\n * This differs in that:\n * - This avoids the shorthand \"collab\" to instead align with our preferred whole word naming convention.\n * - This is `alpha` instead of `public`.\n * - This is available to drivers due to its location in `driver-definitions` instead of `runtime-definitions`.\n * - This does not allow requesting collaboration with pre-2.0.0 versions, including the special case of `2.0.0-defaults`.\n * - Patch versions cannot be set: a given minor release is not guaranteed to be greater or equal compat wise to all patches of the previous release, so we do not enable features based on patch versions (instead fall back to the next minor if needed).\n * Therefore allowing patch versions here could be misleading and could lead to bugs.\n *\n * @input\n * @alpha\n */\nexport type MinimumVersionForCollaboration = `2.${bigint}.0`;\n\n/**\n * Strips patch and prerelease from a SemVer string, returning only the major and minor version.\n * @remarks\n * This formats a version in the same style used by {@link MinimumVersionForCollaboration}, specifying only the major and minor versions,\n * which are the portions used for feature selection.\n * @typeParam major - The major version number of `version` as a string, preserved in the result type.\n * @typeParam minor - The minor version number of `version` as a string, preserved in the result type.\n * @privateRemarks\n * This fills a similar role as cleanedPackageVersion in `@fluidframework/runtime-utils`.\n * It can be used to workaround our generated pkgVersion values being invalid `MinimumVersionForCollaboration` on CI (due to prerelease) or patched release branches.\n * @alpha\n */\nexport function featureVersion<major extends `${bigint}`, minor extends `${bigint}`>(\n\tversion: `${major}.${minor}.${bigint}-${string}` | `${major}.${minor}.${bigint}`,\n): `${major}.${minor}.0` {\n\t// The SemVer package could be used to parse this version, but it wouldn't gain us anything, and would just make it harder to determine that the down casting below is valid.\n\t// Since we have a strongly typed string input, we know exactly which formats are allowed, so we don't need its more general parsing and validation either.\n\t// If we wanted to preserve the patch or prerelease version, that would require more complex parsing and would justify using the SemVer package, but we don't need that here.\n\tconst parsed = version.split(\".\");\n\treturn `${parsed[0] as major}.${parsed[1] as minor}.0`;\n}\n\n/**\n * Options for configuring a {@link ServiceClient}.\n * @remarks\n * These are the options which apply to all services.\n *\n * Individual services will extend with additional options.\n *\n * @input\n * @alpha\n */\nexport interface ServiceOptions {\n\treadonly minVersionForCollaboration: MinimumVersionForCollaboration;\n}\n\n/**\n * A {@link RegistryKey} for a {@link DataStoreKind}.\n * @remarks\n * This is implemented by {@link DataStoreKind}, but alternative implementations can be used if needed.\n *\n * If you want lazy loading and need a key that does not eagerly load the {@link DataStoreKind}, an alternative {@link DataStoreKey} can be implemented.\n * @typeParam T - The type to expose from the {@link DataStoreKind} this key resolves to.\n * @typeParam TAll - The type covering all {@link DataStoreKind}s in the {@link Registry} this key is used with.\n * @privateRemarks\n * TODO: A built in common pattern for the lazy key case should be provided.\n * TODO: things probably break if \"adapt\" does anything except throw or return the result from the input promise.\n * @input\n * @alpha\n */\nexport type DataStoreKey<T, TAll = unknown> = RegistryKey<\n\tPromise<DataStoreKind<T>>,\n\tPromise<DataStoreKind<TAll>>\n>;\n\n/**\n * A context which has a registry and can create data stores using it.\n * @sealed\n * @alpha\n */\nexport interface DataStoreCreator {\n\t/**\n\t * Create a new detached data store `T` which can be attached to the {@link FluidContainer}.\n\t * by adding a handle to a data store or shared object which is already attached to the {@link FluidContainer}.\n\t * @remarks\n\t * `kind` will be looked up in the {@link Registry} used to create or load this {@link DataStoreCreator}.\n\t * It is up to that registry to decide how it handles unknown types, for example by throwing an exception or returning a placeholder.\n\t * @typeParam T - type implemented by the data store to expose in the result, as defined by `kind`.\n\t */\n\tcreateDataStore<T>(kind: DataStoreKey<T>): Promise<T>;\n}\n\n/**\n * A Fluid container.\n * @remarks\n * A document which can be stored to or loaded from a Fluid service using a {@link ServiceClient}.\n *\n * @typeParam TData - The type of the container's root data store, exposed via {@link FluidContainer.data}.\n * @privateRemarks\n * This will likely end up needing many of IFluidContainer's APIs, like disconnect, connectionState, events etc.\n * Before adding them though, care should be taken to consider if they can be improved or simplified.\n * For example maybe a single status enum for `detached -> attaching -> dirty -> saved -> closed` would be good.\n * Or maybe `detached -> attaching -> attached -> closed` and a timer for how long since the last unsaved change was created.\n *\n * The underlying IContainer has a lifecycle which includes both a closed and disposed state.\n * This should be avoidable: the closed but not disposed state exists so its possible to read out some state at that time.\n * We have made the close remove all the timers, so the the dispose step should be unnecessary and we can just have a single closed state.\n *\n * @sealed\n * @alpha\n */\nexport interface FluidContainer<TData = unknown>\n\textends DataStoreCreator,\n\t\tErasedBaseType<readonly [\"FluidContainer\", TData]> {\n\t/**\n\t * The unique identifier for this container within its service.\n\t * @remarks\n\t * `undefined` if the container has not yet been attached to a service.\n\t * This can be used to load another instance of this container from the service using {@link ServiceClient.loadContainer}.\n\t */\n\treadonly id?: string | undefined;\n\n\t/**\n\t * The root data store of the container.\n\t * @remarks\n\t * The type of the root data store is defined by the {@link DataStoreKind} used to create the container.\n\t */\n\treadonly data: TData;\n\n\t/**\n\t * Close the container, stopping all networking and cancelling runtime timers.\n\t *\n\t * @remarks\n\t * After calling `close()`, the container's data can still be read but no further operations can be sent.\n\t * @privateRemarks\n\t * TODO: we should document the what the expected behavior is if one tries to modify the data after close, or tries to call close multiple times.\n\t * TODO: we also likely want to have a way to detect if closed and events for on close.\n\t * TODO: ensure this truly closes all timers: it seems like we might still leak some related to the summarizer.\n\t * TODO: we should clarify how this interacts with unsaved content including inprogress summaries,\n\t * and likely also provide an async API with some options for how to handle that.\n\t */\n\tclose(): void;\n}\n\n/**\n * A Fluid container with an associated {@link ServiceClient} it can attach to.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerWithService<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * Attaches this container to the associated service client.\n\t *\n\t * The returned promise resolves once the container is attached: the container from the promise is the same one passed in as the argument.\n\t */\n\tattach(): Promise<FluidContainerAttached<TData>>;\n\n\t// This could expose access to the ServiceClient if needed.\n}\n\n/**\n * A Fluid container that has been attached to a service.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerAttached<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * {@inheritdoc FluidContainer.id}\n\t */\n\treadonly id: string;\n}\n\n/**\n * Defines a {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind} of data store, allowing creating and loading instances of it.\n * @remarks\n * A `DataStoreKind` acts as the factory and type descriptor for a category of data store:\n * it defines the `type` used to identify the data store in a {@link DataStoreRegistry},\n * and the `T` API surface that instances of that data store expose.\n *\n * Provide a `DataStoreKind` to {@link ServiceClient.(createContainer:1)} or {@link DataStoreCreator.createDataStore}\n * to create new instances, and to {@link ServiceClient.loadContainer} to load existing ones.\n *\n * A `DataStoreKind` is not constructed directly.\n * Instead, obtain one from a framework-provided factory:\n * use {@link @fluidframework/shared-object-base#defineDataStore} to define a data store which wraps a root shared object,\n * or use a more specific wrapper around that,\n * such as {@link @fluidframework/tree#defineTreeDataStore} for a {@link @fluidframework/tree#TreeView}-backed data store.\n *\n * Since it implements {@link DataStoreKey}, a `DataStoreKind` can also be used directly as the key to look\n * itself up in a {@link Registry}.\n * @typeParam T - The API surface that instances of this data store kind expose.\n * @privateRemarks\n * TODO:\n * SharedObjects should be usable as these (though putting shared objects directly in the container might need special logic).\n * Type erased {@link IFluidDataStoreFactory}.\n * @sealed\n * @alpha\n */\nexport interface DataStoreKind<out T = unknown>\n\textends DataStoreKey<T>,\n\t\tErasedBaseType<readonly [\"DataStoreKind\", T]> {}\n\n/**\n * A registry of {@link DataStoreKind}s.\n * @privateRemarks\n * TODO: unify this with SharedObjectRegistry.\n *\n * @typeParam T - The type covering all {@link DataStoreKind}s in the registry.\n * @input\n * @alpha\n */\nexport type DataStoreRegistry<out T = unknown> = Registry<Promise<DataStoreKind<T>>>;\n\n/**\n * A connection to a Fluid storage service.\n * @sealed\n * @alpha\n */\nexport interface ServiceClient {\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKind} to use for the root.\n\t * @remarks\n\t * This overload is a shorthand for a simple case of {@link ServiceClient.(createContainer:2)}\n\t * where a single item registry is produced which contains only the root.\n\t * This is usable only when the root {@link DataStoreKind} is available eagerly (e.g. not lazy loaded),\n\t * and when the container does not need a registry for creating additional data stores beyond the root.\n\t * @privateRemarks\n\t * TODO: As this is a detached container, it should be able to be created synchronously.\n\t *\n\t * TODO: Provide more general alternative to this in the form of a service-independent `createContainer` free function.\n\t * It would work with a `ServiceClient.attachContainer<T>(detached: FluidContainer<T>): Promise<FluidContainerAttached<T>>`\n\t * which returns a promise that resolves once the detached container has been attached\n\t * (pointing to the same container object, but with the new type).\n\t *\n\t * Challenges:\n\t *\n\t * Currently the service must be provided at creation time because `IContainer.attach` does not accept a service client,\n\t * making it unclear whether a truly service-independent path is feasible in the near term.\n\t */\n\tcreateContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKey} used to look up the root's {@link DataStoreKind} from `registry`.\n\t * @param registry - The {@link DataStoreRegistry} supplying the {@link DataStoreKind} for the root and any other data stores the container may need to create.\n\t * @remarks\n\t * Use this overload when the root {@link DataStoreKind} is not available eagerly (e.g. for lazy loading),\n\t * or when the container needs a registry for creating additional data stores beyond the root.\n\t */\n\tcreateContainer<T>(\n\t\troot: DataStoreKey<T>,\n\t\tregistry: DataStoreRegistry,\n\t): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * A shorthand for {@link ServiceClient.(createContainer:1)} followed by {@link FluidContainerWithService.attach}.\n\t * @remarks\n\t * Due to current implementation limitations making container creation async and service specific,\n\t * creating then attaching one is a bit verbose with two awaits that are messy to include inline.\n\t * This provides a convenient way to create and attach a container in a single step.\n\t * @privateRemarks\n\t * TODO: We should fix ergonomics issues that make this helpful,\n\t * then remove (or deprecate) this method in favor of `service.attach(createContainer(root))` as a better orthogonalized API.\n\t * See private remarks on {@link ServiceClient.(createContainer:1)}.\n\t */\n\tcreateAttachedContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerAttached<T>>;\n\n\t/**\n\t * A shorthand for {@link ServiceClient.(createContainer:2)} followed by {@link FluidContainerWithService.attach}.\n\t * @remarks\n\t * Due to current implementation limitations making container creation async and service specific,\n\t * creating then attaching one is a bit verbose with two awaits that are messy to include inline.\n\t * This provides a convenient way to create and attach a container in a single step.\n\t */\n\tcreateAttachedContainer<T>(\n\t\troot: DataStoreKey<T>,\n\t\tregistry: DataStoreRegistry,\n\t): Promise<FluidContainerAttached<T>>;\n\n\t/**\n\t * Loads an existing container from the service.\n\t * @typeParam T - The type of the container's root data store.\n\t * @param id - The unique identifier of the container to load.\n\t * @param root - The {@link DataStoreKind} for the root, or a registry which will be used to look up the root based on its type.\n\t *\n\t * @throws a {@link @fluidframework/telemetry-utils#UsageError} if the DataStoreKind's type (either the root directly or looked up from the registry) does not match the type of the root data store in the container.\n\t *\n\t * @privateRemarks\n\t * The ability to provide a registry here means that it's possible to:\n\t * 1. Load a container which might have a few different possible roots, for example because of versioning.\n\t * 2. Generate the DataStoreKind on demand based on the type: this approach could be used for things like debug tools which can load any possible container.\n\t * 3. Generating the DataStoreKind if the type is unrecognized, for example to provide a placeholder which might support some minimal functionality (like debug inspection, and summary).\n\t *\n\t * The ability to provide just a single DataStoreKind<T> is purely a convenience to make it cleaner to use this in simple cases.\n\t */\n\tloadContainer<T>(\n\t\tid: string,\n\t\troot: DataStoreKind<T> | DataStoreRegistry<T>,\n\t): Promise<FluidContainerAttached<T>>;\n}\n\n// #endregion\n"]}
|
package/lib/serviceClient.d.ts
CHANGED
|
@@ -324,6 +324,26 @@ export interface ServiceClient {
|
|
|
324
324
|
* or when the container needs a registry for creating additional data stores beyond the root.
|
|
325
325
|
*/
|
|
326
326
|
createContainer<T>(root: DataStoreKey<T>, registry: DataStoreRegistry): Promise<FluidContainerWithService<T>>;
|
|
327
|
+
/**
|
|
328
|
+
* A shorthand for {@link ServiceClient.(createContainer:1)} followed by {@link FluidContainerWithService.attach}.
|
|
329
|
+
* @remarks
|
|
330
|
+
* Due to current implementation limitations making container creation async and service specific,
|
|
331
|
+
* creating then attaching one is a bit verbose with two awaits that are messy to include inline.
|
|
332
|
+
* This provides a convenient way to create and attach a container in a single step.
|
|
333
|
+
* @privateRemarks
|
|
334
|
+
* TODO: We should fix ergonomics issues that make this helpful,
|
|
335
|
+
* then remove (or deprecate) this method in favor of `service.attach(createContainer(root))` as a better orthogonalized API.
|
|
336
|
+
* See private remarks on {@link ServiceClient.(createContainer:1)}.
|
|
337
|
+
*/
|
|
338
|
+
createAttachedContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerAttached<T>>;
|
|
339
|
+
/**
|
|
340
|
+
* A shorthand for {@link ServiceClient.(createContainer:2)} followed by {@link FluidContainerWithService.attach}.
|
|
341
|
+
* @remarks
|
|
342
|
+
* Due to current implementation limitations making container creation async and service specific,
|
|
343
|
+
* creating then attaching one is a bit verbose with two awaits that are messy to include inline.
|
|
344
|
+
* This provides a convenient way to create and attach a container in a single step.
|
|
345
|
+
*/
|
|
346
|
+
createAttachedContainer<T>(root: DataStoreKey<T>, registry: DataStoreRegistry): Promise<FluidContainerAttached<T>>;
|
|
327
347
|
/**
|
|
328
348
|
* Loads an existing container from the service.
|
|
329
349
|
* @typeParam T - The type of the container's root data store.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceClient.d.ts","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"serviceClient.d.ts","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":"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"}
|
package/lib/serviceClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceClient.js","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsFH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC/B,QAAuB,EACvB,GAA2B;IAE3B,OAAO,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAI,IAAY;IACrD,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;KACvB,CAAC;AACH,CAAC;AAgCD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAgF;IAEhF,6KAA6K;IAC7K,2JAA2J;IAC3J,6KAA6K;IAC7K,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAU,IAAI,MAAM,CAAC,CAAC,CAAU,IAAI,CAAC;AACxD,CAAC;AAiPD,aAAa","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ErasedBaseType } from \"@fluidframework/core-interfaces/internal\";\n\n/**\n * This file defines the external facing API for the {@link ServiceClient} and related types.\n *\n * It provides an API surface at a similar abstraction level to aqueduct and fluid-static, but is intended to be a replacement for those which solves several problems with them.\n * Mainly it strives to have the encapsulation of implementation details (including all legacy APIs from aqueduct and lower level internals) like fluid-static\n * while being both more flexible and simpler.\n *\n * This aims to be the cleanest practical way to build applications on the Fluid Framework Client.\n * There are however several known cases where the API quality was sacrificed to ease initial implementation,\n * since some of the unification desired in this API's design are not yet implemented in the underlying Fluid Framework Client code or require additional work to implement.\n * These cases are called out with TODOs in this file.\n * These should be considered and addressed before stabilizing this API past alpha.\n *\n * All code interacting through this API surface within a single client must avoid using multiple copies of any Fluid Framework client package (at the same or different versions).\n * This mirrors the `@public` \"declarative model\" APIs and is a deliberate simplification of what is allowed in the legacy API surface.\n * It is enforced best-effort only: `@sealed` nominal erased types catch many mismatches at compile time, and factory identity checks throw a UsageError (\"Conflicting ... with same type\") at run time, but the checking is not exhaustive.\n * See `LayerCompatibilityUnified.md` for the full policy, rationale, and failure signatures.\n *\n * TODO:\n * Before stabilizing any of this past beta, evaluate whether this single-copy requirement must be relaxed, and if so how.\n * Whatever rule is chosen (relaxed or not) should be enforced at both compile time and run time as much as possible.\n *\n * TODO:\n * Fault isolation should be considered in this API design.\n * When are exceptions recoverable and how?\n * Likely we can fault isolate exceptions to containers in most cases,\n * and containers can indicate their status by being closed or disposed.\n * Non fatal errors should not be exceptions.\n */\n\n// #region Registry types\n\n/**\n * A collection of entries looked up by a `type` string.\n * @remarks\n * Use of a function for this allows a few things that most collections would not:\n * 1. It's possible to generate placeholder / error values on demand.\n * 2. It makes loading from some external registry on demand practical.\n * 3. The lookup can throw an exception if appropriate (this would typically indicate a bug and produce a fatal error).\n * 4. Generation of values can be lazy, and even asynchronous if `T` allows for a promise.\n *\n * This flexibility lets the implementer decide how to handle requests for unknown types.\n * They can produce placeholders, assert, fall back to a generic implementation etc.\n * @typeParam T - The type of entry produced for any given `type` string.\n * @input\n * @alpha\n */\nexport type Registry<T> = (type: string) => T;\n\n/**\n * A strongly typed key for a {@link Registry}.\n * Use with {@link lookupInRegistry}.\n * @remarks\n * Used to look up a `TIn` in a `Registry<TIn>`, and produce a `TOut` from it.\n * @typeParam TOut - The type produced by {@link RegistryKey.adapt} from a looked-up entry.\n * @typeParam TIn - The type of the entries in the {@link Registry} this key is used with.\n * @privateRemarks\n * This is currently input and sealed, meaning effectively type erased since the design might change.\n * @input\n * @sealed\n * @alpha\n */\nexport interface RegistryKey<TOut, TIn = unknown> {\n\t/**\n\t * Identifier to provide to the {@link Registry}.\n\t */\n\treadonly type: string;\n\n\t/**\n\t * Convert a value from the registry to the desired output type.\n\t * @remarks\n\t * How this is done is up to the implementation.\n\t *\n\t * This might be a type guard which throws if the input is not valid.\n\t * Or it could be a conversion, an identity function, or something else.\n\t *\n\t * @param value - The value from the registry.\n\t * @returns The converted value.\n\t */\n\tadapt(value: TIn): TOut;\n}\n\n/**\n * Lookup an entry in a {@link Registry} using a {@link RegistryKey}.\n * @typeParam TOut - The type produced from the looked-up entry.\n * @typeParam TIn - The type of the entries in `registry`.\n * @alpha\n */\nexport function lookupInRegistry<TOut, TIn>(\n\tregistry: Registry<TIn>,\n\tkey: RegistryKey<TOut, TIn>,\n): TOut {\n\treturn key.adapt(registry(key.type));\n}\n\n/**\n * Creates a simple {@link RegistryKey} which does no type conversion.\n * @typeParam T - The type of the registry entry, which is returned unchanged by the key.\n * @alpha\n */\nexport function createBasicRegistryKey<T>(type: string): RegistryKey<T, T> {\n\treturn {\n\t\ttype,\n\t\tadapt: (value) => value,\n\t};\n}\n\n// #endregion\n\n// #region ServiceClient types\n\n/**\n * Oldest version of Fluid Framework client packages to support collaborating with.\n * @remarks\n * A string in SemVer format indicating a specific version of the Fluid Framework client package, or the special case of {@link @fluidframework/runtime-utils#defaultMinVersionForCollab}.\n *\n * Collaboration with other clients is only supported when all Fluid Framework client packages used by the client have a version that is greater than or equal\n * to the specified `MinimumVersionForCollaboration`.\n *\n * Cannot exceed the version of any Fluid Framework client package in use by the local client.\n *\n * The higher the version specified, the more features and optimizations will be enabled. *\n * @privateRemarks\n * This is similar to, and a subset of, the `MinimumVersionForCollab` type in `@fluidframework/runtime-definitions`.\n * This differs in that:\n * - This avoids the shorthand \"collab\" to instead align with our preferred whole word naming convention.\n * - This is `alpha` instead of `public`.\n * - This is available to drivers due to its location in `driver-definitions` instead of `runtime-definitions`.\n * - This does not allow requesting collaboration with pre-2.0.0 versions, including the special case of `2.0.0-defaults`.\n * - Patch versions cannot be set: a given minor release is not guaranteed to be greater or equal compat wise to all patches of the previous release, so we do not enable features based on patch versions (instead fall back to the next minor if needed).\n * Therefore allowing patch versions here could be misleading and could lead to bugs.\n *\n * @input\n * @alpha\n */\nexport type MinimumVersionForCollaboration = `2.${bigint}.0`;\n\n/**\n * Strips patch and prerelease from a SemVer string, returning only the major and minor version.\n * @remarks\n * This formats a version in the same style used by {@link MinimumVersionForCollaboration}, specifying only the major and minor versions,\n * which are the portions used for feature selection.\n * @typeParam major - The major version number of `version` as a string, preserved in the result type.\n * @typeParam minor - The minor version number of `version` as a string, preserved in the result type.\n * @privateRemarks\n * This fills a similar role as cleanedPackageVersion in `@fluidframework/runtime-utils`.\n * It can be used to workaround our generated pkgVersion values being invalid `MinimumVersionForCollaboration` on CI (due to prerelease) or patched release branches.\n * @alpha\n */\nexport function featureVersion<major extends `${bigint}`, minor extends `${bigint}`>(\n\tversion: `${major}.${minor}.${bigint}-${string}` | `${major}.${minor}.${bigint}`,\n): `${major}.${minor}.0` {\n\t// The SemVer package could be used to parse this version, but it wouldn't gain us anything, and would just make it harder to determine that the down casting below is valid.\n\t// Since we have a strongly typed string input, we know exactly which formats are allowed, so we don't need its more general parsing and validation either.\n\t// If we wanted to preserve the patch or prerelease version, that would require more complex parsing and would justify using the SemVer package, but we don't need that here.\n\tconst parsed = version.split(\".\");\n\treturn `${parsed[0] as major}.${parsed[1] as minor}.0`;\n}\n\n/**\n * Options for configuring a {@link ServiceClient}.\n * @remarks\n * These are the options which apply to all services.\n *\n * Individual services will extend with additional options.\n *\n * @input\n * @alpha\n */\nexport interface ServiceOptions {\n\treadonly minVersionForCollaboration: MinimumVersionForCollaboration;\n}\n\n/**\n * A {@link RegistryKey} for a {@link DataStoreKind}.\n * @remarks\n * This is implemented by {@link DataStoreKind}, but alternative implementations can be used if needed.\n *\n * If you want lazy loading and need a key that does not eagerly load the {@link DataStoreKind}, an alternative {@link DataStoreKey} can be implemented.\n * @typeParam T - The type to expose from the {@link DataStoreKind} this key resolves to.\n * @typeParam TAll - The type covering all {@link DataStoreKind}s in the {@link Registry} this key is used with.\n * @privateRemarks\n * TODO: A built in common pattern for the lazy key case should be provided.\n * TODO: things probably break if \"adapt\" does anything except throw or return the result from the input promise.\n * @input\n * @alpha\n */\nexport type DataStoreKey<T, TAll = unknown> = RegistryKey<\n\tPromise<DataStoreKind<T>>,\n\tPromise<DataStoreKind<TAll>>\n>;\n\n/**\n * A context which has a registry and can create data stores using it.\n * @sealed\n * @alpha\n */\nexport interface DataStoreCreator {\n\t/**\n\t * Create a new detached data store `T` which can be attached to the {@link FluidContainer}.\n\t * by adding a handle to a data store or shared object which is already attached to the {@link FluidContainer}.\n\t * @remarks\n\t * `kind` will be looked up in the {@link Registry} used to create or load this {@link DataStoreCreator}.\n\t * It is up to that registry to decide how it handles unknown types, for example by throwing an exception or returning a placeholder.\n\t * @typeParam T - type implemented by the data store to expose in the result, as defined by `kind`.\n\t */\n\tcreateDataStore<T>(kind: DataStoreKey<T>): Promise<T>;\n}\n\n/**\n * A Fluid container.\n * @remarks\n * A document which can be stored to or loaded from a Fluid service using a {@link ServiceClient}.\n *\n * @typeParam TData - The type of the container's root data store, exposed via {@link FluidContainer.data}.\n * @privateRemarks\n * This will likely end up needing many of IFluidContainer's APIs, like disconnect, connectionState, events etc.\n * Before adding them though, care should be taken to consider if they can be improved or simplified.\n * For example maybe a single status enum for `detached -> attaching -> dirty -> saved -> closed` would be good.\n * Or maybe `detached -> attaching -> attached -> closed` and a timer for how long since the last unsaved change was created.\n *\n * The underlying IContainer has a lifecycle which includes both a closed and disposed state.\n * This should be avoidable: the closed but not disposed state exists so its possible to read out some state at that time.\n * We have made the close remove all the timers, so the the dispose step should be unnecessary and we can just have a single closed state.\n *\n * @sealed\n * @alpha\n */\nexport interface FluidContainer<TData = unknown>\n\textends DataStoreCreator,\n\t\tErasedBaseType<readonly [\"FluidContainer\", TData]> {\n\t/**\n\t * The unique identifier for this container within its service.\n\t * @remarks\n\t * `undefined` if the container has not yet been attached to a service.\n\t * This can be used to load another instance of this container from the service using {@link ServiceClient.loadContainer}.\n\t */\n\treadonly id?: string | undefined;\n\n\t/**\n\t * The root data store of the container.\n\t * @remarks\n\t * The type of the root data store is defined by the {@link DataStoreKind} used to create the container.\n\t */\n\treadonly data: TData;\n\n\t/**\n\t * Close the container, stopping all networking and cancelling runtime timers.\n\t *\n\t * @remarks\n\t * After calling `close()`, the container's data can still be read but no further operations can be sent.\n\t * @privateRemarks\n\t * TODO: we should document the what the expected behavior is if one tries to modify the data after close, or tries to call close multiple times.\n\t * TODO: we also likely want to have a way to detect if closed and events for on close.\n\t * TODO: ensure this truly closes all timers: it seems like we might still leak some related to the summarizer.\n\t * TODO: we should clarify how this interacts with unsaved content including inprogress summaries,\n\t * and likely also provide an async API with some options for how to handle that.\n\t */\n\tclose(): void;\n}\n\n/**\n * A Fluid container with an associated {@link ServiceClient} it can attach to.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerWithService<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * Attaches this container to the associated service client.\n\t *\n\t * The returned promise resolves once the container is attached: the container from the promise is the same one passed in as the argument.\n\t */\n\tattach(): Promise<FluidContainerAttached<TData>>;\n\n\t// This could expose access to the ServiceClient if needed.\n}\n\n/**\n * A Fluid container that has been attached to a service.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerAttached<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * {@inheritdoc FluidContainer.id}\n\t */\n\treadonly id: string;\n}\n\n/**\n * Defines a {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind} of data store, allowing creating and loading instances of it.\n * @remarks\n * A `DataStoreKind` acts as the factory and type descriptor for a category of data store:\n * it defines the `type` used to identify the data store in a {@link DataStoreRegistry},\n * and the `T` API surface that instances of that data store expose.\n *\n * Provide a `DataStoreKind` to {@link ServiceClient.(createContainer:1)} or {@link DataStoreCreator.createDataStore}\n * to create new instances, and to {@link ServiceClient.loadContainer} to load existing ones.\n *\n * A `DataStoreKind` is not constructed directly.\n * Instead, obtain one from a framework-provided factory:\n * use {@link @fluidframework/shared-object-base#defineDataStore} to define a data store which wraps a root shared object,\n * or use a more specific wrapper around that,\n * such as {@link @fluidframework/tree#defineTreeDataStore} for a {@link @fluidframework/tree#TreeView}-backed data store.\n *\n * Since it implements {@link DataStoreKey}, a `DataStoreKind` can also be used directly as the key to look\n * itself up in a {@link Registry}.\n * @typeParam T - The API surface that instances of this data store kind expose.\n * @privateRemarks\n * TODO:\n * SharedObjects should be usable as these (though putting shared objects directly in the container might need special logic).\n * Type erased {@link IFluidDataStoreFactory}.\n * @sealed\n * @alpha\n */\nexport interface DataStoreKind<out T = unknown>\n\textends DataStoreKey<T>,\n\t\tErasedBaseType<readonly [\"DataStoreKind\", T]> {}\n\n/**\n * A registry of {@link DataStoreKind}s.\n * @privateRemarks\n * TODO: unify this with SharedObjectRegistry.\n *\n * @typeParam T - The type covering all {@link DataStoreKind}s in the registry.\n * @input\n * @alpha\n */\nexport type DataStoreRegistry<out T = unknown> = Registry<Promise<DataStoreKind<T>>>;\n\n/**\n * A connection to a Fluid storage service.\n * @sealed\n * @alpha\n */\nexport interface ServiceClient {\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKind} to use for the root.\n\t * @remarks\n\t * This overload is a shorthand for a simple case of {@link ServiceClient.(createContainer:2)}\n\t * where a single item registry is produced which contains only the root.\n\t * This is usable only when the root {@link DataStoreKind} is available eagerly (e.g. not lazy loaded),\n\t * and when the container does not need a registry for creating additional data stores beyond the root.\n\t * @privateRemarks\n\t * TODO: As this is a detached container, it should be able to be created synchronously.\n\t *\n\t * TODO: Provide more general alternative to this in the form of a service-independent `createContainer` free function.\n\t * It would work with a `ServiceClient.attachContainer<T>(detached: FluidContainer<T>): Promise<FluidContainerAttached<T>>`\n\t * which returns a promise that resolves once the detached container has been attached\n\t * (pointing to the same container object, but with the new type).\n\t *\n\t * Challenges:\n\t *\n\t * Currently the service must be provided at creation time because `IContainer.attach` does not accept a service client,\n\t * making it unclear whether a truly service-independent path is feasible in the near term.\n\t */\n\tcreateContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKey} used to look up the root's {@link DataStoreKind} from `registry`.\n\t * @param registry - The {@link DataStoreRegistry} supplying the {@link DataStoreKind} for the root and any other data stores the container may need to create.\n\t * @remarks\n\t * Use this overload when the root {@link DataStoreKind} is not available eagerly (e.g. for lazy loading),\n\t * or when the container needs a registry for creating additional data stores beyond the root.\n\t */\n\tcreateContainer<T>(\n\t\troot: DataStoreKey<T>,\n\t\tregistry: DataStoreRegistry,\n\t): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * Loads an existing container from the service.\n\t * @typeParam T - The type of the container's root data store.\n\t * @param id - The unique identifier of the container to load.\n\t * @param root - The {@link DataStoreKind} for the root, or a registry which will be used to look up the root based on its type.\n\t *\n\t * @throws a {@link @fluidframework/telemetry-utils#UsageError} if the DataStoreKind's type (either the root directly or looked up from the registry) does not match the type of the root data store in the container.\n\t *\n\t * @privateRemarks\n\t * The ability to provide a registry here means that it's possible to:\n\t * 1. Load a container which might have a few different possible roots, for example because of versioning.\n\t * 2. Generate the DataStoreKind on demand based on the type: this approach could be used for things like debug tools which can load any possible container.\n\t * 3. Generating the DataStoreKind if the type is unrecognized, for example to provide a placeholder which might support some minimal functionality (like debug inspection, and summary).\n\t *\n\t * The ability to provide just a single DataStoreKind<T> is purely a convenience to make it cleaner to use this in simple cases.\n\t */\n\tloadContainer<T>(\n\t\tid: string,\n\t\troot: DataStoreKind<T> | DataStoreRegistry<T>,\n\t): Promise<FluidContainerAttached<T>>;\n}\n\n// #endregion\n"]}
|
|
1
|
+
{"version":3,"file":"serviceClient.js","sourceRoot":"","sources":["../src/serviceClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsFH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC/B,QAAuB,EACvB,GAA2B;IAE3B,OAAO,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAI,IAAY;IACrD,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;KACvB,CAAC;AACH,CAAC;AAgCD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC7B,OAAgF;IAEhF,6KAA6K;IAC7K,2JAA2J;IAC3J,6KAA6K;IAC7K,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAU,IAAI,MAAM,CAAC,CAAC,CAAU,IAAI,CAAC;AACxD,CAAC;AA0QD,aAAa","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ErasedBaseType } from \"@fluidframework/core-interfaces/internal\";\n\n/**\n * This file defines the external facing API for the {@link ServiceClient} and related types.\n *\n * It provides an API surface at a similar abstraction level to aqueduct and fluid-static, but is intended to be a replacement for those which solves several problems with them.\n * Mainly it strives to have the encapsulation of implementation details (including all legacy APIs from aqueduct and lower level internals) like fluid-static\n * while being both more flexible and simpler.\n *\n * This aims to be the cleanest practical way to build applications on the Fluid Framework Client.\n * There are however several known cases where the API quality was sacrificed to ease initial implementation,\n * since some of the unification desired in this API's design are not yet implemented in the underlying Fluid Framework Client code or require additional work to implement.\n * These cases are called out with TODOs in this file.\n * These should be considered and addressed before stabilizing this API past alpha.\n *\n * All code interacting through this API surface within a single client must avoid using multiple copies of any Fluid Framework client package (at the same or different versions).\n * This mirrors the `@public` \"declarative model\" APIs and is a deliberate simplification of what is allowed in the legacy API surface.\n * It is enforced best-effort only: `@sealed` nominal erased types catch many mismatches at compile time, and factory identity checks throw a UsageError (\"Conflicting ... with same type\") at run time, but the checking is not exhaustive.\n * See `LayerCompatibilityUnified.md` for the full policy, rationale, and failure signatures.\n *\n * TODO:\n * Before stabilizing any of this past beta, evaluate whether this single-copy requirement must be relaxed, and if so how.\n * Whatever rule is chosen (relaxed or not) should be enforced at both compile time and run time as much as possible.\n *\n * TODO:\n * Fault isolation should be considered in this API design.\n * When are exceptions recoverable and how?\n * Likely we can fault isolate exceptions to containers in most cases,\n * and containers can indicate their status by being closed or disposed.\n * Non fatal errors should not be exceptions.\n */\n\n// #region Registry types\n\n/**\n * A collection of entries looked up by a `type` string.\n * @remarks\n * Use of a function for this allows a few things that most collections would not:\n * 1. It's possible to generate placeholder / error values on demand.\n * 2. It makes loading from some external registry on demand practical.\n * 3. The lookup can throw an exception if appropriate (this would typically indicate a bug and produce a fatal error).\n * 4. Generation of values can be lazy, and even asynchronous if `T` allows for a promise.\n *\n * This flexibility lets the implementer decide how to handle requests for unknown types.\n * They can produce placeholders, assert, fall back to a generic implementation etc.\n * @typeParam T - The type of entry produced for any given `type` string.\n * @input\n * @alpha\n */\nexport type Registry<T> = (type: string) => T;\n\n/**\n * A strongly typed key for a {@link Registry}.\n * Use with {@link lookupInRegistry}.\n * @remarks\n * Used to look up a `TIn` in a `Registry<TIn>`, and produce a `TOut` from it.\n * @typeParam TOut - The type produced by {@link RegistryKey.adapt} from a looked-up entry.\n * @typeParam TIn - The type of the entries in the {@link Registry} this key is used with.\n * @privateRemarks\n * This is currently input and sealed, meaning effectively type erased since the design might change.\n * @input\n * @sealed\n * @alpha\n */\nexport interface RegistryKey<TOut, TIn = unknown> {\n\t/**\n\t * Identifier to provide to the {@link Registry}.\n\t */\n\treadonly type: string;\n\n\t/**\n\t * Convert a value from the registry to the desired output type.\n\t * @remarks\n\t * How this is done is up to the implementation.\n\t *\n\t * This might be a type guard which throws if the input is not valid.\n\t * Or it could be a conversion, an identity function, or something else.\n\t *\n\t * @param value - The value from the registry.\n\t * @returns The converted value.\n\t */\n\tadapt(value: TIn): TOut;\n}\n\n/**\n * Lookup an entry in a {@link Registry} using a {@link RegistryKey}.\n * @typeParam TOut - The type produced from the looked-up entry.\n * @typeParam TIn - The type of the entries in `registry`.\n * @alpha\n */\nexport function lookupInRegistry<TOut, TIn>(\n\tregistry: Registry<TIn>,\n\tkey: RegistryKey<TOut, TIn>,\n): TOut {\n\treturn key.adapt(registry(key.type));\n}\n\n/**\n * Creates a simple {@link RegistryKey} which does no type conversion.\n * @typeParam T - The type of the registry entry, which is returned unchanged by the key.\n * @alpha\n */\nexport function createBasicRegistryKey<T>(type: string): RegistryKey<T, T> {\n\treturn {\n\t\ttype,\n\t\tadapt: (value) => value,\n\t};\n}\n\n// #endregion\n\n// #region ServiceClient types\n\n/**\n * Oldest version of Fluid Framework client packages to support collaborating with.\n * @remarks\n * A string in SemVer format indicating a specific version of the Fluid Framework client package, or the special case of {@link @fluidframework/runtime-utils#defaultMinVersionForCollab}.\n *\n * Collaboration with other clients is only supported when all Fluid Framework client packages used by the client have a version that is greater than or equal\n * to the specified `MinimumVersionForCollaboration`.\n *\n * Cannot exceed the version of any Fluid Framework client package in use by the local client.\n *\n * The higher the version specified, the more features and optimizations will be enabled. *\n * @privateRemarks\n * This is similar to, and a subset of, the `MinimumVersionForCollab` type in `@fluidframework/runtime-definitions`.\n * This differs in that:\n * - This avoids the shorthand \"collab\" to instead align with our preferred whole word naming convention.\n * - This is `alpha` instead of `public`.\n * - This is available to drivers due to its location in `driver-definitions` instead of `runtime-definitions`.\n * - This does not allow requesting collaboration with pre-2.0.0 versions, including the special case of `2.0.0-defaults`.\n * - Patch versions cannot be set: a given minor release is not guaranteed to be greater or equal compat wise to all patches of the previous release, so we do not enable features based on patch versions (instead fall back to the next minor if needed).\n * Therefore allowing patch versions here could be misleading and could lead to bugs.\n *\n * @input\n * @alpha\n */\nexport type MinimumVersionForCollaboration = `2.${bigint}.0`;\n\n/**\n * Strips patch and prerelease from a SemVer string, returning only the major and minor version.\n * @remarks\n * This formats a version in the same style used by {@link MinimumVersionForCollaboration}, specifying only the major and minor versions,\n * which are the portions used for feature selection.\n * @typeParam major - The major version number of `version` as a string, preserved in the result type.\n * @typeParam minor - The minor version number of `version` as a string, preserved in the result type.\n * @privateRemarks\n * This fills a similar role as cleanedPackageVersion in `@fluidframework/runtime-utils`.\n * It can be used to workaround our generated pkgVersion values being invalid `MinimumVersionForCollaboration` on CI (due to prerelease) or patched release branches.\n * @alpha\n */\nexport function featureVersion<major extends `${bigint}`, minor extends `${bigint}`>(\n\tversion: `${major}.${minor}.${bigint}-${string}` | `${major}.${minor}.${bigint}`,\n): `${major}.${minor}.0` {\n\t// The SemVer package could be used to parse this version, but it wouldn't gain us anything, and would just make it harder to determine that the down casting below is valid.\n\t// Since we have a strongly typed string input, we know exactly which formats are allowed, so we don't need its more general parsing and validation either.\n\t// If we wanted to preserve the patch or prerelease version, that would require more complex parsing and would justify using the SemVer package, but we don't need that here.\n\tconst parsed = version.split(\".\");\n\treturn `${parsed[0] as major}.${parsed[1] as minor}.0`;\n}\n\n/**\n * Options for configuring a {@link ServiceClient}.\n * @remarks\n * These are the options which apply to all services.\n *\n * Individual services will extend with additional options.\n *\n * @input\n * @alpha\n */\nexport interface ServiceOptions {\n\treadonly minVersionForCollaboration: MinimumVersionForCollaboration;\n}\n\n/**\n * A {@link RegistryKey} for a {@link DataStoreKind}.\n * @remarks\n * This is implemented by {@link DataStoreKind}, but alternative implementations can be used if needed.\n *\n * If you want lazy loading and need a key that does not eagerly load the {@link DataStoreKind}, an alternative {@link DataStoreKey} can be implemented.\n * @typeParam T - The type to expose from the {@link DataStoreKind} this key resolves to.\n * @typeParam TAll - The type covering all {@link DataStoreKind}s in the {@link Registry} this key is used with.\n * @privateRemarks\n * TODO: A built in common pattern for the lazy key case should be provided.\n * TODO: things probably break if \"adapt\" does anything except throw or return the result from the input promise.\n * @input\n * @alpha\n */\nexport type DataStoreKey<T, TAll = unknown> = RegistryKey<\n\tPromise<DataStoreKind<T>>,\n\tPromise<DataStoreKind<TAll>>\n>;\n\n/**\n * A context which has a registry and can create data stores using it.\n * @sealed\n * @alpha\n */\nexport interface DataStoreCreator {\n\t/**\n\t * Create a new detached data store `T` which can be attached to the {@link FluidContainer}.\n\t * by adding a handle to a data store or shared object which is already attached to the {@link FluidContainer}.\n\t * @remarks\n\t * `kind` will be looked up in the {@link Registry} used to create or load this {@link DataStoreCreator}.\n\t * It is up to that registry to decide how it handles unknown types, for example by throwing an exception or returning a placeholder.\n\t * @typeParam T - type implemented by the data store to expose in the result, as defined by `kind`.\n\t */\n\tcreateDataStore<T>(kind: DataStoreKey<T>): Promise<T>;\n}\n\n/**\n * A Fluid container.\n * @remarks\n * A document which can be stored to or loaded from a Fluid service using a {@link ServiceClient}.\n *\n * @typeParam TData - The type of the container's root data store, exposed via {@link FluidContainer.data}.\n * @privateRemarks\n * This will likely end up needing many of IFluidContainer's APIs, like disconnect, connectionState, events etc.\n * Before adding them though, care should be taken to consider if they can be improved or simplified.\n * For example maybe a single status enum for `detached -> attaching -> dirty -> saved -> closed` would be good.\n * Or maybe `detached -> attaching -> attached -> closed` and a timer for how long since the last unsaved change was created.\n *\n * The underlying IContainer has a lifecycle which includes both a closed and disposed state.\n * This should be avoidable: the closed but not disposed state exists so its possible to read out some state at that time.\n * We have made the close remove all the timers, so the the dispose step should be unnecessary and we can just have a single closed state.\n *\n * @sealed\n * @alpha\n */\nexport interface FluidContainer<TData = unknown>\n\textends DataStoreCreator,\n\t\tErasedBaseType<readonly [\"FluidContainer\", TData]> {\n\t/**\n\t * The unique identifier for this container within its service.\n\t * @remarks\n\t * `undefined` if the container has not yet been attached to a service.\n\t * This can be used to load another instance of this container from the service using {@link ServiceClient.loadContainer}.\n\t */\n\treadonly id?: string | undefined;\n\n\t/**\n\t * The root data store of the container.\n\t * @remarks\n\t * The type of the root data store is defined by the {@link DataStoreKind} used to create the container.\n\t */\n\treadonly data: TData;\n\n\t/**\n\t * Close the container, stopping all networking and cancelling runtime timers.\n\t *\n\t * @remarks\n\t * After calling `close()`, the container's data can still be read but no further operations can be sent.\n\t * @privateRemarks\n\t * TODO: we should document the what the expected behavior is if one tries to modify the data after close, or tries to call close multiple times.\n\t * TODO: we also likely want to have a way to detect if closed and events for on close.\n\t * TODO: ensure this truly closes all timers: it seems like we might still leak some related to the summarizer.\n\t * TODO: we should clarify how this interacts with unsaved content including inprogress summaries,\n\t * and likely also provide an async API with some options for how to handle that.\n\t */\n\tclose(): void;\n}\n\n/**\n * A Fluid container with an associated {@link ServiceClient} it can attach to.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerWithService<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * Attaches this container to the associated service client.\n\t *\n\t * The returned promise resolves once the container is attached: the container from the promise is the same one passed in as the argument.\n\t */\n\tattach(): Promise<FluidContainerAttached<TData>>;\n\n\t// This could expose access to the ServiceClient if needed.\n}\n\n/**\n * A Fluid container that has been attached to a service.\n * @typeParam TData - The type of the container's root data store.\n * @sealed\n * @alpha\n */\nexport interface FluidContainerAttached<TData = unknown> extends FluidContainer<TData> {\n\t/**\n\t * {@inheritdoc FluidContainer.id}\n\t */\n\treadonly id: string;\n}\n\n/**\n * Defines a {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind} of data store, allowing creating and loading instances of it.\n * @remarks\n * A `DataStoreKind` acts as the factory and type descriptor for a category of data store:\n * it defines the `type` used to identify the data store in a {@link DataStoreRegistry},\n * and the `T` API surface that instances of that data store expose.\n *\n * Provide a `DataStoreKind` to {@link ServiceClient.(createContainer:1)} or {@link DataStoreCreator.createDataStore}\n * to create new instances, and to {@link ServiceClient.loadContainer} to load existing ones.\n *\n * A `DataStoreKind` is not constructed directly.\n * Instead, obtain one from a framework-provided factory:\n * use {@link @fluidframework/shared-object-base#defineDataStore} to define a data store which wraps a root shared object,\n * or use a more specific wrapper around that,\n * such as {@link @fluidframework/tree#defineTreeDataStore} for a {@link @fluidframework/tree#TreeView}-backed data store.\n *\n * Since it implements {@link DataStoreKey}, a `DataStoreKind` can also be used directly as the key to look\n * itself up in a {@link Registry}.\n * @typeParam T - The API surface that instances of this data store kind expose.\n * @privateRemarks\n * TODO:\n * SharedObjects should be usable as these (though putting shared objects directly in the container might need special logic).\n * Type erased {@link IFluidDataStoreFactory}.\n * @sealed\n * @alpha\n */\nexport interface DataStoreKind<out T = unknown>\n\textends DataStoreKey<T>,\n\t\tErasedBaseType<readonly [\"DataStoreKind\", T]> {}\n\n/**\n * A registry of {@link DataStoreKind}s.\n * @privateRemarks\n * TODO: unify this with SharedObjectRegistry.\n *\n * @typeParam T - The type covering all {@link DataStoreKind}s in the registry.\n * @input\n * @alpha\n */\nexport type DataStoreRegistry<out T = unknown> = Registry<Promise<DataStoreKind<T>>>;\n\n/**\n * A connection to a Fluid storage service.\n * @sealed\n * @alpha\n */\nexport interface ServiceClient {\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKind} to use for the root.\n\t * @remarks\n\t * This overload is a shorthand for a simple case of {@link ServiceClient.(createContainer:2)}\n\t * where a single item registry is produced which contains only the root.\n\t * This is usable only when the root {@link DataStoreKind} is available eagerly (e.g. not lazy loaded),\n\t * and when the container does not need a registry for creating additional data stores beyond the root.\n\t * @privateRemarks\n\t * TODO: As this is a detached container, it should be able to be created synchronously.\n\t *\n\t * TODO: Provide more general alternative to this in the form of a service-independent `createContainer` free function.\n\t * It would work with a `ServiceClient.attachContainer<T>(detached: FluidContainer<T>): Promise<FluidContainerAttached<T>>`\n\t * which returns a promise that resolves once the detached container has been attached\n\t * (pointing to the same container object, but with the new type).\n\t *\n\t * Challenges:\n\t *\n\t * Currently the service must be provided at creation time because `IContainer.attach` does not accept a service client,\n\t * making it unclear whether a truly service-independent path is feasible in the near term.\n\t */\n\tcreateContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * Creates a detached container associated with this service client.\n\t * @typeParam T - The type of the container's root data store, as defined by `root`.\n\t * @param root - A {@link DataStoreKey} used to look up the root's {@link DataStoreKind} from `registry`.\n\t * @param registry - The {@link DataStoreRegistry} supplying the {@link DataStoreKind} for the root and any other data stores the container may need to create.\n\t * @remarks\n\t * Use this overload when the root {@link DataStoreKind} is not available eagerly (e.g. for lazy loading),\n\t * or when the container needs a registry for creating additional data stores beyond the root.\n\t */\n\tcreateContainer<T>(\n\t\troot: DataStoreKey<T>,\n\t\tregistry: DataStoreRegistry,\n\t): Promise<FluidContainerWithService<T>>;\n\n\t/**\n\t * A shorthand for {@link ServiceClient.(createContainer:1)} followed by {@link FluidContainerWithService.attach}.\n\t * @remarks\n\t * Due to current implementation limitations making container creation async and service specific,\n\t * creating then attaching one is a bit verbose with two awaits that are messy to include inline.\n\t * This provides a convenient way to create and attach a container in a single step.\n\t * @privateRemarks\n\t * TODO: We should fix ergonomics issues that make this helpful,\n\t * then remove (or deprecate) this method in favor of `service.attach(createContainer(root))` as a better orthogonalized API.\n\t * See private remarks on {@link ServiceClient.(createContainer:1)}.\n\t */\n\tcreateAttachedContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerAttached<T>>;\n\n\t/**\n\t * A shorthand for {@link ServiceClient.(createContainer:2)} followed by {@link FluidContainerWithService.attach}.\n\t * @remarks\n\t * Due to current implementation limitations making container creation async and service specific,\n\t * creating then attaching one is a bit verbose with two awaits that are messy to include inline.\n\t * This provides a convenient way to create and attach a container in a single step.\n\t */\n\tcreateAttachedContainer<T>(\n\t\troot: DataStoreKey<T>,\n\t\tregistry: DataStoreRegistry,\n\t): Promise<FluidContainerAttached<T>>;\n\n\t/**\n\t * Loads an existing container from the service.\n\t * @typeParam T - The type of the container's root data store.\n\t * @param id - The unique identifier of the container to load.\n\t * @param root - The {@link DataStoreKind} for the root, or a registry which will be used to look up the root based on its type.\n\t *\n\t * @throws a {@link @fluidframework/telemetry-utils#UsageError} if the DataStoreKind's type (either the root directly or looked up from the registry) does not match the type of the root data store in the container.\n\t *\n\t * @privateRemarks\n\t * The ability to provide a registry here means that it's possible to:\n\t * 1. Load a container which might have a few different possible roots, for example because of versioning.\n\t * 2. Generate the DataStoreKind on demand based on the type: this approach could be used for things like debug tools which can load any possible container.\n\t * 3. Generating the DataStoreKind if the type is unrecognized, for example to provide a placeholder which might support some minimal functionality (like debug inspection, and summary).\n\t *\n\t * The ability to provide just a single DataStoreKind<T> is purely a convenience to make it cleaner to use this in simple cases.\n\t */\n\tloadContainer<T>(\n\t\tid: string,\n\t\troot: DataStoreKind<T> | DataStoreRegistry<T>,\n\t): Promise<FluidContainerAttached<T>>;\n}\n\n// #endregion\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/driver-definitions",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.115.0",
|
|
4
4
|
"description": "Fluid driver definitions",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"main": "lib/index.js",
|
|
48
48
|
"types": "lib/public.d.ts",
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@fluidframework/core-interfaces": "~2.
|
|
50
|
+
"@fluidframework/core-interfaces": "~2.115.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@arethetypeswrong/cli": "^0.18.2",
|
package/src/serviceClient.ts
CHANGED
|
@@ -381,6 +381,31 @@ export interface ServiceClient {
|
|
|
381
381
|
registry: DataStoreRegistry,
|
|
382
382
|
): Promise<FluidContainerWithService<T>>;
|
|
383
383
|
|
|
384
|
+
/**
|
|
385
|
+
* A shorthand for {@link ServiceClient.(createContainer:1)} followed by {@link FluidContainerWithService.attach}.
|
|
386
|
+
* @remarks
|
|
387
|
+
* Due to current implementation limitations making container creation async and service specific,
|
|
388
|
+
* creating then attaching one is a bit verbose with two awaits that are messy to include inline.
|
|
389
|
+
* This provides a convenient way to create and attach a container in a single step.
|
|
390
|
+
* @privateRemarks
|
|
391
|
+
* TODO: We should fix ergonomics issues that make this helpful,
|
|
392
|
+
* then remove (or deprecate) this method in favor of `service.attach(createContainer(root))` as a better orthogonalized API.
|
|
393
|
+
* See private remarks on {@link ServiceClient.(createContainer:1)}.
|
|
394
|
+
*/
|
|
395
|
+
createAttachedContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerAttached<T>>;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* A shorthand for {@link ServiceClient.(createContainer:2)} followed by {@link FluidContainerWithService.attach}.
|
|
399
|
+
* @remarks
|
|
400
|
+
* Due to current implementation limitations making container creation async and service specific,
|
|
401
|
+
* creating then attaching one is a bit verbose with two awaits that are messy to include inline.
|
|
402
|
+
* This provides a convenient way to create and attach a container in a single step.
|
|
403
|
+
*/
|
|
404
|
+
createAttachedContainer<T>(
|
|
405
|
+
root: DataStoreKey<T>,
|
|
406
|
+
registry: DataStoreRegistry,
|
|
407
|
+
): Promise<FluidContainerAttached<T>>;
|
|
408
|
+
|
|
384
409
|
/**
|
|
385
410
|
* Loads an existing container from the service.
|
|
386
411
|
* @typeParam T - The type of the container's root data store.
|