@fluidframework/odsp-driver 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.5.3.2.178189
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 +16 -0
- package/dist/contracts.d.ts +0 -25
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +7 -1
- package/dist/epochTracker.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -1
- package/dist/odspCache.d.ts +2 -3
- package/dist/odspCache.d.ts.map +1 -1
- package/dist/odspCache.js +5 -5
- package/dist/odspCache.js.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.js +1 -1
- package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +1 -1
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +6 -3
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts +12 -4
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +14 -0
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +2 -0
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts +1 -2
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspUtils.d.ts +2 -1
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +5 -1
- package/dist/odspUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts +1 -1
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +14 -5
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/dist/retryErrorsStorageAdapter.js.map +1 -1
- package/dist/vroom.d.ts +1 -2
- package/dist/vroom.d.ts.map +1 -1
- package/dist/vroom.js.map +1 -1
- package/lib/contracts.d.ts +0 -25
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +8 -2
- package/lib/epochTracker.js.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts +1 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -1
- package/lib/odspCache.d.ts +2 -3
- package/lib/odspCache.d.ts.map +1 -1
- package/lib/odspCache.js +1 -1
- package/lib/odspCache.js.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.js +2 -2
- package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts +1 -1
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +6 -3
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts +12 -4
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +15 -1
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +2 -0
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts +1 -2
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspUtils.d.ts +2 -1
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +3 -0
- package/lib/odspUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/prefetchLatestSnapshot.d.ts +1 -1
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +14 -5
- package/lib/prefetchLatestSnapshot.js.map +1 -1
- package/lib/retryErrorsStorageAdapter.d.ts +1 -1
- package/lib/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/lib/retryErrorsStorageAdapter.js.map +1 -1
- package/lib/vroom.d.ts +1 -2
- package/lib/vroom.d.ts.map +1 -1
- package/lib/vroom.js.map +1 -1
- package/package.json +29 -14
- package/src/contracts.ts +0 -34
- package/src/epochTracker.ts +8 -5
- package/src/localOdspDriver/localOdspDocumentServiceFactory.ts +1 -1
- package/src/odspCache.ts +2 -2
- package/src/odspDelayLoadedDeltaStream.ts +7 -3
- package/src/odspDeltaStorageService.ts +7 -4
- package/src/odspDocumentServiceFactoryCore.ts +27 -2
- package/src/odspDocumentStorageManager.ts +2 -0
- package/src/odspDriverUrlResolverForShareLink.ts +1 -2
- package/src/odspUtils.ts +5 -1
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +15 -6
- package/src/retryErrorsStorageAdapter.ts +1 -1
- package/src/vroom.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @fluidframework/odsp-driver
|
|
2
2
|
|
|
3
|
+
## 2.0.0-internal.5.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- New API getRelaySessionInfo in odsp-driver ([#16300](https://github.com/microsoft/FluidFramework/issues/16300)) [a25789cd37](https://github.com/microsoft/FluidFramework/commits/a25789cd37bf60ebc4a08e1a9f7eaa8c65f4eae2)
|
|
8
|
+
|
|
9
|
+
`OdspDocumentServiceFactory` and `OdspDocumentServiceFactoryCore` now provide a new API `getRelaySessionInfo` to surface relay session info from cache.
|
|
10
|
+
|
|
11
|
+
## 2.0.0-internal.5.2.0
|
|
12
|
+
|
|
13
|
+
Dependency updates only.
|
|
14
|
+
|
|
15
|
+
## 2.0.0-internal.5.1.0
|
|
16
|
+
|
|
17
|
+
Dependency updates only.
|
|
18
|
+
|
|
3
19
|
## 2.0.0-internal.5.0.0
|
|
4
20
|
|
|
5
21
|
Dependency updates only.
|
package/dist/contracts.d.ts
CHANGED
|
@@ -5,31 +5,6 @@
|
|
|
5
5
|
import * as api from "@fluidframework/protocol-definitions";
|
|
6
6
|
import { HostStoragePolicy } from "@fluidframework/odsp-driver-definitions";
|
|
7
7
|
import { ISnapshotContents } from "./odspPublicUtils";
|
|
8
|
-
/**
|
|
9
|
-
* Socket storage discovery api response
|
|
10
|
-
*/
|
|
11
|
-
export interface ISocketStorageDiscovery {
|
|
12
|
-
id: string;
|
|
13
|
-
runtimeTenantId?: string;
|
|
14
|
-
tenantId: string;
|
|
15
|
-
snapshotStorageUrl: string;
|
|
16
|
-
deltaStorageUrl: string;
|
|
17
|
-
/**
|
|
18
|
-
* PUSH URL
|
|
19
|
-
*/
|
|
20
|
-
deltaStreamSocketUrl: string;
|
|
21
|
-
/**
|
|
22
|
-
* The access token for PushChannel. Optionally returned, depending on implementation.
|
|
23
|
-
* OneDrive for Consumer implementation returns it and OneDrive for Business implementation
|
|
24
|
-
* does not return it and instead expects token to be returned via `getWebsocketToken` callback
|
|
25
|
-
* passed as a parameter to `OdspDocumentService.create()` factory.
|
|
26
|
-
*/
|
|
27
|
-
socketToken?: string;
|
|
28
|
-
/**
|
|
29
|
-
* This is the time within which client has to refresh the session on (ODSP) relay service.
|
|
30
|
-
*/
|
|
31
|
-
refreshSessionDurationSeconds?: number;
|
|
32
|
-
}
|
|
33
8
|
/**
|
|
34
9
|
* Interface for error responses for the WebSocket connection
|
|
35
10
|
*/
|
package/dist/contracts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,GAAG,MAAM,sCAAsC,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA0LU,QAAA,0BAA0B,GAAG,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport * as api from \"@fluidframework/protocol-definitions\";\nimport { HostStoragePolicy } from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\n\n/**\n * Interface for error responses for the WebSocket connection\n */\nexport interface IOdspSocketError {\n\t/**\n\t * An error code number for the error that occurred\n\t * It will be a valid HTTP status code\n\t */\n\tcode: number;\n\n\t/**\n\t * A message about the error that occurred for debugging / logging purposes\n\t * This should not be displayed to the user directly\n\t */\n\tmessage: string;\n\n\t/**\n\t * Optional Retry-After time in seconds\n\t * The client should wait this many seconds before retrying its request\n\t */\n\tretryAfter?: number;\n\n\t/**\n\t * Any error supplied by the socket containing codes and inner errors with further\n\t * details about the error.\n\t */\n\terror?: any;\n}\n\n/**\n * Interface for delta storage response.\n * Contains either SequencedDocumentMessages or SequencedDeltaOpMessage.\n */\nexport interface IDeltaStorageGetResponse {\n\tvalue: api.ISequencedDocumentMessage[] | ISequencedDeltaOpMessage[];\n}\n\nexport interface ISequencedDeltaOpMessage {\n\top: api.ISequencedDocumentMessage;\n\tsequenceNumber: number;\n}\n\nexport interface IDocumentStorageGetVersionsResponse {\n\tvalue: IDocumentStorageVersion[];\n}\n\nexport interface IDocumentStorageVersion {\n\tid: string;\n}\n\n/**\n *\n * Data structures that form ODSP Summary\n *\n */\n\nexport interface IOdspSummaryPayload {\n\ttype: \"container\" | \"channel\";\n\tmessage: string;\n\tsequenceNumber: number;\n\tentries: OdspSummaryTreeEntry[];\n}\n\nexport interface IWriteSummaryResponse {\n\tid: string;\n}\n\nexport type OdspSummaryTreeEntry = IOdspSummaryTreeValueEntry | IOdspSummaryTreeHandleEntry;\n\nexport interface IOdspSummaryTreeBaseEntry {\n\tpath: string;\n\ttype: \"blob\" | \"tree\" | \"commit\";\n}\n\nexport interface IOdspSummaryTreeValueEntry extends IOdspSummaryTreeBaseEntry {\n\tvalue: OdspSummaryTreeValue;\n\t// Indicates that this tree entry is unreferenced. If this is not present, the tree entry is considered referenced.\n\tunreferenced?: true;\n}\n\nexport interface IOdspSummaryTreeHandleEntry extends IOdspSummaryTreeBaseEntry {\n\tid: string;\n}\n\nexport type OdspSummaryTreeValue = IOdspSummaryTree | IOdspSummaryBlob;\n\nexport interface IOdspSummaryTree {\n\ttype: \"tree\";\n\tentries?: OdspSummaryTreeEntry[];\n}\n\nexport interface IOdspSummaryBlob {\n\ttype: \"blob\";\n\tcontent: string;\n\tencoding: \"base64\" | \"utf-8\";\n}\n\n/**\n *\n * Data structures that form ODSP Snapshot\n *\n */\n\nexport interface IOdspSnapshotTreeEntryTree {\n\tpath: string;\n\ttype: \"tree\";\n\t// Indicates that this tree entry is unreferenced. If this is not present, the tree entry is considered referenced.\n\tunreferenced?: true;\n}\n\nexport interface IOdspSnapshotTreeEntryCommit {\n\tid: string;\n\tpath: string;\n\ttype: \"commit\";\n}\n\nexport interface IOdspSnapshotTreeEntryBlob {\n\tid: string;\n\tpath: string;\n\ttype: \"blob\";\n}\n\nexport type IOdspSnapshotTreeEntry =\n\t| IOdspSnapshotTreeEntryTree\n\t| IOdspSnapshotTreeEntryCommit\n\t| IOdspSnapshotTreeEntryBlob;\n\nexport interface IOdspSnapshotCommit {\n\tentries: IOdspSnapshotTreeEntry[];\n\tid: string;\n\tsequenceNumber: number;\n}\n\n/**\n * Blob content, represents blobs in downloaded snapshot.\n */\nexport interface IOdspSnapshotBlob {\n\tcontent: string;\n\t// SPO only uses \"base64\" today for download.\n\t// We are adding undefined too, as temp way to roundtrip strings unchanged.\n\tencoding: \"base64\" | undefined;\n\tid: string;\n\tsize: number;\n}\n\nexport interface IOdspSnapshot {\n\tid: string;\n\ttrees: IOdspSnapshotCommit[];\n\tblobs?: IOdspSnapshotBlob[];\n\tops?: ISequencedDeltaOpMessage[];\n}\n\n/**\n * Same as HostStoragePolicy, but adds options that are internal to runtime.\n * All fields should be optional.\n */\nexport interface HostStoragePolicyInternal extends HostStoragePolicy {\n\tsummarizerClient?: boolean;\n}\n\nexport interface ICreateFileResponse {\n\t\"@odata.context\": string;\n\t\"driveId\": string;\n\t\"id\": string;\n\t\"itemId\": string;\n\t\"itemUrl\": string;\n\t\"sequenceNumber\": number;\n\t// sharing object contains shareId, sharingLink data or error in the response\n\t\"sharing\"?: any;\n\t\"sharingLink\"?: string;\n\t\"sharingLinkErrorReason\"?: string;\n}\n\nexport interface IVersionedValueWithEpoch {\n\tvalue: any;\n\tfluidEpoch: string;\n\t// This is same as \"persistedCacheValueVersion\" below. This represents the version of data stored in cache.\n\tversion: 3;\n}\n\nexport const persistedCacheValueVersion = 3;\n\nexport interface IGetOpsResponse {\n\tnonce: string;\n\tcode: number;\n\t/** Time in seconds. Currently never set by PUSH */\n\tretryAfter?: number;\n\tmessages?: api.ISequencedDocumentMessage[];\n}\n\nexport interface IFlushOpsResponse {\n\tnonce: string;\n\tcode: number;\n\t/** Time in seconds */\n\tretryAfter?: number;\n\tlastPersistedSequenceNumber?: number;\n}\n\n/**\n * Represents the cached snapshot value.\n */\nexport interface ISnapshotCachedEntry extends ISnapshotContents {\n\tcacheEntryTime: number;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,mBAAmB,
|
|
1
|
+
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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"}
|
package/dist/epochTracker.js
CHANGED
|
@@ -304,7 +304,13 @@ class EpochTracker {
|
|
|
304
304
|
// If it was categorized as epoch error but the epoch returned in response matches with the client epoch
|
|
305
305
|
// then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling
|
|
306
306
|
// time is 1s.
|
|
307
|
-
|
|
307
|
+
const newError = (0, telemetry_utils_1.wrapError)(error, (message) => {
|
|
308
|
+
return new driver_utils_1.ThrottlingError(`Coherency 409: ${message}`, 1 /* retryAfterSeconds */, {
|
|
309
|
+
[exports.Odsp409Error]: true,
|
|
310
|
+
driverVersion: packageVersion_1.pkgVersion,
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
throw newError;
|
|
308
314
|
}
|
|
309
315
|
}
|
|
310
316
|
checkForEpochErrorCore(epochFromResponse) {
|
package/dist/epochTracker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTracker.js","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAAkC;AAClC,+DAAgE;AAChE,qEAMyC;AACzC,+DAKsC;AACtC,qFASiD;AACjD,2EAAqE;AACrE,2CAMqB;AAErB,2CAAmF;AACnF,uDAA0D;AAC1D,qDAA+D;AAC/D,uEAAiE;AAiBpD,QAAA,YAAY,GAAG,cAAc,CAAC;AAE3C,qCAAqC;AACxB,QAAA,2BAA2B,GAAW,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,eAAe;AAE3F;;;;;;;;;;;;;;GAcG;AACH,MAAa,YAAY;IAQxB,YACoB,KAAsB,EACtB,SAAqB,EACrB,MAA2B,EAC3B,kBAA4B;QAH5B,UAAK,GAAL,KAAK,CAAiB;QACtB,cAAS,GAAT,SAAS,CAAY;QACrB,WAAM,GAAN,MAAM,CAAqB;QAC3B,uBAAkB,GAAlB,kBAAkB,CAAU;QAP/B,aAAQ,GAAG,IAAA,SAAI,GAAE,CAAC;QACnC,8DAA8D;QACtD,sBAAiB,GAAG,CAAC,CAAC;QAO7B,sDAAsD;QACtD,IAAI,CAAC,WAAW,GAAG,IAAI,0BAAW,CAAC,EAAE,CAAC,CAAC;QAEvC,6FAA6F;QAC7F,IAAI,CAAC,4BAA4B,GAAG,IAAA,2CAAyB,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CACtF,qDAAqD,CACrD;YACA,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,mCAA2B,CAAC;IAChC,CAAC;IAED,+BAA+B;IACxB,QAAQ,CAAC,KAAa,EAAE,SAAkB,EAAE,SAA4B;QAC9E,IAAA,qBAAM,EAAC,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACnE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAEzB,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC9B,SAAS,EAAE,uBAAuB;YAClC,KAAK;YACL,SAAS;YACT,SAAS;SACT,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAa;;QAC7B,IAAI;YACH,8FAA8F;YAC9F,MAAM,KAAK,GAA6B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAC3D,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAC9B,CAAC;YACF,0EAA0E;YAC1E,sCAAsC;YACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,sCAA0B,EAAE;gBACxE,OAAO,SAAS,CAAC;aACjB;YACD,IAAA,qBAAM,EAAC,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACrF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE;gBACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC/C,4FAA4F;gBAC5F,qCAAqC;aACrC;iBAAM,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,UAAU,EAAE;gBACjD,OAAO,SAAS,CAAC;aACjB;YACD,6FAA6F;YAC7F,wDAAwD;YACxD,IAAI,KAAK,CAAC,IAAI,KAAK,qCAAW,EAAE;gBAC/B,MAAM,SAAS,GAAG,MAAA,KAAK,CAAC,KAAK,0CAAE,cAAc,CAAC;gBAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC/B,IACC,SAAS,KAAK,SAAS;oBACvB,WAAW,GAAG,SAAS,IAAI,IAAI,CAAC,4BAA4B,EAC3D;oBACD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBAC9B,SAAS,EAAE,0BAA0B;wBACrC,QAAQ,EAAE,WAAW,GAAG,SAAS;wBACjC,aAAa,EAAE,IAAI,CAAC,4BAA4B;qBAChD,CAAC,CAAC;oBACH,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC3B,OAAO,SAAS,CAAC;iBACjB;aACD;YACD,+DAA+D;YAC/D,OAAO,KAAK,CAAC,KAAK,CAAC;SACnB;QAAC,OAAO,KAAK,EAAE;YACf,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YACtF,OAAO,SAAS,CAAC;SACjB;IACF,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAa,EAAE,KAAU;;QACzC,IAAA,qBAAM,EAAC,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC/D,2DAA2D;QAC3D,iFAAiF;QACjF,IAAI,KAAK,CAAC,IAAI,KAAK,qCAAW,EAAE;YAC/B,KAAK,CAAC,cAAc,GAAG,MAAA,KAAK,CAAC,cAAc,mCAAI,IAAI,CAAC,GAAG,EAAE,CAAC;SAC1D;QACD,MAAM,IAAI,GAA6B;YACtC,KAAK;YACL,OAAO,EAAE,sCAA0B;YACnC,UAAU,EAAE,IAAI,CAAC,WAAW;SAC5B,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3E,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YACpF,MAAM,KAAK,CAAC;QACb,CAAC,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,aAAa;QACzB,IAAI;YACH,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SACtD;QAAC,OAAO,KAAK,EAAE;YACf,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,EAAE,KAAK,CAAC,CAAC;SACvE;IACF,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,KAAyB,EAAE,SAAoB;QACzE,IAAA,qBAAM,EAAC,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,IAAI;YACH,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;SACjD;QAAC,OAAO,KAAK,EAAE;YACf,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YACvD,MAAM,KAAK,CAAC;SACZ;IACF,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,mBAAmB,CAC/B,GAAW,EACX,YAAyB,EACzB,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,OAAO,IAAI,CAAC,SAAS,CACpB,GAAG,EACH,YAAY,EACZ,qCAAyB,EACzB,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,KAAK,CACjB,GAAW,EACX,YAAyB,EACzB,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,OAAO,IAAI,CAAC,SAAS,CACpB,GAAG,EACH,YAAY,EACZ,uBAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CACtB,GAAW,EACX,YAAsC,EACtC,OAA2F,EAC3F,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,MAAM,mBAAmB,GAAG,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC;QACxE,8BAA8B;QAC9B,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;QACrE,IAAI,iBAAqC,CAAC;QAC1C,OAAO,IAAI,CAAC,WAAW;aACrB,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;aAChD,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;YAClB,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC1D,IAAI,CAAC,yBAAyB,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;YAC7D,QAAQ,CAAC,UAAU,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;YAC9D,OAAO,QAAQ,CAAC;QACjB,CAAC,CAAC;aACD,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACtB,4FAA4F;YAC5F,6BAA6B;YAC7B,IAAI,iBAAiB,KAAK,SAAS,EAAE;gBACpC,iBAAiB,GAAI,KAAoB,CAAC,WAAW,CAAC;aACtD;YACD,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;YACnE,MAAM,KAAK,CAAC;QACb,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,qGAAqG;YACrG,iBAAiB;YACjB,IACC,IAAA,8BAAY,EAAC,KAAK,CAAC;gBACnB,KAAK,CAAC,SAAS,KAAK,oCAAe,CAAC,+BAA+B,EAClE;gBACD,MAAM,gBAAgB,GAAI,KAAiC,CAAC,gBAAgB,CAAC;gBAC7E,IAAI,gBAAgB,KAAK,SAAS,EAAE;oBACnC,MAAM,WAAW,GAAqB,IAAA,8CAAoB,EACzD,IAAI,CAAC,SAAS,CAAC,WAAW,EAC1B,gBAAgB,CAChB,CAAC;oBACF,MAAM,wBAAwB,GAAG,IAAI,uCAAwB,CAC5D,KAAK,CAAC,OAAO,EACb,WAAW,EACX,EAAE,aAAa,EAAb,2BAAa,EAAE,gBAAgB,EAAE,CACnC,CAAC;oBACF,wBAAwB,CAAC,sBAAsB,CAC9C,KAAK,CAAC,sBAAsB,EAAE,CAC9B,CAAC;oBACF,MAAM,wBAAwB,CAAC;iBAC/B;aACD;YACD,MAAM,KAAK,CAAC;QACb,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,MAAM,UAAU,GAAG,IAAA,gCAAc,EAAC,KAAK,EAAE;gBACxC,KAAK,EAAE,EAAE,mBAAmB,EAAE,mBAAmB,EAAE;aACnD,CAAC,CAAC;YACH,MAAM,UAAU,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,UAAU,CACtB,GAAW,EACX,YAAsC,EACtC,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,OAAO,IAAI,CAAC,SAAS,CACpB,GAAG,EACH,YAAY,EACZ,sBAAU,EACV,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;IACH,CAAC;IAEO,iBAAiB,CACxB,YAAyB,EACzB,SAAkB,EAClB,mBAA2B;QAE3B,MAAM,iBAAiB,GAAG,IAAA,8BAAkB,EAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,iBAAiB,CAAC;QAC3F,IAAI,SAAS,EAAE;YACd,MAAM,OAAO,GAA8B,EAAE,CAAC;YAC9C,OAAO,CAAC,gBAAgB,CAAC,GAAG,mBAAmB,CAAC;YAChD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE;gBAClC,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;aAC3C;YACD,IAAI,iBAAiB,EAAE;gBACtB,OAAO,CAAC,uCAAqB,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC;aAChF;YACD,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;SAC3C;aAAM;YACN,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;gBAC9C,YAAY,CAAC,OAAO,qBAChB,YAAY,CAAC,OAAO,CACvB,CAAC;gBACF,IAAA,qBAAM,EACL,YAAY,CAAC,OAAO,KAAK,SAAS,EAClC,KAAK,CAAC,qCAAqC,CAC3C,CAAC;gBACF,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;YACjC,CAAC,CAAC;YACF,SAAS,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;YACjD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE;gBAClC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;aAC5C;YACD,IAAI,iBAAiB,EAAE;gBACtB,SAAS,CAAC,uCAAqB,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,QAAQ,EAAE,CAAC,CAAC;aACjF;SACD;IACF,CAAC;IAEO,cAAc,CAAC,YAAyB,EAAE,OAAkC;QACnF,0EAA0E;QAC1E,wDAAwD;QACxD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;QAC/B,IAAA,qBAAM,EAAC,OAAO,IAAI,KAAK,QAAQ,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;QACpC,IAAA,qBAAM,EAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAC,IAAI,CAAC,MAAK,IAAI,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACrF,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAChD,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,SAAS,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE;YACnC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,YAAY,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAEO,yBAAyB,CAAC,WAAoB;QACrD,MAAM,KAAK,GAAa;YACvB,YAAY,IAAI,CAAC,QAAQ,EAAE;YAC3B,iBAAiB,IAAI,CAAC,iBAAiB,EAAE,EAAE;YAC3C,iBAAiB,2BAAa,EAAE;YAChC,gBAAgB,IAAI,CAAC,kBAAkB,EAAE;SACzC,CAAC;QACF,IAAI,WAAW,KAAK,SAAS,EAAE;YAC9B,KAAK,CAAC,IAAI,CAAC,eAAe,WAAW,EAAE,CAAC,CAAC;SACzC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAES,yBAAyB,CAClC,iBAAqC,EACrC,SAA4B,EAC5B,YAAqB,KAAK;QAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,KAAK,KAAK,SAAS,EAAE;YACxB,MAAM,KAAK,CAAC;SACZ;QACD,IAAI,iBAAiB,KAAK,SAAS,EAAE;YACpC,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE;gBACnC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;aACvD;SACD;IACF,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAC/B,KAAc,EACd,iBAA4C,EAC5C,SAA4B,EAC5B,YAAqB,KAAK;QAE1B,IAAI,IAAA,8BAAY,EAAC,KAAK,CAAC,IAAI,KAAK,CAAC,SAAS,KAAK,oCAAe,CAAC,wBAAwB,EAAE;YACxF,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;YAClE,IAAI,UAAU,KAAK,SAAS,EAAE;gBAC7B,UAAU,CAAC,sBAAsB,CAAC;oBACjC,SAAS;oBACT,SAAS;iBACT,CAAC,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE,EAAE,UAAU,CAAC,CAAC;gBAClF,kFAAkF;gBAClF,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC3B,MAAM,UAAU,CAAC;aACjB;YACD,wGAAwG;YACxG,0GAA0G;YAC1G,cAAc;YACd,MAAM,IAAI,8BAAe,CACxB,kBAAkB,KAAK,CAAC,OAAO,EAAE,EACjC,CAAC,CAAC,uBAAuB,EACzB,EAAE,CAAC,oBAAY,CAAC,EAAE,IAAI,EAAE,aAAa,EAAb,2BAAa,EAAE,CACvC,CAAC;SACF;IACF,CAAC;IAEO,sBAAsB,CAAC,iBAA4C;QAC1E,8FAA8F;QAC9F,sFAAsF;QACtF,iGAAiG;QACjG,IAAI,IAAI,CAAC,UAAU,IAAI,iBAAiB,IAAI,IAAI,CAAC,UAAU,KAAK,iBAAiB,EAAE;YAClF,6EAA6E;YAC7E,yEAAyE;YACzE,OAAO,IAAI,gCAAiB,CAC3B,gBAAgB,EAChB,oCAAe,CAAC,wBAAwB,EACxC,EAAE,aAAa,EAAb,2BAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE,CAC/E,CAAC;SACF;IACF,CAAC;IAEO,kBAAkB,CAAC,KAAa;QACvC,uCAAY,KAAK,KAAE,IAAI,EAAE,IAAI,CAAC,SAAS,IAAG;IAC3C,CAAC;CACD;AAxYD,oCAwYC;AAED,MAAa,0BAA2B,SAAQ,YAAY;IAG3D,YACoB,KAAsB,EACtB,SAAqB,EACrB,MAA2B,EAC3B,kBAA4B;QAE/C,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;QALjC,UAAK,GAAL,KAAK,CAAiB;QACtB,cAAS,GAAT,SAAS,CAAY;QACrB,WAAM,GAAN,MAAM,CAAqB;QAC3B,uBAAkB,GAAlB,kBAAkB,CAAU;QAN/B,wBAAmB,GAAG,IAAI,uBAAQ,EAAQ,CAAC;QAS3D,2DAA2D;QAC3D,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAES,yBAAyB,CAClC,iBAAqC,EACrC,SAAoB,EACpB,YAAqB,KAAK;QAE1B,KAAK,CAAC,yBAAyB,CAAC,iBAAiB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAEzE,8GAA8G;QAC9G,0GAA0G;QAC1G,oBAAoB;QACpB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;IACpC,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAa;QAC7B,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAE9B,uDAAuD;QACvD,IAAI,KAAK,CAAC,IAAI,KAAK,qCAAW,EAAE;YAC/B,MAAM,GAAG,MAAM;iBACb,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,iGAAiG;gBACjG,8FAA8F;gBAC9F,IAAI,KAAK,KAAK,SAAS,EAAE;oBACxB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;iBACnC;gBACD,+DAA+D;gBAC/D,OAAO,KAAK,CAAC;YACd,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAChB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvC,MAAM,KAAK,CAAC;YACb,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAC/B,GAAW,EACX,YAAsC,EACtC,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,sGAAsG;QACtG,uGAAuG;QACvG,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC;QAEvD,IAAI;YACH,OAAO,MAAM,KAAK,CAAC,mBAAmB,CACrC,GAAG,EACH,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;SACF;QAAC,OAAO,KAAU,EAAE;YACpB,+FAA+F;YAC/F,8EAA8E;YAC9E,8EAA8E;YAC9E,IAAI,SAAS,KAAK,aAAa,EAAE;gBAChC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;aACvC;YACD,IACC,SAAS,KAAK,aAAa;gBAC3B,KAAK,CAAC,UAAU,GAAG,GAAG;gBACtB,KAAK,CAAC,UAAU,GAAG,GAAG;gBACtB,SAAS,EACR;gBACD,MAAM,KAAK,CAAC;aACZ;SACD;QAED,gDAAgD;QAChD,yEAAyE;QACzE,wFAAwF;QAExF,gGAAgG;QAChG,wEAAwE;QACxE,+EAA+E;QAC/E,wGAAwG;QACxG,0BAA0B;QAC1B,MAAM,kCAAgB,CAAC,cAAc,CACpC,IAAI,CAAC,MAAM,EACX,EAAE,SAAS,EAAE,qBAAqB,EAAE,EACpC,KAAK,EAAE,KAAK,EAAE,EAAE;YACf,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC,0BAA0B;YACjD,IAAI,KAAoC,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;gBAChD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,OAAO,CAAC,UAAU,CAAC,CAAC;gBACrB,CAAC,EAAE,KAAK,CAAC,CAAC;YACX,CAAC,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAC9B,QAAQ;gBACR,kFAAkF;gBAClF,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;aACnE,CAAC,CAAC;YACH,IAAI,GAAG,KAAK,UAAU,EAAE;gBACvB,KAAK,CAAC,MAAM,EAAE,CAAC;aACf;QACF,CAAC,EACD,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAC7C,CAAC;QACF,OAAO,KAAK,CAAC,mBAAmB,CAAI,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9E,CAAC;CACD;AAvHD,gEAuHC;AAOD,SAAgB,yBAAyB,CACxC,iBAAkC,EAClC,kBAAuC,EACvC,SAAqB,EACrB,MAA2B,EAC3B,kBAA4B;IAE5B,MAAM,YAAY,GAAG,IAAI,0BAA0B,CAClD,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,kBAAkB,CAClB,CAAC;IACF,OAAO;QACN,KAAK,kCACD,kBAAkB,KACrB,cAAc,EAAE,YAAY,GAC5B;QACD,YAAY;KACZ,CAAC;AACH,CAAC;AApBD,8DAoBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n\tisFluidError,\n\tnormalizeError,\n\tloggerToMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tThrottlingError,\n\tRateLimiter,\n\tNonRetryableError,\n\tLocationRedirectionError,\n} from \"@fluidframework/driver-utils\";\nimport {\n\tsnapshotKey,\n\tICacheEntry,\n\tIEntry,\n\tIFileEntry,\n\tIPersistedCache,\n\tIOdspError,\n\tIOdspErrorAugmentations,\n\tIOdspResolvedUrl,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n\tfetchAndParseAsJSONHelper,\n\tfetchArray,\n\tfetchHelper,\n\tgetOdspResolvedUrl,\n\tIOdspResponse,\n} from \"./odspUtils\";\nimport { IOdspCache, INonPersistentCache, IPersistedFileCache } from \"./odspCache\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\nimport { patchOdspResolvedUrl } from \"./odspLocationRedirection\";\n\nexport type FetchType =\n\t| \"blob\"\n\t| \"createBlob\"\n\t| \"createFile\"\n\t| \"joinSession\"\n\t| \"ops\"\n\t| \"test\"\n\t| \"snapshotTree\"\n\t| \"treesLatest\"\n\t| \"uploadSummary\"\n\t| \"push\"\n\t| \"versions\";\n\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n// Must be less than policy of 5 days\nexport const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000; // 2 days in ms\n\n/**\n * In ODSP, the concept of \"epoch\" refers to binary updates to files. For example, this might include using\n * version restore, or if the user downloads a Fluid file and then uploads it again. These result in the epoch\n * value being incremented.\n *\n * The implications of these binary updates is that the Fluid state is disrupted: the sequence number might\n * go backwards, the data might be inconsistent with the latest state of collaboration, etc. As a result, it's\n * not safe to continue collaboration across an epoch change. We need to detect these epoch changes and\n * error out from the collaboration.\n *\n * This class is a wrapper around fetch calls. It adds epoch to the request made so that the\n * server can match it with its epoch value in order to match the version.\n * It also validates the epoch value received in response of fetch calls. If the epoch does not match,\n * then it also clears all the cached entries for the given container.\n */\nexport class EpochTracker implements IPersistedFileCache {\n\tprivate _fluidEpoch: string | undefined;\n\n\tprivate readonly snapshotCacheExpiryTimeoutMs: number;\n\tpublic readonly rateLimiter: RateLimiter;\n\tprivate readonly driverId = uuid();\n\t// This tracks the request number made by the driver instance.\n\tprivate networkCallNumber = 1;\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\t// Limits the max number of concurrent requests to 24.\n\t\tthis.rateLimiter = new RateLimiter(24);\n\n\t\t// Matches the TestOverride logic for the policy defined in odspDocumentStorageServiceBase.ts\n\t\tthis.snapshotCacheExpiryTimeoutMs = loggerToMonitoringContext(logger).config.getBoolean(\n\t\t\t\"Fluid.Driver.Odsp.TestOverride.DisableSnapshotCache\",\n\t\t)\n\t\t\t? 0\n\t\t\t: defaultCacheExpiryTimeoutMs;\n\t}\n\n\t// public for UT purposes only!\n\tpublic setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {\n\t\tassert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n\t\tthis._fluidEpoch = epoch;\n\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"EpochLearnedFirstTime\",\n\t\t\tepoch,\n\t\t\tfetchType,\n\t\t\tfromCache,\n\t\t});\n\t}\n\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\ttry {\n\t\t\t// Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n\t\t\tconst value: IVersionedValueWithEpoch = await this.cache.get(\n\t\t\t\tthis.fileEntryFromEntry(entry),\n\t\t\t);\n\t\t\t// Version mismatch between what the runtime expects and what it recieved.\n\t\t\t// The cached value should not be used\n\t\t\tif (value === undefined || value.version !== persistedCacheValueVersion) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tassert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n\t\t\tif (this._fluidEpoch === undefined) {\n\t\t\t\tthis.setEpoch(value.fluidEpoch, true, \"cache\");\n\t\t\t\t// Epoch mismatch, the cached value is considerably different from what the current state of\n\t\t\t\t// the runtime and should not be used\n\t\t\t} else if (this._fluidEpoch !== value.fluidEpoch) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\t// Expire the cached snapshot if it's older than snapshotCacheExpiryTimeoutMs and immediately\n\t\t\t// expire all old caches that do not have cacheEntryTime\n\t\t\tif (entry.type === snapshotKey) {\n\t\t\t\tconst cacheTime = value.value?.cacheEntryTime;\n\t\t\t\tconst currentTime = Date.now();\n\t\t\t\tif (\n\t\t\t\t\tcacheTime === undefined ||\n\t\t\t\t\tcurrentTime - cacheTime >= this.snapshotCacheExpiryTimeoutMs\n\t\t\t\t) {\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"odspVersionsCacheExpired\",\n\t\t\t\t\t\tduration: currentTime - cacheTime,\n\t\t\t\t\t\tmaxCacheAgeMs: this.snapshotCacheExpiryTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t\tawait this.removeEntries();\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn value.value;\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tpublic async put(entry: IEntry, value: any) {\n\t\tassert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n\t\t// For snapshots, the value should have the cacheEntryTime.\n\t\t// This will be used to expire snapshots older than snapshotCacheExpiryTimeoutMs.\n\t\tif (entry.type === snapshotKey) {\n\t\t\tvalue.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n\t\t}\n\t\tconst data: IVersionedValueWithEpoch = {\n\t\t\tvalue,\n\t\t\tversion: persistedCacheValueVersion,\n\t\t\tfluidEpoch: this._fluidEpoch,\n\t\t};\n\t\treturn this.cache.put(this.fileEntryFromEntry(entry), data).catch((error) => {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n\t\t\tthrow error;\n\t\t});\n\t}\n\n\tpublic async removeEntries(): Promise<void> {\n\t\ttry {\n\t\t\treturn await this.cache.removeEntries(this.fileEntry);\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n\t\t}\n\t}\n\n\tpublic get fluidEpoch() {\n\t\treturn this._fluidEpoch;\n\t}\n\n\tpublic async validateEpoch(epoch: string | undefined, fetchType: FetchType) {\n\t\tassert(epoch !== undefined, 0x584 /* response should contain epoch */);\n\t\ttry {\n\t\t\tthis.validateEpochFromResponse(epoch, fetchType);\n\t\t} catch (error) {\n\t\t\tawait this.checkForEpochError(error, epoch, fetchType);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\treturn this.fetchCore<T>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchAndParseAsJSONHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetch(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t) {\n\t\treturn this.fetchCore<Response>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate async fetchCore<T>(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t\tfetcher: (url: string, fetchOptions: { [index: string]: any }) => Promise<IOdspResponse<T>>,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t) {\n\t\tconst clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n\t\t// Add epoch in fetch request.\n\t\tthis.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n\t\tlet epochFromResponse: string | undefined;\n\t\treturn this.rateLimiter\n\t\t\t.schedule(async () => fetcher(url, fetchOptions))\n\t\t\t.then((response) => {\n\t\t\t\tepochFromResponse = response.headers.get(\"x-fluid-epoch\");\n\t\t\t\tthis.validateEpochFromResponse(epochFromResponse, fetchType);\n\t\t\t\tresponse.propsToLog.XRequestStatsHeader = clientCorrelationId;\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.catch(async (error) => {\n\t\t\t\t// Get the server epoch from error in case we don't have it as if undefined we won't be able\n\t\t\t\t// to mark it as epoch error.\n\t\t\t\tif (epochFromResponse === undefined) {\n\t\t\t\t\tepochFromResponse = (error as IOdspError).serverEpoch;\n\t\t\t\t}\n\t\t\t\tawait this.checkForEpochError(error, epochFromResponse, fetchType);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// If the error is about location redirection, then we need to generate new resolved url with correct\n\t\t\t\t// location info.\n\t\t\t\tif (\n\t\t\t\t\tisFluidError(error) &&\n\t\t\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError\n\t\t\t\t) {\n\t\t\t\t\tconst redirectLocation = (error as IOdspErrorAugmentations).redirectLocation;\n\t\t\t\t\tif (redirectLocation !== undefined) {\n\t\t\t\t\t\tconst redirectUrl: IOdspResolvedUrl = patchOdspResolvedUrl(\n\t\t\t\t\t\t\tthis.fileEntry.resolvedUrl,\n\t\t\t\t\t\t\tredirectLocation,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst locationRedirectionError = new LocationRedirectionError(\n\t\t\t\t\t\t\terror.message,\n\t\t\t\t\t\t\tredirectUrl,\n\t\t\t\t\t\t\t{ driverVersion, redirectLocation },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlocationRedirectionError.addTelemetryProperties(\n\t\t\t\t\t\t\terror.getTelemetryProperties(),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthrow locationRedirectionError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconst fluidError = normalizeError(error, {\n\t\t\t\t\tprops: { XRequestStatsHeader: clientCorrelationId },\n\t\t\t\t});\n\t\t\t\tthrow fluidError;\n\t\t\t});\n\t}\n\n\t/**\n\t * Api to fetch the response as it is for given request.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchArray(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t) {\n\t\treturn this.fetchCore<ArrayBuffer>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchArray,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate addEpochInRequest(\n\t\tfetchOptions: RequestInit,\n\t\taddInBody: boolean,\n\t\tclientCorrelationId: string,\n\t) {\n\t\tconst isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;\n\t\tif (addInBody) {\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\theaders[\"X-RequestStats\"] = clientCorrelationId;\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\theaders[\"x-fluid-epoch\"] = this.fluidEpoch;\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\theaders[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();\n\t\t\t}\n\t\t\tthis.addParamInBody(fetchOptions, headers);\n\t\t} else {\n\t\t\tconst addHeader = (key: string, val: string) => {\n\t\t\t\tfetchOptions.headers = {\n\t\t\t\t\t...fetchOptions.headers,\n\t\t\t\t};\n\t\t\t\tassert(\n\t\t\t\t\tfetchOptions.headers !== undefined,\n\t\t\t\t\t0x282 /* \"Headers should be present now\" */,\n\t\t\t\t);\n\t\t\t\tfetchOptions.headers[key] = val;\n\t\t\t};\n\t\t\taddHeader(\"X-RequestStats\", clientCorrelationId);\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\taddHeader(\"x-fluid-epoch\", this.fluidEpoch);\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\taddHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string }) {\n\t\t// We use multi part form request for post body where we want to use this.\n\t\t// So extract the form boundary to mark the end of form.\n\t\tconst body = fetchOptions.body;\n\t\tassert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n\t\tconst splitBody = body.split(\"\\r\\n\");\n\t\tconst firstLine = splitBody.shift();\n\t\tassert(firstLine?.startsWith(\"--\") === true, 0x21e /* \"improper boundary format\" */);\n\t\tconst formParams = [firstLine];\n\t\tObject.entries(headers).forEach(([key, value]) => {\n\t\t\tformParams.push(`${key}: ${value}`);\n\t\t});\n\t\tsplitBody.forEach((value: string) => {\n\t\t\tformParams.push(value);\n\t\t});\n\t\tfetchOptions.body = formParams.join(\"\\r\\n\");\n\t}\n\n\tprivate formatClientCorrelationId(fetchReason?: string) {\n\t\tconst items: string[] = [\n\t\t\t`driverId=${this.driverId}`,\n\t\t\t`RequestNumber=${this.networkCallNumber++}`,\n\t\t\t`driverVersion=${driverVersion}`,\n\t\t\t`isSummarizer=${this.clientIsSummarizer}`,\n\t\t];\n\t\tif (fetchReason !== undefined) {\n\t\t\titems.push(`fetchReason=${fetchReason}`);\n\t\t}\n\t\treturn items.join(\", \");\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t) {\n\t\tconst error = this.checkForEpochErrorCore(epochFromResponse);\n\t\tif (error !== undefined) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (epochFromResponse !== undefined) {\n\t\t\tif (this._fluidEpoch === undefined) {\n\t\t\t\tthis.setEpoch(epochFromResponse, fromCache, fetchType);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async checkForEpochError(\n\t\terror: unknown,\n\t\tepochFromResponse: string | null | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t) {\n\t\tif (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {\n\t\t\tconst epochError = this.checkForEpochErrorCore(epochFromResponse);\n\t\t\tif (epochError !== undefined) {\n\t\t\t\tepochError.addTelemetryProperties({\n\t\t\t\t\tfromCache,\n\t\t\t\t\tfetchType,\n\t\t\t\t});\n\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n\t\t\t\t// If the epoch mismatches, then clear all entries for such file entry from cache.\n\t\t\t\tawait this.removeEntries();\n\t\t\t\tthrow epochError;\n\t\t\t}\n\t\t\t// If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n\t\t\t// then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n\t\t\t// time is 1s.\n\t\t\tthrow new ThrottlingError(\n\t\t\t\t`Coherency 409: ${error.message}`,\n\t\t\t\t1 /* retryAfterSeconds */,\n\t\t\t\t{ [Odsp409Error]: true, driverVersion },\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate checkForEpochErrorCore(epochFromResponse: string | null | undefined) {\n\t\t// If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n\t\t// initializes this value. Sometimes response does not contain epoch as it is still in\n\t\t// implementation phase at server side. In that case also, don't compare it with our epoch value.\n\t\tif (this.fluidEpoch && epochFromResponse && this.fluidEpoch !== epochFromResponse) {\n\t\t\t// This is similar in nature to how fluidEpochMismatchError (409) is handled.\n\t\t\t// Difference - client detected mismatch, instead of server detecting it.\n\t\t\treturn new NonRetryableError(\n\t\t\t\t\"Epoch mismatch\",\n\t\t\t\tDriverErrorType.fileOverwrittenInStorage,\n\t\t\t\t{ driverVersion, serverEpoch: epochFromResponse, clientEpoch: this.fluidEpoch },\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate fileEntryFromEntry(entry: IEntry): ICacheEntry {\n\t\treturn { ...entry, file: this.fileEntry };\n\t}\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n\tprivate readonly treesLatestDeferral = new Deferred<void>();\n\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\tsuper(cache, fileEntry, logger, clientIsSummarizer);\n\t\t// Handles the rejected promise within treesLatestDeferral.\n\t\tthis.treesLatestDeferral.promise.catch(() => {});\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchType,\n\t\tfromCache: boolean = false,\n\t) {\n\t\tsuper.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n\t\t// Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n\t\t// That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n\t\t// exploring a file.\n\t\tthis.treesLatestDeferral.resolve();\n\t}\n\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\tlet result = super.get(entry);\n\n\t\t// equivalence of what happens in fetchAndParseAsJSON()\n\t\tif (entry.type === snapshotKey) {\n\t\t\tresult = result\n\t\t\t\t.then((value) => {\n\t\t\t\t\t// If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n\t\t\t\t\t// Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\tthis.treesLatestDeferral.resolve();\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn value;\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t}\n\t\treturn result;\n\t}\n\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\t// Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n\t\t// joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n\t\tconst completed = this.treesLatestDeferral.isCompleted;\n\n\t\ttry {\n\t\t\treturn await super.fetchAndParseAsJSON<T>(\n\t\t\t\turl,\n\t\t\t\tfetchOptions,\n\t\t\t\tfetchType,\n\t\t\t\taddInBody,\n\t\t\t\tfetchReason,\n\t\t\t);\n\t\t} catch (error: any) {\n\t\t\t// Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n\t\t\t// Similar, if getVersions failed, we should not do any further storage calls.\n\t\t\t// So treesLatest is the only call that can have parallel joinSession request.\n\t\t\tif (fetchType === \"treesLatest\") {\n\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tfetchType !== \"joinSession\" ||\n\t\t\t\terror.statusCode < 401 ||\n\t\t\t\terror.statusCode > 404 ||\n\t\t\t\tcompleted\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\t// It is joinSession failing with 401..404 error\n\t\t// Repeat after waiting for treeLatest succeeding (or fail if it failed).\n\t\t// No special handling after first call - if file has been deleted, then it's game over.\n\n\t\t// Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n\t\t// If we waited too long, we will log error event and proceed with call.\n\t\t// It may result in failure for user, but refreshing document would address it.\n\t\t// Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n\t\t// to unblock the process.\n\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\tthis.logger,\n\t\t\t{ eventName: \"JoinSessionSyncWait\" },\n\t\t\tasync (event) => {\n\t\t\t\tconst timeoutRes = 51; // anything will work here\n\t\t\t\tlet timer: ReturnType<typeof setTimeout>;\n\t\t\t\tconst timeoutP = new Promise<number>((resolve) => {\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\tresolve(timeoutRes);\n\t\t\t\t\t}, 15000);\n\t\t\t\t});\n\t\t\t\tconst res = await Promise.race([\n\t\t\t\t\ttimeoutP,\n\t\t\t\t\t// cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n\t\t\t\t\tthis.treesLatestDeferral.promise.finally(() => clearTimeout(timer)),\n\t\t\t\t]);\n\t\t\t\tif (res === timeoutRes) {\n\t\t\t\t\tevent.cancel();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t);\n\t\treturn super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n\t}\n}\n\nexport interface ICacheAndTracker {\n\tcache: IOdspCache;\n\tepochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n\tpersistedCacheArg: IPersistedCache,\n\tnonpersistentCache: INonPersistentCache,\n\tfileEntry: IFileEntry,\n\tlogger: ITelemetryLoggerExt,\n\tclientIsSummarizer?: boolean,\n): ICacheAndTracker {\n\tconst epochTracker = new EpochTrackerWithRedemption(\n\t\tpersistedCacheArg,\n\t\tfileEntry,\n\t\tlogger,\n\t\tclientIsSummarizer,\n\t);\n\treturn {\n\t\tcache: {\n\t\t\t...nonpersistentCache,\n\t\t\tpersistedCache: epochTracker,\n\t\t},\n\t\tepochTracker,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"epochTracker.js","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAAkC;AAClC,+DAAgE;AAChE,qEAOyC;AACzC,+DAKsC;AACtC,qFASiD;AACjD,2EAAqE;AACrE,2CAMqB;AAErB,2CAAmF;AACnF,uDAA0D;AAC1D,qDAA+D;AAC/D,uEAAiE;AAiBpD,QAAA,YAAY,GAAG,cAAc,CAAC;AAE3C,qCAAqC;AACxB,QAAA,2BAA2B,GAAW,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,eAAe;AAE3F;;;;;;;;;;;;;;GAcG;AACH,MAAa,YAAY;IAQxB,YACoB,KAAsB,EACtB,SAAqB,EACrB,MAA2B,EAC3B,kBAA4B;QAH5B,UAAK,GAAL,KAAK,CAAiB;QACtB,cAAS,GAAT,SAAS,CAAY;QACrB,WAAM,GAAN,MAAM,CAAqB;QAC3B,uBAAkB,GAAlB,kBAAkB,CAAU;QAP/B,aAAQ,GAAG,IAAA,SAAI,GAAE,CAAC;QACnC,8DAA8D;QACtD,sBAAiB,GAAG,CAAC,CAAC;QAO7B,sDAAsD;QACtD,IAAI,CAAC,WAAW,GAAG,IAAI,0BAAW,CAAC,EAAE,CAAC,CAAC;QAEvC,6FAA6F;QAC7F,IAAI,CAAC,4BAA4B,GAAG,IAAA,2CAAyB,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CACtF,qDAAqD,CACrD;YACA,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,mCAA2B,CAAC;IAChC,CAAC;IAED,+BAA+B;IACxB,QAAQ,CAAC,KAAa,EAAE,SAAkB,EAAE,SAA4B;QAC9E,IAAA,qBAAM,EAAC,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACnE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAEzB,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC9B,SAAS,EAAE,uBAAuB;YAClC,KAAK;YACL,SAAS;YACT,SAAS;SACT,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAa;;QAC7B,IAAI;YACH,8FAA8F;YAC9F,MAAM,KAAK,GAA6B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAC3D,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAC9B,CAAC;YACF,0EAA0E;YAC1E,sCAAsC;YACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,sCAA0B,EAAE;gBACxE,OAAO,SAAS,CAAC;aACjB;YACD,IAAA,qBAAM,EAAC,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACrF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE;gBACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC/C,4FAA4F;gBAC5F,qCAAqC;aACrC;iBAAM,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,UAAU,EAAE;gBACjD,OAAO,SAAS,CAAC;aACjB;YACD,6FAA6F;YAC7F,wDAAwD;YACxD,IAAI,KAAK,CAAC,IAAI,KAAK,qCAAW,EAAE;gBAC/B,MAAM,SAAS,GAAG,MAAA,KAAK,CAAC,KAAK,0CAAE,cAAc,CAAC;gBAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC/B,IACC,SAAS,KAAK,SAAS;oBACvB,WAAW,GAAG,SAAS,IAAI,IAAI,CAAC,4BAA4B,EAC3D;oBACD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;wBAC9B,SAAS,EAAE,0BAA0B;wBACrC,QAAQ,EAAE,WAAW,GAAG,SAAS;wBACjC,aAAa,EAAE,IAAI,CAAC,4BAA4B;qBAChD,CAAC,CAAC;oBACH,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC3B,OAAO,SAAS,CAAC;iBACjB;aACD;YACD,+DAA+D;YAC/D,OAAO,KAAK,CAAC,KAAK,CAAC;SACnB;QAAC,OAAO,KAAK,EAAE;YACf,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YACtF,OAAO,SAAS,CAAC;SACjB;IACF,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAa,EAAE,KAAU;;QACzC,IAAA,qBAAM,EAAC,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC/D,2DAA2D;QAC3D,iFAAiF;QACjF,IAAI,KAAK,CAAC,IAAI,KAAK,qCAAW,EAAE;YAC/B,KAAK,CAAC,cAAc,GAAG,MAAA,KAAK,CAAC,cAAc,mCAAI,IAAI,CAAC,GAAG,EAAE,CAAC;SAC1D;QACD,MAAM,IAAI,GAA6B;YACtC,KAAK;YACL,OAAO,EAAE,sCAA0B;YACnC,UAAU,EAAE,IAAI,CAAC,WAAW;SAC5B,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3E,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YACpF,MAAM,KAAK,CAAC;QACb,CAAC,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,aAAa;QACzB,IAAI;YACH,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SACtD;QAAC,OAAO,KAAK,EAAE;YACf,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,EAAE,KAAK,CAAC,CAAC;SACvE;IACF,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,KAAyB,EAAE,SAAoB;QACzE,IAAA,qBAAM,EAAC,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,IAAI;YACH,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;SACjD;QAAC,OAAO,KAAK,EAAE;YACf,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;YACvD,MAAM,KAAK,CAAC;SACZ;IACF,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,mBAAmB,CAC/B,GAAW,EACX,YAAyB,EACzB,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,OAAO,IAAI,CAAC,SAAS,CACpB,GAAG,EACH,YAAY,EACZ,qCAAyB,EACzB,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,KAAK,CACjB,GAAW,EACX,YAAyB,EACzB,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,OAAO,IAAI,CAAC,SAAS,CACpB,GAAG,EACH,YAAY,EACZ,uBAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CACtB,GAAW,EACX,YAAsC,EACtC,OAA2F,EAC3F,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,MAAM,mBAAmB,GAAG,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC;QACxE,8BAA8B;QAC9B,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;QACrE,IAAI,iBAAqC,CAAC;QAC1C,OAAO,IAAI,CAAC,WAAW;aACrB,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;aAChD,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;YAClB,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC1D,IAAI,CAAC,yBAAyB,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;YAC7D,QAAQ,CAAC,UAAU,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;YAC9D,OAAO,QAAQ,CAAC;QACjB,CAAC,CAAC;aACD,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACtB,4FAA4F;YAC5F,6BAA6B;YAC7B,IAAI,iBAAiB,KAAK,SAAS,EAAE;gBACpC,iBAAiB,GAAI,KAAoB,CAAC,WAAW,CAAC;aACtD;YACD,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;YACnE,MAAM,KAAK,CAAC;QACb,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,qGAAqG;YACrG,iBAAiB;YACjB,IACC,IAAA,8BAAY,EAAC,KAAK,CAAC;gBACnB,KAAK,CAAC,SAAS,KAAK,oCAAe,CAAC,+BAA+B,EAClE;gBACD,MAAM,gBAAgB,GAAI,KAAiC,CAAC,gBAAgB,CAAC;gBAC7E,IAAI,gBAAgB,KAAK,SAAS,EAAE;oBACnC,MAAM,WAAW,GAAqB,IAAA,8CAAoB,EACzD,IAAI,CAAC,SAAS,CAAC,WAAW,EAC1B,gBAAgB,CAChB,CAAC;oBACF,MAAM,wBAAwB,GAAG,IAAI,uCAAwB,CAC5D,KAAK,CAAC,OAAO,EACb,WAAW,EACX,EAAE,aAAa,EAAb,2BAAa,EAAE,gBAAgB,EAAE,CACnC,CAAC;oBACF,wBAAwB,CAAC,sBAAsB,CAC9C,KAAK,CAAC,sBAAsB,EAAE,CAC9B,CAAC;oBACF,MAAM,wBAAwB,CAAC;iBAC/B;aACD;YACD,MAAM,KAAK,CAAC;QACb,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,MAAM,UAAU,GAAG,IAAA,gCAAc,EAAC,KAAK,EAAE;gBACxC,KAAK,EAAE,EAAE,mBAAmB,EAAE,mBAAmB,EAAE;aACnD,CAAC,CAAC;YACH,MAAM,UAAU,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,UAAU,CACtB,GAAW,EACX,YAAsC,EACtC,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,OAAO,IAAI,CAAC,SAAS,CACpB,GAAG,EACH,YAAY,EACZ,sBAAU,EACV,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;IACH,CAAC;IAEO,iBAAiB,CACxB,YAAyB,EACzB,SAAkB,EAClB,mBAA2B;QAE3B,MAAM,iBAAiB,GAAG,IAAA,8BAAkB,EAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,iBAAiB,CAAC;QAC3F,IAAI,SAAS,EAAE;YACd,MAAM,OAAO,GAA8B,EAAE,CAAC;YAC9C,OAAO,CAAC,gBAAgB,CAAC,GAAG,mBAAmB,CAAC;YAChD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE;gBAClC,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;aAC3C;YACD,IAAI,iBAAiB,EAAE;gBACtB,OAAO,CAAC,uCAAqB,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC;aAChF;YACD,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;SAC3C;aAAM;YACN,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;gBAC9C,YAAY,CAAC,OAAO,qBAChB,YAAY,CAAC,OAAO,CACvB,CAAC;gBACF,IAAA,qBAAM,EACL,YAAY,CAAC,OAAO,KAAK,SAAS,EAClC,KAAK,CAAC,qCAAqC,CAC3C,CAAC;gBACF,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;YACjC,CAAC,CAAC;YACF,SAAS,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;YACjD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE;gBAClC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;aAC5C;YACD,IAAI,iBAAiB,EAAE;gBACtB,SAAS,CAAC,uCAAqB,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,QAAQ,EAAE,CAAC,CAAC;aACjF;SACD;IACF,CAAC;IAEO,cAAc,CAAC,YAAyB,EAAE,OAAkC;QACnF,0EAA0E;QAC1E,wDAAwD;QACxD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;QAC/B,IAAA,qBAAM,EAAC,OAAO,IAAI,KAAK,QAAQ,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;QACpC,IAAA,qBAAM,EAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAC,IAAI,CAAC,MAAK,IAAI,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACrF,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAChD,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,SAAS,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,EAAE;YACnC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,YAAY,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAEO,yBAAyB,CAAC,WAAoB;QACrD,MAAM,KAAK,GAAa;YACvB,YAAY,IAAI,CAAC,QAAQ,EAAE;YAC3B,iBAAiB,IAAI,CAAC,iBAAiB,EAAE,EAAE;YAC3C,iBAAiB,2BAAa,EAAE;YAChC,gBAAgB,IAAI,CAAC,kBAAkB,EAAE;SACzC,CAAC;QACF,IAAI,WAAW,KAAK,SAAS,EAAE;YAC9B,KAAK,CAAC,IAAI,CAAC,eAAe,WAAW,EAAE,CAAC,CAAC;SACzC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAES,yBAAyB,CAClC,iBAAqC,EACrC,SAA4B,EAC5B,YAAqB,KAAK;QAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,KAAK,KAAK,SAAS,EAAE;YACxB,MAAM,KAAK,CAAC;SACZ;QACD,IAAI,iBAAiB,KAAK,SAAS,EAAE;YACpC,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE;gBACnC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;aACvD;SACD;IACF,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAC/B,KAAc,EACd,iBAA4C,EAC5C,SAA4B,EAC5B,YAAqB,KAAK;QAE1B,IAAI,IAAA,8BAAY,EAAC,KAAK,CAAC,IAAI,KAAK,CAAC,SAAS,KAAK,oCAAe,CAAC,wBAAwB,EAAE;YACxF,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;YAClE,IAAI,UAAU,KAAK,SAAS,EAAE;gBAC7B,UAAU,CAAC,sBAAsB,CAAC;oBACjC,SAAS;oBACT,SAAS;iBACT,CAAC,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE,EAAE,UAAU,CAAC,CAAC;gBAClF,kFAAkF;gBAClF,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC3B,MAAM,UAAU,CAAC;aACjB;YACD,wGAAwG;YACxG,0GAA0G;YAC1G,cAAc;YACd,MAAM,QAAQ,GAAG,IAAA,2BAAS,EAAC,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE;gBACrD,OAAO,IAAI,8BAAe,CAAC,kBAAkB,OAAO,EAAE,EAAE,CAAC,CAAC,uBAAuB,EAAE;oBAClF,CAAC,oBAAY,CAAC,EAAE,IAAI;oBACpB,aAAa,EAAb,2BAAa;iBACb,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,MAAM,QAAQ,CAAC;SACf;IACF,CAAC;IAEO,sBAAsB,CAAC,iBAA4C;QAC1E,8FAA8F;QAC9F,sFAAsF;QACtF,iGAAiG;QACjG,IAAI,IAAI,CAAC,UAAU,IAAI,iBAAiB,IAAI,IAAI,CAAC,UAAU,KAAK,iBAAiB,EAAE;YAClF,6EAA6E;YAC7E,yEAAyE;YACzE,OAAO,IAAI,gCAAiB,CAC3B,gBAAgB,EAChB,oCAAe,CAAC,wBAAwB,EACxC,EAAE,aAAa,EAAb,2BAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE,CAC/E,CAAC;SACF;IACF,CAAC;IAEO,kBAAkB,CAAC,KAAa;QACvC,uCAAY,KAAK,KAAE,IAAI,EAAE,IAAI,CAAC,SAAS,IAAG;IAC3C,CAAC;CACD;AA1YD,oCA0YC;AAED,MAAa,0BAA2B,SAAQ,YAAY;IAG3D,YACoB,KAAsB,EACtB,SAAqB,EACrB,MAA2B,EAC3B,kBAA4B;QAE/C,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;QALjC,UAAK,GAAL,KAAK,CAAiB;QACtB,cAAS,GAAT,SAAS,CAAY;QACrB,WAAM,GAAN,MAAM,CAAqB;QAC3B,uBAAkB,GAAlB,kBAAkB,CAAU;QAN/B,wBAAmB,GAAG,IAAI,uBAAQ,EAAQ,CAAC;QAS3D,2DAA2D;QAC3D,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAES,yBAAyB,CAClC,iBAAqC,EACrC,SAAoB,EACpB,YAAqB,KAAK;QAE1B,KAAK,CAAC,yBAAyB,CAAC,iBAAiB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAEzE,8GAA8G;QAC9G,0GAA0G;QAC1G,oBAAoB;QACpB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;IACpC,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,KAAa;QAC7B,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAE9B,uDAAuD;QACvD,IAAI,KAAK,CAAC,IAAI,KAAK,qCAAW,EAAE;YAC/B,MAAM,GAAG,MAAM;iBACb,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,iGAAiG;gBACjG,8FAA8F;gBAC9F,IAAI,KAAK,KAAK,SAAS,EAAE;oBACxB,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;iBACnC;gBACD,+DAA+D;gBAC/D,OAAO,KAAK,CAAC;YACd,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAChB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvC,MAAM,KAAK,CAAC;YACb,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAC/B,GAAW,EACX,YAAsC,EACtC,SAAoB,EACpB,YAAqB,KAAK,EAC1B,WAAoB;QAEpB,sGAAsG;QACtG,uGAAuG;QACvG,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC;QAEvD,IAAI;YACH,OAAO,MAAM,KAAK,CAAC,mBAAmB,CACrC,GAAG,EACH,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,CACX,CAAC;SACF;QAAC,OAAO,KAAU,EAAE;YACpB,+FAA+F;YAC/F,8EAA8E;YAC9E,8EAA8E;YAC9E,IAAI,SAAS,KAAK,aAAa,EAAE;gBAChC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;aACvC;YACD,IACC,SAAS,KAAK,aAAa;gBAC3B,KAAK,CAAC,UAAU,GAAG,GAAG;gBACtB,KAAK,CAAC,UAAU,GAAG,GAAG;gBACtB,SAAS,EACR;gBACD,MAAM,KAAK,CAAC;aACZ;SACD;QAED,gDAAgD;QAChD,yEAAyE;QACzE,wFAAwF;QAExF,gGAAgG;QAChG,wEAAwE;QACxE,+EAA+E;QAC/E,wGAAwG;QACxG,0BAA0B;QAC1B,MAAM,kCAAgB,CAAC,cAAc,CACpC,IAAI,CAAC,MAAM,EACX,EAAE,SAAS,EAAE,qBAAqB,EAAE,EACpC,KAAK,EAAE,KAAK,EAAE,EAAE;YACf,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC,0BAA0B;YACjD,IAAI,KAAoC,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;gBAChD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,OAAO,CAAC,UAAU,CAAC,CAAC;gBACrB,CAAC,EAAE,KAAK,CAAC,CAAC;YACX,CAAC,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAC9B,QAAQ;gBACR,kFAAkF;gBAClF,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;aACnE,CAAC,CAAC;YACH,IAAI,GAAG,KAAK,UAAU,EAAE;gBACvB,KAAK,CAAC,MAAM,EAAE,CAAC;aACf;QACF,CAAC,EACD,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAC7C,CAAC;QACF,OAAO,KAAK,CAAC,mBAAmB,CAAI,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9E,CAAC;CACD;AAvHD,gEAuHC;AAOD,SAAgB,yBAAyB,CACxC,iBAAkC,EAClC,kBAAuC,EACvC,SAAqB,EACrB,MAA2B,EAC3B,kBAA4B;IAE5B,MAAM,YAAY,GAAG,IAAI,0BAA0B,CAClD,iBAAiB,EACjB,SAAS,EACT,MAAM,EACN,kBAAkB,CAClB,CAAC;IACF,OAAO;QACN,KAAK,kCACD,kBAAkB,KACrB,cAAc,EAAE,YAAY,GAC5B;QACD,YAAY;KACZ,CAAC;AACH,CAAC;AApBD,8DAoBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n\tisFluidError,\n\tnormalizeError,\n\tloggerToMonitoringContext,\n\twrapError,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tThrottlingError,\n\tRateLimiter,\n\tNonRetryableError,\n\tLocationRedirectionError,\n} from \"@fluidframework/driver-utils\";\nimport {\n\tsnapshotKey,\n\tICacheEntry,\n\tIEntry,\n\tIFileEntry,\n\tIPersistedCache,\n\tIOdspError,\n\tIOdspErrorAugmentations,\n\tIOdspResolvedUrl,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n\tfetchAndParseAsJSONHelper,\n\tfetchArray,\n\tfetchHelper,\n\tgetOdspResolvedUrl,\n\tIOdspResponse,\n} from \"./odspUtils\";\nimport { IOdspCache, INonPersistentCache, IPersistedFileCache } from \"./odspCache\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\nimport { patchOdspResolvedUrl } from \"./odspLocationRedirection\";\n\nexport type FetchType =\n\t| \"blob\"\n\t| \"createBlob\"\n\t| \"createFile\"\n\t| \"joinSession\"\n\t| \"ops\"\n\t| \"test\"\n\t| \"snapshotTree\"\n\t| \"treesLatest\"\n\t| \"uploadSummary\"\n\t| \"push\"\n\t| \"versions\";\n\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n// Must be less than policy of 5 days\nexport const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000; // 2 days in ms\n\n/**\n * In ODSP, the concept of \"epoch\" refers to binary updates to files. For example, this might include using\n * version restore, or if the user downloads a Fluid file and then uploads it again. These result in the epoch\n * value being incremented.\n *\n * The implications of these binary updates is that the Fluid state is disrupted: the sequence number might\n * go backwards, the data might be inconsistent with the latest state of collaboration, etc. As a result, it's\n * not safe to continue collaboration across an epoch change. We need to detect these epoch changes and\n * error out from the collaboration.\n *\n * This class is a wrapper around fetch calls. It adds epoch to the request made so that the\n * server can match it with its epoch value in order to match the version.\n * It also validates the epoch value received in response of fetch calls. If the epoch does not match,\n * then it also clears all the cached entries for the given container.\n */\nexport class EpochTracker implements IPersistedFileCache {\n\tprivate _fluidEpoch: string | undefined;\n\n\tprivate readonly snapshotCacheExpiryTimeoutMs: number;\n\tpublic readonly rateLimiter: RateLimiter;\n\tprivate readonly driverId = uuid();\n\t// This tracks the request number made by the driver instance.\n\tprivate networkCallNumber = 1;\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\t// Limits the max number of concurrent requests to 24.\n\t\tthis.rateLimiter = new RateLimiter(24);\n\n\t\t// Matches the TestOverride logic for the policy defined in odspDocumentStorageServiceBase.ts\n\t\tthis.snapshotCacheExpiryTimeoutMs = loggerToMonitoringContext(logger).config.getBoolean(\n\t\t\t\"Fluid.Driver.Odsp.TestOverride.DisableSnapshotCache\",\n\t\t)\n\t\t\t? 0\n\t\t\t: defaultCacheExpiryTimeoutMs;\n\t}\n\n\t// public for UT purposes only!\n\tpublic setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {\n\t\tassert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n\t\tthis._fluidEpoch = epoch;\n\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"EpochLearnedFirstTime\",\n\t\t\tepoch,\n\t\t\tfetchType,\n\t\t\tfromCache,\n\t\t});\n\t}\n\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\ttry {\n\t\t\t// Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n\t\t\tconst value: IVersionedValueWithEpoch = await this.cache.get(\n\t\t\t\tthis.fileEntryFromEntry(entry),\n\t\t\t);\n\t\t\t// Version mismatch between what the runtime expects and what it recieved.\n\t\t\t// The cached value should not be used\n\t\t\tif (value === undefined || value.version !== persistedCacheValueVersion) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tassert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n\t\t\tif (this._fluidEpoch === undefined) {\n\t\t\t\tthis.setEpoch(value.fluidEpoch, true, \"cache\");\n\t\t\t\t// Epoch mismatch, the cached value is considerably different from what the current state of\n\t\t\t\t// the runtime and should not be used\n\t\t\t} else if (this._fluidEpoch !== value.fluidEpoch) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\t// Expire the cached snapshot if it's older than snapshotCacheExpiryTimeoutMs and immediately\n\t\t\t// expire all old caches that do not have cacheEntryTime\n\t\t\tif (entry.type === snapshotKey) {\n\t\t\t\tconst cacheTime = value.value?.cacheEntryTime;\n\t\t\t\tconst currentTime = Date.now();\n\t\t\t\tif (\n\t\t\t\t\tcacheTime === undefined ||\n\t\t\t\t\tcurrentTime - cacheTime >= this.snapshotCacheExpiryTimeoutMs\n\t\t\t\t) {\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"odspVersionsCacheExpired\",\n\t\t\t\t\t\tduration: currentTime - cacheTime,\n\t\t\t\t\t\tmaxCacheAgeMs: this.snapshotCacheExpiryTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t\tawait this.removeEntries();\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn value.value;\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tpublic async put(entry: IEntry, value: any) {\n\t\tassert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n\t\t// For snapshots, the value should have the cacheEntryTime.\n\t\t// This will be used to expire snapshots older than snapshotCacheExpiryTimeoutMs.\n\t\tif (entry.type === snapshotKey) {\n\t\t\tvalue.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n\t\t}\n\t\tconst data: IVersionedValueWithEpoch = {\n\t\t\tvalue,\n\t\t\tversion: persistedCacheValueVersion,\n\t\t\tfluidEpoch: this._fluidEpoch,\n\t\t};\n\t\treturn this.cache.put(this.fileEntryFromEntry(entry), data).catch((error) => {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n\t\t\tthrow error;\n\t\t});\n\t}\n\n\tpublic async removeEntries(): Promise<void> {\n\t\ttry {\n\t\t\treturn await this.cache.removeEntries(this.fileEntry);\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n\t\t}\n\t}\n\n\tpublic get fluidEpoch() {\n\t\treturn this._fluidEpoch;\n\t}\n\n\tpublic async validateEpoch(epoch: string | undefined, fetchType: FetchType) {\n\t\tassert(epoch !== undefined, 0x584 /* response should contain epoch */);\n\t\ttry {\n\t\t\tthis.validateEpochFromResponse(epoch, fetchType);\n\t\t} catch (error) {\n\t\t\tawait this.checkForEpochError(error, epoch, fetchType);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\treturn this.fetchCore<T>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchAndParseAsJSONHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetch(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t) {\n\t\treturn this.fetchCore<Response>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate async fetchCore<T>(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t\tfetcher: (url: string, fetchOptions: { [index: string]: any }) => Promise<IOdspResponse<T>>,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t) {\n\t\tconst clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n\t\t// Add epoch in fetch request.\n\t\tthis.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n\t\tlet epochFromResponse: string | undefined;\n\t\treturn this.rateLimiter\n\t\t\t.schedule(async () => fetcher(url, fetchOptions))\n\t\t\t.then((response) => {\n\t\t\t\tepochFromResponse = response.headers.get(\"x-fluid-epoch\");\n\t\t\t\tthis.validateEpochFromResponse(epochFromResponse, fetchType);\n\t\t\t\tresponse.propsToLog.XRequestStatsHeader = clientCorrelationId;\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.catch(async (error) => {\n\t\t\t\t// Get the server epoch from error in case we don't have it as if undefined we won't be able\n\t\t\t\t// to mark it as epoch error.\n\t\t\t\tif (epochFromResponse === undefined) {\n\t\t\t\t\tepochFromResponse = (error as IOdspError).serverEpoch;\n\t\t\t\t}\n\t\t\t\tawait this.checkForEpochError(error, epochFromResponse, fetchType);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// If the error is about location redirection, then we need to generate new resolved url with correct\n\t\t\t\t// location info.\n\t\t\t\tif (\n\t\t\t\t\tisFluidError(error) &&\n\t\t\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError\n\t\t\t\t) {\n\t\t\t\t\tconst redirectLocation = (error as IOdspErrorAugmentations).redirectLocation;\n\t\t\t\t\tif (redirectLocation !== undefined) {\n\t\t\t\t\t\tconst redirectUrl: IOdspResolvedUrl = patchOdspResolvedUrl(\n\t\t\t\t\t\t\tthis.fileEntry.resolvedUrl,\n\t\t\t\t\t\t\tredirectLocation,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst locationRedirectionError = new LocationRedirectionError(\n\t\t\t\t\t\t\terror.message,\n\t\t\t\t\t\t\tredirectUrl,\n\t\t\t\t\t\t\t{ driverVersion, redirectLocation },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlocationRedirectionError.addTelemetryProperties(\n\t\t\t\t\t\t\terror.getTelemetryProperties(),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthrow locationRedirectionError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconst fluidError = normalizeError(error, {\n\t\t\t\t\tprops: { XRequestStatsHeader: clientCorrelationId },\n\t\t\t\t});\n\t\t\t\tthrow fluidError;\n\t\t\t});\n\t}\n\n\t/**\n\t * Api to fetch the response as it is for given request.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchArray(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t) {\n\t\treturn this.fetchCore<ArrayBuffer>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchArray,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate addEpochInRequest(\n\t\tfetchOptions: RequestInit,\n\t\taddInBody: boolean,\n\t\tclientCorrelationId: string,\n\t) {\n\t\tconst isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;\n\t\tif (addInBody) {\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\theaders[\"X-RequestStats\"] = clientCorrelationId;\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\theaders[\"x-fluid-epoch\"] = this.fluidEpoch;\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\theaders[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();\n\t\t\t}\n\t\t\tthis.addParamInBody(fetchOptions, headers);\n\t\t} else {\n\t\t\tconst addHeader = (key: string, val: string) => {\n\t\t\t\tfetchOptions.headers = {\n\t\t\t\t\t...fetchOptions.headers,\n\t\t\t\t};\n\t\t\t\tassert(\n\t\t\t\t\tfetchOptions.headers !== undefined,\n\t\t\t\t\t0x282 /* \"Headers should be present now\" */,\n\t\t\t\t);\n\t\t\t\tfetchOptions.headers[key] = val;\n\t\t\t};\n\t\t\taddHeader(\"X-RequestStats\", clientCorrelationId);\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\taddHeader(\"x-fluid-epoch\", this.fluidEpoch);\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\taddHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string }) {\n\t\t// We use multi part form request for post body where we want to use this.\n\t\t// So extract the form boundary to mark the end of form.\n\t\tconst body = fetchOptions.body;\n\t\tassert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n\t\tconst splitBody = body.split(\"\\r\\n\");\n\t\tconst firstLine = splitBody.shift();\n\t\tassert(firstLine?.startsWith(\"--\") === true, 0x21e /* \"improper boundary format\" */);\n\t\tconst formParams = [firstLine];\n\t\tObject.entries(headers).forEach(([key, value]) => {\n\t\t\tformParams.push(`${key}: ${value}`);\n\t\t});\n\t\tsplitBody.forEach((value: string) => {\n\t\t\tformParams.push(value);\n\t\t});\n\t\tfetchOptions.body = formParams.join(\"\\r\\n\");\n\t}\n\n\tprivate formatClientCorrelationId(fetchReason?: string) {\n\t\tconst items: string[] = [\n\t\t\t`driverId=${this.driverId}`,\n\t\t\t`RequestNumber=${this.networkCallNumber++}`,\n\t\t\t`driverVersion=${driverVersion}`,\n\t\t\t`isSummarizer=${this.clientIsSummarizer}`,\n\t\t];\n\t\tif (fetchReason !== undefined) {\n\t\t\titems.push(`fetchReason=${fetchReason}`);\n\t\t}\n\t\treturn items.join(\", \");\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t) {\n\t\tconst error = this.checkForEpochErrorCore(epochFromResponse);\n\t\tif (error !== undefined) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (epochFromResponse !== undefined) {\n\t\t\tif (this._fluidEpoch === undefined) {\n\t\t\t\tthis.setEpoch(epochFromResponse, fromCache, fetchType);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async checkForEpochError(\n\t\terror: unknown,\n\t\tepochFromResponse: string | null | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t) {\n\t\tif (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {\n\t\t\tconst epochError = this.checkForEpochErrorCore(epochFromResponse);\n\t\t\tif (epochError !== undefined) {\n\t\t\t\tepochError.addTelemetryProperties({\n\t\t\t\t\tfromCache,\n\t\t\t\t\tfetchType,\n\t\t\t\t});\n\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n\t\t\t\t// If the epoch mismatches, then clear all entries for such file entry from cache.\n\t\t\t\tawait this.removeEntries();\n\t\t\t\tthrow epochError;\n\t\t\t}\n\t\t\t// If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n\t\t\t// then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n\t\t\t// time is 1s.\n\t\t\tconst newError = wrapError(error, (message: string) => {\n\t\t\t\treturn new ThrottlingError(`Coherency 409: ${message}`, 1 /* retryAfterSeconds */, {\n\t\t\t\t\t[Odsp409Error]: true,\n\t\t\t\t\tdriverVersion,\n\t\t\t\t});\n\t\t\t});\n\t\t\tthrow newError;\n\t\t}\n\t}\n\n\tprivate checkForEpochErrorCore(epochFromResponse: string | null | undefined) {\n\t\t// If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n\t\t// initializes this value. Sometimes response does not contain epoch as it is still in\n\t\t// implementation phase at server side. In that case also, don't compare it with our epoch value.\n\t\tif (this.fluidEpoch && epochFromResponse && this.fluidEpoch !== epochFromResponse) {\n\t\t\t// This is similar in nature to how fluidEpochMismatchError (409) is handled.\n\t\t\t// Difference - client detected mismatch, instead of server detecting it.\n\t\t\treturn new NonRetryableError(\n\t\t\t\t\"Epoch mismatch\",\n\t\t\t\tDriverErrorType.fileOverwrittenInStorage,\n\t\t\t\t{ driverVersion, serverEpoch: epochFromResponse, clientEpoch: this.fluidEpoch },\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate fileEntryFromEntry(entry: IEntry): ICacheEntry {\n\t\treturn { ...entry, file: this.fileEntry };\n\t}\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n\tprivate readonly treesLatestDeferral = new Deferred<void>();\n\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\tsuper(cache, fileEntry, logger, clientIsSummarizer);\n\t\t// Handles the rejected promise within treesLatestDeferral.\n\t\tthis.treesLatestDeferral.promise.catch(() => {});\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchType,\n\t\tfromCache: boolean = false,\n\t) {\n\t\tsuper.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n\t\t// Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n\t\t// That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n\t\t// exploring a file.\n\t\tthis.treesLatestDeferral.resolve();\n\t}\n\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\tlet result = super.get(entry);\n\n\t\t// equivalence of what happens in fetchAndParseAsJSON()\n\t\tif (entry.type === snapshotKey) {\n\t\t\tresult = result\n\t\t\t\t.then((value) => {\n\t\t\t\t\t// If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n\t\t\t\t\t// Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\tthis.treesLatestDeferral.resolve();\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn value;\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t}\n\t\treturn result;\n\t}\n\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\t// Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n\t\t// joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n\t\tconst completed = this.treesLatestDeferral.isCompleted;\n\n\t\ttry {\n\t\t\treturn await super.fetchAndParseAsJSON<T>(\n\t\t\t\turl,\n\t\t\t\tfetchOptions,\n\t\t\t\tfetchType,\n\t\t\t\taddInBody,\n\t\t\t\tfetchReason,\n\t\t\t);\n\t\t} catch (error: any) {\n\t\t\t// Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n\t\t\t// Similar, if getVersions failed, we should not do any further storage calls.\n\t\t\t// So treesLatest is the only call that can have parallel joinSession request.\n\t\t\tif (fetchType === \"treesLatest\") {\n\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tfetchType !== \"joinSession\" ||\n\t\t\t\terror.statusCode < 401 ||\n\t\t\t\terror.statusCode > 404 ||\n\t\t\t\tcompleted\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\t// It is joinSession failing with 401..404 error\n\t\t// Repeat after waiting for treeLatest succeeding (or fail if it failed).\n\t\t// No special handling after first call - if file has been deleted, then it's game over.\n\n\t\t// Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n\t\t// If we waited too long, we will log error event and proceed with call.\n\t\t// It may result in failure for user, but refreshing document would address it.\n\t\t// Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n\t\t// to unblock the process.\n\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\tthis.logger,\n\t\t\t{ eventName: \"JoinSessionSyncWait\" },\n\t\t\tasync (event) => {\n\t\t\t\tconst timeoutRes = 51; // anything will work here\n\t\t\t\tlet timer: ReturnType<typeof setTimeout>;\n\t\t\t\tconst timeoutP = new Promise<number>((resolve) => {\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\tresolve(timeoutRes);\n\t\t\t\t\t}, 15000);\n\t\t\t\t});\n\t\t\t\tconst res = await Promise.race([\n\t\t\t\t\ttimeoutP,\n\t\t\t\t\t// cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n\t\t\t\t\tthis.treesLatestDeferral.promise.finally(() => clearTimeout(timer)),\n\t\t\t\t]);\n\t\t\t\tif (res === timeoutRes) {\n\t\t\t\t\tevent.cancel();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t);\n\t\treturn super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n\t}\n}\n\nexport interface ICacheAndTracker {\n\tcache: IOdspCache;\n\tepochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n\tpersistedCacheArg: IPersistedCache,\n\tnonpersistentCache: INonPersistentCache,\n\tfileEntry: IFileEntry,\n\tlogger: ITelemetryLoggerExt,\n\tclientIsSummarizer?: boolean,\n): ICacheAndTracker {\n\tconst epochTracker = new EpochTrackerWithRedemption(\n\t\tpersistedCacheArg,\n\t\tfileEntry,\n\t\tlogger,\n\t\tclientIsSummarizer,\n\t);\n\treturn {\n\t\tcache: {\n\t\t\t...nonpersistentCache,\n\t\t\tpersistedCache: epochTracker,\n\t\t},\n\t\tepochTracker,\n\t};\n}\n"]}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { IDocumentService, IResolvedUrl } from "@fluidframework/driver-definitions";
|
|
6
6
|
import { TelemetryLogger } from "@fluidframework/telemetry-utils";
|
|
7
7
|
import { ISummaryTree } from "@fluidframework/protocol-definitions";
|
|
8
|
-
import { ITelemetryBaseLogger } from "@fluidframework/
|
|
8
|
+
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
9
9
|
import { ICacheAndTracker } from "../epochTracker";
|
|
10
10
|
import { OdspDocumentServiceFactoryCore } from "../odspDocumentServiceFactoryCore";
|
|
11
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localOdspDocumentServiceFactory.d.ts","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentServiceFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"localOdspDocumentServiceFactory.d.ts","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentServiceFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAGnF;;;;GAIG;AACH,qBAAa,+BAAgC,SAAQ,8BAA8B;IAGtE,OAAO,CAAC,QAAQ,CAAC,aAAa;IAF1C,OAAO,CAAC,MAAM,CAA8B;gBAEf,aAAa,EAAE,UAAU,GAAG,MAAM;IAO/D,OAAO,CAAC,0BAA0B;IAQ3B,eAAe,CACrB,iBAAiB,EAAE,YAAY,GAAG,SAAS,EAC3C,qBAAqB,EAAE,YAAY,EACnC,MAAM,CAAC,EAAE,oBAAoB,EAC7B,mBAAmB,CAAC,EAAE,OAAO,GAC3B,KAAK;cAQQ,yBAAyB,CACxC,WAAW,EAAE,YAAY,EACzB,UAAU,EAAE,eAAe,EAC3B,mBAAmB,CAAC,EAAE,gBAAgB,EACtC,mBAAmB,CAAC,EAAE,OAAO,GAC3B,OAAO,CAAC,gBAAgB,CAAC;CAc5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localOdspDocumentServiceFactory.js","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentServiceFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAA0D;AAI1D,4CAAoE;AAEpE,sFAAmF;AACnF,yEAAsE;AAEtE;;;;GAIG;AACH,MAAa,+BAAgC,SAAQ,+DAA8B;IAGlF,YAA6B,aAAkC;QAC9D,KAAK,CACJ,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,uBAAuB,CAAC,EACtE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,yBAAyB,CAAC,CACxE,CAAC;QAJ0B,kBAAa,GAAb,aAAa,CAAqB;IAK/D,CAAC;IAEO,0BAA0B,CAAC,mBAA2B;;QAC7D,MAAM,OAAO,GAAG,IAAI,yBAAU,CAC7B,GAAG,mBAAmB,sDAAsD,CAC5E,CAAC;QACF,MAAA,IAAI,CAAC,MAAM,0CAAE,cAAc,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;QACxE,MAAM,OAAO,CAAC;IACf,CAAC;IAEM,eAAe,CACrB,iBAA2C,EAC3C,qBAAmC,EACnC,MAA6B,EAC7B,mBAA6B;QAE7B,MAAM,OAAO,GAAG,IAAI,yBAAU,CAC7B,uEAAuE,CACvE,CAAC;QACF,IAAA,4BAAgB,EAAC,MAAM,CAAC,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;QACpF,MAAM,OAAO,CAAC;IACf,CAAC;IAES,KAAK,CAAC,yBAAyB,CACxC,WAAyB,EACzB,UAA2B,EAC3B,mBAAsC,EACtC,mBAA6B;QAE7B,IAAI,mBAAmB,KAAK,SAAS,EAAE;YACtC,MAAM,IAAI,yBAAU,CAAC,6DAA6D,CAAC,CAAC;SACpF;QACD,IAAI,mBAAmB,EAAE;YACxB,MAAM,IAAI,yBAAU,CAAC,6DAA6D,CAAC,CAAC;SACpF;QACD,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;QACzB,OAAO,IAAI,mDAAwB,CAClC,IAAA,8BAAkB,EAAC,WAAW,CAAC,EAC/B,UAAU,EACV,IAAI,CAAC,aAAa,CAClB,CAAC;IACH,CAAC;CACD;AAlDD,0EAkDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDocumentService, IResolvedUrl } from \"@fluidframework/driver-definitions\";\nimport { UsageError } from \"@fluidframework/driver-utils\";\nimport { TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/
|
|
1
|
+
{"version":3,"file":"localOdspDocumentServiceFactory.js","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentServiceFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+DAA0D;AAI1D,4CAAoE;AAEpE,sFAAmF;AACnF,yEAAsE;AAEtE;;;;GAIG;AACH,MAAa,+BAAgC,SAAQ,+DAA8B;IAGlF,YAA6B,aAAkC;QAC9D,KAAK,CACJ,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,uBAAuB,CAAC,EACtE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,yBAAyB,CAAC,CACxE,CAAC;QAJ0B,kBAAa,GAAb,aAAa,CAAqB;IAK/D,CAAC;IAEO,0BAA0B,CAAC,mBAA2B;;QAC7D,MAAM,OAAO,GAAG,IAAI,yBAAU,CAC7B,GAAG,mBAAmB,sDAAsD,CAC5E,CAAC;QACF,MAAA,IAAI,CAAC,MAAM,0CAAE,cAAc,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;QACxE,MAAM,OAAO,CAAC;IACf,CAAC;IAEM,eAAe,CACrB,iBAA2C,EAC3C,qBAAmC,EACnC,MAA6B,EAC7B,mBAA6B;QAE7B,MAAM,OAAO,GAAG,IAAI,yBAAU,CAC7B,uEAAuE,CACvE,CAAC;QACF,IAAA,4BAAgB,EAAC,MAAM,CAAC,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;QACpF,MAAM,OAAO,CAAC;IACf,CAAC;IAES,KAAK,CAAC,yBAAyB,CACxC,WAAyB,EACzB,UAA2B,EAC3B,mBAAsC,EACtC,mBAA6B;QAE7B,IAAI,mBAAmB,KAAK,SAAS,EAAE;YACtC,MAAM,IAAI,yBAAU,CAAC,6DAA6D,CAAC,CAAC;SACpF;QACD,IAAI,mBAAmB,EAAE;YACxB,MAAM,IAAI,yBAAU,CAAC,6DAA6D,CAAC,CAAC;SACpF;QACD,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;QACzB,OAAO,IAAI,mDAAwB,CAClC,IAAA,8BAAkB,EAAC,WAAW,CAAC,EAC/B,UAAU,EACV,IAAI,CAAC,aAAa,CAClB,CAAC;IACH,CAAC;CACD;AAlDD,0EAkDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDocumentService, IResolvedUrl } from \"@fluidframework/driver-definitions\";\nimport { UsageError } from \"@fluidframework/driver-utils\";\nimport { TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { createOdspLogger, getOdspResolvedUrl } from \"../odspUtils\";\nimport { ICacheAndTracker } from \"../epochTracker\";\nimport { OdspDocumentServiceFactoryCore } from \"../odspDocumentServiceFactoryCore\";\nimport { LocalOdspDocumentService } from \"./localOdspDocumentService\";\n\n/**\n * Factory for creating sharepoint document service with a provided snapshot.\n * Use if you don't want to connect to any kind of external/internal storages and want to provide\n * content directly.\n */\nexport class LocalOdspDocumentServiceFactory extends OdspDocumentServiceFactoryCore {\n\tprivate logger: TelemetryLogger | undefined;\n\n\tconstructor(private readonly localSnapshot: Uint8Array | string) {\n\t\tsuper(\n\t\t\t(_options) => this.throwUnsupportedUsageError(\"Getting storage token\"),\n\t\t\t(_options) => this.throwUnsupportedUsageError(\"Getting websocket token\"),\n\t\t);\n\t}\n\n\tprivate throwUnsupportedUsageError(unsupportedFuncName: string): never {\n\t\tconst toThrow = new UsageError(\n\t\t\t`${unsupportedFuncName} is not supported by LocalOdspDocumentServiceFactory`,\n\t\t);\n\t\tthis.logger?.sendErrorEvent({ eventName: \"UnsupportedUsage\" }, toThrow);\n\t\tthrow toThrow;\n\t}\n\n\tpublic createContainer(\n\t\t_createNewSummary: ISummaryTree | undefined,\n\t\t_createNewResolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\t_clientIsSummarizer?: boolean,\n\t): never {\n\t\tconst toThrow = new UsageError(\n\t\t\t'\"createContainer\" is not supported by LocalOdspDocumentServiceFactory',\n\t\t);\n\t\tcreateOdspLogger(logger).sendErrorEvent({ eventName: \"UnsupportedUsage\" }, toThrow);\n\t\tthrow toThrow;\n\t}\n\n\tprotected async createDocumentServiceCore(\n\t\tresolvedUrl: IResolvedUrl,\n\t\todspLogger: TelemetryLogger,\n\t\t_cacheAndTrackerArg?: ICacheAndTracker,\n\t\t_clientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\tif (_cacheAndTrackerArg !== undefined) {\n\t\t\tthrow new UsageError('Invalid usage. \"_cacheAndTrackerArg\" should not be provided');\n\t\t}\n\t\tif (_clientIsSummarizer) {\n\t\t\tthrow new UsageError('Invalid usage. \"_clientIsSummarizer\" should not be provided');\n\t\t}\n\t\tthis.logger = odspLogger;\n\t\treturn new LocalOdspDocumentService(\n\t\t\tgetOdspResolvedUrl(resolvedUrl),\n\t\t\todspLogger,\n\t\t\tthis.localSnapshot,\n\t\t);\n\t}\n}\n"]}
|
package/dist/odspCache.d.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { PromiseCache } from "@fluidframework/
|
|
6
|
-
import { IOdspResolvedUrl, IFileEntry, IEntry, IPersistedCache, ICacheEntry } from "@fluidframework/odsp-driver-definitions";
|
|
7
|
-
import { ISocketStorageDiscovery } from "./contracts";
|
|
5
|
+
import { PromiseCache } from "@fluidframework/core-utils";
|
|
6
|
+
import { IOdspResolvedUrl, IFileEntry, IEntry, IPersistedCache, ICacheEntry, ISocketStorageDiscovery } from "@fluidframework/odsp-driver-definitions";
|
|
8
7
|
import { ISnapshotContents } from "./odspPublicUtils";
|
|
9
8
|
/**
|
|
10
9
|
* Similar to IPersistedCache, but exposes cache interface for single file
|
package/dist/odspCache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odspCache.d.ts","sourceRoot":"","sources":["../src/odspCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"odspCache.d.ts","sourceRoot":"","sources":["../src/odspCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACN,gBAAgB,EAChB,UAAU,EACV,MAAM,EACN,eAAe,EACf,WAAW,EACX,uBAAuB,EAEvB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAKxC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAJxD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAEhD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoD;gBAEnD,oBAAoB,SAAc;IAEhE,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAMrC,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG;IAMlC,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,OAAO,CAAC,2BAA2B;IAcnC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,qBAAqB;CAS7B;AACD,qBAAa,oCAAoC,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;gBACvE,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,OAAO;CAG/C;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC;;OAEG;IACH,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CACtC,MAAM,EACN;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,uBAAuB,CAAA;KAAE,CACnE,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAE9D;;;OAGG;IACH,QAAQ,CAAC,2BAA2B,EAAE,YAAY,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;CACtF;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,mBAAmB;IACtD;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;CAC7C;AAED,qBAAa,kBAAmB,YAAW,mBAAmB;IAC7D,SAAgB,gBAAgB;mBAElB,MAAM;6BAAuB,uBAAuB;OAC9D;IAEJ,SAAgB,YAAY,yCAAgD;IAE5E,SAAgB,2BAA2B,kDAGvC;CACJ;AAED,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC1B"}
|
package/dist/odspCache.js
CHANGED
|
@@ -5,7 +5,7 @@ exports.NonPersistentCache = exports.PromiseCacheWithOneHourSlidingExpiry = expo
|
|
|
5
5
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
6
6
|
* Licensed under the MIT License.
|
|
7
7
|
*/
|
|
8
|
-
const
|
|
8
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
9
9
|
const odsp_driver_definitions_1 = require("@fluidframework/odsp-driver-definitions");
|
|
10
10
|
/**
|
|
11
11
|
* Default local-only implementation of IPersistedCache,
|
|
@@ -59,7 +59,7 @@ class LocalPersistentCache {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
exports.LocalPersistentCache = LocalPersistentCache;
|
|
62
|
-
class PromiseCacheWithOneHourSlidingExpiry extends
|
|
62
|
+
class PromiseCacheWithOneHourSlidingExpiry extends core_utils_1.PromiseCache {
|
|
63
63
|
constructor(removeOnError) {
|
|
64
64
|
super({ expiry: { policy: "sliding", durationMs: 3600000 }, removeOnError });
|
|
65
65
|
}
|
|
@@ -67,9 +67,9 @@ class PromiseCacheWithOneHourSlidingExpiry extends common_utils_1.PromiseCache {
|
|
|
67
67
|
exports.PromiseCacheWithOneHourSlidingExpiry = PromiseCacheWithOneHourSlidingExpiry;
|
|
68
68
|
class NonPersistentCache {
|
|
69
69
|
constructor() {
|
|
70
|
-
this.sessionJoinCache = new
|
|
71
|
-
this.fileUrlCache = new
|
|
72
|
-
this.snapshotPrefetchResultCache = new
|
|
70
|
+
this.sessionJoinCache = new core_utils_1.PromiseCache();
|
|
71
|
+
this.fileUrlCache = new core_utils_1.PromiseCache();
|
|
72
|
+
this.snapshotPrefetchResultCache = new core_utils_1.PromiseCache();
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
exports.NonPersistentCache = NonPersistentCache;
|
package/dist/odspCache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odspCache.js","sourceRoot":"","sources":["../src/odspCache.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH
|
|
1
|
+
{"version":3,"file":"odspCache.js","sourceRoot":"","sources":["../src/odspCache.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,2DAA0D;AAC1D,qFAQiD;AAYjD;;;GAGG;AACH,MAAa,oBAAoB;IAKhC,YAAoC,uBAAuB,IAAI,GAAG,IAAI;QAAlC,yBAAoB,GAApB,oBAAoB,CAAc;QAJrD,UAAK,GAAG,IAAI,GAAG,EAAe,CAAC;QAChD,wGAAwG;QACvF,uBAAkB,GAAG,IAAI,GAAG,EAAyC,CAAC;IAEd,CAAC;IAE1E,KAAK,CAAC,GAAG,CAAC,KAAkB;QAC3B,MAAM,GAAG,GAAG,IAAA,6CAAmB,EAAC,KAAK,CAAC,CAAC;QACvC,+DAA+D;QAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAkB,EAAE,KAAU;QACvC,MAAM,GAAG,GAAG,IAAA,6CAAmB,EAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC3B,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAgB;QACnC,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAEO,2BAA2B,CAAC,KAAa;QAChD,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;aAC3B,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE;YACtB,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE;gBAC9B,OAAO,IAAI,CAAC;aACZ;QACF,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE;YACnB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,qBAAqB,CAAC,KAAa;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,OAAO,KAAK,SAAS,EAAE;YAC1B,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SACtC;IACF,CAAC;IAEO,qBAAqB,CAAC,KAAa;QAC1C,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAC1B,KAAK,EACL,UAAU,CAAC,GAAG,EAAE;YACf,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAC7B,CAAC;IACH,CAAC;CACD;AAtDD,oDAsDC;AACD,MAAa,oCAAwC,SAAQ,yBAAuB;IACnF,YAAY,aAAmC;QAC9C,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;IAC9E,CAAC;CACD;AAJD,oFAIC;AAoCD,MAAa,kBAAkB;IAA/B;QACiB,qBAAgB,GAAG,IAAI,yBAAY,EAGhD,CAAC;QAEY,iBAAY,GAAG,IAAI,yBAAY,EAA4B,CAAC;QAE5D,gCAA2B,GAAG,IAAI,yBAAY,EAG3D,CAAC;IACL,CAAC;CAAA;AAZD,gDAYC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { PromiseCache } from \"@fluidframework/core-utils\";\nimport {\n\tIOdspResolvedUrl,\n\tIFileEntry,\n\tIEntry,\n\tIPersistedCache,\n\tICacheEntry,\n\tISocketStorageDiscovery,\n\tgetKeyForCacheEntry,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\n\n/**\n * Similar to IPersistedCache, but exposes cache interface for single file\n */\nexport interface IPersistedFileCache {\n\tget(entry: IEntry): Promise<any>;\n\tput(entry: IEntry, value: any): Promise<void>;\n\tremoveEntries(): Promise<void>;\n}\n\n/**\n * Default local-only implementation of IPersistedCache,\n * used if no persisted cache is provided by the host\n */\nexport class LocalPersistentCache implements IPersistedCache {\n\tprivate readonly cache = new Map<string, any>();\n\t// For every document id there will be a single expiration entry inspite of the number of cache entries.\n\tprivate readonly docIdExpirationMap = new Map<string, ReturnType<typeof setTimeout>>();\n\n\tpublic constructor(private readonly snapshotExpiryPolicy = 3600 * 1000) {}\n\n\tasync get(entry: ICacheEntry): Promise<any> {\n\t\tconst key = getKeyForCacheEntry(entry);\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn this.cache.get(key);\n\t}\n\n\tasync put(entry: ICacheEntry, value: any) {\n\t\tconst key = getKeyForCacheEntry(entry);\n\t\tthis.cache.set(key, value);\n\t\tthis.updateExpirationEntry(entry.file.docId);\n\t}\n\n\tasync removeEntries(file: IFileEntry): Promise<void> {\n\t\tthis.removeDocIdEntriesFromCache(file.docId);\n\t}\n\n\tprivate removeDocIdEntriesFromCache(docId: string) {\n\t\tthis.removeExpirationEntry(docId);\n\t\treturn Array.from(this.cache)\n\t\t\t.filter(([cachekey]) => {\n\t\t\t\tconst docIdFromKey = cachekey.split(\"_\");\n\t\t\t\tif (docIdFromKey[0] === docId) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t})\n\t\t\t.map(([cachekey]) => {\n\t\t\t\tthis.cache.delete(cachekey);\n\t\t\t});\n\t}\n\n\tprivate removeExpirationEntry(docId: string) {\n\t\tconst timeout = this.docIdExpirationMap.get(docId);\n\t\tif (timeout !== undefined) {\n\t\t\tclearTimeout(timeout);\n\t\t\tthis.docIdExpirationMap.delete(docId);\n\t\t}\n\t}\n\n\tprivate updateExpirationEntry(docId: string) {\n\t\tthis.removeExpirationEntry(docId);\n\t\tthis.docIdExpirationMap.set(\n\t\t\tdocId,\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.removeDocIdEntriesFromCache(docId);\n\t\t\t}, this.snapshotExpiryPolicy),\n\t\t);\n\t}\n}\nexport class PromiseCacheWithOneHourSlidingExpiry<T> extends PromiseCache<string, T> {\n\tconstructor(removeOnError?: (e: any) => boolean) {\n\t\tsuper({ expiry: { policy: \"sliding\", durationMs: 3600000 }, removeOnError });\n\t}\n}\n\n/**\n * Internal cache interface used within driver only\n */\nexport interface INonPersistentCache {\n\t/**\n\t * Cache of joined/joining session info\n\t */\n\treadonly sessionJoinCache: PromiseCache<\n\t\tstring,\n\t\t{ entryTime: number; joinSessionResponse: ISocketStorageDiscovery }\n\t>;\n\n\t/**\n\t * Cache of resolved/resolving file URLs\n\t */\n\treadonly fileUrlCache: PromiseCache<string, IOdspResolvedUrl>;\n\n\t/**\n\t * Used to store the snapshot fetch promise if the prefetch has been made using the prefetchLatestSnapshot api.\n\t * This is then used later to look for the promise during the container load.\n\t */\n\treadonly snapshotPrefetchResultCache: PromiseCache<string, IPrefetchSnapshotContents>;\n}\n\n/**\n * Internal cache interface used within driver only\n */\nexport interface IOdspCache extends INonPersistentCache {\n\t/**\n\t * Persisted cache - only serializable content is allowed\n\t */\n\treadonly persistedCache: IPersistedFileCache;\n}\n\nexport class NonPersistentCache implements INonPersistentCache {\n\tpublic readonly sessionJoinCache = new PromiseCache<\n\t\tstring,\n\t\t{ entryTime: number; joinSessionResponse: ISocketStorageDiscovery }\n\t>();\n\n\tpublic readonly fileUrlCache = new PromiseCache<string, IOdspResolvedUrl>();\n\n\tpublic readonly snapshotPrefetchResultCache = new PromiseCache<\n\t\tstring,\n\t\tIPrefetchSnapshotContents\n\t>();\n}\n\nexport interface IPrefetchSnapshotContents extends ISnapshotContents {\n\tfluidEpoch: string;\n\tprefetchStartTime: number;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odspDelayLoadedDeltaStream.d.ts","sourceRoot":"","sources":["../src/odspDelayLoadedDeltaStream.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,iBAAiB,EAEjB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACN,wBAAwB,EACxB,YAAY,EACZ,wBAAwB,EAExB,MAAM,oCAAoC,CAAC;AAK5C,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EACN,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,+BAA+B,
|
|
1
|
+
{"version":3,"file":"odspDelayLoadedDeltaStream.d.ts","sourceRoot":"","sources":["../src/odspDelayLoadedDeltaStream.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAEN,iBAAiB,EAEjB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACN,wBAAwB,EACxB,YAAY,EACZ,wBAAwB,EAExB,MAAM,oCAAoC,CAAC;AAK5C,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EACN,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,+BAA+B,EAG/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAO5E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;GAGG;AACH,qBAAa,0BAA0B;aA0BrB,eAAe,EAAE,gBAAgB;IAC1C,QAAQ,EAAE,wBAAwB;IACzC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAGlC,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAnC3C,OAAO,CAAC,uBAAuB,CAA4C;IAE3E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,iBAAiB,CAAC,CAA8B;IAExD,OAAO,CAAC,+BAA+B,CAAqB;IAE5D;;;;;;;;;;;;;;OAcG;gBAEc,eAAe,EAAE,gBAAgB,EAC1C,QAAQ,EAAE,wBAAwB,EACxB,eAAe,EAAE,+BAA+B,EAChD,iBAAiB,EAC/B,CAAC,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,GACxD,SAAS,EACK,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,iBAAiB,EAC7B,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,CAAC,GAAG,EAAE,yBAAyB,EAAE,KAAK,IAAI,EACvD,wBAAwB,CAAC,oBAAQ;IAKnD,IAAW,WAAW,IAAI,YAAY,CAErC;IAED,IAAW,sBAAsB,IAAI,2BAA2B,GAAG,SAAS,CAE3E;IAED,IAAW,8BAA8B,IAAI,MAAM,GAAG,SAAS,CAE9D;IAED,uEAAuE;IACvE,OAAO,CAAC,uBAAuB;IAa/B;;;;OAIG;IACU,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA6FrF,OAAO,CAAC,qBAAqB;YAOf,0BAA0B;YAmC1B,WAAW;YA8DX,eAAe;IAqF7B,OAAO,CAAC,gCAAgC;IAQxC;;;;;;;;OAQG;YACW,qBAAqB;IAgC5B,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG;CAK1B"}
|
|
@@ -46,7 +46,7 @@ class OdspDelayLoadedDeltaStream {
|
|
|
46
46
|
this.epochTracker = epochTracker;
|
|
47
47
|
this.opsReceived = opsReceived;
|
|
48
48
|
this.socketReferenceKeyPrefix = socketReferenceKeyPrefix;
|
|
49
|
-
this.joinSessionKey =
|
|
49
|
+
this.joinSessionKey = (0, odspUtils_1.getJoinSessionCacheKey)(this.odspResolvedUrl);
|
|
50
50
|
}
|
|
51
51
|
get resolvedUrl() {
|
|
52
52
|
return this.odspResolvedUrl;
|