@fluidframework/container-loader 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.224419
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/.eslintrc.js +18 -21
- package/.mocharc.js +12 -0
- package/CHANGELOG.md +364 -0
- package/README.md +152 -56
- package/api-extractor-lint.json +4 -0
- package/api-extractor.json +2 -2
- package/api-report/container-loader.api.md +143 -0
- package/dist/{audience.js → audience.cjs} +15 -13
- package/dist/audience.cjs.map +1 -0
- package/dist/audience.d.ts +4 -6
- package/dist/audience.d.ts.map +1 -1
- package/dist/catchUpMonitor.cjs +43 -0
- package/dist/catchUpMonitor.cjs.map +1 -0
- package/dist/catchUpMonitor.d.ts +29 -0
- package/dist/catchUpMonitor.d.ts.map +1 -0
- package/dist/{connectionManager.js → connectionManager.cjs} +397 -240
- package/dist/connectionManager.cjs.map +1 -0
- package/dist/connectionManager.d.ts +23 -33
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/{connectionState.js → connectionState.cjs} +5 -7
- package/dist/connectionState.cjs.map +1 -0
- package/dist/connectionState.d.ts +3 -5
- package/dist/connectionState.d.ts.map +1 -1
- package/dist/connectionStateHandler.cjs +474 -0
- package/dist/connectionStateHandler.cjs.map +1 -0
- package/dist/connectionStateHandler.d.ts +127 -29
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/container-loader-alpha.d.ts +274 -0
- package/dist/container-loader-beta.d.ts +75 -0
- package/dist/container-loader-public.d.ts +75 -0
- package/dist/container-loader-untrimmed.d.ts +331 -0
- package/dist/container.cjs +1585 -0
- package/dist/container.cjs.map +1 -0
- package/dist/container.d.ts +227 -83
- package/dist/container.d.ts.map +1 -1
- package/dist/containerContext.cjs +74 -0
- package/dist/containerContext.cjs.map +1 -0
- package/dist/containerContext.d.ts +33 -59
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerStorageAdapter.cjs +234 -0
- package/dist/containerStorageAdapter.cjs.map +1 -0
- package/dist/containerStorageAdapter.d.ts +48 -23
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/{contracts.js → contracts.cjs} +5 -5
- package/dist/contracts.cjs.map +1 -0
- package/dist/contracts.d.ts +45 -17
- package/dist/contracts.d.ts.map +1 -1
- package/dist/debugLogger.cjs +101 -0
- package/dist/debugLogger.cjs.map +1 -0
- package/dist/debugLogger.d.ts +30 -0
- package/dist/debugLogger.d.ts.map +1 -0
- package/dist/{deltaManager.js → deltaManager.cjs} +379 -186
- package/dist/deltaManager.cjs.map +1 -0
- package/dist/deltaManager.d.ts +54 -18
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/{deltaQueue.js → deltaQueue.cjs} +29 -28
- package/dist/deltaQueue.cjs.map +1 -0
- package/dist/deltaQueue.d.ts +3 -4
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/disposal.cjs +25 -0
- package/dist/disposal.cjs.map +1 -0
- package/dist/disposal.d.ts +13 -0
- package/dist/disposal.d.ts.map +1 -0
- package/dist/error.cjs +32 -0
- package/dist/error.cjs.map +1 -0
- package/dist/error.d.ts +23 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/loader.cjs +148 -0
- package/dist/loader.cjs.map +1 -0
- package/dist/loader.d.ts +38 -19
- package/dist/loader.d.ts.map +1 -1
- package/dist/location-redirection-utilities/index.cjs +11 -0
- package/dist/location-redirection-utilities/index.cjs.map +1 -0
- package/dist/location-redirection-utilities/index.d.ts +6 -0
- package/dist/location-redirection-utilities/index.d.ts.map +1 -0
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.cjs +53 -0
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.cjs.map +1 -0
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +24 -0
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -0
- package/dist/{collabWindowTracker.js → noopHeuristic.cjs} +37 -39
- package/dist/noopHeuristic.cjs.map +1 -0
- package/dist/noopHeuristic.d.ts +23 -0
- package/dist/noopHeuristic.d.ts.map +1 -0
- package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
- package/dist/packageVersion.cjs.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/protocol.cjs +99 -0
- package/dist/protocol.cjs.map +1 -0
- package/dist/protocol.d.ts +38 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/{protocolTreeDocumentStorageService.js → protocolTreeDocumentStorageService.cjs} +8 -5
- package/dist/protocolTreeDocumentStorageService.cjs.map +1 -0
- package/dist/protocolTreeDocumentStorageService.d.ts +8 -4
- package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/dist/quorum.cjs +16 -0
- package/dist/quorum.cjs.map +1 -0
- package/dist/quorum.d.ts +1 -14
- package/dist/quorum.d.ts.map +1 -1
- package/dist/{retriableDocumentStorageService.js → retriableDocumentStorageService.cjs} +36 -21
- package/dist/retriableDocumentStorageService.cjs.map +1 -0
- package/dist/retriableDocumentStorageService.d.ts +7 -5
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/{utils.js → utils.cjs} +52 -14
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.ts +34 -1
- package/dist/utils.d.ts.map +1 -1
- package/lib/{audience.d.ts → audience.d.mts} +4 -10
- package/lib/audience.d.mts.map +1 -0
- package/lib/{audience.js → audience.mjs} +15 -17
- package/lib/audience.mjs.map +1 -0
- package/lib/catchUpMonitor.d.mts +29 -0
- package/lib/catchUpMonitor.d.mts.map +1 -0
- package/lib/catchUpMonitor.mjs +39 -0
- package/lib/catchUpMonitor.mjs.map +1 -0
- package/lib/{connectionManager.d.ts → connectionManager.d.mts} +23 -33
- package/lib/connectionManager.d.mts.map +1 -0
- package/lib/{connectionManager.js → connectionManager.mjs} +378 -218
- package/lib/connectionManager.mjs.map +1 -0
- package/lib/{connectionState.d.ts → connectionState.d.mts} +3 -5
- package/lib/connectionState.d.mts.map +1 -0
- package/lib/{connectionState.js → connectionState.mjs} +4 -6
- package/lib/connectionState.mjs.map +1 -0
- package/lib/connectionStateHandler.d.mts +179 -0
- package/lib/connectionStateHandler.d.mts.map +1 -0
- package/lib/connectionStateHandler.mjs +469 -0
- package/lib/connectionStateHandler.mjs.map +1 -0
- package/lib/container-loader-alpha.d.mts +274 -0
- package/lib/container-loader-beta.d.mts +75 -0
- package/lib/container-loader-public.d.mts +75 -0
- package/lib/container-loader-untrimmed.d.mts +331 -0
- package/lib/container.d.mts +382 -0
- package/lib/container.d.mts.map +1 -0
- package/lib/container.mjs +1579 -0
- package/lib/container.mjs.map +1 -0
- package/lib/containerContext.d.mts +58 -0
- package/lib/containerContext.d.mts.map +1 -0
- package/lib/containerContext.mjs +70 -0
- package/lib/containerContext.mjs.map +1 -0
- package/lib/containerStorageAdapter.d.mts +73 -0
- package/lib/containerStorageAdapter.d.mts.map +1 -0
- package/lib/containerStorageAdapter.mjs +228 -0
- package/lib/containerStorageAdapter.mjs.map +1 -0
- package/lib/{contracts.d.ts → contracts.d.mts} +45 -17
- package/lib/contracts.d.mts.map +1 -0
- package/lib/{contracts.js → contracts.mjs} +4 -4
- package/lib/contracts.mjs.map +1 -0
- package/lib/debugLogger.d.mts +30 -0
- package/lib/debugLogger.d.mts.map +1 -0
- package/lib/debugLogger.mjs +93 -0
- package/lib/debugLogger.mjs.map +1 -0
- package/lib/{deltaManager.d.ts → deltaManager.d.mts} +54 -18
- package/lib/deltaManager.d.mts.map +1 -0
- package/lib/{deltaManager.js → deltaManager.mjs} +361 -165
- package/lib/deltaManager.mjs.map +1 -0
- package/lib/{deltaQueue.d.ts → deltaQueue.d.mts} +3 -4
- package/lib/deltaQueue.d.mts.map +1 -0
- package/lib/{deltaQueue.js → deltaQueue.mjs} +25 -24
- package/lib/deltaQueue.mjs.map +1 -0
- package/lib/disposal.d.mts +13 -0
- package/lib/disposal.d.mts.map +1 -0
- package/lib/disposal.mjs +21 -0
- package/lib/disposal.mjs.map +1 -0
- package/lib/error.d.mts +23 -0
- package/lib/error.d.mts.map +1 -0
- package/lib/error.mjs +28 -0
- package/lib/error.mjs.map +1 -0
- package/lib/index.d.mts +11 -0
- package/lib/index.d.mts.map +1 -0
- package/lib/index.mjs +10 -0
- package/lib/index.mjs.map +1 -0
- package/lib/{loader.d.ts → loader.d.mts} +39 -20
- package/lib/loader.d.mts.map +1 -0
- package/lib/loader.mjs +143 -0
- package/lib/loader.mjs.map +1 -0
- package/lib/location-redirection-utilities/index.d.mts +6 -0
- package/lib/location-redirection-utilities/index.d.mts.map +1 -0
- package/lib/location-redirection-utilities/index.mjs +6 -0
- package/lib/location-redirection-utilities/index.mjs.map +1 -0
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.mts +24 -0
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.mts.map +1 -0
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.mjs +48 -0
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.mjs.map +1 -0
- package/lib/noopHeuristic.d.mts +23 -0
- package/lib/noopHeuristic.d.mts.map +1 -0
- package/lib/{collabWindowTracker.js → noopHeuristic.mjs} +33 -35
- package/lib/noopHeuristic.mjs.map +1 -0
- package/lib/{packageVersion.d.ts → packageVersion.d.mts} +1 -1
- package/lib/{packageVersion.d.ts.map → packageVersion.d.mts.map} +1 -1
- package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
- package/lib/packageVersion.mjs.map +1 -0
- package/lib/protocol.d.mts +38 -0
- package/lib/protocol.d.mts.map +1 -0
- package/lib/protocol.mjs +94 -0
- package/lib/protocol.mjs.map +1 -0
- package/lib/{protocolTreeDocumentStorageService.d.ts → protocolTreeDocumentStorageService.d.mts} +8 -4
- package/lib/protocolTreeDocumentStorageService.d.mts.map +1 -0
- package/lib/{protocolTreeDocumentStorageService.js → protocolTreeDocumentStorageService.mjs} +8 -5
- package/lib/protocolTreeDocumentStorageService.mjs.map +1 -0
- package/lib/quorum.d.mts +4 -0
- package/lib/quorum.d.mts.map +1 -0
- package/lib/quorum.mjs +12 -0
- package/lib/quorum.mjs.map +1 -0
- package/lib/{retriableDocumentStorageService.d.ts → retriableDocumentStorageService.d.mts} +7 -5
- package/lib/retriableDocumentStorageService.d.mts.map +1 -0
- package/lib/{retriableDocumentStorageService.js → retriableDocumentStorageService.mjs} +35 -20
- package/lib/retriableDocumentStorageService.mjs.map +1 -0
- package/lib/utils.d.mts +67 -0
- package/lib/utils.d.mts.map +1 -0
- package/lib/{utils.js → utils.mjs} +47 -11
- package/lib/utils.mjs.map +1 -0
- package/package.json +163 -70
- package/prettier.config.cjs +8 -0
- package/src/audience.ts +59 -49
- package/src/catchUpMonitor.ts +61 -0
- package/src/connectionManager.ts +1154 -910
- package/src/connectionState.ts +22 -25
- package/src/connectionStateHandler.ts +689 -319
- package/src/container.ts +2476 -1792
- package/src/containerContext.ts +98 -330
- package/src/containerStorageAdapter.ts +301 -105
- package/src/contracts.ts +184 -146
- package/src/debugLogger.ts +123 -0
- package/src/deltaManager.ts +1165 -900
- package/src/deltaQueue.ts +156 -152
- package/src/disposal.ts +25 -0
- package/src/error.ts +44 -0
- package/src/index.ts +14 -15
- package/src/loader.ts +356 -427
- package/src/location-redirection-utilities/index.ts +9 -0
- package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +61 -0
- package/src/noopHeuristic.ts +107 -0
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +150 -0
- package/src/protocolTreeDocumentStorageService.ts +35 -35
- package/src/quorum.ts +11 -50
- package/src/retriableDocumentStorageService.ts +135 -95
- package/src/utils.ts +159 -86
- package/tsc-multi.test.json +4 -0
- package/tsconfig.json +10 -12
- package/dist/audience.js.map +0 -1
- package/dist/collabWindowTracker.d.ts +0 -19
- package/dist/collabWindowTracker.d.ts.map +0 -1
- package/dist/collabWindowTracker.js.map +0 -1
- package/dist/connectionManager.js.map +0 -1
- package/dist/connectionState.js.map +0 -1
- package/dist/connectionStateHandler.js +0 -280
- package/dist/connectionStateHandler.js.map +0 -1
- package/dist/container.js +0 -1284
- package/dist/container.js.map +0 -1
- package/dist/containerContext.js +0 -217
- package/dist/containerContext.js.map +0 -1
- package/dist/containerStorageAdapter.js +0 -104
- package/dist/containerStorageAdapter.js.map +0 -1
- package/dist/contracts.js.map +0 -1
- package/dist/deltaManager.js.map +0 -1
- package/dist/deltaManagerProxy.d.ts +0 -54
- package/dist/deltaManagerProxy.d.ts.map +0 -1
- package/dist/deltaManagerProxy.js +0 -115
- package/dist/deltaManagerProxy.js.map +0 -1
- package/dist/deltaQueue.js.map +0 -1
- package/dist/index.js +0 -16
- package/dist/index.js.map +0 -1
- package/dist/loader.js +0 -241
- package/dist/loader.js.map +0 -1
- package/dist/packageVersion.js.map +0 -1
- package/dist/protocolTreeDocumentStorageService.js.map +0 -1
- package/dist/quorum.js +0 -44
- package/dist/quorum.js.map +0 -1
- package/dist/retriableDocumentStorageService.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/lib/audience.d.ts.map +0 -1
- package/lib/audience.js.map +0 -1
- package/lib/collabWindowTracker.d.ts +0 -19
- package/lib/collabWindowTracker.d.ts.map +0 -1
- package/lib/collabWindowTracker.js.map +0 -1
- package/lib/connectionManager.d.ts.map +0 -1
- package/lib/connectionManager.js.map +0 -1
- package/lib/connectionState.d.ts.map +0 -1
- package/lib/connectionState.js.map +0 -1
- package/lib/connectionStateHandler.d.ts +0 -81
- package/lib/connectionStateHandler.d.ts.map +0 -1
- package/lib/connectionStateHandler.js +0 -276
- package/lib/connectionStateHandler.js.map +0 -1
- package/lib/container.d.ts +0 -238
- package/lib/container.d.ts.map +0 -1
- package/lib/container.js +0 -1276
- package/lib/container.js.map +0 -1
- package/lib/containerContext.d.ts +0 -84
- package/lib/containerContext.d.ts.map +0 -1
- package/lib/containerContext.js +0 -213
- package/lib/containerContext.js.map +0 -1
- package/lib/containerStorageAdapter.d.ts +0 -48
- package/lib/containerStorageAdapter.d.ts.map +0 -1
- package/lib/containerStorageAdapter.js +0 -99
- package/lib/containerStorageAdapter.js.map +0 -1
- package/lib/contracts.d.ts.map +0 -1
- package/lib/contracts.js.map +0 -1
- package/lib/deltaManager.d.ts.map +0 -1
- package/lib/deltaManager.js.map +0 -1
- package/lib/deltaManagerProxy.d.ts +0 -54
- package/lib/deltaManagerProxy.d.ts.map +0 -1
- package/lib/deltaManagerProxy.js +0 -110
- package/lib/deltaManagerProxy.js.map +0 -1
- package/lib/deltaQueue.d.ts.map +0 -1
- package/lib/deltaQueue.js.map +0 -1
- package/lib/index.d.ts +0 -8
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -8
- package/lib/index.js.map +0 -1
- package/lib/loader.d.ts.map +0 -1
- package/lib/loader.js +0 -236
- package/lib/loader.js.map +0 -1
- package/lib/packageVersion.js.map +0 -1
- package/lib/protocolTreeDocumentStorageService.d.ts.map +0 -1
- package/lib/protocolTreeDocumentStorageService.js.map +0 -1
- package/lib/quorum.d.ts +0 -21
- package/lib/quorum.d.ts.map +0 -1
- package/lib/quorum.js +0 -38
- package/lib/quorum.js.map +0 -1
- package/lib/retriableDocumentStorageService.d.ts.map +0 -1
- package/lib/retriableDocumentStorageService.js.map +0 -1
- package/lib/utils.d.ts +0 -34
- package/lib/utils.d.ts.map +0 -1
- package/lib/utils.js.map +0 -1
- package/src/collabWindowTracker.ts +0 -102
- package/src/deltaManagerProxy.ts +0 -158
- package/tsconfig.esnext.json +0 -7
|
@@ -3,126 +3,322 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { IDisposable } from "@fluidframework/core-interfaces";
|
|
7
|
+
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
8
|
+
import { bufferToString, stringToBuffer } from "@fluid-internal/client-utils";
|
|
9
|
+
import { assert } from "@fluidframework/core-utils";
|
|
7
10
|
import { ISnapshotTreeWithBlobContents } from "@fluidframework/container-definitions";
|
|
8
11
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
FetchSource,
|
|
13
|
+
IDocumentService,
|
|
14
|
+
IDocumentStorageService,
|
|
15
|
+
IDocumentStorageServicePolicies,
|
|
16
|
+
ISummaryContext,
|
|
12
17
|
} from "@fluidframework/driver-definitions";
|
|
18
|
+
import { UsageError } from "@fluidframework/driver-utils";
|
|
13
19
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
ICreateBlobResponse,
|
|
21
|
+
ISnapshotTree,
|
|
22
|
+
ISummaryHandle,
|
|
23
|
+
ISummaryTree,
|
|
24
|
+
IVersion,
|
|
19
25
|
} from "@fluidframework/protocol-definitions";
|
|
20
26
|
import { IDetachedBlobStorage } from "./loader";
|
|
27
|
+
import { ProtocolTreeStorageService } from "./protocolTreeDocumentStorageService";
|
|
28
|
+
import { RetriableDocumentStorageService } from "./retriableDocumentStorageService";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Stringified blobs from a summary/snapshot tree.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export interface ISerializableBlobContents {
|
|
35
|
+
[id: string]: string;
|
|
36
|
+
}
|
|
21
37
|
|
|
22
38
|
/**
|
|
23
39
|
* This class wraps the actual storage and make sure no wrong apis are called according to
|
|
24
40
|
* container attach state.
|
|
25
41
|
*/
|
|
26
|
-
export class ContainerStorageAdapter implements IDocumentStorageService {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
42
|
+
export class ContainerStorageAdapter implements IDocumentStorageService, IDisposable {
|
|
43
|
+
private _storageService: IDocumentStorageService & Partial<IDisposable>;
|
|
44
|
+
|
|
45
|
+
private _summarizeProtocolTree: boolean | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Whether the adapter will enforce sending combined summary trees.
|
|
48
|
+
*/
|
|
49
|
+
public get summarizeProtocolTree() {
|
|
50
|
+
return this._summarizeProtocolTree === true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then
|
|
55
|
+
* after connecting to a real service augments it with retry and combined summary tree enforcement.
|
|
56
|
+
* @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service
|
|
57
|
+
* @param logger - Telemetry logger
|
|
58
|
+
* @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to
|
|
59
|
+
* upload, and fix it up with a protocol tree if needed
|
|
60
|
+
* @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
|
|
61
|
+
*/
|
|
62
|
+
public constructor(
|
|
63
|
+
detachedBlobStorage: IDetachedBlobStorage | undefined,
|
|
64
|
+
private readonly logger: ITelemetryLoggerExt,
|
|
65
|
+
/**
|
|
66
|
+
* ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot
|
|
67
|
+
*/
|
|
68
|
+
private readonly blobContents: { [id: string]: ArrayBufferLike | string } = {},
|
|
69
|
+
private readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,
|
|
70
|
+
forceEnableSummarizeProtocolTree: boolean | undefined,
|
|
71
|
+
) {
|
|
72
|
+
this._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);
|
|
73
|
+
this._summarizeProtocolTree = forceEnableSummarizeProtocolTree;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
disposed: boolean = false;
|
|
77
|
+
dispose(error?: Error): void {
|
|
78
|
+
this._storageService?.dispose?.(error);
|
|
79
|
+
this.disposed = true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public connectToService(service: IDocumentService): void {
|
|
83
|
+
if (!(this._storageService instanceof BlobOnlyStorage)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const storageServiceP = service.connectToStorage();
|
|
88
|
+
const retriableStorage = (this._storageService = new RetriableDocumentStorageService(
|
|
89
|
+
storageServiceP,
|
|
90
|
+
this.logger,
|
|
91
|
+
));
|
|
92
|
+
|
|
93
|
+
this._summarizeProtocolTree =
|
|
94
|
+
this._summarizeProtocolTree ?? service.policies?.summarizeProtocolTree;
|
|
95
|
+
if (this.summarizeProtocolTree) {
|
|
96
|
+
this.logger.sendTelemetryEvent({ eventName: "summarizeProtocolTreeEnabled" });
|
|
97
|
+
this._storageService = new ProtocolTreeStorageService(
|
|
98
|
+
retriableStorage,
|
|
99
|
+
this.addProtocolSummaryIfMissing,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public loadSnapshotForRehydratingContainer(snapshotTree: ISnapshotTreeWithBlobContents) {
|
|
105
|
+
this.getBlobContents(snapshotTree);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private getBlobContents(snapshotTree: ISnapshotTreeWithBlobContents) {
|
|
109
|
+
if (snapshotTree.blobsContents !== undefined) {
|
|
110
|
+
for (const [id, value] of Object.entries(snapshotTree.blobsContents ?? {})) {
|
|
111
|
+
this.blobContents[id] = value;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const [_, tree] of Object.entries(snapshotTree.trees)) {
|
|
115
|
+
this.getBlobContents(tree);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public get policies(): IDocumentStorageServicePolicies | undefined {
|
|
120
|
+
// back-compat 0.40 containerRuntime requests policies even in detached container if storage is present
|
|
121
|
+
// and storage is always present in >=0.41.
|
|
122
|
+
try {
|
|
123
|
+
return this._storageService.policies;
|
|
124
|
+
} catch (e) {}
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public get repositoryUrl(): string {
|
|
129
|
+
return this._storageService.repositoryUrl;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public async getSnapshotTree(
|
|
133
|
+
version?: IVersion,
|
|
134
|
+
scenarioName?: string,
|
|
135
|
+
): Promise<ISnapshotTree | null> {
|
|
136
|
+
return this._storageService.getSnapshotTree(version, scenarioName);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public async readBlob(id: string): Promise<ArrayBufferLike> {
|
|
140
|
+
const maybeBlob = this.blobContents[id];
|
|
141
|
+
if (maybeBlob !== undefined) {
|
|
142
|
+
if (typeof maybeBlob === "string") {
|
|
143
|
+
const blob = stringToBuffer(maybeBlob, "utf8");
|
|
144
|
+
return blob;
|
|
145
|
+
}
|
|
146
|
+
return maybeBlob;
|
|
147
|
+
}
|
|
148
|
+
return this._storageService.readBlob(id);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public async getVersions(
|
|
152
|
+
versionId: string | null,
|
|
153
|
+
count: number,
|
|
154
|
+
scenarioName?: string,
|
|
155
|
+
fetchSource?: FetchSource,
|
|
156
|
+
): Promise<IVersion[]> {
|
|
157
|
+
return this._storageService.getVersions(versionId, count, scenarioName, fetchSource);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public async uploadSummaryWithContext(
|
|
161
|
+
summary: ISummaryTree,
|
|
162
|
+
context: ISummaryContext,
|
|
163
|
+
): Promise<string> {
|
|
164
|
+
return this._storageService.uploadSummaryWithContext(summary, context);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {
|
|
168
|
+
return this._storageService.downloadSummary(handle);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {
|
|
172
|
+
return this._storageService.createBlob(file);
|
|
173
|
+
}
|
|
83
174
|
}
|
|
84
175
|
|
|
85
176
|
/**
|
|
86
177
|
* Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support
|
|
87
178
|
* blobs in detached containers.
|
|
88
179
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
180
|
+
class BlobOnlyStorage implements IDocumentStorageService {
|
|
181
|
+
constructor(
|
|
182
|
+
private readonly detachedStorage: IDetachedBlobStorage | undefined,
|
|
183
|
+
private readonly logger: ITelemetryLoggerExt,
|
|
184
|
+
) {}
|
|
185
|
+
|
|
186
|
+
public async createBlob(content: ArrayBufferLike): Promise<ICreateBlobResponse> {
|
|
187
|
+
return this.verifyStorage().createBlob(content);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public async readBlob(blobId: string): Promise<ArrayBufferLike> {
|
|
191
|
+
return this.verifyStorage().readBlob(blobId);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private verifyStorage(): IDetachedBlobStorage {
|
|
195
|
+
if (this.detachedStorage === undefined) {
|
|
196
|
+
throw new UsageError("Real storage calls not allowed in Unattached container");
|
|
197
|
+
}
|
|
198
|
+
return this.detachedStorage;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public get policies(): IDocumentStorageServicePolicies | undefined {
|
|
202
|
+
return this.notCalled();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public get repositoryUrl(): string {
|
|
206
|
+
return this.notCalled();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
210
|
+
public getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;
|
|
211
|
+
public getVersions: () => Promise<IVersion[]> = this.notCalled;
|
|
212
|
+
public write: () => Promise<IVersion> = this.notCalled;
|
|
213
|
+
public uploadSummaryWithContext: () => Promise<string> = this.notCalled;
|
|
214
|
+
public downloadSummary: () => Promise<ISummaryTree> = this.notCalled;
|
|
215
|
+
/* eslint-enable @typescript-eslint/unbound-method */
|
|
216
|
+
|
|
217
|
+
private notCalled(): never {
|
|
218
|
+
this.verifyStorage();
|
|
219
|
+
try {
|
|
220
|
+
// some browsers may not populate stack unless exception is thrown
|
|
221
|
+
throw new Error("BlobOnlyStorage not implemented method used");
|
|
222
|
+
} catch (err) {
|
|
223
|
+
this.logger.sendTelemetryEvent({ eventName: "BlobOnlyStorageWrongCall" }, err);
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// runtime will write a tree to the summary containing "attachment" type entries
|
|
230
|
+
// which reference attachment blobs by ID, along with a blob containing the blob redirect table.
|
|
231
|
+
// However, some drivers do not support the "attachment" type and will convert them to "blob" type
|
|
232
|
+
// entries. We want to avoid saving these to reduce the size of stashed change blobs, but we
|
|
233
|
+
// need to make sure the blob redirect table is saved.
|
|
234
|
+
const blobsTreeName = ".blobs";
|
|
235
|
+
const redirectTableBlobName = ".redirectTable";
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Get blob contents of a snapshot tree from storage (or, ideally, cache)
|
|
239
|
+
*/
|
|
240
|
+
export async function getBlobContentsFromTree(
|
|
241
|
+
snapshot: ISnapshotTree,
|
|
242
|
+
storage: IDocumentStorageService,
|
|
243
|
+
): Promise<ISerializableBlobContents> {
|
|
244
|
+
const blobs = {};
|
|
245
|
+
await getBlobContentsFromTreeCore(snapshot, blobs, storage);
|
|
246
|
+
return blobs;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async function getBlobContentsFromTreeCore(
|
|
250
|
+
tree: ISnapshotTree,
|
|
251
|
+
blobs: ISerializableBlobContents,
|
|
252
|
+
storage: IDocumentStorageService,
|
|
253
|
+
root = true,
|
|
254
|
+
) {
|
|
255
|
+
const treePs: Promise<any>[] = [];
|
|
256
|
+
for (const [key, subTree] of Object.entries(tree.trees)) {
|
|
257
|
+
if (root && key === blobsTreeName) {
|
|
258
|
+
treePs.push(getBlobManagerTreeFromTree(subTree, blobs, storage));
|
|
259
|
+
} else {
|
|
260
|
+
treePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
for (const id of Object.values(tree.blobs)) {
|
|
264
|
+
const blob = await storage.readBlob(id);
|
|
265
|
+
// ArrayBufferLike will not survive JSON.stringify()
|
|
266
|
+
blobs[id] = bufferToString(blob, "utf8");
|
|
267
|
+
}
|
|
268
|
+
return Promise.all(treePs);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// save redirect table from .blobs tree but nothing else
|
|
272
|
+
async function getBlobManagerTreeFromTree(
|
|
273
|
+
tree: ISnapshotTree,
|
|
274
|
+
blobs: ISerializableBlobContents,
|
|
275
|
+
storage: IDocumentStorageService,
|
|
276
|
+
) {
|
|
277
|
+
const id = tree.blobs[redirectTableBlobName];
|
|
278
|
+
const blob = await storage.readBlob(id);
|
|
279
|
+
// ArrayBufferLike will not survive JSON.stringify()
|
|
280
|
+
blobs[id] = bufferToString(blob, "utf8");
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Extract blob contents from a snapshot tree with blob contents
|
|
285
|
+
*/
|
|
286
|
+
export function getBlobContentsFromTreeWithBlobContents(
|
|
287
|
+
snapshot: ISnapshotTreeWithBlobContents,
|
|
288
|
+
): ISerializableBlobContents {
|
|
289
|
+
const blobs = {};
|
|
290
|
+
getBlobContentsFromTreeWithBlobContentsCore(snapshot, blobs);
|
|
291
|
+
return blobs;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function getBlobContentsFromTreeWithBlobContentsCore(
|
|
295
|
+
tree: ISnapshotTreeWithBlobContents,
|
|
296
|
+
blobs: ISerializableBlobContents,
|
|
297
|
+
root = true,
|
|
298
|
+
) {
|
|
299
|
+
for (const [key, subTree] of Object.entries(tree.trees)) {
|
|
300
|
+
if (root && key === blobsTreeName) {
|
|
301
|
+
getBlobManagerTreeFromTreeWithBlobContents(subTree, blobs);
|
|
302
|
+
} else {
|
|
303
|
+
getBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
for (const id of Object.values(tree.blobs)) {
|
|
307
|
+
const blob = tree.blobsContents?.[id];
|
|
308
|
+
assert(blob !== undefined, 0x2ec /* "Blob must be present in blobsContents" */);
|
|
309
|
+
// ArrayBufferLike will not survive JSON.stringify()
|
|
310
|
+
blobs[id] = bufferToString(blob, "utf8");
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// save redirect table from .blobs tree but nothing else
|
|
315
|
+
function getBlobManagerTreeFromTreeWithBlobContents(
|
|
316
|
+
tree: ISnapshotTreeWithBlobContents,
|
|
317
|
+
blobs: ISerializableBlobContents,
|
|
318
|
+
) {
|
|
319
|
+
const id = tree.blobs[redirectTableBlobName];
|
|
320
|
+
const blob = tree.blobsContents?.[id];
|
|
321
|
+
assert(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);
|
|
322
|
+
// ArrayBufferLike will not survive JSON.stringify()
|
|
323
|
+
blobs[id] = bufferToString(blob, "utf8");
|
|
128
324
|
}
|