@fluidframework/runtime-utils 2.0.0-rc.3.0.2 → 2.0.0-rc.4.0.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 CHANGED
@@ -1,5 +1,35 @@
1
1
  # @fluidframework/runtime-utils
2
2
 
3
+ ## 2.0.0-rc.4.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Deprecated members of IFluidHandle are split off into new IFluidHandleInternal interface [96872186d0](https://github.com/microsoft/FluidFramework/commit/96872186d0d0f245c1fece7d19b3743e501679b6)
8
+
9
+ Split IFluidHandle into two interfaces, `IFluidHandle` and `IFluidHandleInternal`.
10
+ Code depending on the previously deprecated members of IFluidHandle can access them by using `toFluidHandleInternal` from `@fluidframework/runtime-utils/legacy`.
11
+
12
+ External implementation of the `IFluidHandle` interface are not supported: this change makes the typing better convey this using the `ErasedType` pattern.
13
+ Any existing and previously working, and now broken, external implementations of `IFluidHandle` should still work at runtime, but will need some unsafe type casts to compile.
14
+ Such handle implementation may break in the future and thus should be replaced with use of handles produced by the Fluid Framework client packages.
15
+
16
+ - Type Erase IFluidDataStoreRuntime.deltaManager [96872186d0](https://github.com/microsoft/FluidFramework/commit/96872186d0d0f245c1fece7d19b3743e501679b6)
17
+
18
+ Make IFluidDataStoreRuntime.deltaManager have an opaque type.
19
+ Marks the following types which were reachable from it as alpha:
20
+
21
+ - IConnectionDetails
22
+ - IDeltaSender
23
+ - IDeltaManagerEvents
24
+ - IDeltaManager
25
+ - IDeltaQueueEvents
26
+ - IDeltaQueue
27
+ - ReadOnlyInfo
28
+
29
+ As a temporary workaround, users needing access to the full delta manager API can use the `@alpha` `toDeltaManagerInternal` API to retrieve its members, but should migrate away from requiring access to those APIs.
30
+
31
+ Implementing a custom `IFluidDataStoreRuntime` is not supported: this is now indicated by it being marked with `@sealed`.
32
+
3
33
  ## 2.0.0-rc.3.0.0
4
34
 
5
35
  ### Major Changes
@@ -4,12 +4,19 @@
4
4
 
5
5
  ```ts
6
6
 
7
+ import { fluidHandleSymbol } from '@fluidframework/core-interfaces';
7
8
  import { IChannelStorageService } from '@fluidframework/datastore-definitions';
8
9
  import { IContainerContext } from '@fluidframework/container-definitions/internal';
9
10
  import { IContainerRuntime } from '@fluidframework/container-runtime-definitions/internal';
11
+ import type { IDeltaManager } from '@fluidframework/container-definitions/internal';
12
+ import type { IDeltaManagerErased } from '@fluidframework/datastore-definitions';
13
+ import type { IDocumentMessage } from '@fluidframework/protocol-definitions';
10
14
  import { IFluidDataStoreFactory } from '@fluidframework/runtime-definitions/internal';
11
15
  import { IFluidDataStoreRegistry } from '@fluidframework/runtime-definitions/internal';
16
+ import { IFluidHandle } from '@fluidframework/core-interfaces';
12
17
  import { IFluidHandleContext } from '@fluidframework/core-interfaces';
18
+ import type { IFluidHandleErased } from '@fluidframework/core-interfaces/internal';
19
+ import type { IFluidHandleInternal } from '@fluidframework/core-interfaces/internal';
13
20
  import { IGarbageCollectionData } from '@fluidframework/runtime-definitions';
14
21
  import { IProvideFluidDataStoreRegistry } from '@fluidframework/runtime-definitions/internal';
15
22
  import { IRequest } from '@fluidframework/core-interfaces';
@@ -17,6 +24,7 @@ import { IRequestHeader } from '@fluidframework/core-interfaces';
17
24
  import { IResponse } from '@fluidframework/core-interfaces';
18
25
  import { IRuntime } from '@fluidframework/container-definitions/internal';
19
26
  import { IRuntimeFactory } from '@fluidframework/container-definitions/internal';
27
+ import type { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
20
28
  import { ISnapshotTree } from '@fluidframework/protocol-definitions';
21
29
  import { ISnapshotTreeWithBlobContents } from '@fluidframework/container-definitions/internal';
22
30
  import { ISummarizeResult } from '@fluidframework/runtime-definitions/internal';
@@ -71,6 +79,23 @@ export function exceptionToResponse(err: any): IResponse;
71
79
  // @internal (undocumented)
72
80
  export type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;
73
81
 
82
+ // @alpha
83
+ export abstract class FluidHandleBase<T> implements IFluidHandleInternal<T> {
84
+ // (undocumented)
85
+ get [fluidHandleSymbol](): IFluidHandleErased<T>;
86
+ // (undocumented)
87
+ abstract absolutePath: string;
88
+ // (undocumented)
89
+ abstract attachGraph(): void;
90
+ // (undocumented)
91
+ abstract bind(handle: IFluidHandleInternal): void;
92
+ // (undocumented)
93
+ abstract get(): Promise<T>;
94
+ get IFluidHandle(): IFluidHandleInternal;
95
+ // (undocumented)
96
+ abstract readonly isAttached: boolean;
97
+ }
98
+
74
99
  // @internal
75
100
  export class GCDataBuilder implements IGarbageCollectionData {
76
101
  // (undocumented)
@@ -108,9 +133,15 @@ export interface ISerializedHandle {
108
133
  url: string;
109
134
  }
110
135
 
136
+ // @internal
137
+ export function isFluidHandle(value: unknown): value is IFluidHandle;
138
+
111
139
  // @internal
112
140
  export const isSerializedHandle: (value: any) => value is ISerializedHandle;
113
141
 
142
+ // @internal
143
+ export function isSnapshotFetchRequiredForLoadingGroupId(snapshotTree: ISnapshotTree, blobContents: Map<string, ArrayBuffer>): boolean;
144
+
114
145
  // @internal (undocumented)
115
146
  export function listBlobsAtTreePath(inputTree: ITree | undefined, path: string): Promise<string[]>;
116
147
 
@@ -200,6 +231,18 @@ export class TelemetryContext implements ITelemetryContext {
200
231
  setMultiple(prefix: string, property: string, values: Record<string, TelemetryBaseEventPropertyType>): void;
201
232
  }
202
233
 
234
+ // @internal
235
+ export function toDeltaManagerErased(deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>): IDeltaManagerErased;
236
+
237
+ // @alpha
238
+ export function toDeltaManagerInternal(deltaManager: IDeltaManagerErased): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
239
+
240
+ // @alpha
241
+ export function toFluidHandleErased<T>(handle: IFluidHandleInternal<T>): IFluidHandleErased<T>;
242
+
243
+ // @alpha
244
+ export function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleInternal<T>;
245
+
203
246
  // @internal
204
247
  export function unpackChildNodesUsedRoutes(usedRoutes: readonly string[]): Map<string, string[]>;
205
248
 
@@ -0,0 +1,19 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import type { IDeltaManager } from "@fluidframework/container-definitions/internal";
6
+ import type { IDeltaManagerErased } from "@fluidframework/datastore-definitions";
7
+ import type { IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
+ /**
9
+ * Casts the public API for delta manager into the internal one,
10
+ * exposing access to APIs needed by the implementation of Fluid Framework but not its users.
11
+ * @alpha
12
+ */
13
+ export declare function toDeltaManagerInternal(deltaManager: IDeltaManagerErased): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
14
+ /**
15
+ * Casts the the internal API for delta manager into the public type erased API for returning from public APIs that should not have access to any of its members.
16
+ * @internal
17
+ */
18
+ export declare function toDeltaManagerErased(deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>): IDeltaManagerErased;
19
+ //# sourceMappingURL=deltaManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,KAAK,EACX,gBAAgB,EAChB,yBAAyB,EACzB,MAAM,sCAAsC,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,sBAAsB,CACrC,YAAY,EAAE,mBAAmB,GAC/B,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CAE5D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,GACtE,mBAAmB,CAErB"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.toDeltaManagerErased = exports.toDeltaManagerInternal = void 0;
8
+ /**
9
+ * Casts the public API for delta manager into the internal one,
10
+ * exposing access to APIs needed by the implementation of Fluid Framework but not its users.
11
+ * @alpha
12
+ */
13
+ function toDeltaManagerInternal(deltaManager) {
14
+ return deltaManager;
15
+ }
16
+ exports.toDeltaManagerInternal = toDeltaManagerInternal;
17
+ /**
18
+ * Casts the the internal API for delta manager into the public type erased API for returning from public APIs that should not have access to any of its members.
19
+ * @internal
20
+ */
21
+ function toDeltaManagerErased(deltaManager) {
22
+ return deltaManager;
23
+ }
24
+ exports.toDeltaManagerErased = toDeltaManagerErased;
25
+ //# sourceMappingURL=deltaManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltaManager.js","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH;;;;GAIG;AACH,SAAgB,sBAAsB,CACrC,YAAiC;IAEjC,OAAO,YAAqF,CAAC;AAC9F,CAAC;AAJD,wDAIC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CACnC,YAAwE;IAExE,OAAO,YAA8C,CAAC;AACvD,CAAC;AAJD,oDAIC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IDeltaManager } from \"@fluidframework/container-definitions/internal\";\nimport type { IDeltaManagerErased } from \"@fluidframework/datastore-definitions\";\nimport type {\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/protocol-definitions\";\n\n/**\n * Casts the public API for delta manager into the internal one,\n * exposing access to APIs needed by the implementation of Fluid Framework but not its users.\n * @alpha\n */\nexport function toDeltaManagerInternal(\n\tdeltaManager: IDeltaManagerErased,\n): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {\n\treturn deltaManager as unknown as IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;\n}\n\n/**\n * Casts the the internal API for delta manager into the public type erased API for returning from public APIs that should not have access to any of its members.\n * @internal\n */\nexport function toDeltaManagerErased(\n\tdeltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n): IDeltaManagerErased {\n\treturn deltaManager as unknown as IDeltaManagerErased;\n}\n"]}
package/dist/handles.d.ts CHANGED
@@ -2,6 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import type { IFluidHandleErased, IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
6
+ import { IFluidHandle, fluidHandleSymbol } from "@fluidframework/core-interfaces";
5
7
  /**
6
8
  * JSON serialized form of an IFluidHandle
7
9
  * @internal
@@ -15,4 +17,37 @@ export interface ISerializedHandle {
15
17
  * @internal
16
18
  */
17
19
  export declare const isSerializedHandle: (value: any) => value is ISerializedHandle;
20
+ /**
21
+ * Check if a value is an IFluidHandle.
22
+ * @remarks
23
+ * Objects which have a field named `IFluidHandle` can in some cases produce a false positive.
24
+ * @internal
25
+ */
26
+ export declare function isFluidHandle(value: unknown): value is IFluidHandle;
27
+ /**
28
+ * Downcast an IFluidHandle to an IFluidHandleInternal.
29
+ * @alpha
30
+ */
31
+ export declare function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleInternal<T>;
32
+ /**
33
+ * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.
34
+ * @alpha
35
+ */
36
+ export declare function toFluidHandleErased<T>(handle: IFluidHandleInternal<T>): IFluidHandleErased<T>;
37
+ /**
38
+ * Base class which can be uses to assist implementing IFluidHandleInternal.
39
+ * @alpha
40
+ */
41
+ export declare abstract class FluidHandleBase<T> implements IFluidHandleInternal<T> {
42
+ abstract absolutePath: string;
43
+ abstract attachGraph(): void;
44
+ abstract bind(handle: IFluidHandleInternal): void;
45
+ abstract readonly isAttached: boolean;
46
+ abstract get(): Promise<T>;
47
+ /**
48
+ * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}
49
+ */
50
+ get IFluidHandle(): IFluidHandleInternal;
51
+ get [fluidHandleSymbol](): IFluidHandleErased<T>;
52
+ }
18
53
  //# sourceMappingURL=handles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAEjC,IAAI,EAAE,kBAAkB,CAAC;IAGzB,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAW,GAAG,+BACV,CAAC"}
1
+ {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,kBAAkB,EAClB,oBAAoB,EACpB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAElF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAEjC,IAAI,EAAE,kBAAkB,CAAC;IAGzB,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAW,GAAG,+BACV,CAAC;AAcpC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAkBnE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAWzF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAE7F;AAED;;;GAGG;AACH,8BAAsB,eAAe,CAAC,CAAC,CAAE,YAAW,oBAAoB,CAAC,CAAC,CAAC;IAC1E,SAAgB,YAAY,EAAE,MAAM,CAAC;aACrB,WAAW,IAAI,IAAI;aACnB,IAAI,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IACxD,kBAAyB,UAAU,EAAE,OAAO,CAAC;aAC7B,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAEjC;;OAEG;IACH,IAAW,YAAY,IAAI,oBAAoB,CAE9C;IAED,IAAW,CAAC,iBAAiB,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,CAEtD;CACD"}
package/dist/handles.js CHANGED
@@ -4,11 +4,89 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.isSerializedHandle = void 0;
7
+ exports.FluidHandleBase = exports.toFluidHandleErased = exports.toFluidHandleInternal = exports.isFluidHandle = exports.isSerializedHandle = void 0;
8
+ const core_interfaces_1 = require("@fluidframework/core-interfaces");
8
9
  /**
9
10
  * Is the input object a @see ISerializedHandle?
10
11
  * @internal
11
12
  */
12
13
  const isSerializedHandle = (value) => value?.type === "__fluid_handle__";
13
14
  exports.isSerializedHandle = isSerializedHandle;
15
+ /**
16
+ * Setting to opt into compatibility with handles from before {@link fluidHandleSymbol} existed (Fluid Framework client 2.0.0-rc.3.0.0 and earlier).
17
+ *
18
+ * Some code which uses this library might dynamically load multiple versions of it,
19
+ * as well as old or duplicated versions of packages which produce or implement handles.
20
+ * To correctly interoperate with this old packages and object produced by them, the old in-memory format for handles, without the symbol, are explicitly supported.
21
+ *
22
+ * This setting mostly exists as a way to easily find any code that only exists to provide this compatibility and clarify how to remove that compatibility.
23
+ * At some point this might be removed or turned into an actual configuration option, but for now its really just documentation.
24
+ */
25
+ const enableBackwardsCompatibility = true;
26
+ /**
27
+ * Check if a value is an IFluidHandle.
28
+ * @remarks
29
+ * Objects which have a field named `IFluidHandle` can in some cases produce a false positive.
30
+ * @internal
31
+ */
32
+ function isFluidHandle(value) {
33
+ // `in` gives a type error on non-objects and null, so filter them out
34
+ if (typeof value !== "object" || value === null) {
35
+ return false;
36
+ }
37
+ if (core_interfaces_1.fluidHandleSymbol in value) {
38
+ return true;
39
+ }
40
+ // If enableBackwardsCompatibility, run check for FluidHandles predating use of fluidHandleSymbol.
41
+ if (enableBackwardsCompatibility && core_interfaces_1.IFluidHandle in value) {
42
+ // Since this check can have false positives, make it a bit more robust by checking value[IFluidHandle][IFluidHandle]
43
+ const inner = value[core_interfaces_1.IFluidHandle];
44
+ if (typeof inner !== "object" || inner === null) {
45
+ return false;
46
+ }
47
+ return core_interfaces_1.IFluidHandle in inner;
48
+ }
49
+ return false;
50
+ }
51
+ exports.isFluidHandle = isFluidHandle;
52
+ /**
53
+ * Downcast an IFluidHandle to an IFluidHandleInternal.
54
+ * @alpha
55
+ */
56
+ function toFluidHandleInternal(handle) {
57
+ if (!(core_interfaces_1.fluidHandleSymbol in handle) || !(core_interfaces_1.fluidHandleSymbol in handle[core_interfaces_1.fluidHandleSymbol])) {
58
+ if (enableBackwardsCompatibility && core_interfaces_1.IFluidHandle in handle) {
59
+ return handle[core_interfaces_1.IFluidHandle];
60
+ }
61
+ throw new TypeError("Invalid IFluidHandle");
62
+ }
63
+ // This casts the IFluidHandleErased from the symbol instead of `handle` to ensure that if someone
64
+ // implements their own IFluidHandle in terms of an existing handle, it won't break anything.
65
+ return handle[core_interfaces_1.fluidHandleSymbol];
66
+ }
67
+ exports.toFluidHandleInternal = toFluidHandleInternal;
68
+ /**
69
+ * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.
70
+ * @alpha
71
+ */
72
+ function toFluidHandleErased(handle) {
73
+ return handle;
74
+ }
75
+ exports.toFluidHandleErased = toFluidHandleErased;
76
+ /**
77
+ * Base class which can be uses to assist implementing IFluidHandleInternal.
78
+ * @alpha
79
+ */
80
+ class FluidHandleBase {
81
+ /**
82
+ * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}
83
+ */
84
+ get IFluidHandle() {
85
+ return this;
86
+ }
87
+ get [core_interfaces_1.fluidHandleSymbol]() {
88
+ return toFluidHandleErased(this);
89
+ }
90
+ }
91
+ exports.FluidHandleBase = FluidHandleBase;
14
92
  //# sourceMappingURL=handles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handles.js","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAcH;;;GAGG;AACI,MAAM,kBAAkB,GAAG,CAAC,KAAU,EAA8B,EAAE,CAC5E,KAAK,EAAE,IAAI,KAAK,kBAAkB,CAAC;AADvB,QAAA,kBAAkB,sBACK","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * JSON serialized form of an IFluidHandle\n * @internal\n */\nexport interface ISerializedHandle {\n\t// Marker to indicate to JSON.parse that the object is a Fluid handle\n\ttype: \"__fluid_handle__\";\n\n\t// URL to the object. Relative URLs are relative to the handle context passed to the stringify.\n\turl: string;\n}\n\n/**\n * Is the input object a @see ISerializedHandle?\n * @internal\n */\nexport const isSerializedHandle = (value: any): value is ISerializedHandle =>\n\tvalue?.type === \"__fluid_handle__\";\n"]}
1
+ {"version":3,"file":"handles.js","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAMH,qEAAkF;AAclF;;;GAGG;AACI,MAAM,kBAAkB,GAAG,CAAC,KAAU,EAA8B,EAAE,CAC5E,KAAK,EAAE,IAAI,KAAK,kBAAkB,CAAC;AADvB,QAAA,kBAAkB,sBACK;AAEpC;;;;;;;;;GASG;AACH,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAE1C;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,KAAc;IAC3C,sEAAsE;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;QAChD,OAAO,KAAK,CAAC;KACb;IACD,IAAI,mCAAiB,IAAI,KAAK,EAAE;QAC/B,OAAO,IAAI,CAAC;KACZ;IACD,kGAAkG;IAClG,IAAI,4BAA4B,IAAI,8BAAY,IAAI,KAAK,EAAE;QAC1D,qHAAqH;QACrH,MAAM,KAAK,GAAG,KAAK,CAAC,8BAAY,CAAiB,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;YAChD,OAAO,KAAK,CAAC;SACb;QACD,OAAO,8BAAY,IAAI,KAAK,CAAC;KAC7B;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAlBD,sCAkBC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CAAI,MAAuB;IAC/D,IAAI,CAAC,CAAC,mCAAiB,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,mCAAiB,IAAI,MAAM,CAAC,mCAAiB,CAAC,CAAC,EAAE;QACxF,IAAI,4BAA4B,IAAI,8BAAY,IAAI,MAAM,EAAE;YAC3D,OAAO,MAAM,CAAC,8BAAY,CAA4B,CAAC;SACvD;QACD,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC;KAC5C;IAED,kGAAkG;IAClG,6FAA6F;IAC7F,OAAO,MAAM,CAAC,mCAAiB,CAAuC,CAAC;AACxE,CAAC;AAXD,sDAWC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CAAI,MAA+B;IACrE,OAAO,MAA0C,CAAC;AACnD,CAAC;AAFD,kDAEC;AAED;;;GAGG;AACH,MAAsB,eAAe;IAOpC;;OAEG;IACH,IAAW,YAAY;QACtB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAW,CAAC,mCAAiB,CAAC;QAC7B,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACD;AAjBD,0CAiBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIFluidHandleErased,\n\tIFluidHandleInternal,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { IFluidHandle, fluidHandleSymbol } from \"@fluidframework/core-interfaces\";\n\n/**\n * JSON serialized form of an IFluidHandle\n * @internal\n */\nexport interface ISerializedHandle {\n\t// Marker to indicate to JSON.parse that the object is a Fluid handle\n\ttype: \"__fluid_handle__\";\n\n\t// URL to the object. Relative URLs are relative to the handle context passed to the stringify.\n\turl: string;\n}\n\n/**\n * Is the input object a @see ISerializedHandle?\n * @internal\n */\nexport const isSerializedHandle = (value: any): value is ISerializedHandle =>\n\tvalue?.type === \"__fluid_handle__\";\n\n/**\n * Setting to opt into compatibility with handles from before {@link fluidHandleSymbol} existed (Fluid Framework client 2.0.0-rc.3.0.0 and earlier).\n *\n * Some code which uses this library might dynamically load multiple versions of it,\n * as well as old or duplicated versions of packages which produce or implement handles.\n * To correctly interoperate with this old packages and object produced by them, the old in-memory format for handles, without the symbol, are explicitly supported.\n *\n * This setting mostly exists as a way to easily find any code that only exists to provide this compatibility and clarify how to remove that compatibility.\n * At some point this might be removed or turned into an actual configuration option, but for now its really just documentation.\n */\nconst enableBackwardsCompatibility = true;\n\n/**\n * Check if a value is an IFluidHandle.\n * @remarks\n * Objects which have a field named `IFluidHandle` can in some cases produce a false positive.\n * @internal\n */\nexport function isFluidHandle(value: unknown): value is IFluidHandle {\n\t// `in` gives a type error on non-objects and null, so filter them out\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tif (fluidHandleSymbol in value) {\n\t\treturn true;\n\t}\n\t// If enableBackwardsCompatibility, run check for FluidHandles predating use of fluidHandleSymbol.\n\tif (enableBackwardsCompatibility && IFluidHandle in value) {\n\t\t// Since this check can have false positives, make it a bit more robust by checking value[IFluidHandle][IFluidHandle]\n\t\tconst inner = value[IFluidHandle] as IFluidHandle;\n\t\tif (typeof inner !== \"object\" || inner === null) {\n\t\t\treturn false;\n\t\t}\n\t\treturn IFluidHandle in inner;\n\t}\n\treturn false;\n}\n\n/**\n * Downcast an IFluidHandle to an IFluidHandleInternal.\n * @alpha\n */\nexport function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleInternal<T> {\n\tif (!(fluidHandleSymbol in handle) || !(fluidHandleSymbol in handle[fluidHandleSymbol])) {\n\t\tif (enableBackwardsCompatibility && IFluidHandle in handle) {\n\t\t\treturn handle[IFluidHandle] as IFluidHandleInternal<T>;\n\t\t}\n\t\tthrow new TypeError(\"Invalid IFluidHandle\");\n\t}\n\n\t// This casts the IFluidHandleErased from the symbol instead of `handle` to ensure that if someone\n\t// implements their own IFluidHandle in terms of an existing handle, it won't break anything.\n\treturn handle[fluidHandleSymbol] as unknown as IFluidHandleInternal<T>;\n}\n\n/**\n * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.\n * @alpha\n */\nexport function toFluidHandleErased<T>(handle: IFluidHandleInternal<T>): IFluidHandleErased<T> {\n\treturn handle as unknown as IFluidHandleErased<T>;\n}\n\n/**\n * Base class which can be uses to assist implementing IFluidHandleInternal.\n * @alpha\n */\nexport abstract class FluidHandleBase<T> implements IFluidHandleInternal<T> {\n\tpublic abstract absolutePath: string;\n\tpublic abstract attachGraph(): void;\n\tpublic abstract bind(handle: IFluidHandleInternal): void;\n\tpublic abstract readonly isAttached: boolean;\n\tpublic abstract get(): Promise<T>;\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}\n\t */\n\tpublic get IFluidHandle(): IFluidHandleInternal {\n\t\treturn this;\n\t}\n\n\tpublic get [fluidHandleSymbol](): IFluidHandleErased<T> {\n\t\treturn toFluidHandleErased(this);\n\t}\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { generateHandleContextPath } from "./dataStoreHandleContextUtils.js";
6
6
  export { create404Response, createDataStoreFactory, createResponseError, exceptionToResponse, Factory, responseToException, } from "./dataStoreHelpers.js";
7
- export { ISerializedHandle, isSerializedHandle } from "./handles.js";
7
+ export { ISerializedHandle, isSerializedHandle, isFluidHandle, toFluidHandleErased, toFluidHandleInternal, FluidHandleBase, } from "./handles.js";
8
8
  export { ObjectStoragePartition } from "./objectstoragepartition.js";
9
9
  export { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from "./objectstorageutils.js";
10
10
  export { RequestParser } from "./requestParser.js";
@@ -12,4 +12,6 @@ export { RuntimeFactoryHelper } from "./runtimeFactoryHelper.js";
12
12
  export { addBlobToSummary, addSummarizeResultToSummary, calculateStats, convertSnapshotTreeToSummaryTree, convertSummaryTreeToITree, convertToSummaryTree, convertToSummaryTreeWithStats, GCDataBuilder, getBlobSize, mergeStats, processAttachMessageGCData, SummaryTreeBuilder, TelemetryContext, utf8ByteLength, } from "./summaryUtils.js";
13
13
  export { unpackChildNodesUsedRoutes } from "./unpackUsedRoutes.js";
14
14
  export { ReadAndParseBlob, seqFromTree, encodeCompactIdToString } from "./utils.js";
15
+ export { isSnapshotFetchRequiredForLoadingGroupId } from "./snapshotUtils.js";
16
+ export { toDeltaManagerErased, toDeltaManagerInternal } from "./deltaManager.js";
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EACN,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,OAAO,EACP,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,cAAc,EACd,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EACN,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,OAAO,EACP,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,cAAc,EACd,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,wCAAwC,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.encodeCompactIdToString = exports.seqFromTree = exports.unpackChildNodesUsedRoutes = exports.utf8ByteLength = exports.TelemetryContext = exports.SummaryTreeBuilder = exports.processAttachMessageGCData = exports.mergeStats = exports.getBlobSize = exports.GCDataBuilder = exports.convertToSummaryTreeWithStats = exports.convertToSummaryTree = exports.convertSummaryTreeToITree = exports.convertSnapshotTreeToSummaryTree = exports.calculateStats = exports.addSummarizeResultToSummary = exports.addBlobToSummary = exports.RuntimeFactoryHelper = exports.RequestParser = exports.listBlobsAtTreePath = exports.getNormalizedObjectStoragePathParts = exports.ObjectStoragePartition = exports.isSerializedHandle = exports.responseToException = exports.exceptionToResponse = exports.createResponseError = exports.createDataStoreFactory = exports.create404Response = exports.generateHandleContextPath = void 0;
7
+ exports.toDeltaManagerInternal = exports.toDeltaManagerErased = exports.isSnapshotFetchRequiredForLoadingGroupId = exports.encodeCompactIdToString = exports.seqFromTree = exports.unpackChildNodesUsedRoutes = exports.utf8ByteLength = exports.TelemetryContext = exports.SummaryTreeBuilder = exports.processAttachMessageGCData = exports.mergeStats = exports.getBlobSize = exports.GCDataBuilder = exports.convertToSummaryTreeWithStats = exports.convertToSummaryTree = exports.convertSummaryTreeToITree = exports.convertSnapshotTreeToSummaryTree = exports.calculateStats = exports.addSummarizeResultToSummary = exports.addBlobToSummary = exports.RuntimeFactoryHelper = exports.RequestParser = exports.listBlobsAtTreePath = exports.getNormalizedObjectStoragePathParts = exports.ObjectStoragePartition = exports.FluidHandleBase = exports.toFluidHandleInternal = exports.toFluidHandleErased = exports.isFluidHandle = exports.isSerializedHandle = exports.responseToException = exports.exceptionToResponse = exports.createResponseError = exports.createDataStoreFactory = exports.create404Response = exports.generateHandleContextPath = void 0;
8
8
  var dataStoreHandleContextUtils_js_1 = require("./dataStoreHandleContextUtils.js");
9
9
  Object.defineProperty(exports, "generateHandleContextPath", { enumerable: true, get: function () { return dataStoreHandleContextUtils_js_1.generateHandleContextPath; } });
10
10
  var dataStoreHelpers_js_1 = require("./dataStoreHelpers.js");
@@ -15,6 +15,10 @@ Object.defineProperty(exports, "exceptionToResponse", { enumerable: true, get: f
15
15
  Object.defineProperty(exports, "responseToException", { enumerable: true, get: function () { return dataStoreHelpers_js_1.responseToException; } });
16
16
  var handles_js_1 = require("./handles.js");
17
17
  Object.defineProperty(exports, "isSerializedHandle", { enumerable: true, get: function () { return handles_js_1.isSerializedHandle; } });
18
+ Object.defineProperty(exports, "isFluidHandle", { enumerable: true, get: function () { return handles_js_1.isFluidHandle; } });
19
+ Object.defineProperty(exports, "toFluidHandleErased", { enumerable: true, get: function () { return handles_js_1.toFluidHandleErased; } });
20
+ Object.defineProperty(exports, "toFluidHandleInternal", { enumerable: true, get: function () { return handles_js_1.toFluidHandleInternal; } });
21
+ Object.defineProperty(exports, "FluidHandleBase", { enumerable: true, get: function () { return handles_js_1.FluidHandleBase; } });
18
22
  var objectstoragepartition_js_1 = require("./objectstoragepartition.js");
19
23
  Object.defineProperty(exports, "ObjectStoragePartition", { enumerable: true, get: function () { return objectstoragepartition_js_1.ObjectStoragePartition; } });
20
24
  var objectstorageutils_js_1 = require("./objectstorageutils.js");
@@ -44,4 +48,9 @@ Object.defineProperty(exports, "unpackChildNodesUsedRoutes", { enumerable: true,
44
48
  var utils_js_1 = require("./utils.js");
45
49
  Object.defineProperty(exports, "seqFromTree", { enumerable: true, get: function () { return utils_js_1.seqFromTree; } });
46
50
  Object.defineProperty(exports, "encodeCompactIdToString", { enumerable: true, get: function () { return utils_js_1.encodeCompactIdToString; } });
51
+ var snapshotUtils_js_1 = require("./snapshotUtils.js");
52
+ Object.defineProperty(exports, "isSnapshotFetchRequiredForLoadingGroupId", { enumerable: true, get: function () { return snapshotUtils_js_1.isSnapshotFetchRequiredForLoadingGroupId; } });
53
+ var deltaManager_js_1 = require("./deltaManager.js");
54
+ Object.defineProperty(exports, "toDeltaManagerErased", { enumerable: true, get: function () { return deltaManager_js_1.toDeltaManagerErased; } });
55
+ Object.defineProperty(exports, "toDeltaManagerInternal", { enumerable: true, get: function () { return deltaManager_js_1.toDeltaManagerInternal; } });
47
56
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,mFAA6E;AAApE,2IAAA,yBAAyB,OAAA;AAClC,6DAO+B;AAN9B,wHAAA,iBAAiB,OAAA;AACjB,6HAAA,sBAAsB,OAAA;AACtB,0HAAA,mBAAmB,OAAA;AACnB,0HAAA,mBAAmB,OAAA;AAEnB,0HAAA,mBAAmB,OAAA;AAEpB,2CAAqE;AAAzC,gHAAA,kBAAkB,OAAA;AAC9C,yEAAqE;AAA5D,mIAAA,sBAAsB,OAAA;AAC/B,iEAAmG;AAA1F,4IAAA,mCAAmC,OAAA;AAAE,4HAAA,mBAAmB,OAAA;AACjE,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,qEAAiE;AAAxD,+HAAA,oBAAoB,OAAA;AAC7B,qDAe2B;AAd1B,mHAAA,gBAAgB,OAAA;AAChB,8HAAA,2BAA2B,OAAA;AAC3B,iHAAA,cAAc,OAAA;AACd,mIAAA,gCAAgC,OAAA;AAChC,4HAAA,yBAAyB,OAAA;AACzB,uHAAA,oBAAoB,OAAA;AACpB,gIAAA,6BAA6B,OAAA;AAC7B,gHAAA,aAAa,OAAA;AACb,8GAAA,WAAW,OAAA;AACX,6GAAA,UAAU,OAAA;AACV,6HAAA,0BAA0B,OAAA;AAC1B,qHAAA,kBAAkB,OAAA;AAClB,mHAAA,gBAAgB,OAAA;AAChB,iHAAA,cAAc,OAAA;AAEf,6DAAmE;AAA1D,iIAAA,0BAA0B,OAAA;AACnC,uCAAoF;AAAzD,uGAAA,WAAW,OAAA;AAAE,mHAAA,uBAAuB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { generateHandleContextPath } from \"./dataStoreHandleContextUtils.js\";\nexport {\n\tcreate404Response,\n\tcreateDataStoreFactory,\n\tcreateResponseError,\n\texceptionToResponse,\n\tFactory,\n\tresponseToException,\n} from \"./dataStoreHelpers.js\";\nexport { ISerializedHandle, isSerializedHandle } from \"./handles.js\";\nexport { ObjectStoragePartition } from \"./objectstoragepartition.js\";\nexport { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from \"./objectstorageutils.js\";\nexport { RequestParser } from \"./requestParser.js\";\nexport { RuntimeFactoryHelper } from \"./runtimeFactoryHelper.js\";\nexport {\n\taddBlobToSummary,\n\taddSummarizeResultToSummary,\n\tcalculateStats,\n\tconvertSnapshotTreeToSummaryTree,\n\tconvertSummaryTreeToITree,\n\tconvertToSummaryTree,\n\tconvertToSummaryTreeWithStats,\n\tGCDataBuilder,\n\tgetBlobSize,\n\tmergeStats,\n\tprocessAttachMessageGCData,\n\tSummaryTreeBuilder,\n\tTelemetryContext,\n\tutf8ByteLength,\n} from \"./summaryUtils.js\";\nexport { unpackChildNodesUsedRoutes } from \"./unpackUsedRoutes.js\";\nexport { ReadAndParseBlob, seqFromTree, encodeCompactIdToString } from \"./utils.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,mFAA6E;AAApE,2IAAA,yBAAyB,OAAA;AAClC,6DAO+B;AAN9B,wHAAA,iBAAiB,OAAA;AACjB,6HAAA,sBAAsB,OAAA;AACtB,0HAAA,mBAAmB,OAAA;AACnB,0HAAA,mBAAmB,OAAA;AAEnB,0HAAA,mBAAmB,OAAA;AAEpB,2CAOsB;AALrB,gHAAA,kBAAkB,OAAA;AAClB,2GAAA,aAAa,OAAA;AACb,iHAAA,mBAAmB,OAAA;AACnB,mHAAA,qBAAqB,OAAA;AACrB,6GAAA,eAAe,OAAA;AAEhB,yEAAqE;AAA5D,mIAAA,sBAAsB,OAAA;AAC/B,iEAAmG;AAA1F,4IAAA,mCAAmC,OAAA;AAAE,4HAAA,mBAAmB,OAAA;AACjE,uDAAmD;AAA1C,iHAAA,aAAa,OAAA;AACtB,qEAAiE;AAAxD,+HAAA,oBAAoB,OAAA;AAC7B,qDAe2B;AAd1B,mHAAA,gBAAgB,OAAA;AAChB,8HAAA,2BAA2B,OAAA;AAC3B,iHAAA,cAAc,OAAA;AACd,mIAAA,gCAAgC,OAAA;AAChC,4HAAA,yBAAyB,OAAA;AACzB,uHAAA,oBAAoB,OAAA;AACpB,gIAAA,6BAA6B,OAAA;AAC7B,gHAAA,aAAa,OAAA;AACb,8GAAA,WAAW,OAAA;AACX,6GAAA,UAAU,OAAA;AACV,6HAAA,0BAA0B,OAAA;AAC1B,qHAAA,kBAAkB,OAAA;AAClB,mHAAA,gBAAgB,OAAA;AAChB,iHAAA,cAAc,OAAA;AAEf,6DAAmE;AAA1D,iIAAA,0BAA0B,OAAA;AACnC,uCAAoF;AAAzD,uGAAA,WAAW,OAAA;AAAE,mHAAA,uBAAuB,OAAA;AAC/D,uDAA8E;AAArE,4IAAA,wCAAwC,OAAA;AACjD,qDAAiF;AAAxE,uHAAA,oBAAoB,OAAA;AAAE,yHAAA,sBAAsB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { generateHandleContextPath } from \"./dataStoreHandleContextUtils.js\";\nexport {\n\tcreate404Response,\n\tcreateDataStoreFactory,\n\tcreateResponseError,\n\texceptionToResponse,\n\tFactory,\n\tresponseToException,\n} from \"./dataStoreHelpers.js\";\nexport {\n\tISerializedHandle,\n\tisSerializedHandle,\n\tisFluidHandle,\n\ttoFluidHandleErased,\n\ttoFluidHandleInternal,\n\tFluidHandleBase,\n} from \"./handles.js\";\nexport { ObjectStoragePartition } from \"./objectstoragepartition.js\";\nexport { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from \"./objectstorageutils.js\";\nexport { RequestParser } from \"./requestParser.js\";\nexport { RuntimeFactoryHelper } from \"./runtimeFactoryHelper.js\";\nexport {\n\taddBlobToSummary,\n\taddSummarizeResultToSummary,\n\tcalculateStats,\n\tconvertSnapshotTreeToSummaryTree,\n\tconvertSummaryTreeToITree,\n\tconvertToSummaryTree,\n\tconvertToSummaryTreeWithStats,\n\tGCDataBuilder,\n\tgetBlobSize,\n\tmergeStats,\n\tprocessAttachMessageGCData,\n\tSummaryTreeBuilder,\n\tTelemetryContext,\n\tutf8ByteLength,\n} from \"./summaryUtils.js\";\nexport { unpackChildNodesUsedRoutes } from \"./unpackUsedRoutes.js\";\nexport { ReadAndParseBlob, seqFromTree, encodeCompactIdToString } from \"./utils.js\";\nexport { isSnapshotFetchRequiredForLoadingGroupId } from \"./snapshotUtils.js\";\nexport { toDeltaManagerErased, toDeltaManagerInternal } from \"./deltaManager.js\";\n"]}
package/dist/legacy.d.ts CHANGED
@@ -9,10 +9,14 @@
9
9
  */
10
10
 
11
11
  export {
12
- // alpha APIs
12
+ // @alpha APIs
13
+ FluidHandleBase,
13
14
  RequestParser,
14
15
  RuntimeFactoryHelper,
15
16
  SummaryTreeBuilder,
16
17
  convertToSummaryTreeWithStats,
17
- create404Response
18
+ create404Response,
19
+ toDeltaManagerInternal,
20
+ toFluidHandleErased,
21
+ toFluidHandleInternal
18
22
  } from "./index.js";
@@ -0,0 +1,14 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import type { ISnapshotTree } from "@fluidframework/protocol-definitions";
6
+ /**
7
+ * Utility function to check if any blobs under a snapshot tree is missing and if so, then return
8
+ * true if that is the case.
9
+ * @internal
10
+ * @param snapshotTree - snapshotTree to be evaluated for missing blobs.
11
+ * @param blobContents - blobContents of the snapshot.
12
+ */
13
+ export declare function isSnapshotFetchRequiredForLoadingGroupId(snapshotTree: ISnapshotTree, blobContents: Map<string, ArrayBuffer>): boolean;
14
+ //# sourceMappingURL=snapshotUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotUtils.d.ts","sourceRoot":"","sources":["../src/snapshotUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAE1E;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACvD,YAAY,EAAE,aAAa,EAC3B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GACpC,OAAO,CAoBT"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isSnapshotFetchRequiredForLoadingGroupId = void 0;
8
+ /**
9
+ * Utility function to check if any blobs under a snapshot tree is missing and if so, then return
10
+ * true if that is the case.
11
+ * @internal
12
+ * @param snapshotTree - snapshotTree to be evaluated for missing blobs.
13
+ * @param blobContents - blobContents of the snapshot.
14
+ */
15
+ function isSnapshotFetchRequiredForLoadingGroupId(snapshotTree, blobContents) {
16
+ for (const [_, id] of Object.entries(snapshotTree.blobs)) {
17
+ if (!blobContents.has(id)) {
18
+ return true;
19
+ }
20
+ }
21
+ for (const [_, childTree] of Object.entries(snapshotTree.trees)) {
22
+ // Only evaluate childTree if it does not have a loading groupId because if the childTree has a loading
23
+ // groupId then it will be evaluated whether we want to fetch blobs for that childTree or not when
24
+ // that particular childTree is getting realized. Now we just want to check for blobs which belongs to
25
+ // tree with current loading groupId. Note: Child with no loading groupId, will fall under parent with
26
+ // a loading groupId as it does not have its own loading groupId.
27
+ if (childTree.groupId === undefined) {
28
+ const value = isSnapshotFetchRequiredForLoadingGroupId(childTree, blobContents);
29
+ if (value) {
30
+ return true;
31
+ }
32
+ }
33
+ }
34
+ return false;
35
+ }
36
+ exports.isSnapshotFetchRequiredForLoadingGroupId = isSnapshotFetchRequiredForLoadingGroupId;
37
+ //# sourceMappingURL=snapshotUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotUtils.js","sourceRoot":"","sources":["../src/snapshotUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH;;;;;;GAMG;AACH,SAAgB,wCAAwC,CACvD,YAA2B,EAC3B,YAAsC;IAEtC,KAAK,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;QACzD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC1B,OAAO,IAAI,CAAC;SACZ;KACD;IACD,KAAK,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;QAChE,uGAAuG;QACvG,kGAAkG;QAClG,sGAAsG;QACtG,sGAAsG;QACtG,iEAAiE;QACjE,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,EAAE;YACpC,MAAM,KAAK,GAAG,wCAAwC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YAChF,IAAI,KAAK,EAAE;gBACV,OAAO,IAAI,CAAC;aACZ;SACD;KACD;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAvBD,4FAuBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\n\n/**\n * Utility function to check if any blobs under a snapshot tree is missing and if so, then return\n * true if that is the case.\n * @internal\n * @param snapshotTree - snapshotTree to be evaluated for missing blobs.\n * @param blobContents - blobContents of the snapshot.\n */\nexport function isSnapshotFetchRequiredForLoadingGroupId(\n\tsnapshotTree: ISnapshotTree,\n\tblobContents: Map<string, ArrayBuffer>,\n): boolean {\n\tfor (const [_, id] of Object.entries(snapshotTree.blobs)) {\n\t\tif (!blobContents.has(id)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\tfor (const [_, childTree] of Object.entries(snapshotTree.trees)) {\n\t\t// Only evaluate childTree if it does not have a loading groupId because if the childTree has a loading\n\t\t// groupId then it will be evaluated whether we want to fetch blobs for that childTree or not when\n\t\t// that particular childTree is getting realized. Now we just want to check for blobs which belongs to\n\t\t// tree with current loading groupId. Note: Child with no loading groupId, will fall under parent with\n\t\t// a loading groupId as it does not have its own loading groupId.\n\t\tif (childTree.groupId === undefined) {\n\t\t\tconst value = isSnapshotFetchRequiredForLoadingGroupId(childTree, blobContents);\n\t\t\tif (value) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n"]}
@@ -0,0 +1,19 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import type { IDeltaManager } from "@fluidframework/container-definitions/internal";
6
+ import type { IDeltaManagerErased } from "@fluidframework/datastore-definitions";
7
+ import type { IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
+ /**
9
+ * Casts the public API for delta manager into the internal one,
10
+ * exposing access to APIs needed by the implementation of Fluid Framework but not its users.
11
+ * @alpha
12
+ */
13
+ export declare function toDeltaManagerInternal(deltaManager: IDeltaManagerErased): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
14
+ /**
15
+ * Casts the the internal API for delta manager into the public type erased API for returning from public APIs that should not have access to any of its members.
16
+ * @internal
17
+ */
18
+ export declare function toDeltaManagerErased(deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>): IDeltaManagerErased;
19
+ //# sourceMappingURL=deltaManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,KAAK,EACX,gBAAgB,EAChB,yBAAyB,EACzB,MAAM,sCAAsC,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,sBAAsB,CACrC,YAAY,EAAE,mBAAmB,GAC/B,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CAE5D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,GACtE,mBAAmB,CAErB"}
@@ -0,0 +1,20 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * Casts the public API for delta manager into the internal one,
7
+ * exposing access to APIs needed by the implementation of Fluid Framework but not its users.
8
+ * @alpha
9
+ */
10
+ export function toDeltaManagerInternal(deltaManager) {
11
+ return deltaManager;
12
+ }
13
+ /**
14
+ * Casts the the internal API for delta manager into the public type erased API for returning from public APIs that should not have access to any of its members.
15
+ * @internal
16
+ */
17
+ export function toDeltaManagerErased(deltaManager) {
18
+ return deltaManager;
19
+ }
20
+ //# sourceMappingURL=deltaManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltaManager.js","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACrC,YAAiC;IAEjC,OAAO,YAAqF,CAAC;AAC9F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CACnC,YAAwE;IAExE,OAAO,YAA8C,CAAC;AACvD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IDeltaManager } from \"@fluidframework/container-definitions/internal\";\nimport type { IDeltaManagerErased } from \"@fluidframework/datastore-definitions\";\nimport type {\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/protocol-definitions\";\n\n/**\n * Casts the public API for delta manager into the internal one,\n * exposing access to APIs needed by the implementation of Fluid Framework but not its users.\n * @alpha\n */\nexport function toDeltaManagerInternal(\n\tdeltaManager: IDeltaManagerErased,\n): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {\n\treturn deltaManager as unknown as IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;\n}\n\n/**\n * Casts the the internal API for delta manager into the public type erased API for returning from public APIs that should not have access to any of its members.\n * @internal\n */\nexport function toDeltaManagerErased(\n\tdeltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n): IDeltaManagerErased {\n\treturn deltaManager as unknown as IDeltaManagerErased;\n}\n"]}
package/lib/handles.d.ts CHANGED
@@ -2,6 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import type { IFluidHandleErased, IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
6
+ import { IFluidHandle, fluidHandleSymbol } from "@fluidframework/core-interfaces";
5
7
  /**
6
8
  * JSON serialized form of an IFluidHandle
7
9
  * @internal
@@ -15,4 +17,37 @@ export interface ISerializedHandle {
15
17
  * @internal
16
18
  */
17
19
  export declare const isSerializedHandle: (value: any) => value is ISerializedHandle;
20
+ /**
21
+ * Check if a value is an IFluidHandle.
22
+ * @remarks
23
+ * Objects which have a field named `IFluidHandle` can in some cases produce a false positive.
24
+ * @internal
25
+ */
26
+ export declare function isFluidHandle(value: unknown): value is IFluidHandle;
27
+ /**
28
+ * Downcast an IFluidHandle to an IFluidHandleInternal.
29
+ * @alpha
30
+ */
31
+ export declare function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleInternal<T>;
32
+ /**
33
+ * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.
34
+ * @alpha
35
+ */
36
+ export declare function toFluidHandleErased<T>(handle: IFluidHandleInternal<T>): IFluidHandleErased<T>;
37
+ /**
38
+ * Base class which can be uses to assist implementing IFluidHandleInternal.
39
+ * @alpha
40
+ */
41
+ export declare abstract class FluidHandleBase<T> implements IFluidHandleInternal<T> {
42
+ abstract absolutePath: string;
43
+ abstract attachGraph(): void;
44
+ abstract bind(handle: IFluidHandleInternal): void;
45
+ abstract readonly isAttached: boolean;
46
+ abstract get(): Promise<T>;
47
+ /**
48
+ * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}
49
+ */
50
+ get IFluidHandle(): IFluidHandleInternal;
51
+ get [fluidHandleSymbol](): IFluidHandleErased<T>;
52
+ }
18
53
  //# sourceMappingURL=handles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAEjC,IAAI,EAAE,kBAAkB,CAAC;IAGzB,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAW,GAAG,+BACV,CAAC"}
1
+ {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,kBAAkB,EAClB,oBAAoB,EACpB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAElF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAEjC,IAAI,EAAE,kBAAkB,CAAC;IAGzB,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAW,GAAG,+BACV,CAAC;AAcpC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAkBnE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAWzF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAE7F;AAED;;;GAGG;AACH,8BAAsB,eAAe,CAAC,CAAC,CAAE,YAAW,oBAAoB,CAAC,CAAC,CAAC;IAC1E,SAAgB,YAAY,EAAE,MAAM,CAAC;aACrB,WAAW,IAAI,IAAI;aACnB,IAAI,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IACxD,kBAAyB,UAAU,EAAE,OAAO,CAAC;aAC7B,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IAEjC;;OAEG;IACH,IAAW,YAAY,IAAI,oBAAoB,CAE9C;IAED,IAAW,CAAC,iBAAiB,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,CAEtD;CACD"}
package/lib/handles.js CHANGED
@@ -2,9 +2,83 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import { IFluidHandle, fluidHandleSymbol } from "@fluidframework/core-interfaces";
5
6
  /**
6
7
  * Is the input object a @see ISerializedHandle?
7
8
  * @internal
8
9
  */
9
10
  export const isSerializedHandle = (value) => value?.type === "__fluid_handle__";
11
+ /**
12
+ * Setting to opt into compatibility with handles from before {@link fluidHandleSymbol} existed (Fluid Framework client 2.0.0-rc.3.0.0 and earlier).
13
+ *
14
+ * Some code which uses this library might dynamically load multiple versions of it,
15
+ * as well as old or duplicated versions of packages which produce or implement handles.
16
+ * To correctly interoperate with this old packages and object produced by them, the old in-memory format for handles, without the symbol, are explicitly supported.
17
+ *
18
+ * This setting mostly exists as a way to easily find any code that only exists to provide this compatibility and clarify how to remove that compatibility.
19
+ * At some point this might be removed or turned into an actual configuration option, but for now its really just documentation.
20
+ */
21
+ const enableBackwardsCompatibility = true;
22
+ /**
23
+ * Check if a value is an IFluidHandle.
24
+ * @remarks
25
+ * Objects which have a field named `IFluidHandle` can in some cases produce a false positive.
26
+ * @internal
27
+ */
28
+ export function isFluidHandle(value) {
29
+ // `in` gives a type error on non-objects and null, so filter them out
30
+ if (typeof value !== "object" || value === null) {
31
+ return false;
32
+ }
33
+ if (fluidHandleSymbol in value) {
34
+ return true;
35
+ }
36
+ // If enableBackwardsCompatibility, run check for FluidHandles predating use of fluidHandleSymbol.
37
+ if (enableBackwardsCompatibility && IFluidHandle in value) {
38
+ // Since this check can have false positives, make it a bit more robust by checking value[IFluidHandle][IFluidHandle]
39
+ const inner = value[IFluidHandle];
40
+ if (typeof inner !== "object" || inner === null) {
41
+ return false;
42
+ }
43
+ return IFluidHandle in inner;
44
+ }
45
+ return false;
46
+ }
47
+ /**
48
+ * Downcast an IFluidHandle to an IFluidHandleInternal.
49
+ * @alpha
50
+ */
51
+ export function toFluidHandleInternal(handle) {
52
+ if (!(fluidHandleSymbol in handle) || !(fluidHandleSymbol in handle[fluidHandleSymbol])) {
53
+ if (enableBackwardsCompatibility && IFluidHandle in handle) {
54
+ return handle[IFluidHandle];
55
+ }
56
+ throw new TypeError("Invalid IFluidHandle");
57
+ }
58
+ // This casts the IFluidHandleErased from the symbol instead of `handle` to ensure that if someone
59
+ // implements their own IFluidHandle in terms of an existing handle, it won't break anything.
60
+ return handle[fluidHandleSymbol];
61
+ }
62
+ /**
63
+ * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.
64
+ * @alpha
65
+ */
66
+ export function toFluidHandleErased(handle) {
67
+ return handle;
68
+ }
69
+ /**
70
+ * Base class which can be uses to assist implementing IFluidHandleInternal.
71
+ * @alpha
72
+ */
73
+ export class FluidHandleBase {
74
+ /**
75
+ * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}
76
+ */
77
+ get IFluidHandle() {
78
+ return this;
79
+ }
80
+ get [fluidHandleSymbol]() {
81
+ return toFluidHandleErased(this);
82
+ }
83
+ }
10
84
  //# sourceMappingURL=handles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handles.js","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAU,EAA8B,EAAE,CAC5E,KAAK,EAAE,IAAI,KAAK,kBAAkB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * JSON serialized form of an IFluidHandle\n * @internal\n */\nexport interface ISerializedHandle {\n\t// Marker to indicate to JSON.parse that the object is a Fluid handle\n\ttype: \"__fluid_handle__\";\n\n\t// URL to the object. Relative URLs are relative to the handle context passed to the stringify.\n\turl: string;\n}\n\n/**\n * Is the input object a @see ISerializedHandle?\n * @internal\n */\nexport const isSerializedHandle = (value: any): value is ISerializedHandle =>\n\tvalue?.type === \"__fluid_handle__\";\n"]}
1
+ {"version":3,"file":"handles.js","sourceRoot":"","sources":["../src/handles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAclF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAU,EAA8B,EAAE,CAC5E,KAAK,EAAE,IAAI,KAAK,kBAAkB,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC3C,sEAAsE;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;QAChD,OAAO,KAAK,CAAC;KACb;IACD,IAAI,iBAAiB,IAAI,KAAK,EAAE;QAC/B,OAAO,IAAI,CAAC;KACZ;IACD,kGAAkG;IAClG,IAAI,4BAA4B,IAAI,YAAY,IAAI,KAAK,EAAE;QAC1D,qHAAqH;QACrH,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAiB,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE;YAChD,OAAO,KAAK,CAAC;SACb;QACD,OAAO,YAAY,IAAI,KAAK,CAAC;KAC7B;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAI,MAAuB;IAC/D,IAAI,CAAC,CAAC,iBAAiB,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,iBAAiB,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAC,EAAE;QACxF,IAAI,4BAA4B,IAAI,YAAY,IAAI,MAAM,EAAE;YAC3D,OAAO,MAAM,CAAC,YAAY,CAA4B,CAAC;SACvD;QACD,MAAM,IAAI,SAAS,CAAC,sBAAsB,CAAC,CAAC;KAC5C;IAED,kGAAkG;IAClG,6FAA6F;IAC7F,OAAO,MAAM,CAAC,iBAAiB,CAAuC,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAI,MAA+B;IACrE,OAAO,MAA0C,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,OAAgB,eAAe;IAOpC;;OAEG;IACH,IAAW,YAAY;QACtB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAW,CAAC,iBAAiB,CAAC;QAC7B,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tIFluidHandleErased,\n\tIFluidHandleInternal,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { IFluidHandle, fluidHandleSymbol } from \"@fluidframework/core-interfaces\";\n\n/**\n * JSON serialized form of an IFluidHandle\n * @internal\n */\nexport interface ISerializedHandle {\n\t// Marker to indicate to JSON.parse that the object is a Fluid handle\n\ttype: \"__fluid_handle__\";\n\n\t// URL to the object. Relative URLs are relative to the handle context passed to the stringify.\n\turl: string;\n}\n\n/**\n * Is the input object a @see ISerializedHandle?\n * @internal\n */\nexport const isSerializedHandle = (value: any): value is ISerializedHandle =>\n\tvalue?.type === \"__fluid_handle__\";\n\n/**\n * Setting to opt into compatibility with handles from before {@link fluidHandleSymbol} existed (Fluid Framework client 2.0.0-rc.3.0.0 and earlier).\n *\n * Some code which uses this library might dynamically load multiple versions of it,\n * as well as old or duplicated versions of packages which produce or implement handles.\n * To correctly interoperate with this old packages and object produced by them, the old in-memory format for handles, without the symbol, are explicitly supported.\n *\n * This setting mostly exists as a way to easily find any code that only exists to provide this compatibility and clarify how to remove that compatibility.\n * At some point this might be removed or turned into an actual configuration option, but for now its really just documentation.\n */\nconst enableBackwardsCompatibility = true;\n\n/**\n * Check if a value is an IFluidHandle.\n * @remarks\n * Objects which have a field named `IFluidHandle` can in some cases produce a false positive.\n * @internal\n */\nexport function isFluidHandle(value: unknown): value is IFluidHandle {\n\t// `in` gives a type error on non-objects and null, so filter them out\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tif (fluidHandleSymbol in value) {\n\t\treturn true;\n\t}\n\t// If enableBackwardsCompatibility, run check for FluidHandles predating use of fluidHandleSymbol.\n\tif (enableBackwardsCompatibility && IFluidHandle in value) {\n\t\t// Since this check can have false positives, make it a bit more robust by checking value[IFluidHandle][IFluidHandle]\n\t\tconst inner = value[IFluidHandle] as IFluidHandle;\n\t\tif (typeof inner !== \"object\" || inner === null) {\n\t\t\treturn false;\n\t\t}\n\t\treturn IFluidHandle in inner;\n\t}\n\treturn false;\n}\n\n/**\n * Downcast an IFluidHandle to an IFluidHandleInternal.\n * @alpha\n */\nexport function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleInternal<T> {\n\tif (!(fluidHandleSymbol in handle) || !(fluidHandleSymbol in handle[fluidHandleSymbol])) {\n\t\tif (enableBackwardsCompatibility && IFluidHandle in handle) {\n\t\t\treturn handle[IFluidHandle] as IFluidHandleInternal<T>;\n\t\t}\n\t\tthrow new TypeError(\"Invalid IFluidHandle\");\n\t}\n\n\t// This casts the IFluidHandleErased from the symbol instead of `handle` to ensure that if someone\n\t// implements their own IFluidHandle in terms of an existing handle, it won't break anything.\n\treturn handle[fluidHandleSymbol] as unknown as IFluidHandleInternal<T>;\n}\n\n/**\n * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.\n * @alpha\n */\nexport function toFluidHandleErased<T>(handle: IFluidHandleInternal<T>): IFluidHandleErased<T> {\n\treturn handle as unknown as IFluidHandleErased<T>;\n}\n\n/**\n * Base class which can be uses to assist implementing IFluidHandleInternal.\n * @alpha\n */\nexport abstract class FluidHandleBase<T> implements IFluidHandleInternal<T> {\n\tpublic abstract absolutePath: string;\n\tpublic abstract attachGraph(): void;\n\tpublic abstract bind(handle: IFluidHandleInternal): void;\n\tpublic abstract readonly isAttached: boolean;\n\tpublic abstract get(): Promise<T>;\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}\n\t */\n\tpublic get IFluidHandle(): IFluidHandleInternal {\n\t\treturn this;\n\t}\n\n\tpublic get [fluidHandleSymbol](): IFluidHandleErased<T> {\n\t\treturn toFluidHandleErased(this);\n\t}\n}\n"]}
package/lib/index.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { generateHandleContextPath } from "./dataStoreHandleContextUtils.js";
6
6
  export { create404Response, createDataStoreFactory, createResponseError, exceptionToResponse, Factory, responseToException, } from "./dataStoreHelpers.js";
7
- export { ISerializedHandle, isSerializedHandle } from "./handles.js";
7
+ export { ISerializedHandle, isSerializedHandle, isFluidHandle, toFluidHandleErased, toFluidHandleInternal, FluidHandleBase, } from "./handles.js";
8
8
  export { ObjectStoragePartition } from "./objectstoragepartition.js";
9
9
  export { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from "./objectstorageutils.js";
10
10
  export { RequestParser } from "./requestParser.js";
@@ -12,4 +12,6 @@ export { RuntimeFactoryHelper } from "./runtimeFactoryHelper.js";
12
12
  export { addBlobToSummary, addSummarizeResultToSummary, calculateStats, convertSnapshotTreeToSummaryTree, convertSummaryTreeToITree, convertToSummaryTree, convertToSummaryTreeWithStats, GCDataBuilder, getBlobSize, mergeStats, processAttachMessageGCData, SummaryTreeBuilder, TelemetryContext, utf8ByteLength, } from "./summaryUtils.js";
13
13
  export { unpackChildNodesUsedRoutes } from "./unpackUsedRoutes.js";
14
14
  export { ReadAndParseBlob, seqFromTree, encodeCompactIdToString } from "./utils.js";
15
+ export { isSnapshotFetchRequiredForLoadingGroupId } from "./snapshotUtils.js";
16
+ export { toDeltaManagerErased, toDeltaManagerInternal } from "./deltaManager.js";
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EACN,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,OAAO,EACP,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,cAAc,EACd,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EACN,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,OAAO,EACP,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,cAAc,EACd,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,wCAAwC,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
package/lib/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { generateHandleContextPath } from "./dataStoreHandleContextUtils.js";
6
6
  export { create404Response, createDataStoreFactory, createResponseError, exceptionToResponse, responseToException, } from "./dataStoreHelpers.js";
7
- export { isSerializedHandle } from "./handles.js";
7
+ export { isSerializedHandle, isFluidHandle, toFluidHandleErased, toFluidHandleInternal, FluidHandleBase, } from "./handles.js";
8
8
  export { ObjectStoragePartition } from "./objectstoragepartition.js";
9
9
  export { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from "./objectstorageutils.js";
10
10
  export { RequestParser } from "./requestParser.js";
@@ -12,4 +12,6 @@ export { RuntimeFactoryHelper } from "./runtimeFactoryHelper.js";
12
12
  export { addBlobToSummary, addSummarizeResultToSummary, calculateStats, convertSnapshotTreeToSummaryTree, convertSummaryTreeToITree, convertToSummaryTree, convertToSummaryTreeWithStats, GCDataBuilder, getBlobSize, mergeStats, processAttachMessageGCData, SummaryTreeBuilder, TelemetryContext, utf8ByteLength, } from "./summaryUtils.js";
13
13
  export { unpackChildNodesUsedRoutes } from "./unpackUsedRoutes.js";
14
14
  export { seqFromTree, encodeCompactIdToString } from "./utils.js";
15
+ export { isSnapshotFetchRequiredForLoadingGroupId } from "./snapshotUtils.js";
16
+ export { toDeltaManagerErased, toDeltaManagerInternal } from "./deltaManager.js";
15
17
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EACN,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EAEnB,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAqB,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,cAAc,EACd,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAoB,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { generateHandleContextPath } from \"./dataStoreHandleContextUtils.js\";\nexport {\n\tcreate404Response,\n\tcreateDataStoreFactory,\n\tcreateResponseError,\n\texceptionToResponse,\n\tFactory,\n\tresponseToException,\n} from \"./dataStoreHelpers.js\";\nexport { ISerializedHandle, isSerializedHandle } from \"./handles.js\";\nexport { ObjectStoragePartition } from \"./objectstoragepartition.js\";\nexport { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from \"./objectstorageutils.js\";\nexport { RequestParser } from \"./requestParser.js\";\nexport { RuntimeFactoryHelper } from \"./runtimeFactoryHelper.js\";\nexport {\n\taddBlobToSummary,\n\taddSummarizeResultToSummary,\n\tcalculateStats,\n\tconvertSnapshotTreeToSummaryTree,\n\tconvertSummaryTreeToITree,\n\tconvertToSummaryTree,\n\tconvertToSummaryTreeWithStats,\n\tGCDataBuilder,\n\tgetBlobSize,\n\tmergeStats,\n\tprocessAttachMessageGCData,\n\tSummaryTreeBuilder,\n\tTelemetryContext,\n\tutf8ByteLength,\n} from \"./summaryUtils.js\";\nexport { unpackChildNodesUsedRoutes } from \"./unpackUsedRoutes.js\";\nexport { ReadAndParseBlob, seqFromTree, encodeCompactIdToString } from \"./utils.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EACN,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EAEnB,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEN,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,cAAc,EACd,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAoB,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,wCAAwC,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { generateHandleContextPath } from \"./dataStoreHandleContextUtils.js\";\nexport {\n\tcreate404Response,\n\tcreateDataStoreFactory,\n\tcreateResponseError,\n\texceptionToResponse,\n\tFactory,\n\tresponseToException,\n} from \"./dataStoreHelpers.js\";\nexport {\n\tISerializedHandle,\n\tisSerializedHandle,\n\tisFluidHandle,\n\ttoFluidHandleErased,\n\ttoFluidHandleInternal,\n\tFluidHandleBase,\n} from \"./handles.js\";\nexport { ObjectStoragePartition } from \"./objectstoragepartition.js\";\nexport { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from \"./objectstorageutils.js\";\nexport { RequestParser } from \"./requestParser.js\";\nexport { RuntimeFactoryHelper } from \"./runtimeFactoryHelper.js\";\nexport {\n\taddBlobToSummary,\n\taddSummarizeResultToSummary,\n\tcalculateStats,\n\tconvertSnapshotTreeToSummaryTree,\n\tconvertSummaryTreeToITree,\n\tconvertToSummaryTree,\n\tconvertToSummaryTreeWithStats,\n\tGCDataBuilder,\n\tgetBlobSize,\n\tmergeStats,\n\tprocessAttachMessageGCData,\n\tSummaryTreeBuilder,\n\tTelemetryContext,\n\tutf8ByteLength,\n} from \"./summaryUtils.js\";\nexport { unpackChildNodesUsedRoutes } from \"./unpackUsedRoutes.js\";\nexport { ReadAndParseBlob, seqFromTree, encodeCompactIdToString } from \"./utils.js\";\nexport { isSnapshotFetchRequiredForLoadingGroupId } from \"./snapshotUtils.js\";\nexport { toDeltaManagerErased, toDeltaManagerInternal } from \"./deltaManager.js\";\n"]}
package/lib/legacy.d.ts CHANGED
@@ -9,10 +9,14 @@
9
9
  */
10
10
 
11
11
  export {
12
- // alpha APIs
12
+ // @alpha APIs
13
+ FluidHandleBase,
13
14
  RequestParser,
14
15
  RuntimeFactoryHelper,
15
16
  SummaryTreeBuilder,
16
17
  convertToSummaryTreeWithStats,
17
- create404Response
18
+ create404Response,
19
+ toDeltaManagerInternal,
20
+ toFluidHandleErased,
21
+ toFluidHandleInternal
18
22
  } from "./index.js";
@@ -0,0 +1,14 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import type { ISnapshotTree } from "@fluidframework/protocol-definitions";
6
+ /**
7
+ * Utility function to check if any blobs under a snapshot tree is missing and if so, then return
8
+ * true if that is the case.
9
+ * @internal
10
+ * @param snapshotTree - snapshotTree to be evaluated for missing blobs.
11
+ * @param blobContents - blobContents of the snapshot.
12
+ */
13
+ export declare function isSnapshotFetchRequiredForLoadingGroupId(snapshotTree: ISnapshotTree, blobContents: Map<string, ArrayBuffer>): boolean;
14
+ //# sourceMappingURL=snapshotUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotUtils.d.ts","sourceRoot":"","sources":["../src/snapshotUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAE1E;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACvD,YAAY,EAAE,aAAa,EAC3B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GACpC,OAAO,CAoBT"}
@@ -0,0 +1,33 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * Utility function to check if any blobs under a snapshot tree is missing and if so, then return
7
+ * true if that is the case.
8
+ * @internal
9
+ * @param snapshotTree - snapshotTree to be evaluated for missing blobs.
10
+ * @param blobContents - blobContents of the snapshot.
11
+ */
12
+ export function isSnapshotFetchRequiredForLoadingGroupId(snapshotTree, blobContents) {
13
+ for (const [_, id] of Object.entries(snapshotTree.blobs)) {
14
+ if (!blobContents.has(id)) {
15
+ return true;
16
+ }
17
+ }
18
+ for (const [_, childTree] of Object.entries(snapshotTree.trees)) {
19
+ // Only evaluate childTree if it does not have a loading groupId because if the childTree has a loading
20
+ // groupId then it will be evaluated whether we want to fetch blobs for that childTree or not when
21
+ // that particular childTree is getting realized. Now we just want to check for blobs which belongs to
22
+ // tree with current loading groupId. Note: Child with no loading groupId, will fall under parent with
23
+ // a loading groupId as it does not have its own loading groupId.
24
+ if (childTree.groupId === undefined) {
25
+ const value = isSnapshotFetchRequiredForLoadingGroupId(childTree, blobContents);
26
+ if (value) {
27
+ return true;
28
+ }
29
+ }
30
+ }
31
+ return false;
32
+ }
33
+ //# sourceMappingURL=snapshotUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotUtils.js","sourceRoot":"","sources":["../src/snapshotUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,wCAAwC,CACvD,YAA2B,EAC3B,YAAsC;IAEtC,KAAK,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;QACzD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC1B,OAAO,IAAI,CAAC;SACZ;KACD;IACD,KAAK,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;QAChE,uGAAuG;QACvG,kGAAkG;QAClG,sGAAsG;QACtG,sGAAsG;QACtG,iEAAiE;QACjE,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,EAAE;YACpC,MAAM,KAAK,GAAG,wCAAwC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YAChF,IAAI,KAAK,EAAE;gBACV,OAAO,IAAI,CAAC;aACZ;SACD;KACD;IACD,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\n\n/**\n * Utility function to check if any blobs under a snapshot tree is missing and if so, then return\n * true if that is the case.\n * @internal\n * @param snapshotTree - snapshotTree to be evaluated for missing blobs.\n * @param blobContents - blobContents of the snapshot.\n */\nexport function isSnapshotFetchRequiredForLoadingGroupId(\n\tsnapshotTree: ISnapshotTree,\n\tblobContents: Map<string, ArrayBuffer>,\n): boolean {\n\tfor (const [_, id] of Object.entries(snapshotTree.blobs)) {\n\t\tif (!blobContents.has(id)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\tfor (const [_, childTree] of Object.entries(snapshotTree.trees)) {\n\t\t// Only evaluate childTree if it does not have a loading groupId because if the childTree has a loading\n\t\t// groupId then it will be evaluated whether we want to fetch blobs for that childTree or not when\n\t\t// that particular childTree is getting realized. Now we just want to check for blobs which belongs to\n\t\t// tree with current loading groupId. Note: Child with no loading groupId, will fall under parent with\n\t\t// a loading groupId as it does not have its own loading groupId.\n\t\tif (childTree.groupId === undefined) {\n\t\t\tconst value = isSnapshotFetchRequiredForLoadingGroupId(childTree, blobContents);\n\t\t\tif (value) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.42.3"
8
+ "packageVersion": "7.43.1"
9
9
  }
10
10
  ]
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/runtime-utils",
3
- "version": "2.0.0-rc.3.0.2",
3
+ "version": "2.0.0-rc.4.0.0",
4
4
  "description": "Collection of utility functions for Fluid Runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -67,27 +67,27 @@
67
67
  "temp-directory": "nyc/.nyc_output"
68
68
  },
69
69
  "dependencies": {
70
- "@fluid-internal/client-utils": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
71
- "@fluidframework/container-definitions": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
72
- "@fluidframework/container-runtime-definitions": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
73
- "@fluidframework/core-interfaces": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
74
- "@fluidframework/core-utils": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
75
- "@fluidframework/datastore-definitions": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
76
- "@fluidframework/driver-utils": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
70
+ "@fluid-internal/client-utils": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
71
+ "@fluidframework/container-definitions": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
72
+ "@fluidframework/container-runtime-definitions": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
73
+ "@fluidframework/core-interfaces": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
74
+ "@fluidframework/core-utils": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
75
+ "@fluidframework/datastore-definitions": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
76
+ "@fluidframework/driver-utils": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
77
77
  "@fluidframework/protocol-definitions": "^3.2.0",
78
- "@fluidframework/runtime-definitions": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
79
- "@fluidframework/telemetry-utils": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0"
78
+ "@fluidframework/runtime-definitions": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
79
+ "@fluidframework/telemetry-utils": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0"
80
80
  },
81
81
  "devDependencies": {
82
82
  "@arethetypeswrong/cli": "^0.15.2",
83
83
  "@biomejs/biome": "^1.6.2",
84
- "@fluid-internal/mocha-test-setup": ">=2.0.0-rc.3.0.2 <2.0.0-rc.3.1.0",
85
- "@fluid-tools/build-cli": "^0.37.0",
84
+ "@fluid-internal/mocha-test-setup": ">=2.0.0-rc.4.0.0 <2.0.0-rc.4.1.0",
85
+ "@fluid-tools/build-cli": "^0.38.0",
86
86
  "@fluidframework/build-common": "^2.0.3",
87
- "@fluidframework/build-tools": "^0.37.0",
87
+ "@fluidframework/build-tools": "^0.38.0",
88
88
  "@fluidframework/eslint-config-fluid": "^5.1.0",
89
- "@fluidframework/runtime-utils-previous": "npm:@fluidframework/runtime-utils@2.0.0-internal.8.0.0",
90
- "@microsoft/api-extractor": "^7.42.3",
89
+ "@fluidframework/runtime-utils-previous": "npm:@fluidframework/runtime-utils@2.0.0-rc.3.0.0",
90
+ "@microsoft/api-extractor": "^7.43.1",
91
91
  "@types/mocha": "^9.1.1",
92
92
  "@types/node": "^18.19.0",
93
93
  "@types/sinon": "^17.0.3",
@@ -106,12 +106,7 @@
106
106
  "typescript": "~5.1.6"
107
107
  },
108
108
  "typeValidation": {
109
- "broken": {
110
- "RemovedFunctionDeclaration_addTreeToSummary": {
111
- "forwardCompat": false,
112
- "backCompat": false
113
- }
114
- }
109
+ "broken": {}
115
110
  },
116
111
  "scripts": {
117
112
  "api": "fluid-build . --task api",
@@ -143,7 +138,7 @@
143
138
  "test:mocha:esm": "mocha --recursive \"lib/test/**/*.spec.*js\" --exit",
144
139
  "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
145
140
  "tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
146
- "typetests:gen": "fluid-type-test-generator",
141
+ "typetests:gen": "flub generate typetests --dir . -v --publicFallback",
147
142
  "typetests:prepare": "flub typetests --dir . --reset --previous --normalize"
148
143
  }
149
144
  }
@@ -0,0 +1,32 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type { IDeltaManager } from "@fluidframework/container-definitions/internal";
7
+ import type { IDeltaManagerErased } from "@fluidframework/datastore-definitions";
8
+ import type {
9
+ IDocumentMessage,
10
+ ISequencedDocumentMessage,
11
+ } from "@fluidframework/protocol-definitions";
12
+
13
+ /**
14
+ * Casts the public API for delta manager into the internal one,
15
+ * exposing access to APIs needed by the implementation of Fluid Framework but not its users.
16
+ * @alpha
17
+ */
18
+ export function toDeltaManagerInternal(
19
+ deltaManager: IDeltaManagerErased,
20
+ ): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
21
+ return deltaManager as unknown as IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
22
+ }
23
+
24
+ /**
25
+ * Casts the the internal API for delta manager into the public type erased API for returning from public APIs that should not have access to any of its members.
26
+ * @internal
27
+ */
28
+ export function toDeltaManagerErased(
29
+ deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
30
+ ): IDeltaManagerErased {
31
+ return deltaManager as unknown as IDeltaManagerErased;
32
+ }
package/src/handles.ts CHANGED
@@ -3,6 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import type {
7
+ IFluidHandleErased,
8
+ IFluidHandleInternal,
9
+ } from "@fluidframework/core-interfaces/internal";
10
+ import { IFluidHandle, fluidHandleSymbol } from "@fluidframework/core-interfaces";
11
+
6
12
  /**
7
13
  * JSON serialized form of an IFluidHandle
8
14
  * @internal
@@ -21,3 +27,89 @@ export interface ISerializedHandle {
21
27
  */
22
28
  export const isSerializedHandle = (value: any): value is ISerializedHandle =>
23
29
  value?.type === "__fluid_handle__";
30
+
31
+ /**
32
+ * Setting to opt into compatibility with handles from before {@link fluidHandleSymbol} existed (Fluid Framework client 2.0.0-rc.3.0.0 and earlier).
33
+ *
34
+ * Some code which uses this library might dynamically load multiple versions of it,
35
+ * as well as old or duplicated versions of packages which produce or implement handles.
36
+ * To correctly interoperate with this old packages and object produced by them, the old in-memory format for handles, without the symbol, are explicitly supported.
37
+ *
38
+ * This setting mostly exists as a way to easily find any code that only exists to provide this compatibility and clarify how to remove that compatibility.
39
+ * At some point this might be removed or turned into an actual configuration option, but for now its really just documentation.
40
+ */
41
+ const enableBackwardsCompatibility = true;
42
+
43
+ /**
44
+ * Check if a value is an IFluidHandle.
45
+ * @remarks
46
+ * Objects which have a field named `IFluidHandle` can in some cases produce a false positive.
47
+ * @internal
48
+ */
49
+ export function isFluidHandle(value: unknown): value is IFluidHandle {
50
+ // `in` gives a type error on non-objects and null, so filter them out
51
+ if (typeof value !== "object" || value === null) {
52
+ return false;
53
+ }
54
+ if (fluidHandleSymbol in value) {
55
+ return true;
56
+ }
57
+ // If enableBackwardsCompatibility, run check for FluidHandles predating use of fluidHandleSymbol.
58
+ if (enableBackwardsCompatibility && IFluidHandle in value) {
59
+ // Since this check can have false positives, make it a bit more robust by checking value[IFluidHandle][IFluidHandle]
60
+ const inner = value[IFluidHandle] as IFluidHandle;
61
+ if (typeof inner !== "object" || inner === null) {
62
+ return false;
63
+ }
64
+ return IFluidHandle in inner;
65
+ }
66
+ return false;
67
+ }
68
+
69
+ /**
70
+ * Downcast an IFluidHandle to an IFluidHandleInternal.
71
+ * @alpha
72
+ */
73
+ export function toFluidHandleInternal<T>(handle: IFluidHandle<T>): IFluidHandleInternal<T> {
74
+ if (!(fluidHandleSymbol in handle) || !(fluidHandleSymbol in handle[fluidHandleSymbol])) {
75
+ if (enableBackwardsCompatibility && IFluidHandle in handle) {
76
+ return handle[IFluidHandle] as IFluidHandleInternal<T>;
77
+ }
78
+ throw new TypeError("Invalid IFluidHandle");
79
+ }
80
+
81
+ // This casts the IFluidHandleErased from the symbol instead of `handle` to ensure that if someone
82
+ // implements their own IFluidHandle in terms of an existing handle, it won't break anything.
83
+ return handle[fluidHandleSymbol] as unknown as IFluidHandleInternal<T>;
84
+ }
85
+
86
+ /**
87
+ * Type erase IFluidHandleInternal for use with {@link @fluidframework/core-interfaces#fluidHandleSymbol}.
88
+ * @alpha
89
+ */
90
+ export function toFluidHandleErased<T>(handle: IFluidHandleInternal<T>): IFluidHandleErased<T> {
91
+ return handle as unknown as IFluidHandleErased<T>;
92
+ }
93
+
94
+ /**
95
+ * Base class which can be uses to assist implementing IFluidHandleInternal.
96
+ * @alpha
97
+ */
98
+ export abstract class FluidHandleBase<T> implements IFluidHandleInternal<T> {
99
+ public abstract absolutePath: string;
100
+ public abstract attachGraph(): void;
101
+ public abstract bind(handle: IFluidHandleInternal): void;
102
+ public abstract readonly isAttached: boolean;
103
+ public abstract get(): Promise<T>;
104
+
105
+ /**
106
+ * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}
107
+ */
108
+ public get IFluidHandle(): IFluidHandleInternal {
109
+ return this;
110
+ }
111
+
112
+ public get [fluidHandleSymbol](): IFluidHandleErased<T> {
113
+ return toFluidHandleErased(this);
114
+ }
115
+ }
package/src/index.ts CHANGED
@@ -12,7 +12,14 @@ export {
12
12
  Factory,
13
13
  responseToException,
14
14
  } from "./dataStoreHelpers.js";
15
- export { ISerializedHandle, isSerializedHandle } from "./handles.js";
15
+ export {
16
+ ISerializedHandle,
17
+ isSerializedHandle,
18
+ isFluidHandle,
19
+ toFluidHandleErased,
20
+ toFluidHandleInternal,
21
+ FluidHandleBase,
22
+ } from "./handles.js";
16
23
  export { ObjectStoragePartition } from "./objectstoragepartition.js";
17
24
  export { getNormalizedObjectStoragePathParts, listBlobsAtTreePath } from "./objectstorageutils.js";
18
25
  export { RequestParser } from "./requestParser.js";
@@ -35,3 +42,5 @@ export {
35
42
  } from "./summaryUtils.js";
36
43
  export { unpackChildNodesUsedRoutes } from "./unpackUsedRoutes.js";
37
44
  export { ReadAndParseBlob, seqFromTree, encodeCompactIdToString } from "./utils.js";
45
+ export { isSnapshotFetchRequiredForLoadingGroupId } from "./snapshotUtils.js";
46
+ export { toDeltaManagerErased, toDeltaManagerInternal } from "./deltaManager.js";
@@ -0,0 +1,38 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type { ISnapshotTree } from "@fluidframework/protocol-definitions";
7
+
8
+ /**
9
+ * Utility function to check if any blobs under a snapshot tree is missing and if so, then return
10
+ * true if that is the case.
11
+ * @internal
12
+ * @param snapshotTree - snapshotTree to be evaluated for missing blobs.
13
+ * @param blobContents - blobContents of the snapshot.
14
+ */
15
+ export function isSnapshotFetchRequiredForLoadingGroupId(
16
+ snapshotTree: ISnapshotTree,
17
+ blobContents: Map<string, ArrayBuffer>,
18
+ ): boolean {
19
+ for (const [_, id] of Object.entries(snapshotTree.blobs)) {
20
+ if (!blobContents.has(id)) {
21
+ return true;
22
+ }
23
+ }
24
+ for (const [_, childTree] of Object.entries(snapshotTree.trees)) {
25
+ // Only evaluate childTree if it does not have a loading groupId because if the childTree has a loading
26
+ // groupId then it will be evaluated whether we want to fetch blobs for that childTree or not when
27
+ // that particular childTree is getting realized. Now we just want to check for blobs which belongs to
28
+ // tree with current loading groupId. Note: Child with no loading groupId, will fall under parent with
29
+ // a loading groupId as it does not have its own loading groupId.
30
+ if (childTree.groupId === undefined) {
31
+ const value = isSnapshotFetchRequiredForLoadingGroupId(childTree, blobContents);
32
+ if (value) {
33
+ return true;
34
+ }
35
+ }
36
+ }
37
+ return false;
38
+ }