@fluidframework/container-loader 2.118.1 → 3.0.1
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 +74 -4
- package/README.md +53 -50
- package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
- package/api-report/container-loader.legacy.alpha.api.md +4 -3
- package/dist/attachment.d.ts.map +1 -1
- package/dist/audience.js +3 -2
- package/dist/audience.js.map +1 -1
- package/dist/captureReferencedContents.js +9 -9
- package/dist/captureReferencedContents.js.map +1 -1
- package/dist/catchUpMonitor.js +11 -8
- package/dist/catchUpMonitor.js.map +1 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +86 -51
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.js +40 -14
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +1 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +193 -143
- package/dist/container.js.map +1 -1
- package/dist/containerContext.js +48 -11
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.js +25 -17
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/createAndLoadContainerUtils.d.ts +34 -13
- package/dist/createAndLoadContainerUtils.d.ts.map +1 -1
- package/dist/createAndLoadContainerUtils.js +97 -37
- package/dist/createAndLoadContainerUtils.js.map +1 -1
- package/dist/debugLogger.d.ts +7 -22
- package/dist/debugLogger.d.ts.map +1 -1
- package/dist/debugLogger.js +34 -34
- package/dist/debugLogger.js.map +1 -1
- package/dist/deltaManager.d.ts +16 -4
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +73 -48
- package/dist/deltaManager.js.map +1 -1
- package/dist/deltaManagerFactory.d.ts +23 -0
- package/dist/deltaManagerFactory.d.ts.map +1 -0
- package/dist/deltaManagerFactory.js +17 -0
- package/dist/deltaManagerFactory.js.map +1 -0
- package/dist/deltaQueue.js +14 -7
- package/dist/deltaQueue.js.map +1 -1
- package/dist/disposal.js +1 -2
- package/dist/disposal.js.map +1 -1
- package/dist/error.js +5 -4
- package/dist/error.js.map +1 -1
- package/dist/frozenServices.d.ts +2 -2
- package/dist/frozenServices.d.ts.map +1 -1
- package/dist/frozenServices.js +52 -34
- package/dist/frozenServices.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/loadContainerToSequenceNumber.js +1 -2
- package/dist/loadContainerToSequenceNumber.js.map +1 -1
- package/dist/loadPaused.js +1 -2
- package/dist/loadPaused.js.map +1 -1
- package/dist/loader.js +5 -1
- package/dist/loader.js.map +1 -1
- package/dist/loaderLayerCompatState.d.ts +25 -1
- package/dist/loaderLayerCompatState.d.ts.map +1 -1
- package/dist/loaderLayerCompatState.js +79 -11
- package/dist/loaderLayerCompatState.js.map +1 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +2 -3
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
- package/dist/memoryBlobStorage.js +2 -3
- package/dist/memoryBlobStorage.js.map +1 -1
- package/dist/noopHeuristic.js +3 -1
- package/dist/noopHeuristic.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingLocalStateStore.d.ts +4 -3
- package/dist/pendingLocalStateStore.d.ts.map +1 -1
- package/dist/pendingLocalStateStore.js +26 -37
- package/dist/pendingLocalStateStore.js.map +1 -1
- package/dist/pointInTimeServices.js +4 -2
- package/dist/pointInTimeServices.js.map +1 -1
- package/dist/protocol/protocol.js +3 -0
- package/dist/protocol/protocol.js.map +1 -1
- package/dist/protocol/quorum.js +26 -5
- package/dist/protocol/quorum.js.map +1 -1
- package/dist/protocol.js +5 -3
- package/dist/protocol.js.map +1 -1
- package/dist/protocolTreeDocumentStorageService.js +10 -0
- package/dist/protocolTreeDocumentStorageService.js.map +1 -1
- package/dist/quorum.js +1 -2
- package/dist/quorum.js.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js +5 -1
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/serializedStateManager.d.ts +6 -0
- package/dist/serializedStateManager.d.ts.map +1 -1
- package/dist/serializedStateManager.js +19 -24
- package/dist/serializedStateManager.js.map +1 -1
- package/dist/snapshotRefresher.js +31 -36
- package/dist/snapshotRefresher.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +13 -13
- package/dist/utils.js.map +1 -1
- package/lib/attachment.d.ts.map +1 -1
- package/lib/audience.js +3 -2
- package/lib/audience.js.map +1 -1
- package/lib/catchUpMonitor.js +11 -8
- package/lib/catchUpMonitor.js.map +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +86 -51
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.js +37 -11
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +1 -1
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +191 -141
- package/lib/container.js.map +1 -1
- package/lib/containerContext.js +48 -11
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.js +22 -14
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts.map +1 -1
- package/lib/createAndLoadContainerUtils.d.ts +34 -13
- package/lib/createAndLoadContainerUtils.d.ts.map +1 -1
- package/lib/createAndLoadContainerUtils.js +93 -32
- package/lib/createAndLoadContainerUtils.js.map +1 -1
- package/lib/debugLogger.d.ts +7 -22
- package/lib/debugLogger.d.ts.map +1 -1
- package/lib/debugLogger.js +34 -33
- package/lib/debugLogger.js.map +1 -1
- package/lib/deltaManager.d.ts +16 -4
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +73 -48
- package/lib/deltaManager.js.map +1 -1
- package/lib/deltaManagerFactory.d.ts +23 -0
- package/lib/deltaManagerFactory.d.ts.map +1 -0
- package/lib/deltaManagerFactory.js +14 -0
- package/lib/deltaManagerFactory.js.map +1 -0
- package/lib/deltaQueue.js +14 -7
- package/lib/deltaQueue.js.map +1 -1
- package/lib/error.js +5 -4
- package/lib/error.js.map +1 -1
- package/lib/frozenServices.d.ts +2 -2
- package/lib/frozenServices.d.ts.map +1 -1
- package/lib/frozenServices.js +48 -30
- package/lib/frozenServices.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/legacyAlpha.d.ts +1 -1
- package/lib/loader.js +6 -2
- package/lib/loader.js.map +1 -1
- package/lib/loaderLayerCompatState.d.ts +25 -1
- package/lib/loaderLayerCompatState.d.ts.map +1 -1
- package/lib/loaderLayerCompatState.js +76 -9
- package/lib/loaderLayerCompatState.js.map +1 -1
- package/lib/noopHeuristic.js +3 -1
- package/lib/noopHeuristic.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingLocalStateStore.d.ts +4 -3
- package/lib/pendingLocalStateStore.d.ts.map +1 -1
- package/lib/pendingLocalStateStore.js +26 -37
- package/lib/pendingLocalStateStore.js.map +1 -1
- package/lib/pointInTimeServices.js +2 -0
- package/lib/pointInTimeServices.js.map +1 -1
- package/lib/protocol/protocol.js +3 -0
- package/lib/protocol/protocol.js.map +1 -1
- package/lib/protocol/quorum.js +26 -5
- package/lib/protocol/quorum.js.map +1 -1
- package/lib/protocol.js +2 -0
- package/lib/protocol.js.map +1 -1
- package/lib/protocolTreeDocumentStorageService.js +10 -0
- package/lib/protocolTreeDocumentStorageService.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js +5 -1
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/serializedStateManager.d.ts +6 -0
- package/lib/serializedStateManager.d.ts.map +1 -1
- package/lib/serializedStateManager.js +15 -20
- package/lib/serializedStateManager.js.map +1 -1
- package/lib/snapshotRefresher.js +31 -36
- package/lib/snapshotRefresher.js.map +1 -1
- package/lib/utils.d.ts +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +3 -3
- package/lib/utils.js.map +1 -1
- package/package.json +44 -106
- package/src/container.ts +35 -22
- package/src/createAndLoadContainerUtils.ts +131 -46
- package/src/debugLogger.ts +39 -40
- package/src/deltaManager.ts +16 -4
- package/src/deltaManagerFactory.ts +53 -0
- package/src/frozenServices.ts +6 -7
- package/src/index.ts +1 -0
- package/src/loader.ts +2 -2
- package/src/loaderLayerCompatState.ts +85 -20
- package/src/packageVersion.ts +1 -1
- package/src/pendingLocalStateStore.ts +7 -3
- package/src/serializedStateManager.ts +6 -0
- package/src/utils.ts +3 -3
- package/tsconfig.json +1 -1
- package/internal.d.ts +0 -11
- package/legacy/alpha.d.ts +0 -11
- package/legacy.d.ts +0 -11
- /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
- /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
|
@@ -13,7 +13,7 @@ export declare const loaderCoreCompatDetails: {
|
|
|
13
13
|
/**
|
|
14
14
|
* The package version of the Loader layer.
|
|
15
15
|
*/
|
|
16
|
-
readonly pkgVersion: "
|
|
16
|
+
readonly pkgVersion: "3.0.1";
|
|
17
17
|
/**
|
|
18
18
|
* The current generation of the Loader layer.
|
|
19
19
|
*/
|
|
@@ -24,6 +24,11 @@ export declare const loaderCoreCompatDetails: {
|
|
|
24
24
|
* @internal
|
|
25
25
|
*/
|
|
26
26
|
export declare const loaderCompatDetailsForRuntime: ILayerCompatDetails;
|
|
27
|
+
/**
|
|
28
|
+
* Loader's compatibility details that is validated against the Driver layer's requirements.
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export declare const loaderCompatDetailsForDriver: ILayerCompatDetails;
|
|
27
32
|
/**
|
|
28
33
|
* The requirements that the Runtime layer must meet to be compatible with this Loader.
|
|
29
34
|
* @internal
|
|
@@ -44,4 +49,23 @@ export declare function validateRuntimeCompatibility(maybeRuntimeCompatDetails:
|
|
|
44
49
|
* @internal
|
|
45
50
|
*/
|
|
46
51
|
export declare function validateDriverCompatibility(maybeDriverCompatDetails: ILayerCompatDetails | undefined, disposeFn: (error?: ICriticalContainerError) => void, mc: MonitoringContext): void;
|
|
52
|
+
/**
|
|
53
|
+
* Validates that the Loader layer is compatible with the Driver.
|
|
54
|
+
*
|
|
55
|
+
* @remarks
|
|
56
|
+
* This is the reverse of {@link validateDriverCompatibility} and is intentionally a separate function because it
|
|
57
|
+
* does not follow the standard layer-validation pattern. Normally each layer validates the layer it holds a
|
|
58
|
+
* reference to - the Loader validates the Driver, the Runtime validates the Loader, and so on. The Driver, however,
|
|
59
|
+
* has no reference to the Loader and therefore cannot run this validation itself. To still enforce compatibility in
|
|
60
|
+
* both directions across the Driver / Loader boundary, the Driver publishes the requirements it has for the Loader
|
|
61
|
+
* (via ILayerCompatSupportRequirements) and the Loader validates itself against them here, on the Driver's behalf.
|
|
62
|
+
*
|
|
63
|
+
* @param maybeDriverCompatDetails - The Driver's compatibility details, used only to attribute the version /
|
|
64
|
+
* generation of the Driver in telemetry if the Loader is found to be incompatible.
|
|
65
|
+
* @param maybeDriverCompatRequirements - The requirements the Driver has for the Loader. Older Drivers may not
|
|
66
|
+
* publish these, in which case there is nothing to validate in this direction.
|
|
67
|
+
*
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
export declare function validateLoaderCompatibilityWithDriver(maybeDriverCompatDetails: ILayerCompatDetails | undefined, maybeDriverCompatRequirements: ILayerCompatSupportRequirements | undefined, disposeFn: (error?: ICriticalContainerError) => void, mc: MonitoringContext): void;
|
|
47
71
|
//# sourceMappingURL=loaderLayerCompatState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaderLayerCompatState.d.ts","sourceRoot":"","sources":["../src/loaderLayerCompatState.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"loaderLayerCompatState.d.ts","sourceRoot":"","sources":["../src/loaderLayerCompatState.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIN,KAAK,mBAAmB,EACxB,KAAK,+BAA+B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAEN,KAAK,iBAAiB,EACtB,MAAM,0CAA0C,CAAC;AAIlD;;;GAGG;AACH,eAAO,MAAM,uBAAuB;IACnC;;OAEG;;IAEH;;OAEG;;CAEM,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,6BAA6B,EAAE,mBAM3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,mBAM1C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,+BAgBjD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kCAAkC,EAAE,+BAgBhD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,yBAAyB,EAAE,mBAAmB,GAAG,SAAS,EAC1D,EAAE,EAAE,iBAAiB,GACnB,IAAI,CAgBN;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAC1C,wBAAwB,EAAE,mBAAmB,GAAG,SAAS,EACzD,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,uBAAuB,KAAK,IAAI,EACpD,EAAE,EAAE,iBAAiB,GACnB,IAAI,CAaN;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qCAAqC,CACpD,wBAAwB,EAAE,mBAAmB,GAAG,SAAS,EACzD,6BAA6B,EAAE,+BAA+B,GAAG,SAAS,EAC1E,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,uBAAuB,KAAK,IAAI,EACpD,EAAE,EAAE,iBAAiB,GACnB,IAAI,CAgBN"}
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.driverSupportRequirementsForLoader = exports.runtimeSupportRequirementsForLoader = exports.loaderCompatDetailsForDriver = exports.loaderCompatDetailsForRuntime = exports.loaderCoreCompatDetails = void 0;
|
|
8
|
+
exports.validateRuntimeCompatibility = validateRuntimeCompatibility;
|
|
9
|
+
exports.validateDriverCompatibility = validateDriverCompatibility;
|
|
10
|
+
exports.validateLoaderCompatibilityWithDriver = validateLoaderCompatibilityWithDriver;
|
|
8
11
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
12
|
const internal_1 = require("@fluidframework/telemetry-utils/internal");
|
|
10
13
|
const packageVersion_js_1 = require("./packageVersion.js");
|
|
@@ -33,6 +36,17 @@ exports.loaderCompatDetailsForRuntime = {
|
|
|
33
36
|
*/
|
|
34
37
|
supportedFeatures: new Set(),
|
|
35
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Loader's compatibility details that is validated against the Driver layer's requirements.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
exports.loaderCompatDetailsForDriver = {
|
|
44
|
+
...exports.loaderCoreCompatDetails,
|
|
45
|
+
/**
|
|
46
|
+
* The features supported by the Loader layer across the Loader / Driver boundary.
|
|
47
|
+
*/
|
|
48
|
+
supportedFeatures: new Set(),
|
|
49
|
+
};
|
|
36
50
|
/**
|
|
37
51
|
* The requirements that the Runtime layer must meet to be compatible with this Loader.
|
|
38
52
|
* @internal
|
|
@@ -40,11 +54,12 @@ exports.loaderCompatDetailsForRuntime = {
|
|
|
40
54
|
exports.runtimeSupportRequirementsForLoader = {
|
|
41
55
|
/**
|
|
42
56
|
* Minimum generation that Runtime must be at to be compatible with this Loader. This is calculated
|
|
43
|
-
* based on the LayerCompatibilityPolicyWindowMonths.
|
|
44
|
-
* the Runtime layer be compared to the Loader layer for them to still be considered compatible.
|
|
57
|
+
* based on the LayerCompatibilityPolicyWindowMonths.NewLoaderOldRuntime value which defines how many months
|
|
58
|
+
* old can the Runtime layer be compared to the Loader layer for them to still be considered compatible.
|
|
45
59
|
* The minimum valid generation value is 0.
|
|
46
60
|
*/
|
|
47
|
-
minSupportedGeneration: Math.max(0, exports.loaderCoreCompatDetails.generation -
|
|
61
|
+
minSupportedGeneration: Math.max(0, exports.loaderCoreCompatDetails.generation -
|
|
62
|
+
client_utils_1.LayerCompatibilityPolicyWindowMonths.NewLoaderOldRuntime),
|
|
48
63
|
/**
|
|
49
64
|
* The features that the Runtime must support to be compatible with Loader.
|
|
50
65
|
*/
|
|
@@ -57,11 +72,12 @@ exports.runtimeSupportRequirementsForLoader = {
|
|
|
57
72
|
exports.driverSupportRequirementsForLoader = {
|
|
58
73
|
/**
|
|
59
74
|
* Minimum generation that Driver must be at to be compatible with this Loader. This is calculated
|
|
60
|
-
* based on the LayerCompatibilityPolicyWindowMonths.
|
|
61
|
-
* the Driver layer be compared to the Loader layer for them to still be considered compatible.
|
|
75
|
+
* based on the LayerCompatibilityPolicyWindowMonths.NewLoaderOldDriver value which defines how many months
|
|
76
|
+
* old can the Driver layer be compared to the Loader layer for them to still be considered compatible.
|
|
62
77
|
* The minimum valid generation value is 0.
|
|
63
78
|
*/
|
|
64
|
-
minSupportedGeneration: Math.max(0, exports.loaderCoreCompatDetails.generation -
|
|
79
|
+
minSupportedGeneration: Math.max(0, exports.loaderCoreCompatDetails.generation -
|
|
80
|
+
client_utils_1.LayerCompatibilityPolicyWindowMonths.NewLoaderOldDriver),
|
|
65
81
|
/**
|
|
66
82
|
* The features that the Driver must support to be compatible with Loader.
|
|
67
83
|
*/
|
|
@@ -72,15 +88,67 @@ exports.driverSupportRequirementsForLoader = {
|
|
|
72
88
|
* @internal
|
|
73
89
|
*/
|
|
74
90
|
function validateRuntimeCompatibility(maybeRuntimeCompatDetails, mc) {
|
|
75
|
-
(0, internal_1.validateLayerCompatibility)(
|
|
91
|
+
(0, internal_1.validateLayerCompatibility)(
|
|
92
|
+
/* validatingLayer */ {
|
|
93
|
+
layer: "loader",
|
|
94
|
+
packageInfo: exports.loaderCoreCompatDetails,
|
|
95
|
+
compatSupportRequirements: exports.runtimeSupportRequirementsForLoader,
|
|
96
|
+
},
|
|
97
|
+
/* targetLayer */ {
|
|
98
|
+
layer: "runtime",
|
|
99
|
+
compatDetails: maybeRuntimeCompatDetails,
|
|
100
|
+
}, {
|
|
101
|
+
disposeFn: () => { } /* no op. This will be handled by the caller */,
|
|
102
|
+
mc,
|
|
103
|
+
});
|
|
76
104
|
}
|
|
77
|
-
exports.validateRuntimeCompatibility = validateRuntimeCompatibility;
|
|
78
105
|
/**
|
|
79
106
|
* Validates that the Driver layer is compatible with the Loader.
|
|
80
107
|
* @internal
|
|
81
108
|
*/
|
|
82
109
|
function validateDriverCompatibility(maybeDriverCompatDetails, disposeFn, mc) {
|
|
83
|
-
(0, internal_1.validateLayerCompatibility)(
|
|
110
|
+
(0, internal_1.validateLayerCompatibility)(
|
|
111
|
+
/* validatingLayer */ {
|
|
112
|
+
layer: "loader",
|
|
113
|
+
packageInfo: exports.loaderCoreCompatDetails,
|
|
114
|
+
compatSupportRequirements: exports.driverSupportRequirementsForLoader,
|
|
115
|
+
},
|
|
116
|
+
/* targetLayer */ {
|
|
117
|
+
layer: "driver",
|
|
118
|
+
compatDetails: maybeDriverCompatDetails,
|
|
119
|
+
}, { disposeFn, mc });
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validates that the Loader layer is compatible with the Driver.
|
|
123
|
+
*
|
|
124
|
+
* @remarks
|
|
125
|
+
* This is the reverse of {@link validateDriverCompatibility} and is intentionally a separate function because it
|
|
126
|
+
* does not follow the standard layer-validation pattern. Normally each layer validates the layer it holds a
|
|
127
|
+
* reference to - the Loader validates the Driver, the Runtime validates the Loader, and so on. The Driver, however,
|
|
128
|
+
* has no reference to the Loader and therefore cannot run this validation itself. To still enforce compatibility in
|
|
129
|
+
* both directions across the Driver / Loader boundary, the Driver publishes the requirements it has for the Loader
|
|
130
|
+
* (via ILayerCompatSupportRequirements) and the Loader validates itself against them here, on the Driver's behalf.
|
|
131
|
+
*
|
|
132
|
+
* @param maybeDriverCompatDetails - The Driver's compatibility details, used only to attribute the version /
|
|
133
|
+
* generation of the Driver in telemetry if the Loader is found to be incompatible.
|
|
134
|
+
* @param maybeDriverCompatRequirements - The requirements the Driver has for the Loader. Older Drivers may not
|
|
135
|
+
* publish these, in which case there is nothing to validate in this direction.
|
|
136
|
+
*
|
|
137
|
+
* @internal
|
|
138
|
+
*/
|
|
139
|
+
function validateLoaderCompatibilityWithDriver(maybeDriverCompatDetails, maybeDriverCompatRequirements, disposeFn, mc) {
|
|
140
|
+
if (maybeDriverCompatRequirements === undefined) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
(0, internal_1.validateLayerCompatibility)(
|
|
144
|
+
/* validatingLayer */ {
|
|
145
|
+
layer: "driver",
|
|
146
|
+
packageInfo: maybeDriverCompatDetails ?? client_utils_1.defaultLayerCompatDetails,
|
|
147
|
+
compatSupportRequirements: maybeDriverCompatRequirements,
|
|
148
|
+
},
|
|
149
|
+
/* targetLayer */ {
|
|
150
|
+
layer: "loader",
|
|
151
|
+
compatDetails: exports.loaderCompatDetailsForDriver,
|
|
152
|
+
}, { disposeFn, mc });
|
|
84
153
|
}
|
|
85
|
-
exports.validateDriverCompatibility = validateDriverCompatibility;
|
|
86
154
|
//# sourceMappingURL=loaderLayerCompatState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaderLayerCompatState.js","sourceRoot":"","sources":["../src/loaderLayerCompatState.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"loaderLayerCompatState.js","sourceRoot":"","sources":["../src/loaderLayerCompatState.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAwGH,oEAmBC;AAMD,kEAiBC;AAoBD,sFAqBC;AAzLD,+DAMsC;AAEtC,uEAGkD;AAElD,2DAAiD;AAEjD;;;GAGG;AACU,QAAA,uBAAuB,GAAG;IACtC;;OAEG;IACH,UAAU,EAAV,8BAAU;IACV;;OAEG;IACH,UAAU,EAAV,yBAAU;CACD,CAAC;AAEX;;;GAGG;AACU,QAAA,6BAA6B,GAAwB;IACjE,GAAG,+BAAuB;IAC1B;;OAEG;IACH,iBAAiB,EAAE,IAAI,GAAG,EAAU;CACpC,CAAC;AAEF;;;GAGG;AACU,QAAA,4BAA4B,GAAwB;IAChE,GAAG,+BAAuB;IAC1B;;OAEG;IACH,iBAAiB,EAAE,IAAI,GAAG,EAAU;CACpC,CAAC;AAEF;;;GAGG;AACU,QAAA,mCAAmC,GAAoC;IACnF;;;;;OAKG;IACH,sBAAsB,EAAE,IAAI,CAAC,GAAG,CAC/B,CAAC,EACD,+BAAuB,CAAC,UAAU;QACjC,mDAAoC,CAAC,mBAAmB,CACzD;IACD;;OAEG;IACH,gBAAgB,EAAE,EAAE;CACpB,CAAC;AAEF;;;GAGG;AACU,QAAA,kCAAkC,GAAoC;IAClF;;;;;OAKG;IACH,sBAAsB,EAAE,IAAI,CAAC,GAAG,CAC/B,CAAC,EACD,+BAAuB,CAAC,UAAU;QACjC,mDAAoC,CAAC,kBAAkB,CACxD;IACD;;OAEG;IACH,gBAAgB,EAAE,EAAE;CACpB,CAAC;AAEF;;;GAGG;AACH,SAAgB,4BAA4B,CAC3C,yBAA0D,EAC1D,EAAqB;IAErB,IAAA,qCAA0B;IACzB,qBAAqB,CAAC;QACrB,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,+BAAuB;QACpC,yBAAyB,EAAE,2CAAmC;KAC9D;IACD,iBAAiB,CAAC;QACjB,KAAK,EAAE,SAAS;QAChB,aAAa,EAAE,yBAAyB;KACxC,EACD;QACC,SAAS,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,+CAA+C;QACnE,EAAE;KACF,CACD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CAC1C,wBAAyD,EACzD,SAAoD,EACpD,EAAqB;IAErB,IAAA,qCAA0B;IACzB,qBAAqB,CAAC;QACrB,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,+BAAuB;QACpC,yBAAyB,EAAE,0CAAkC;KAC7D;IACD,iBAAiB,CAAC;QACjB,KAAK,EAAE,QAAQ;QACf,aAAa,EAAE,wBAAwB;KACvC,EACD,EAAE,SAAS,EAAE,EAAE,EAAE,CACjB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,qCAAqC,CACpD,wBAAyD,EACzD,6BAA0E,EAC1E,SAAoD,EACpD,EAAqB;IAErB,IAAI,6BAA6B,KAAK,SAAS,EAAE,CAAC;QACjD,OAAO;IACR,CAAC;IACD,IAAA,qCAA0B;IACzB,qBAAqB,CAAC;QACrB,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,wBAAwB,IAAI,wCAAyB;QAClE,yBAAyB,EAAE,6BAA6B;KACxD;IACD,iBAAiB,CAAC;QACjB,KAAK,EAAE,QAAQ;QACf,aAAa,EAAE,oCAA4B;KAC3C,EACD,EAAE,SAAS,EAAE,EAAE,EAAE,CACjB,CAAC;AACH,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tgeneration,\n\tdefaultLayerCompatDetails,\n\tLayerCompatibilityPolicyWindowMonths,\n\ttype ILayerCompatDetails,\n\ttype ILayerCompatSupportRequirements,\n} from \"@fluid-internal/client-utils\";\nimport type { ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport {\n\tvalidateLayerCompatibility,\n\ttype MonitoringContext,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * The core compatibility details of the Loader layer that is the same across all layer boundaries.\n * @internal\n */\nexport const loaderCoreCompatDetails = {\n\t/**\n\t * The package version of the Loader layer.\n\t */\n\tpkgVersion,\n\t/**\n\t * The current generation of the Loader layer.\n\t */\n\tgeneration,\n} as const;\n\n/**\n * Loader's compatibility details that is exposed to the Runtime layer.\n * @internal\n */\nexport const loaderCompatDetailsForRuntime: ILayerCompatDetails = {\n\t...loaderCoreCompatDetails,\n\t/**\n\t * The features supported by the Loader layer across the Loader / Runtime boundary.\n\t */\n\tsupportedFeatures: new Set<string>(),\n};\n\n/**\n * Loader's compatibility details that is validated against the Driver layer's requirements.\n * @internal\n */\nexport const loaderCompatDetailsForDriver: ILayerCompatDetails = {\n\t...loaderCoreCompatDetails,\n\t/**\n\t * The features supported by the Loader layer across the Loader / Driver boundary.\n\t */\n\tsupportedFeatures: new Set<string>(),\n};\n\n/**\n * The requirements that the Runtime layer must meet to be compatible with this Loader.\n * @internal\n */\nexport const runtimeSupportRequirementsForLoader: ILayerCompatSupportRequirements = {\n\t/**\n\t * Minimum generation that Runtime must be at to be compatible with this Loader. This is calculated\n\t * based on the LayerCompatibilityPolicyWindowMonths.NewLoaderOldRuntime value which defines how many months\n\t * old can the Runtime layer be compared to the Loader layer for them to still be considered compatible.\n\t * The minimum valid generation value is 0.\n\t */\n\tminSupportedGeneration: Math.max(\n\t\t0,\n\t\tloaderCoreCompatDetails.generation -\n\t\t\tLayerCompatibilityPolicyWindowMonths.NewLoaderOldRuntime,\n\t),\n\t/**\n\t * The features that the Runtime must support to be compatible with Loader.\n\t */\n\trequiredFeatures: [],\n};\n\n/**\n * The requirements that the Driver layer must meet to be compatible with this Loader.\n * @internal\n */\nexport const driverSupportRequirementsForLoader: ILayerCompatSupportRequirements = {\n\t/**\n\t * Minimum generation that Driver must be at to be compatible with this Loader. This is calculated\n\t * based on the LayerCompatibilityPolicyWindowMonths.NewLoaderOldDriver value which defines how many months\n\t * old can the Driver layer be compared to the Loader layer for them to still be considered compatible.\n\t * The minimum valid generation value is 0.\n\t */\n\tminSupportedGeneration: Math.max(\n\t\t0,\n\t\tloaderCoreCompatDetails.generation -\n\t\t\tLayerCompatibilityPolicyWindowMonths.NewLoaderOldDriver,\n\t),\n\t/**\n\t * The features that the Driver must support to be compatible with Loader.\n\t */\n\trequiredFeatures: [],\n};\n\n/**\n * Validates that the Runtime layer is compatible with the Loader. *\n * @internal\n */\nexport function validateRuntimeCompatibility(\n\tmaybeRuntimeCompatDetails: ILayerCompatDetails | undefined,\n\tmc: MonitoringContext,\n): void {\n\tvalidateLayerCompatibility(\n\t\t/* validatingLayer */ {\n\t\t\tlayer: \"loader\",\n\t\t\tpackageInfo: loaderCoreCompatDetails,\n\t\t\tcompatSupportRequirements: runtimeSupportRequirementsForLoader,\n\t\t},\n\t\t/* targetLayer */ {\n\t\t\tlayer: \"runtime\",\n\t\t\tcompatDetails: maybeRuntimeCompatDetails,\n\t\t},\n\t\t{\n\t\t\tdisposeFn: () => {} /* no op. This will be handled by the caller */,\n\t\t\tmc,\n\t\t},\n\t);\n}\n\n/**\n * Validates that the Driver layer is compatible with the Loader.\n * @internal\n */\nexport function validateDriverCompatibility(\n\tmaybeDriverCompatDetails: ILayerCompatDetails | undefined,\n\tdisposeFn: (error?: ICriticalContainerError) => void,\n\tmc: MonitoringContext,\n): void {\n\tvalidateLayerCompatibility(\n\t\t/* validatingLayer */ {\n\t\t\tlayer: \"loader\",\n\t\t\tpackageInfo: loaderCoreCompatDetails,\n\t\t\tcompatSupportRequirements: driverSupportRequirementsForLoader,\n\t\t},\n\t\t/* targetLayer */ {\n\t\t\tlayer: \"driver\",\n\t\t\tcompatDetails: maybeDriverCompatDetails,\n\t\t},\n\t\t{ disposeFn, mc },\n\t);\n}\n\n/**\n * Validates that the Loader layer is compatible with the Driver.\n *\n * @remarks\n * This is the reverse of {@link validateDriverCompatibility} and is intentionally a separate function because it\n * does not follow the standard layer-validation pattern. Normally each layer validates the layer it holds a\n * reference to - the Loader validates the Driver, the Runtime validates the Loader, and so on. The Driver, however,\n * has no reference to the Loader and therefore cannot run this validation itself. To still enforce compatibility in\n * both directions across the Driver / Loader boundary, the Driver publishes the requirements it has for the Loader\n * (via ILayerCompatSupportRequirements) and the Loader validates itself against them here, on the Driver's behalf.\n *\n * @param maybeDriverCompatDetails - The Driver's compatibility details, used only to attribute the version /\n * generation of the Driver in telemetry if the Loader is found to be incompatible.\n * @param maybeDriverCompatRequirements - The requirements the Driver has for the Loader. Older Drivers may not\n * publish these, in which case there is nothing to validate in this direction.\n *\n * @internal\n */\nexport function validateLoaderCompatibilityWithDriver(\n\tmaybeDriverCompatDetails: ILayerCompatDetails | undefined,\n\tmaybeDriverCompatRequirements: ILayerCompatSupportRequirements | undefined,\n\tdisposeFn: (error?: ICriticalContainerError) => void,\n\tmc: MonitoringContext,\n): void {\n\tif (maybeDriverCompatRequirements === undefined) {\n\t\treturn;\n\t}\n\tvalidateLayerCompatibility(\n\t\t/* validatingLayer */ {\n\t\t\tlayer: \"driver\",\n\t\t\tpackageInfo: maybeDriverCompatDetails ?? defaultLayerCompatDetails,\n\t\t\tcompatSupportRequirements: maybeDriverCompatRequirements,\n\t\t},\n\t\t/* targetLayer */ {\n\t\t\tlayer: \"loader\",\n\t\t\tcompatDetails: loaderCompatDetailsForDriver,\n\t\t},\n\t\t{ disposeFn, mc },\n\t);\n}\n"]}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.isLocationRedirectionError = isLocationRedirectionError;
|
|
8
|
+
exports.resolveWithLocationRedirectionHandling = resolveWithLocationRedirectionHandling;
|
|
8
9
|
const internal_1 = require("@fluidframework/driver-definitions/internal");
|
|
9
10
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
10
11
|
/**
|
|
@@ -19,7 +20,6 @@ function isLocationRedirectionError(error) {
|
|
|
19
20
|
error.errorType ===
|
|
20
21
|
internal_1.DriverErrorTypes.locationRedirection);
|
|
21
22
|
}
|
|
22
|
-
exports.isLocationRedirectionError = isLocationRedirectionError;
|
|
23
23
|
/**
|
|
24
24
|
* Handles location redirection while fulfilling the loader request.
|
|
25
25
|
* @param api - Callback in which user can wrap the loader.resolve or loader.request call.
|
|
@@ -51,5 +51,4 @@ async function resolveWithLocationRedirectionHandling(api, request, urlResolver,
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
exports.resolveWithLocationRedirectionHandling = resolveWithLocationRedirectionHandling;
|
|
55
54
|
//# sourceMappingURL=resolveWithLocationRedirection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveWithLocationRedirection.js","sourceRoot":"","sources":["../../src/location-redirection-utilities/resolveWithLocationRedirection.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"resolveWithLocationRedirection.js","sourceRoot":"","sources":["../../src/location-redirection-utilities/resolveWithLocationRedirection.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAgBH,gEASC;AAYD,wFAwBC;AA1DD,0EAIqD;AACrD,uEAA6E;AAE7E;;;;;GAKG;AACH,SAAgB,0BAA0B,CACzC,KAAc;IAEd,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAA4C,CAAC,SAAS;YACtD,2BAAgB,CAAC,mBAAmB,CACrC,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,sCAAsC,CAC3D,GAAsC,EACtC,OAAiB,EACjB,WAAyB,EACzB,MAA6B;IAE7B,IAAI,GAAG,GAAa,OAAO,CAAC;IAC5B,MAAM,WAAW,GAAG,IAAA,4BAAiB,EAAC,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,CAAC;IACpF,SAAS,CAAC;QACT,IAAI,CAAC;YACJ,OAAO,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACzB,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxC,MAAM,KAAK,CAAC;YACb,CAAC;YACD,WAAW,CAAC,kBAAkB,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAC1E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;YACtC,yGAAyG;YACzG,kGAAkG;YAClG,oCAAoC;YACpC,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,cAAc,CAAC,WAAW,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;YACjF,GAAG,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAClD,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IRequest, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport {\n\ttype ILocationRedirectionError,\n\ttype IUrlResolver,\n\tDriverErrorTypes,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * Checks if the error is location redirection error.\n * @param error - error whose type is to be determined.\n * @returns `true` is the error is location redirection error, otherwise `false`.\n * @internal\n */\nexport function isLocationRedirectionError(\n\terror: unknown,\n): error is ILocationRedirectionError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error as Partial<ILocationRedirectionError>).errorType ===\n\t\t\tDriverErrorTypes.locationRedirection\n\t);\n}\n\n/**\n * Handles location redirection while fulfilling the loader request.\n * @param api - Callback in which user can wrap the loader.resolve or loader.request call.\n * @param request - request to be resolved.\n * @param urlResolver - resolver used to resolve the url.\n * @param logger - logger to send events.\n * @returns Response from the API call.\n * @legacy\n * @beta\n */\nexport async function resolveWithLocationRedirectionHandling<T>(\n\tapi: (request: IRequest) => Promise<T>,\n\trequest: IRequest,\n\turlResolver: IUrlResolver,\n\tlogger?: ITelemetryBaseLogger,\n): Promise<T> {\n\tlet req: IRequest = request;\n\tconst childLogger = createChildLogger({ logger, namespace: \"LocationRedirection\" });\n\tfor (;;) {\n\t\ttry {\n\t\t\treturn await api(req);\n\t\t} catch (error: unknown) {\n\t\t\tif (!isLocationRedirectionError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tchildLogger.sendTelemetryEvent({ eventName: \"LocationRedirectionError\" });\n\t\t\tconst resolvedUrl = error.redirectUrl;\n\t\t\t// Generate the new request with new location details from the resolved url. For datastore/relative path,\n\t\t\t// we don't need to pass \"/\" as host could have asked for a specific data store. So driver need to\n\t\t\t// extract it from the resolved url.\n\t\t\tconst absoluteUrl = await urlResolver.getAbsoluteUrl(resolvedUrl, \"\", undefined);\n\t\t\treq = { url: absoluteUrl, headers: req.headers };\n\t\t}\n\t}\n}\n"]}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.tryInitializeMemoryDetachedBlobStorage = tryInitializeMemoryDetachedBlobStorage;
|
|
8
|
+
exports.createMemoryDetachedBlobStorage = createMemoryDetachedBlobStorage;
|
|
8
9
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
10
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
10
11
|
function tryInitializeMemoryDetachedBlobStorage(detachedStorage, attachmentBlobs) {
|
|
@@ -15,7 +16,6 @@ function tryInitializeMemoryDetachedBlobStorage(detachedStorage, attachmentBlobs
|
|
|
15
16
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
16
17
|
detachedStorage.initialize(maybeAttachmentBlobs);
|
|
17
18
|
}
|
|
18
|
-
exports.tryInitializeMemoryDetachedBlobStorage = tryInitializeMemoryDetachedBlobStorage;
|
|
19
19
|
/**
|
|
20
20
|
* Creates a new instance of `MemoryDetachedBlobStorage`.
|
|
21
21
|
* The returned storage allows for creating, reading, and managing blobs in memory.
|
|
@@ -41,5 +41,4 @@ function createMemoryDetachedBlobStorage() {
|
|
|
41
41
|
};
|
|
42
42
|
return storage;
|
|
43
43
|
}
|
|
44
|
-
exports.createMemoryDetachedBlobStorage = createMemoryDetachedBlobStorage;
|
|
45
44
|
//# sourceMappingURL=memoryBlobStorage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoryBlobStorage.js","sourceRoot":"","sources":["../src/memoryBlobStorage.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"memoryBlobStorage.js","sourceRoot":"","sources":["../src/memoryBlobStorage.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAiCH,wFAWC;AAQD,0EAqBC;AAvED,+DAA8E;AAC9E,kEAA6D;AA8B7D,SAAgB,sCAAsC,CACrD,eAA0C,EAC1C,eAAuB;IAEvB,IAAA,iBAAM,EAAC,eAAe,CAAC,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACjF,mEAAmE;IACnE,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACzD,IAAA,iBAAM,EAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAEjF,iEAAiE;IACjE,eAAe,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,+BAA+B;IAC9C,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,MAAM,OAAO,GAA8B;QAC1C,UAAU,EAAE,KAAK,EAAE,IAAqB,EAAgC,EAAE,CAAC,CAAC;YAC3E,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;SAC7B,CAAC;QACF,QAAQ,EAAE,KAAK,EAAE,EAAU,EAA4B,EAAE,CACxD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACxE,IAAI,IAAI;YACP,OAAO,KAAK,CAAC,MAAM,CAAC;QACrB,CAAC;QACD,UAAU,EAAE,GAAa,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9B,SAAS,EAAE,GAAG,EAAE,CACf,KAAK,CAAC,MAAM,GAAG,CAAC;YACf,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,6BAAc,EAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7D,CAAC,CAAC,SAAS;QACb,UAAU,EAAE,CAAC,eAAyB,EAAE,EAAE,CACzC,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAA,6BAAc,EAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;KACrF,CAAC;IACF,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { bufferToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tICreateBlobResponse,\n\tIDocumentStorageService,\n} from \"@fluidframework/driver-definitions/internal\";\n\n/**\n * An interface used to manage blobs in memory for detached containers.\n *\n * @remarks\n * On attach of the container the blobs are read, and uploaded to the server.\n * The interface also supports serialization and initialization which is\n * used when serializing and rehydrating a detached container with blobs.\n */\nexport interface MemoryDetachedBlobStorage\n\textends Pick<IDocumentStorageService, \"createBlob\" | \"readBlob\"> {\n\tsize: number;\n\t/**\n\t * Return an array of all blob IDs present in storage\n\t */\n\tgetBlobIds(): string[];\n\n\t/**\n\t * After the container is attached, the detached blob storage is no longer needed and will be disposed.\n\t */\n\tdispose?(): void;\n\tinitialize(attachmentBlobs: string[]): void;\n\tserialize(): string | undefined;\n}\n\nexport function tryInitializeMemoryDetachedBlobStorage(\n\tdetachedStorage: MemoryDetachedBlobStorage,\n\tattachmentBlobs: string,\n): void {\n\tassert(detachedStorage.size === 0, 0x99e /* Blob storage already initialized */);\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\tconst maybeAttachmentBlobs = JSON.parse(attachmentBlobs);\n\tassert(Array.isArray(maybeAttachmentBlobs), 0x99f /* Invalid attachmentBlobs */);\n\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\tdetachedStorage.initialize(maybeAttachmentBlobs);\n}\n\n/**\n * Creates a new instance of `MemoryDetachedBlobStorage`.\n * The returned storage allows for creating, reading, and managing blobs in memory.\n * It also provides methods for serialization and initialization with attachment blobs.\n * @returns A new `MemoryDetachedBlobStorage` instance.\n */\nexport function createMemoryDetachedBlobStorage(): MemoryDetachedBlobStorage {\n\tconst blobs: ArrayBufferLike[] = [];\n\tconst storage: MemoryDetachedBlobStorage = {\n\t\tcreateBlob: async (file: ArrayBufferLike): Promise<ICreateBlobResponse> => ({\n\t\t\tid: `${blobs.push(file) - 1}`,\n\t\t}),\n\t\treadBlob: async (id: string): Promise<ArrayBufferLike> =>\n\t\t\tblobs[Number(id)] ?? Promise.reject(new Error(`Blob not found: ${id}`)),\n\t\tget size() {\n\t\t\treturn blobs.length;\n\t\t},\n\t\tgetBlobIds: (): string[] => blobs.map((_, i) => `${i}`),\n\t\tdispose: () => blobs.splice(0),\n\t\tserialize: () =>\n\t\t\tblobs.length > 0\n\t\t\t\t? JSON.stringify(blobs.map((b) => bufferToString(b, \"utf8\")))\n\t\t\t\t: undefined,\n\t\tinitialize: (attachmentBlobs: string[]) =>\n\t\t\tblobs.push(...attachmentBlobs.map((maybeBlob) => stringToBuffer(maybeBlob, \"utf8\"))),\n\t};\n\treturn storage;\n}\n"]}
|
package/dist/noopHeuristic.js
CHANGED
|
@@ -30,10 +30,12 @@ const defaultNoopCountFrequency = 50;
|
|
|
30
30
|
// 2. If there are more than 50 ops received without sending any ops, send noop to keep collab window small.
|
|
31
31
|
// Note that system ops (including noops themselves) are excluded, so it's 1 noop per 50 real ops.
|
|
32
32
|
class NoopHeuristic extends client_utils_1.TypedEventEmitter {
|
|
33
|
+
NoopCountFrequency;
|
|
34
|
+
opsProcessedSinceOpSent = 0;
|
|
35
|
+
timer;
|
|
33
36
|
constructor(NoopTimeFrequency = defaultNoopTimeFrequency, NoopCountFrequency = defaultNoopCountFrequency) {
|
|
34
37
|
super();
|
|
35
38
|
this.NoopCountFrequency = NoopCountFrequency;
|
|
36
|
-
this.opsProcessedSinceOpSent = 0;
|
|
37
39
|
if (NoopTimeFrequency !== Number.POSITIVE_INFINITY) {
|
|
38
40
|
this.timer = new internal_1.Timer(NoopTimeFrequency, () => {
|
|
39
41
|
// We allow the timer to expire even if an op is sent or we disconnect.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noopHeuristic.js","sourceRoot":"","sources":["../src/noopHeuristic.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAEjE,kEAAoE;AAEpE,oEAAyE;AAEzE,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAMrC,6FAA6F;AAC7F,4GAA4G;AAC5G,yGAAyG;AACzG,2CAA2C;AAC3C,oHAAoH;AACpH,2FAA2F;AAC3F,kHAAkH;AAClH,+CAA+C;AAC/C,gHAAgH;AAChH,yFAAyF;AACzF,qHAAqH;AACrH,oDAAoD;AACpD,EAAE;AACF,kDAAkD;AAClD,oGAAoG;AACpG,iHAAiH;AACjH,sEAAsE;AACtE,4GAA4G;AAC5G,qGAAqG;AACrG,MAAa,aAAc,SAAQ,gCAAoC;
|
|
1
|
+
{"version":3,"file":"noopHeuristic.js","sourceRoot":"","sources":["../src/noopHeuristic.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAEjE,kEAAoE;AAEpE,oEAAyE;AAEzE,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAMrC,6FAA6F;AAC7F,4GAA4G;AAC5G,yGAAyG;AACzG,2CAA2C;AAC3C,oHAAoH;AACpH,2FAA2F;AAC3F,kHAAkH;AAClH,+CAA+C;AAC/C,gHAAgH;AAChH,yFAAyF;AACzF,qHAAqH;AACrH,oDAAoD;AACpD,EAAE;AACF,kDAAkD;AAClD,oGAAoG;AACpG,iHAAiH;AACjH,sEAAsE;AACtE,4GAA4G;AAC5G,qGAAqG;AACrG,MAAa,aAAc,SAAQ,gCAAoC;IAMpD;IALV,uBAAuB,GAAG,CAAC,CAAC;IACnB,KAAK,CAAoB;IAE1C,YACC,oBAA4B,wBAAwB,EACnC,qBAA6B,yBAAyB;QAEvE,KAAK,EAAE,CAAC;QAFS,uBAAkB,GAAlB,kBAAkB,CAAoC;QAGvE,IAAI,iBAAiB,KAAK,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACpD,IAAI,CAAC,KAAK,GAAG,IAAI,gBAAK,CAAC,iBAAiB,EAAE,GAAG,EAAE;gBAC9C,uEAAuE;gBACvE,gFAAgF;gBAChF,IAAI,IAAI,CAAC,uBAAuB,KAAK,CAAC,EAAE,CAAC;oBACxC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACxB,CAAC;YACF,CAAC,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED;;OAEG;IACI,sBAAsB,CAAC,OAAkC;QAC/D,gFAAgF;QAChF,+DAA+D;QAC/D,sFAAsF;QACtF,yCAAyC;QACzC,IAAI,CAAC,IAAA,2BAAgB,EAAC,OAAO,CAAC,EAAE,CAAC;YAChC,OAAO;QACR,CAAC;QAED,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,uBAAuB,KAAK,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC9D,qGAAqG;YACrG,gJAAgJ;YAChJ,+FAA+F;YAC/F,cAAc,CAAC,GAAG,EAAE;gBACnB,IAAI,IAAI,CAAC,uBAAuB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC7D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBACvB,IAAA,iBAAM,EACL,IAAI,CAAC,uBAAuB,KAAK,CAAC,EAClC,KAAK,CAAC,gDAAgD,CACtD,CAAC;gBACH,CAAC;gBACD,OAAO;YACR,CAAC,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,yDAAyD;YACzD,6HAA6H;YAC7H,IAAI,IAAI,CAAC,uBAAuB,KAAK,CAAC,EAAE,CAAC;gBACxC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACtB,CAAC;YAED,IAAA,iBAAM,EAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACtD,CAAC;IACF,CAAC;IAEM,gBAAgB;QACtB,2GAA2G;QAC3G,IAAI,CAAC,uBAAuB,GAAG,CAAC,CAAC;IAClC,CAAC;IAEM,iBAAiB;QACvB,6DAA6D;QAC7D,IAAI,CAAC,uBAAuB,GAAG,CAAC,CAAC;IAClC,CAAC;CACD;AArED,sCAqEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IEvent } from \"@fluidframework/core-interfaces\";\nimport { assert, Timer } from \"@fluidframework/core-utils/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { isRuntimeMessage } from \"@fluidframework/driver-utils/internal\";\n\nconst defaultNoopTimeFrequency = 2000;\nconst defaultNoopCountFrequency = 50;\n\nexport interface INoopSenderEvents extends IEvent {\n\t(event: \"wantsNoop\", listener: () => void);\n}\n\n// Here are key considerations when deciding conditions for when to send non-immediate noops:\n// 1. Sending them too often results in increase in file size and bandwidth, as well as catch up performance\n// 2. Sending too infrequently ensures that collab window is large, and as result Sequence DDS would have\n// large catchUp blobs - see Issue #6364\n// 3. Similarly, processes that rely on \"core\" snapshot (and can't parse trailing ops, including above), like search\n// parser in SPO, will result in non-accurate results due to presence of catch up blobs.\n// 4. Ordering service used 250ms timeout to coalesce non-immediate noops. It was changed to 2000 ms to allow more\n// aggressive noop sending from client side.\n// 5. Number of ops sent by all clients is proportional to number of \"write\" clients (every client sends noops),\n// but number of sequenced noops is a function of time (one op per 2 seconds at most).\n// We should consider impact to both outbound traffic (might be huge, depends on number of clients) and file size.\n// Please also see Issue #5629 for more discussions.\n//\n// With that, the current algorithm is as follows:\n// 1. Sent noop 2000 ms of receiving an op if no ops were sent by this client within this timeframe.\n// This will ensure that MSN moves forward with reasonable speed. If that results in too many sequenced noops,\n// server timeout of 2000ms should be reconsidered to be increased.\n// 2. If there are more than 50 ops received without sending any ops, send noop to keep collab window small.\n// Note that system ops (including noops themselves) are excluded, so it's 1 noop per 50 real ops.\nexport class NoopHeuristic extends TypedEventEmitter<INoopSenderEvents> {\n\tprivate opsProcessedSinceOpSent = 0;\n\tprivate readonly timer: Timer | undefined;\n\n\tconstructor(\n\t\tNoopTimeFrequency: number = defaultNoopTimeFrequency,\n\t\tprivate readonly NoopCountFrequency: number = defaultNoopCountFrequency,\n\t) {\n\t\tsuper();\n\t\tif (NoopTimeFrequency !== Number.POSITIVE_INFINITY) {\n\t\t\tthis.timer = new Timer(NoopTimeFrequency, () => {\n\t\t\t\t// We allow the timer to expire even if an op is sent or we disconnect.\n\t\t\t\t// This condition is to guard against trying to send a noop anyway in that case.\n\t\t\t\tif (this.opsProcessedSinceOpSent !== 0) {\n\t\t\t\t\tthis.emit(\"wantsNoop\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Schedules as ack to the server to update the reference sequence number\n\t */\n\tpublic notifyMessageProcessed(message: ISequencedDocumentMessage): void {\n\t\t// We don't acknowledge no-ops to avoid acknowledgement cycles (i.e. ack the MSN\n\t\t// update, which updates the MSN, then ack the update, etc...).\n\t\t// Intent here is for runtime (and DDSes) not to keep too much tracking state / memory\n\t\t// due to runtime ops from other clients.\n\t\tif (!isRuntimeMessage(message)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.opsProcessedSinceOpSent++;\n\t\tif (this.opsProcessedSinceOpSent === this.NoopCountFrequency) {\n\t\t\t// Wait to send a noop if we are still synchronously processing ops. This guards against two things:\n\t\t\t// 1. If we're processing many ops, we may pass the frequency threshold many times. We only need to send one noop at the very end in this case.\n\t\t\t// 2. We may send another (non-noop) op in response to processing those ops, e.g. an Accept op.\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tif (this.opsProcessedSinceOpSent >= this.NoopCountFrequency) {\n\t\t\t\t\tthis.emit(\"wantsNoop\");\n\t\t\t\t\tassert(\n\t\t\t\t\t\tthis.opsProcessedSinceOpSent === 0,\n\t\t\t\t\t\t0x243 /* \"Expected a noop to be synchronously sent\" */,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t});\n\t\t}\n\n\t\tif (this.timer !== undefined) {\n\t\t\t// Start the timer if we newly have ops that want a noop.\n\t\t\t// If the timer was already running (e.g. we surpassed the op count and sent a noop) this will reset it to its full duration.\n\t\t\tif (this.opsProcessedSinceOpSent === 1) {\n\t\t\t\tthis.timer.restart();\n\t\t\t}\n\n\t\t\tassert(this.timer.hasTimer, 0x242 /* \"has timer\" */);\n\t\t}\n\t}\n\n\tpublic notifyDisconnect(): void {\n\t\t// No need to noop for any ops processed prior to disconnect - we are already removed from MSN calculation.\n\t\tthis.opsProcessedSinceOpSent = 0;\n\t}\n\n\tpublic notifyMessageSent(): void {\n\t\t// Sending any message is as good as a noop for updating MSN.\n\t\tthis.opsProcessedSinceOpSent = 0;\n\t}\n}\n"]}
|
package/dist/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/container-loader";
|
|
8
|
-
export declare const pkgVersion = "
|
|
8
|
+
export declare const pkgVersion = "3.0.1";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,eAAO,MAAM,UAAU,UAAU,CAAC"}
|
package/dist/packageVersion.js
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.pkgVersion = exports.pkgName = void 0;
|
|
10
10
|
exports.pkgName = "@fluidframework/container-loader";
|
|
11
|
-
exports.pkgVersion = "
|
|
11
|
+
exports.pkgVersion = "3.0.1";
|
|
12
12
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,kCAAkC,CAAC;AAC7C,QAAA,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,kCAAkC,CAAC;AAC7C,QAAA,UAAU,GAAG,OAAO,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-loader\";\nexport const pkgVersion = \"3.0.1\";\n"]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
import type { FluidIterableIterator } from "@fluidframework/core-interfaces";
|
|
5
6
|
/**
|
|
6
7
|
* A Map-like store for managing pending local container states from attached containers.
|
|
7
8
|
* Optimizes storage by deduplicating shared resources across stored states.
|
|
@@ -71,14 +72,14 @@ export declare class PendingLocalStateStore<TKey> {
|
|
|
71
72
|
/**
|
|
72
73
|
* Returns an iterator over [key, serializedState] pairs.
|
|
73
74
|
*/
|
|
74
|
-
entries():
|
|
75
|
+
entries(): FluidIterableIterator<[TKey, string]>;
|
|
75
76
|
/**
|
|
76
77
|
* Returns an iterator over the stored keys.
|
|
77
78
|
*/
|
|
78
|
-
keys():
|
|
79
|
+
keys(): FluidIterableIterator<TKey>;
|
|
79
80
|
/**
|
|
80
81
|
* Makes the store iterable with `for...of` loops.
|
|
81
82
|
*/
|
|
82
|
-
[Symbol.iterator]():
|
|
83
|
+
[Symbol.iterator](): FluidIterableIterator<[TKey, string]>;
|
|
83
84
|
}
|
|
84
85
|
//# sourceMappingURL=pendingLocalStateStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pendingLocalStateStore.d.ts","sourceRoot":"","sources":["../src/pendingLocalStateStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"pendingLocalStateStore.d.ts","sourceRoot":"","sources":["../src/pendingLocalStateStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAU7E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,sBAAsB,CAAC,IAAI;;IAQvC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO;IAI1B;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS;IAIlC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO;IAIvB;;;;;;;;OAQG;IACH,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,GAAG,IAAI;IAuC/C;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,OAAO,IAAI,qBAAqB,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAiBhD;;OAEG;IACH,IAAI,IAAI,qBAAqB,CAAC,IAAI,CAAC;IAInC;;OAEG;IACH,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,qBAAqB,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;CAG1D"}
|
|
@@ -3,18 +3,6 @@
|
|
|
3
3
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
7
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
8
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
9
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
10
|
-
};
|
|
11
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
12
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
13
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
14
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
15
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
16
|
-
};
|
|
17
|
-
var _PendingLocalStateStore_firstUrl, _PendingLocalStateStore_pendingStates, _PendingLocalStateStore_savedOps, _PendingLocalStateStore_blobs, _PendingLocalStateStore_attachmentBlobs, _PendingLocalStateStore_loadingGroups;
|
|
18
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
7
|
exports.PendingLocalStateStore = void 0;
|
|
20
8
|
const internal_1 = require("@fluidframework/telemetry-utils/internal");
|
|
@@ -48,19 +36,17 @@ const utils_js_1 = require("./utils.js");
|
|
|
48
36
|
* @legacy @alpha
|
|
49
37
|
*/
|
|
50
38
|
class PendingLocalStateStore {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
_PendingLocalStateStore_loadingGroups.set(this, {});
|
|
58
|
-
}
|
|
39
|
+
#firstUrl;
|
|
40
|
+
#pendingStates = new Map();
|
|
41
|
+
#savedOps = {};
|
|
42
|
+
#blobs = {};
|
|
43
|
+
#attachmentBlobs = {};
|
|
44
|
+
#loadingGroups = {};
|
|
59
45
|
/**
|
|
60
46
|
* Removes all stored pending states.
|
|
61
47
|
*/
|
|
62
48
|
clear() {
|
|
63
|
-
return
|
|
49
|
+
return this.#pendingStates.clear();
|
|
64
50
|
}
|
|
65
51
|
/**
|
|
66
52
|
* Removes the pending state for the specified key.
|
|
@@ -69,7 +55,7 @@ class PendingLocalStateStore {
|
|
|
69
55
|
* @returns `true` if the state existed and was removed, `false` otherwise
|
|
70
56
|
*/
|
|
71
57
|
delete(key) {
|
|
72
|
-
return
|
|
58
|
+
return this.#pendingStates.delete(key);
|
|
73
59
|
}
|
|
74
60
|
/**
|
|
75
61
|
* Retrieves the serialized pending state for the specified key.
|
|
@@ -78,13 +64,13 @@ class PendingLocalStateStore {
|
|
|
78
64
|
* @returns The serialized state as a JSON string, or `undefined` if not found
|
|
79
65
|
*/
|
|
80
66
|
get(key) {
|
|
81
|
-
return JSON.stringify(
|
|
67
|
+
return JSON.stringify(this.#pendingStates.get(key));
|
|
82
68
|
}
|
|
83
69
|
/**
|
|
84
70
|
* Checks whether a pending state exists for the specified key.
|
|
85
71
|
*/
|
|
86
72
|
has(key) {
|
|
87
|
-
return
|
|
73
|
+
return this.#pendingStates.has(key);
|
|
88
74
|
}
|
|
89
75
|
/**
|
|
90
76
|
* Stores a pending state from `container.getPendingLocalState()`.
|
|
@@ -100,44 +86,44 @@ class PendingLocalStateStore {
|
|
|
100
86
|
const { savedOps, snapshotBlobs, attachmentBlobContents, loadedGroupIdSnapshots, url } = state;
|
|
101
87
|
// Normalize URL by removing trailing slash for comparison
|
|
102
88
|
const normalizedUrl = url.replace(/\/$/, "");
|
|
103
|
-
const normalizedFirstUrl =
|
|
104
|
-
|
|
89
|
+
const normalizedFirstUrl = this.#firstUrl?.replace(/\/$/, "");
|
|
90
|
+
this.#firstUrl ??= url;
|
|
105
91
|
if (normalizedFirstUrl !== undefined && normalizedFirstUrl !== normalizedUrl) {
|
|
106
92
|
throw new internal_1.UsageError("PendingLocalStateStore can only be used with a single container.");
|
|
107
93
|
}
|
|
108
94
|
for (let i = 0; i < savedOps.length; i++) {
|
|
109
|
-
savedOps[i] =
|
|
95
|
+
savedOps[i] = this.#savedOps[savedOps[i].sequenceNumber] ??= savedOps[i];
|
|
110
96
|
}
|
|
111
97
|
for (const [id, blob] of Object.entries(snapshotBlobs)) {
|
|
112
|
-
snapshotBlobs[id] =
|
|
98
|
+
snapshotBlobs[id] = this.#blobs[id] ??= blob;
|
|
113
99
|
}
|
|
114
100
|
if (attachmentBlobContents !== undefined) {
|
|
115
101
|
for (const [id, blob] of Object.entries(attachmentBlobContents)) {
|
|
116
|
-
attachmentBlobContents[id] =
|
|
102
|
+
attachmentBlobContents[id] = this.#attachmentBlobs[id] ??= blob;
|
|
117
103
|
}
|
|
118
104
|
}
|
|
119
105
|
if (loadedGroupIdSnapshots !== undefined) {
|
|
120
106
|
for (const [id, lg] of Object.entries(loadedGroupIdSnapshots)) {
|
|
121
|
-
if (
|
|
122
|
-
lg.snapshotSequenceNumber <
|
|
123
|
-
loadedGroupIdSnapshots[id] =
|
|
107
|
+
if (this.#loadingGroups[id] === undefined ||
|
|
108
|
+
lg.snapshotSequenceNumber < this.#loadingGroups[id].snapshotSequenceNumber) {
|
|
109
|
+
loadedGroupIdSnapshots[id] = this.#loadingGroups[id] = lg;
|
|
124
110
|
}
|
|
125
111
|
}
|
|
126
112
|
}
|
|
127
|
-
|
|
113
|
+
this.#pendingStates.set(key, state);
|
|
128
114
|
return this;
|
|
129
115
|
}
|
|
130
116
|
/**
|
|
131
117
|
* Gets the number of stored pending states.
|
|
132
118
|
*/
|
|
133
119
|
get size() {
|
|
134
|
-
return
|
|
120
|
+
return this.#pendingStates.size;
|
|
135
121
|
}
|
|
136
122
|
/**
|
|
137
123
|
* Returns an iterator over [key, serializedState] pairs.
|
|
138
124
|
*/
|
|
139
125
|
entries() {
|
|
140
|
-
const iterator =
|
|
126
|
+
const iterator = this.#pendingStates.entries();
|
|
141
127
|
return {
|
|
142
128
|
next: () => {
|
|
143
129
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
@@ -147,18 +133,21 @@ class PendingLocalStateStore {
|
|
|
147
133
|
}
|
|
148
134
|
return { done, value: [value[0], JSON.stringify(value[1])] };
|
|
149
135
|
},
|
|
136
|
+
[Symbol.iterator]() {
|
|
137
|
+
return this;
|
|
138
|
+
},
|
|
150
139
|
};
|
|
151
140
|
}
|
|
152
141
|
/**
|
|
153
142
|
* Returns an iterator over the stored keys.
|
|
154
143
|
*/
|
|
155
144
|
keys() {
|
|
156
|
-
return
|
|
145
|
+
return this.#pendingStates.keys();
|
|
157
146
|
}
|
|
158
147
|
/**
|
|
159
148
|
* Makes the store iterable with `for...of` loops.
|
|
160
149
|
*/
|
|
161
|
-
[
|
|
150
|
+
[Symbol.iterator]() {
|
|
162
151
|
return this.entries();
|
|
163
152
|
}
|
|
164
153
|
}
|