@fluidframework/odsp-driver 0.55.1 → 0.56.0-49831
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/dist/checkUrl.d.ts.map +1 -1
- package/dist/checkUrl.js +0 -1
- package/dist/checkUrl.js.map +1 -1
- package/dist/contractsPublic.d.ts +7 -1
- package/dist/contractsPublic.d.ts.map +1 -1
- package/dist/contractsPublic.js +7 -1
- package/dist/contractsPublic.js.map +1 -1
- package/dist/createFile.d.ts +3 -3
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +7 -7
- package/dist/createFile.js.map +1 -1
- package/dist/epochTracker.d.ts +3 -3
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +20 -8
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +3 -2
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +28 -16
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.js +4 -4
- package/dist/getFileLink.js.map +1 -1
- package/dist/getUrlAndHeadersWithAuth.d.ts +1 -1
- package/dist/getUrlAndHeadersWithAuth.d.ts.map +1 -1
- package/dist/getUrlAndHeadersWithAuth.js +20 -33
- package/dist/getUrlAndHeadersWithAuth.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +1 -4
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +2 -2
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +1 -0
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +16 -9
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +5 -2
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +1 -2
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts +2 -1
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +3 -2
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts +2 -1
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +3 -2
- 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/lib/checkUrl.d.ts.map +1 -1
- package/lib/checkUrl.js +0 -1
- package/lib/checkUrl.js.map +1 -1
- package/lib/contractsPublic.d.ts +7 -1
- package/lib/contractsPublic.d.ts.map +1 -1
- package/lib/contractsPublic.js +6 -0
- package/lib/contractsPublic.js.map +1 -1
- package/lib/createFile.d.ts +3 -3
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +7 -7
- package/lib/createFile.js.map +1 -1
- package/lib/epochTracker.d.ts +3 -3
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +21 -9
- package/lib/epochTracker.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +3 -2
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +28 -16
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.js +4 -4
- package/lib/getFileLink.js.map +1 -1
- package/lib/getUrlAndHeadersWithAuth.d.ts +1 -1
- package/lib/getUrlAndHeadersWithAuth.d.ts.map +1 -1
- package/lib/getUrlAndHeadersWithAuth.js +20 -33
- package/lib/getUrlAndHeadersWithAuth.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +1 -4
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +2 -2
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +1 -0
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +16 -9
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDriverUrlResolver.d.ts.map +1 -1
- package/lib/odspDriverUrlResolver.js +5 -2
- package/lib/odspDriverUrlResolver.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js +1 -2
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspSummaryUploadManager.d.ts +2 -1
- package/lib/odspSummaryUploadManager.d.ts.map +1 -1
- package/lib/odspSummaryUploadManager.js +3 -2
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/prefetchLatestSnapshot.d.ts +2 -1
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +3 -2
- 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/package.json +9 -9
- package/src/checkUrl.ts +0 -1
- package/src/contractsPublic.ts +11 -1
- package/src/createFile.ts +16 -4
- package/src/epochTracker.ts +21 -6
- package/src/fetchSnapshot.ts +33 -16
- package/src/getFileLink.ts +7 -2
- package/src/getUrlAndHeadersWithAuth.ts +24 -38
- package/src/odspDeltaStorageService.ts +1 -3
- package/src/odspDocumentServiceFactoryCore.ts +1 -0
- package/src/odspDocumentStorageManager.ts +39 -8
- package/src/odspDriverUrlResolver.ts +3 -0
- package/src/odspDriverUrlResolverForShareLink.ts +1 -2
- package/src/odspSummaryUploadManager.ts +6 -1
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +3 -0
- package/src/retryErrorsStorageAdapter.ts +1 -1
package/dist/checkUrl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkUrl.d.ts","sourceRoot":"","sources":["../src/checkUrl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAGxE;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,WAAW,EAAE,GAAG,GAAG,kBAAkB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"checkUrl.d.ts","sourceRoot":"","sources":["../src/checkUrl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAGxE;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,WAAW,EAAE,GAAG,GAAG,kBAAkB,GAAG,SAAS,CAmBzE"}
|
package/dist/checkUrl.js
CHANGED
|
@@ -25,7 +25,6 @@ function checkUrl(documentUrl) {
|
|
|
25
25
|
}
|
|
26
26
|
catch (_a) { }
|
|
27
27
|
return {
|
|
28
|
-
containerPath: locator.dataStorePath,
|
|
29
28
|
codeDetailsHint: locator === null || locator === void 0 ? void 0 : locator.containerPackageName,
|
|
30
29
|
// Add the snapshot endpoint, which has the same domain as the site URL
|
|
31
30
|
criticalBootDomains: siteOrigin ? [siteOrigin] : undefined,
|
package/dist/checkUrl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkUrl.js","sourceRoot":"","sources":["../src/checkUrl.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,2DAA4D;AAE5D;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,WAAgB;IACvC,MAAM,OAAO,GAAG,yCAAqB,CAAC,WAAW,CAAC,CAAC;IAEnD,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,UAA8B,CAAC;IACnC,IAAI;QACF,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,EAAE;YACpB,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,CAAC,MAAM,CAAC;SAC/C;KACF;IAAC,WAAM,GAAE;IAEV,OAAO;QACL,
|
|
1
|
+
{"version":3,"file":"checkUrl.js","sourceRoot":"","sources":["../src/checkUrl.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,2DAA4D;AAE5D;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,WAAgB;IACvC,MAAM,OAAO,GAAG,yCAAqB,CAAC,WAAW,CAAC,CAAC;IAEnD,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,UAA8B,CAAC;IACnC,IAAI;QACF,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,EAAE;YACpB,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,CAAC,MAAM,CAAC;SAC/C;KACF;IAAC,WAAM,GAAE;IAEV,OAAO;QACL,eAAe,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB;QAC9C,uEAAuE;QACvE,mBAAmB,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;KAC3D,CAAC;AACJ,CAAC;AAnBD,4BAmBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { DriverPreCheckInfo } from \"@fluidframework/driver-definitions\";\nimport { getLocatorFromOdspUrl } from \"./odspFluidFileLink\";\n\n/**\n * A check that returns DriverPreCheckInfo if the URL format is likely supported by this driver.\n * Note that returning information here is NOT a full guarentee that resolve will ultimately be successsful.\n * Instead, this should be used as a lightweight check that can filter out easily detectable unsupported URLs\n * before the entire Fluid loading process needs to be kicked off.\n */\nexport function checkUrl(documentUrl: URL): DriverPreCheckInfo | undefined {\n const locator = getLocatorFromOdspUrl(documentUrl);\n\n if (!locator) {\n return undefined;\n }\n\n let siteOrigin: string | undefined;\n try {\n if (locator?.siteUrl) {\n siteOrigin = new URL(locator?.siteUrl).origin;\n }\n } catch {}\n\n return {\n codeDetailsHint: locator?.containerPackageName,\n // Add the snapshot endpoint, which has the same domain as the site URL\n criticalBootDomains: siteOrigin ? [siteOrigin] : undefined,\n };\n}\n"]}
|
|
@@ -15,8 +15,14 @@ export declare enum SharingLinkHeader {
|
|
|
15
15
|
export interface ISharingLinkHeader {
|
|
16
16
|
[SharingLinkHeader.isSharingLinkToRedeem]: boolean;
|
|
17
17
|
}
|
|
18
|
+
export declare enum ClpCompliantAppHeader {
|
|
19
|
+
isClpCompliantApp = "X-CLP-Compliant-App"
|
|
20
|
+
}
|
|
21
|
+
export interface IClpCompliantAppHeader {
|
|
22
|
+
[ClpCompliantAppHeader.isClpCompliantApp]: boolean;
|
|
23
|
+
}
|
|
18
24
|
declare module "@fluidframework/core-interfaces" {
|
|
19
|
-
interface IRequestHeader extends Partial<ISharingLinkHeader> {
|
|
25
|
+
interface IRequestHeader extends Partial<ISharingLinkHeader>, Partial<IClpCompliantAppHeader> {
|
|
20
26
|
}
|
|
21
27
|
}
|
|
22
28
|
//# sourceMappingURL=contractsPublic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contractsPublic.d.ts","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAExE,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oBAAY,iBAAiB;IAGzB,qBAAqB,0BAA0B;CAClD;AAED,MAAM,WAAW,kBAAkB;IAC/B,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACtD;AAED,OAAO,QAAQ,iCAAiC,CAAC;IAE7C,UAAiB,cAAe,SAAQ,OAAO,CAAC,kBAAkB,CAAC;KAAI;
|
|
1
|
+
{"version":3,"file":"contractsPublic.d.ts","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAExE,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oBAAY,iBAAiB;IAGzB,qBAAqB,0BAA0B;CAClD;AAED,MAAM,WAAW,kBAAkB;IAC/B,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACtD;AAED,oBAAY,qBAAqB;IAG7B,iBAAiB,wBAAwB;CAC5C;AAED,MAAM,WAAW,sBAAsB;IACnC,CAAC,qBAAqB,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtD;AAED,OAAO,QAAQ,iCAAiC,CAAC;IAE7C,UAAiB,cAAe,SAAQ,OAAO,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC;KAAI;CAC3G"}
|
package/dist/contractsPublic.js
CHANGED
|
@@ -4,11 +4,17 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.SharingLinkHeader = void 0;
|
|
7
|
+
exports.ClpCompliantAppHeader = exports.SharingLinkHeader = void 0;
|
|
8
8
|
var SharingLinkHeader;
|
|
9
9
|
(function (SharingLinkHeader) {
|
|
10
10
|
// Can be used in request made to resolver, to tell the resolver that the passed in URL is a sharing link
|
|
11
11
|
// which can be redeemed at server to get permissions.
|
|
12
12
|
SharingLinkHeader["isSharingLinkToRedeem"] = "isSharingLinkToRedeem";
|
|
13
13
|
})(SharingLinkHeader = exports.SharingLinkHeader || (exports.SharingLinkHeader = {}));
|
|
14
|
+
var ClpCompliantAppHeader;
|
|
15
|
+
(function (ClpCompliantAppHeader) {
|
|
16
|
+
// Can be used in request made to resolver, to tell the resolver that the host app is CLP compliant.
|
|
17
|
+
// Odsp will not return Classified, labeled, or protected documents if the host app cannot support them.
|
|
18
|
+
ClpCompliantAppHeader["isClpCompliantApp"] = "X-CLP-Compliant-App";
|
|
19
|
+
})(ClpCompliantAppHeader = exports.ClpCompliantAppHeader || (exports.ClpCompliantAppHeader = {}));
|
|
14
20
|
//# sourceMappingURL=contractsPublic.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contractsPublic.js","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAWH,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IACzB,yGAAyG;IACzG,sDAAsD;IACtD,oEAA+C,CAAA;AACnD,CAAC,EAJW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAI5B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IOdspUrlParts } from \"@fluidframework/odsp-driver-definitions\";\n\nexport interface OdspFluidDataStoreLocator extends IOdspUrlParts {\n dataStorePath: string;\n appName?: string;\n containerPackageName?: string;\n fileVersion?: string;\n}\n\nexport enum SharingLinkHeader {\n // Can be used in request made to resolver, to tell the resolver that the passed in URL is a sharing link\n // which can be redeemed at server to get permissions.\n isSharingLinkToRedeem = \"isSharingLinkToRedeem\",\n}\n\nexport interface ISharingLinkHeader {\n [SharingLinkHeader.isSharingLinkToRedeem]: boolean;\n}\n\ndeclare module \"@fluidframework/core-interfaces\" {\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n export interface IRequestHeader extends Partial<ISharingLinkHeader> { }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"contractsPublic.js","sourceRoot":"","sources":["../src/contractsPublic.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAWH,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IACzB,yGAAyG;IACzG,sDAAsD;IACtD,oEAA+C,CAAA;AACnD,CAAC,EAJW,iBAAiB,GAAjB,yBAAiB,KAAjB,yBAAiB,QAI5B;AAMD,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC7B,oGAAoG;IACpG,wGAAwG;IACxG,kEAAyC,CAAA;AAC7C,CAAC,EAJW,qBAAqB,GAArB,6BAAqB,KAArB,6BAAqB,QAIhC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IOdspUrlParts } from \"@fluidframework/odsp-driver-definitions\";\n\nexport interface OdspFluidDataStoreLocator extends IOdspUrlParts {\n dataStorePath: string;\n appName?: string;\n containerPackageName?: string;\n fileVersion?: string;\n}\n\nexport enum SharingLinkHeader {\n // Can be used in request made to resolver, to tell the resolver that the passed in URL is a sharing link\n // which can be redeemed at server to get permissions.\n isSharingLinkToRedeem = \"isSharingLinkToRedeem\",\n}\n\nexport interface ISharingLinkHeader {\n [SharingLinkHeader.isSharingLinkToRedeem]: boolean;\n}\n\nexport enum ClpCompliantAppHeader {\n // Can be used in request made to resolver, to tell the resolver that the host app is CLP compliant.\n // Odsp will not return Classified, labeled, or protected documents if the host app cannot support them.\n isClpCompliantApp = \"X-CLP-Compliant-App\",\n}\n\nexport interface IClpCompliantAppHeader {\n [ClpCompliantAppHeader.isClpCompliantApp]: boolean;\n}\n\ndeclare module \"@fluidframework/core-interfaces\" {\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n export interface IRequestHeader extends Partial<ISharingLinkHeader>, Partial<IClpCompliantAppHeader> { }\n}\n"]}
|
package/dist/createFile.d.ts
CHANGED
|
@@ -12,9 +12,9 @@ import { EpochTracker } from "./epochTracker";
|
|
|
12
12
|
* Creates a new Fluid file.
|
|
13
13
|
* Returns resolved url
|
|
14
14
|
*/
|
|
15
|
-
export declare function createNewFluidFile(getStorageToken: InstrumentedStorageTokenFetcher, newFileInfo: INewFileInfo, logger: ITelemetryLogger, createNewSummary: ISummaryTree | undefined, epochTracker: EpochTracker, fileEntry: IFileEntry, createNewCaching: boolean): Promise<IOdspResolvedUrl>;
|
|
16
|
-
export declare function createNewEmptyFluidFile(getStorageToken: InstrumentedStorageTokenFetcher, newFileInfo: INewFileInfo, logger: ITelemetryLogger, epochTracker: EpochTracker): Promise<string>;
|
|
17
|
-
export declare function createNewFluidFileFromSummary(getStorageToken: InstrumentedStorageTokenFetcher, newFileInfo: INewFileInfo, logger: ITelemetryLogger, createNewSummary: ISummaryTree, epochTracker: EpochTracker): Promise<ICreateFileResponse>;
|
|
15
|
+
export declare function createNewFluidFile(getStorageToken: InstrumentedStorageTokenFetcher, newFileInfo: INewFileInfo, logger: ITelemetryLogger, createNewSummary: ISummaryTree | undefined, epochTracker: EpochTracker, fileEntry: IFileEntry, createNewCaching: boolean, forceAccessTokenViaAuthorizationHeader: boolean): Promise<IOdspResolvedUrl>;
|
|
16
|
+
export declare function createNewEmptyFluidFile(getStorageToken: InstrumentedStorageTokenFetcher, newFileInfo: INewFileInfo, logger: ITelemetryLogger, epochTracker: EpochTracker, forceAccessTokenViaAuthorizationHeader: boolean): Promise<string>;
|
|
17
|
+
export declare function createNewFluidFileFromSummary(getStorageToken: InstrumentedStorageTokenFetcher, newFileInfo: INewFileInfo, logger: ITelemetryLogger, createNewSummary: ISummaryTree, epochTracker: EpochTracker, forceAccessTokenViaAuthorizationHeader: boolean): Promise<ICreateFileResponse>;
|
|
18
18
|
/**
|
|
19
19
|
* Converts a summary tree to ODSP tree
|
|
20
20
|
*/
|
package/dist/createFile.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFile.d.ts","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAe,YAAY,EAAgB,MAAM,sCAAsC,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EACH,UAAU,EACV,+BAA+B,EAC/B,gBAAgB,EAEnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EACH,gBAAgB,EAGhB,mBAAmB,EAEtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAGH,YAAY,EAGf,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAU9C;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,eAAe,EAAE,+BAA+B,EAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,UAAU,EACrB,gBAAgB,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"createFile.d.ts","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAe,YAAY,EAAgB,MAAM,sCAAsC,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EACH,UAAU,EACV,+BAA+B,EAC/B,gBAAgB,EAEnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EACH,gBAAgB,EAGhB,mBAAmB,EAEtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAGH,YAAY,EAGf,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAU9C;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,eAAe,EAAE,+BAA+B,EAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,UAAU,EACrB,gBAAgB,EAAE,OAAO,EACzB,sCAAsC,EAAE,OAAO,GAChD,OAAO,CAAC,gBAAgB,CAAC,CAqD3B;AAED,wBAAsB,uBAAuB,CACzC,eAAe,EAAE,+BAA+B,EAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,YAAY,EAC1B,sCAAsC,EAAE,OAAO,GAChD,OAAO,CAAC,MAAM,CAAC,CAgDjB;AAED,wBAAsB,6BAA6B,CAC/C,eAAe,EAAE,+BAA+B,EAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,EAAE,YAAY,EAC9B,YAAY,EAAE,YAAY,EAC1B,sCAAsC,EAAE,OAAO,GAChD,OAAO,CAAC,mBAAmB,CAAC,CAoD9B;AA+BD;;GAEG;AACH,wBAAgB,wCAAwC,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,CAoDhG"}
|
package/dist/createFile.js
CHANGED
|
@@ -27,7 +27,7 @@ const isInvalidFileName = (fileName) => {
|
|
|
27
27
|
* Creates a new Fluid file.
|
|
28
28
|
* Returns resolved url
|
|
29
29
|
*/
|
|
30
|
-
async function createNewFluidFile(getStorageToken, newFileInfo, logger, createNewSummary, epochTracker, fileEntry, createNewCaching) {
|
|
30
|
+
async function createNewFluidFile(getStorageToken, newFileInfo, logger, createNewSummary, epochTracker, fileEntry, createNewCaching, forceAccessTokenViaAuthorizationHeader) {
|
|
31
31
|
// Check for valid filename before the request to create file is actually made.
|
|
32
32
|
if (isInvalidFileName(newFileInfo.filename)) {
|
|
33
33
|
throw new driver_utils_1.NonRetryableError("createNewInvalidFilename", "Invalid filename", odsp_driver_definitions_1.OdspErrorType.invalidFileNameError);
|
|
@@ -37,10 +37,10 @@ async function createNewFluidFile(getStorageToken, newFileInfo, logger, createNe
|
|
|
37
37
|
let sharingLink;
|
|
38
38
|
let sharingLinkErrorReason;
|
|
39
39
|
if (createNewSummary === undefined) {
|
|
40
|
-
itemId = await createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epochTracker);
|
|
40
|
+
itemId = await createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epochTracker, forceAccessTokenViaAuthorizationHeader);
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
43
|
-
const content = await createNewFluidFileFromSummary(getStorageToken, newFileInfo, logger, createNewSummary, epochTracker);
|
|
43
|
+
const content = await createNewFluidFileFromSummary(getStorageToken, newFileInfo, logger, createNewSummary, epochTracker, forceAccessTokenViaAuthorizationHeader);
|
|
44
44
|
itemId = content.itemId;
|
|
45
45
|
summaryHandle = content.id;
|
|
46
46
|
sharingLink = content.sharingLink;
|
|
@@ -70,7 +70,7 @@ async function createNewFluidFile(getStorageToken, newFileInfo, logger, createNe
|
|
|
70
70
|
return odspResolvedUrl;
|
|
71
71
|
}
|
|
72
72
|
exports.createNewFluidFile = createNewFluidFile;
|
|
73
|
-
async function createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epochTracker) {
|
|
73
|
+
async function createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epochTracker, forceAccessTokenViaAuthorizationHeader) {
|
|
74
74
|
const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : "";
|
|
75
75
|
// add .tmp extension to empty file (host is expected to rename)
|
|
76
76
|
const encodedFilename = encodeURIComponent(`${newFileInfo.filename}.tmp`);
|
|
@@ -78,7 +78,7 @@ async function createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epo
|
|
|
78
78
|
return odspUtils_1.getWithRetryForTokenRefresh(async (options) => {
|
|
79
79
|
const storageToken = await getStorageToken(options, "CreateNewFile");
|
|
80
80
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, { eventName: "createNewEmptyFile" }, async (event) => {
|
|
81
|
-
const { url, headers } = getUrlAndHeadersWithAuth_1.getUrlAndHeadersWithAuth(initialUrl, storageToken);
|
|
81
|
+
const { url, headers } = getUrlAndHeadersWithAuth_1.getUrlAndHeadersWithAuth(initialUrl, storageToken, forceAccessTokenViaAuthorizationHeader);
|
|
82
82
|
headers["Content-Type"] = "application/json";
|
|
83
83
|
const fetchResponse = await retryUtils_1.runWithRetry(async () => epochTracker.fetchAndParseAsJSON(url, {
|
|
84
84
|
body: undefined,
|
|
@@ -95,7 +95,7 @@ async function createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epo
|
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
exports.createNewEmptyFluidFile = createNewEmptyFluidFile;
|
|
98
|
-
async function createNewFluidFileFromSummary(getStorageToken, newFileInfo, logger, createNewSummary, epochTracker) {
|
|
98
|
+
async function createNewFluidFileFromSummary(getStorageToken, newFileInfo, logger, createNewSummary, epochTracker, forceAccessTokenViaAuthorizationHeader) {
|
|
99
99
|
const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : "";
|
|
100
100
|
const encodedFilename = encodeURIComponent(newFileInfo.filename);
|
|
101
101
|
const baseUrl = `${odspUrlHelper_1.getApiRoot(odspUtils_1.getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:` +
|
|
@@ -106,7 +106,7 @@ async function createNewFluidFileFromSummary(getStorageToken, newFileInfo, logge
|
|
|
106
106
|
return odspUtils_1.getWithRetryForTokenRefresh(async (options) => {
|
|
107
107
|
const storageToken = await getStorageToken(options, "CreateNewFile");
|
|
108
108
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, { eventName: "createNewFile" }, async (event) => {
|
|
109
|
-
const { url, headers } = getUrlAndHeadersWithAuth_1.getUrlAndHeadersWithAuth(initialUrl, storageToken);
|
|
109
|
+
const { url, headers } = getUrlAndHeadersWithAuth_1.getUrlAndHeadersWithAuth(initialUrl, storageToken, forceAccessTokenViaAuthorizationHeader);
|
|
110
110
|
headers["Content-Type"] = "application/json";
|
|
111
111
|
const fetchResponse = await retryUtils_1.runWithRetry(async () => epochTracker.fetchAndParseAsJSON(url, {
|
|
112
112
|
body: JSON.stringify(containerSnapshot),
|
package/dist/createFile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFile.js","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, Uint8ArrayToString } from \"@fluidframework/common-utils\";\nimport { getDocAttributesFromProtocolSummary, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { getGitType } from \"@fluidframework/protocol-base\";\nimport { SummaryType, ISummaryTree, ISummaryBlob } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport {\n IFileEntry,\n InstrumentedStorageTokenFetcher,\n IOdspResolvedUrl,\n OdspErrorType,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspSummaryTree,\n OdspSummaryTreeValue,\n OdspSummaryTreeEntry,\n ICreateFileResponse,\n IOdspSummaryPayload,\n} from \"./contracts\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n createCacheSnapshotKey,\n getWithRetryForTokenRefresh,\n INewFileInfo,\n getOrigin,\n ISnapshotContents,\n} from \"./odspUtils\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { getApiRoot } from \"./odspUrlHelper\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver\";\nimport { convertCreateNewSummaryTreeToTreeAndBlobs } from \"./createNewUtils\";\nimport { runWithRetry } from \"./retryUtils\";\n\nconst isInvalidFileName = (fileName: string): boolean => {\n const invalidCharsRegex = /[\"*/:<>?\\\\|]+/g;\n return !!fileName.match(invalidCharsRegex);\n};\n\n/**\n * Creates a new Fluid file.\n * Returns resolved url\n */\nexport async function createNewFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree | undefined,\n epochTracker: EpochTracker,\n fileEntry: IFileEntry,\n createNewCaching: boolean,\n): Promise<IOdspResolvedUrl> {\n // Check for valid filename before the request to create file is actually made.\n if (isInvalidFileName(newFileInfo.filename)) {\n throw new NonRetryableError(\n \"createNewInvalidFilename\", \"Invalid filename\", OdspErrorType.invalidFileNameError);\n }\n\n let itemId: string;\n let summaryHandle: string = \"\";\n let sharingLink: string | undefined;\n let sharingLinkErrorReason: string | undefined;\n if (createNewSummary === undefined) {\n itemId = await createNewEmptyFluidFile(getStorageToken, newFileInfo, logger, epochTracker);\n } else {\n const content = await createNewFluidFileFromSummary(\n getStorageToken, newFileInfo, logger, createNewSummary, epochTracker);\n itemId = content.itemId;\n summaryHandle = content.id;\n sharingLink = content.sharingLink;\n sharingLinkErrorReason = content.sharingLinkErrorReason;\n }\n\n const odspUrl = createOdspUrl({... newFileInfo, itemId, dataStorePath: \"/\"});\n const resolver = new OdspDriverUrlResolver();\n const odspResolvedUrl = await resolver.resolve({ url: odspUrl });\n fileEntry.docId = odspResolvedUrl.hashedDocumentId;\n fileEntry.resolvedUrl = odspResolvedUrl;\n\n if(sharingLink || sharingLinkErrorReason) {\n odspResolvedUrl.shareLinkInfo = {\n createLink: {\n type: newFileInfo.createLinkType,\n link: sharingLink,\n error: sharingLinkErrorReason,\n },\n };\n }\n\n if (createNewSummary !== undefined && createNewCaching) {\n assert(summaryHandle !== undefined, 0x203 /* \"Summary handle is undefined\" */);\n // converting summary and getting sequence number\n const snapshot: ISnapshotContents = convertCreateNewSummaryTreeToTreeAndBlobs(createNewSummary, summaryHandle);\n // caching the converted summary\n await epochTracker.put(createCacheSnapshotKey(odspResolvedUrl), snapshot);\n }\n return odspResolvedUrl;\n}\n\nexport async function createNewEmptyFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n epochTracker: EpochTracker,\n): Promise<string> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n // add .tmp extension to empty file (host is expected to rename)\n const encodedFilename = encodeURIComponent(`${newFileInfo.filename}.tmp`);\n const initialUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:/${filePath\n }/${encodedFilename}:/content?@name.conflictBehavior=rename&select=id,name,parentReference`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewEmptyFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(initialUrl, storageToken);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: undefined,\n headers,\n method: \"PUT\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.id) {\n throw new NonRetryableError(\n \"createEmptyFileNoItemId\",\n \"ODSP CreateFile call returned no item ID\",\n DriverErrorType.incorrectServerResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n ...fetchResponse.commonSpoHeaders,\n });\n return content.id;\n },\n { end: true, cancel: \"error\" });\n });\n}\n\nexport async function createNewFluidFileFromSummary(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree,\n epochTracker: EpochTracker,\n): Promise<ICreateFileResponse> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n const encodedFilename = encodeURIComponent(newFileInfo.filename);\n const baseUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:` +\n `${filePath}/${encodedFilename}`;\n\n const containerSnapshot = convertSummaryIntoContainerSnapshot(createNewSummary);\n const initialUrl = `${baseUrl}:/opStream/snapshots/snapshot${newFileInfo.createLinkType ?\n `?createLinkType=${newFileInfo.createLinkType}` : \"\"}`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(initialUrl, storageToken);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: JSON.stringify(containerSnapshot),\n headers,\n method: \"POST\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.itemId) {\n throw new NonRetryableError(\n \"createFileNoItemId\",\n \"ODSP CreateFile call returned no item ID\",\n DriverErrorType.incorrectServerResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n attempts: options.refresh ? 2 : 1,\n ...fetchResponse.commonSpoHeaders,\n });\n return content;\n },\n );\n });\n}\n\nfunction convertSummaryIntoContainerSnapshot(createNewSummary: ISummaryTree) {\n const appSummary = createNewSummary.tree[\".app\"] as ISummaryTree;\n const protocolSummary = createNewSummary.tree[\".protocol\"] as ISummaryTree;\n if (!(appSummary && protocolSummary)) {\n throw new Error(\"App and protocol summary required for create new path!!\");\n }\n const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n const attributesSummaryBlob: ISummaryBlob = {\n type: SummaryType.Blob,\n content: JSON.stringify(documentAttributes),\n };\n protocolSummary.tree.attributes = attributesSummaryBlob;\n const convertedCreateNewSummary: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {\n \".protocol\": protocolSummary,\n \".app\": appSummary,\n },\n };\n const snapshotTree = convertSummaryToSnapshotTreeForCreateNew(convertedCreateNewSummary);\n const snapshot: IOdspSummaryPayload = {\n entries: snapshotTree.entries ?? [],\n message: \"app\",\n sequenceNumber: documentAttributes.sequenceNumber,\n type: \"container\",\n };\n return snapshot;\n}\n\n/**\n * Converts a summary tree to ODSP tree\n */\nexport function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspSummaryTree {\n const snapshotTree: IOdspSummaryTree = {\n type: \"tree\",\n entries: [],\n };\n\n const keys = Object.keys(summary.tree);\n for (const key of keys) {\n const summaryObject = summary.tree[key];\n\n let value: OdspSummaryTreeValue;\n // Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the\n // property is not present, the tree entry is considered referenced. If the property is present and is true,\n // the tree entry is considered unreferenced.\n let unreferenced: true | undefined;\n\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n value = convertSummaryToSnapshotTreeForCreateNew(summaryObject);\n unreferenced = summaryObject.unreferenced;\n break;\n }\n case SummaryType.Blob: {\n const content = typeof summaryObject.content === \"string\" ?\n summaryObject.content : Uint8ArrayToString(summaryObject.content, \"base64\");\n const encoding = typeof summaryObject.content === \"string\" ? \"utf-8\" : \"base64\";\n\n value = {\n type: \"blob\",\n content,\n encoding,\n };\n break;\n }\n case SummaryType.Handle: {\n throw new Error(\"No handle should be present for first summary!!\");\n }\n default: {\n throw new Error(`Unknown tree type ${summaryObject.type}`);\n }\n }\n\n const entry: OdspSummaryTreeEntry = {\n path: encodeURIComponent(key),\n type: getGitType(summaryObject),\n value,\n unreferenced,\n };\n snapshotTree.entries?.push(entry);\n }\n\n return snapshotTree;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createFile.js","sourceRoot":"","sources":["../src/createFile.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, Uint8ArrayToString } from \"@fluidframework/common-utils\";\nimport { getDocAttributesFromProtocolSummary, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { getGitType } from \"@fluidframework/protocol-base\";\nimport { SummaryType, ISummaryTree, ISummaryBlob } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport {\n IFileEntry,\n InstrumentedStorageTokenFetcher,\n IOdspResolvedUrl,\n OdspErrorType,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspSummaryTree,\n OdspSummaryTreeValue,\n OdspSummaryTreeEntry,\n ICreateFileResponse,\n IOdspSummaryPayload,\n} from \"./contracts\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n createCacheSnapshotKey,\n getWithRetryForTokenRefresh,\n INewFileInfo,\n getOrigin,\n ISnapshotContents,\n} from \"./odspUtils\";\nimport { createOdspUrl } from \"./createOdspUrl\";\nimport { getApiRoot } from \"./odspUrlHelper\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver\";\nimport { convertCreateNewSummaryTreeToTreeAndBlobs } from \"./createNewUtils\";\nimport { runWithRetry } from \"./retryUtils\";\n\nconst isInvalidFileName = (fileName: string): boolean => {\n const invalidCharsRegex = /[\"*/:<>?\\\\|]+/g;\n return !!fileName.match(invalidCharsRegex);\n};\n\n/**\n * Creates a new Fluid file.\n * Returns resolved url\n */\nexport async function createNewFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree | undefined,\n epochTracker: EpochTracker,\n fileEntry: IFileEntry,\n createNewCaching: boolean,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<IOdspResolvedUrl> {\n // Check for valid filename before the request to create file is actually made.\n if (isInvalidFileName(newFileInfo.filename)) {\n throw new NonRetryableError(\n \"createNewInvalidFilename\", \"Invalid filename\", OdspErrorType.invalidFileNameError);\n }\n\n let itemId: string;\n let summaryHandle: string = \"\";\n let sharingLink: string | undefined;\n let sharingLinkErrorReason: string | undefined;\n if (createNewSummary === undefined) {\n itemId = await createNewEmptyFluidFile(\n getStorageToken, newFileInfo, logger, epochTracker, forceAccessTokenViaAuthorizationHeader);\n } else {\n const content = await createNewFluidFileFromSummary(\n getStorageToken,\n newFileInfo,\n logger,\n createNewSummary,\n epochTracker,\n forceAccessTokenViaAuthorizationHeader,\n );\n itemId = content.itemId;\n summaryHandle = content.id;\n sharingLink = content.sharingLink;\n sharingLinkErrorReason = content.sharingLinkErrorReason;\n }\n\n const odspUrl = createOdspUrl({... newFileInfo, itemId, dataStorePath: \"/\"});\n const resolver = new OdspDriverUrlResolver();\n const odspResolvedUrl = await resolver.resolve({ url: odspUrl });\n fileEntry.docId = odspResolvedUrl.hashedDocumentId;\n fileEntry.resolvedUrl = odspResolvedUrl;\n\n if(sharingLink || sharingLinkErrorReason) {\n odspResolvedUrl.shareLinkInfo = {\n createLink: {\n type: newFileInfo.createLinkType,\n link: sharingLink,\n error: sharingLinkErrorReason,\n },\n };\n }\n\n if (createNewSummary !== undefined && createNewCaching) {\n assert(summaryHandle !== undefined, 0x203 /* \"Summary handle is undefined\" */);\n // converting summary and getting sequence number\n const snapshot: ISnapshotContents = convertCreateNewSummaryTreeToTreeAndBlobs(createNewSummary, summaryHandle);\n // caching the converted summary\n await epochTracker.put(createCacheSnapshotKey(odspResolvedUrl), snapshot);\n }\n return odspResolvedUrl;\n}\n\nexport async function createNewEmptyFluidFile(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n epochTracker: EpochTracker,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<string> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n // add .tmp extension to empty file (host is expected to rename)\n const encodedFilename = encodeURIComponent(`${newFileInfo.filename}.tmp`);\n const initialUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:/${filePath\n }/${encodedFilename}:/content?@name.conflictBehavior=rename&select=id,name,parentReference`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewEmptyFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(\n initialUrl, storageToken, forceAccessTokenViaAuthorizationHeader);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: undefined,\n headers,\n method: \"PUT\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.id) {\n throw new NonRetryableError(\n \"createEmptyFileNoItemId\",\n \"ODSP CreateFile call returned no item ID\",\n DriverErrorType.incorrectServerResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n ...fetchResponse.commonSpoHeaders,\n });\n return content.id;\n },\n { end: true, cancel: \"error\" });\n });\n}\n\nexport async function createNewFluidFileFromSummary(\n getStorageToken: InstrumentedStorageTokenFetcher,\n newFileInfo: INewFileInfo,\n logger: ITelemetryLogger,\n createNewSummary: ISummaryTree,\n epochTracker: EpochTracker,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<ICreateFileResponse> {\n const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : \"\";\n const encodedFilename = encodeURIComponent(newFileInfo.filename);\n const baseUrl =\n `${getApiRoot(getOrigin(newFileInfo.siteUrl))}/drives/${newFileInfo.driveId}/items/root:` +\n `${filePath}/${encodedFilename}`;\n\n const containerSnapshot = convertSummaryIntoContainerSnapshot(createNewSummary);\n const initialUrl = `${baseUrl}:/opStream/snapshots/snapshot${newFileInfo.createLinkType ?\n `?createLinkType=${newFileInfo.createLinkType}` : \"\"}`;\n\n return getWithRetryForTokenRefresh(async (options) => {\n const storageToken = await getStorageToken(options, \"CreateNewFile\");\n\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"createNewFile\" },\n async (event) => {\n const { url, headers } = getUrlAndHeadersWithAuth(\n initialUrl, storageToken, forceAccessTokenViaAuthorizationHeader);\n headers[\"Content-Type\"] = \"application/json\";\n\n const fetchResponse = await runWithRetry(\n async () => epochTracker.fetchAndParseAsJSON<ICreateFileResponse>(\n url,\n {\n body: JSON.stringify(containerSnapshot),\n headers,\n method: \"POST\",\n },\n \"createFile\",\n ),\n \"createFile\",\n logger,\n );\n\n const content = fetchResponse.content;\n if (!content || !content.itemId) {\n throw new NonRetryableError(\n \"createFileNoItemId\",\n \"ODSP CreateFile call returned no item ID\",\n DriverErrorType.incorrectServerResponse);\n }\n event.end({\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n attempts: options.refresh ? 2 : 1,\n ...fetchResponse.commonSpoHeaders,\n });\n return content;\n },\n );\n });\n}\n\nfunction convertSummaryIntoContainerSnapshot(createNewSummary: ISummaryTree) {\n const appSummary = createNewSummary.tree[\".app\"] as ISummaryTree;\n const protocolSummary = createNewSummary.tree[\".protocol\"] as ISummaryTree;\n if (!(appSummary && protocolSummary)) {\n throw new Error(\"App and protocol summary required for create new path!!\");\n }\n const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n const attributesSummaryBlob: ISummaryBlob = {\n type: SummaryType.Blob,\n content: JSON.stringify(documentAttributes),\n };\n protocolSummary.tree.attributes = attributesSummaryBlob;\n const convertedCreateNewSummary: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {\n \".protocol\": protocolSummary,\n \".app\": appSummary,\n },\n };\n const snapshotTree = convertSummaryToSnapshotTreeForCreateNew(convertedCreateNewSummary);\n const snapshot: IOdspSummaryPayload = {\n entries: snapshotTree.entries ?? [],\n message: \"app\",\n sequenceNumber: documentAttributes.sequenceNumber,\n type: \"container\",\n };\n return snapshot;\n}\n\n/**\n * Converts a summary tree to ODSP tree\n */\nexport function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspSummaryTree {\n const snapshotTree: IOdspSummaryTree = {\n type: \"tree\",\n entries: [],\n };\n\n const keys = Object.keys(summary.tree);\n for (const key of keys) {\n const summaryObject = summary.tree[key];\n\n let value: OdspSummaryTreeValue;\n // Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the\n // property is not present, the tree entry is considered referenced. If the property is present and is true,\n // the tree entry is considered unreferenced.\n let unreferenced: true | undefined;\n\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n value = convertSummaryToSnapshotTreeForCreateNew(summaryObject);\n unreferenced = summaryObject.unreferenced;\n break;\n }\n case SummaryType.Blob: {\n const content = typeof summaryObject.content === \"string\" ?\n summaryObject.content : Uint8ArrayToString(summaryObject.content, \"base64\");\n const encoding = typeof summaryObject.content === \"string\" ? \"utf-8\" : \"base64\";\n\n value = {\n type: \"blob\",\n content,\n encoding,\n };\n break;\n }\n case SummaryType.Handle: {\n throw new Error(\"No handle should be present for first summary!!\");\n }\n default: {\n throw new Error(`Unknown tree type ${summaryObject.type}`);\n }\n }\n\n const entry: OdspSummaryTreeEntry = {\n path: encodeURIComponent(key),\n type: getGitType(summaryObject),\n value,\n unreferenced,\n };\n snapshotTree.entries?.push(entry);\n }\n\n return snapshotTree;\n}\n"]}
|
package/dist/epochTracker.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare class EpochTracker implements IPersistedFileCache {
|
|
|
40
40
|
* @param fetchType - method for which fetch is called.
|
|
41
41
|
* @param addInBody - Pass True if caller wants to add epoch in post body.
|
|
42
42
|
*/
|
|
43
|
-
fetchAndParseAsJSON<T>(url: string, fetchOptions: RequestInit, fetchType: FetchType, addInBody?: boolean): Promise<IOdspResponse<T>>;
|
|
43
|
+
fetchAndParseAsJSON<T>(url: string, fetchOptions: RequestInit, fetchType: FetchType, addInBody?: boolean, fetchReason?: string): Promise<IOdspResponse<T>>;
|
|
44
44
|
/**
|
|
45
45
|
* Api to fetch the response as it is for given request.
|
|
46
46
|
* @param url - url of the request
|
|
@@ -50,7 +50,7 @@ export declare class EpochTracker implements IPersistedFileCache {
|
|
|
50
50
|
*/
|
|
51
51
|
fetchArray(url: string, fetchOptions: {
|
|
52
52
|
[index: string]: any;
|
|
53
|
-
}, fetchType: FetchType, addInBody?: boolean): Promise<IOdspResponse<ArrayBuffer>>;
|
|
53
|
+
}, fetchType: FetchType, addInBody?: boolean, fetchReason?: string): Promise<IOdspResponse<ArrayBuffer>>;
|
|
54
54
|
private addEpochInRequest;
|
|
55
55
|
private addParamInBody;
|
|
56
56
|
private formatClientCorrelationId;
|
|
@@ -65,7 +65,7 @@ export declare class EpochTrackerWithRedemption extends EpochTracker {
|
|
|
65
65
|
get(entry: IEntry): Promise<any>;
|
|
66
66
|
fetchAndParseAsJSON<T>(url: string, fetchOptions: {
|
|
67
67
|
[index: string]: any;
|
|
68
|
-
}, fetchType: FetchType, addInBody?: boolean): Promise<IOdspResponse<T>>;
|
|
68
|
+
}, fetchType: FetchType, addInBody?: boolean, fetchReason?: string): Promise<IOdspResponse<T>>;
|
|
69
69
|
}
|
|
70
70
|
export interface ICacheAndTracker {
|
|
71
71
|
cache: IOdspCache;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAmB,WAAW,EAAqB,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAClE,OAAO,EAGH,MAAM,EACN,UAAU,EACV,eAAe,EAElB,MAAM,yCAAyC,CAAC;AAGjD,OAAO,
|
|
1
|
+
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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"}
|
package/dist/epochTracker.js
CHANGED
|
@@ -13,6 +13,7 @@ const driver_definitions_1 = require("@fluidframework/driver-definitions");
|
|
|
13
13
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
14
14
|
const odspUtils_1 = require("./odspUtils");
|
|
15
15
|
const contracts_1 = require("./contracts");
|
|
16
|
+
const contractsPublic_1 = require("./contractsPublic");
|
|
16
17
|
exports.Odsp409Error = "Odsp409Error";
|
|
17
18
|
// Please update the README file in odsp-driver-definitions if you change the defaultCacheExpiryTimeoutMs.
|
|
18
19
|
exports.defaultCacheExpiryTimeoutMs = 2 * 24 * 60 * 60 * 1000;
|
|
@@ -134,8 +135,8 @@ class EpochTracker {
|
|
|
134
135
|
* @param fetchType - method for which fetch is called.
|
|
135
136
|
* @param addInBody - Pass True if caller wants to add epoch in post body.
|
|
136
137
|
*/
|
|
137
|
-
async fetchAndParseAsJSON(url, fetchOptions, fetchType, addInBody = false) {
|
|
138
|
-
const clientCorrelationId = this.formatClientCorrelationId();
|
|
138
|
+
async fetchAndParseAsJSON(url, fetchOptions, fetchType, addInBody = false, fetchReason) {
|
|
139
|
+
const clientCorrelationId = this.formatClientCorrelationId(fetchReason);
|
|
139
140
|
// Add epoch in fetch request.
|
|
140
141
|
this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
|
|
141
142
|
let epochFromResponse;
|
|
@@ -164,8 +165,8 @@ class EpochTracker {
|
|
|
164
165
|
* @param fetchType - method for which fetch is called.
|
|
165
166
|
* @param addInBody - Pass True if caller wants to add epoch in post body.
|
|
166
167
|
*/
|
|
167
|
-
async fetchArray(url, fetchOptions, fetchType, addInBody = false) {
|
|
168
|
-
const clientCorrelationId = this.formatClientCorrelationId();
|
|
168
|
+
async fetchArray(url, fetchOptions, fetchType, addInBody = false, fetchReason) {
|
|
169
|
+
const clientCorrelationId = this.formatClientCorrelationId(fetchReason);
|
|
169
170
|
// Add epoch in fetch request.
|
|
170
171
|
this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
|
|
171
172
|
let epochFromResponse;
|
|
@@ -188,12 +189,16 @@ class EpochTracker {
|
|
|
188
189
|
});
|
|
189
190
|
}
|
|
190
191
|
addEpochInRequest(fetchOptions, addInBody, clientCorrelationId) {
|
|
192
|
+
const isClpCompliantApp = odspUtils_1.getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;
|
|
191
193
|
if (addInBody) {
|
|
192
194
|
const headers = {};
|
|
193
195
|
headers["X-RequestStats"] = clientCorrelationId;
|
|
194
196
|
if (this.fluidEpoch !== undefined) {
|
|
195
197
|
headers["x-fluid-epoch"] = this.fluidEpoch;
|
|
196
198
|
}
|
|
199
|
+
if (isClpCompliantApp) {
|
|
200
|
+
headers[contractsPublic_1.ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();
|
|
201
|
+
}
|
|
197
202
|
this.addParamInBody(fetchOptions, headers);
|
|
198
203
|
}
|
|
199
204
|
else {
|
|
@@ -206,6 +211,9 @@ class EpochTracker {
|
|
|
206
211
|
if (this.fluidEpoch !== undefined) {
|
|
207
212
|
addHeader("x-fluid-epoch", this.fluidEpoch);
|
|
208
213
|
}
|
|
214
|
+
if (isClpCompliantApp) {
|
|
215
|
+
addHeader(contractsPublic_1.ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());
|
|
216
|
+
}
|
|
209
217
|
}
|
|
210
218
|
}
|
|
211
219
|
addParamInBody(fetchOptions, headers) {
|
|
@@ -225,8 +233,12 @@ class EpochTracker {
|
|
|
225
233
|
});
|
|
226
234
|
fetchOptions.body = formParams.join("\r\n");
|
|
227
235
|
}
|
|
228
|
-
formatClientCorrelationId() {
|
|
229
|
-
|
|
236
|
+
formatClientCorrelationId(fetchReason) {
|
|
237
|
+
const items = [`driverId=${this.driverId}`, `RequestNumber=${this.networkCallNumber++}`];
|
|
238
|
+
if (fetchReason !== undefined) {
|
|
239
|
+
items.push(`fetchReason=${fetchReason}`);
|
|
240
|
+
}
|
|
241
|
+
return items.join(", ");
|
|
230
242
|
}
|
|
231
243
|
validateEpochFromResponse(epochFromResponse, fetchType, fromCache = false) {
|
|
232
244
|
const error = this.checkForEpochErrorCore(epochFromResponse);
|
|
@@ -308,12 +320,12 @@ class EpochTrackerWithRedemption extends EpochTracker {
|
|
|
308
320
|
}
|
|
309
321
|
return result;
|
|
310
322
|
}
|
|
311
|
-
async fetchAndParseAsJSON(url, fetchOptions, fetchType, addInBody = false) {
|
|
323
|
+
async fetchAndParseAsJSON(url, fetchOptions, fetchType, addInBody = false, fetchReason) {
|
|
312
324
|
// Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started
|
|
313
325
|
// joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.
|
|
314
326
|
const completed = this.treesLatestDeferral.isCompleted;
|
|
315
327
|
try {
|
|
316
|
-
return await super.fetchAndParseAsJSON(url, fetchOptions, fetchType, addInBody);
|
|
328
|
+
return await super.fetchAndParseAsJSON(url, fetchOptions, fetchType, addInBody, fetchReason);
|
|
317
329
|
}
|
|
318
330
|
catch (error) {
|
|
319
331
|
// Only handling here treesLatest. If createFile failed, we should never try to do joinSession.
|
package/dist/epochTracker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTracker.js","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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","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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ThrottlingError, RateLimiter, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { IConnected } from \"@fluidframework/protocol-definitions\";\nimport {\n snapshotKey,\n ICacheEntry,\n IEntry,\n IFileEntry,\n IPersistedCache,\n IOdspError,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { PerformanceEvent, isFluidError, normalizeError } from \"@fluidframework/telemetry-utils\";\nimport { fetchAndParseAsJSONHelper, fetchArray, IOdspResponse } from \"./odspUtils\";\nimport {\n IOdspCache,\n INonPersistentCache,\n IPersistedFileCache,\n } from \"./odspCache\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\n\nexport type FetchType = \"blob\" | \"createBlob\" | \"createFile\" | \"joinSession\" | \"ops\" | \"test\" | \"snapshotTree\" |\n \"treesLatest\" | \"uploadSummary\" | \"push\" | \"versions\";\n\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n// Please update the README file in odsp-driver-definitions if you change the defaultCacheExpiryTimeoutMs.\nexport const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000;\n\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 private _fluidEpoch: string | undefined;\n\n public readonly rateLimiter: RateLimiter;\n private readonly driverId = uuid();\n // This tracks the request number made by the driver instance.\n private networkCallNumber = 1;\n constructor(\n protected readonly cache: IPersistedCache,\n protected readonly fileEntry: IFileEntry,\n protected readonly logger: ITelemetryLogger,\n ) {\n // Limits the max number of concurrent requests to 24.\n this.rateLimiter = new RateLimiter(24);\n }\n\n // public for UT purposes only!\n public setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {\n assert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n this._fluidEpoch = epoch;\n\n this.logger.sendTelemetryEvent(\n {\n eventName: \"EpochLearnedFirstTime\",\n epoch,\n fetchType,\n fromCache,\n },\n );\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n try {\n // Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n const value: IVersionedValueWithEpoch = await this.cache.get(this.fileEntryFromEntry(entry));\n // Version mismatch between what the runtime expects and what it recieved.\n // The cached value should not be used\n if (value === undefined || value.version !== persistedCacheValueVersion) {\n return undefined;\n }\n assert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n if (this._fluidEpoch === undefined) {\n this.setEpoch(value.fluidEpoch, true, \"cache\");\n // Epoch mismatch, the cached value is considerably different from what the current state of\n // the runtime and should not be used\n } else if (this._fluidEpoch !== value.fluidEpoch) {\n return undefined;\n }\n // Expire the cached snapshot if it's older than the defaultCacheExpiryTimeoutMs and immediately\n // expire all old caches that do not have cacheEntryTime\n if (entry.type === snapshotKey) {\n const cacheTime = value.value?.cacheEntryTime;\n const currentTime = Date.now();\n if (cacheTime === undefined || currentTime - cacheTime >= defaultCacheExpiryTimeoutMs) {\n this.logger.sendTelemetryEvent(\n {\n eventName: \"odspVersionsCacheExpired\",\n duration: currentTime - cacheTime,\n maxCacheAgeMs: defaultCacheExpiryTimeoutMs,\n });\n await this.removeEntries();\n return undefined;\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value.value;\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n return undefined;\n }\n }\n\n public async put(entry: IEntry, value: any) {\n assert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n // For snapshots, the value should have the cacheEntryTime. This will be used to expire snapshots older\n // than the defaultCacheExpiryTimeoutMs.\n if (entry.type === snapshotKey) {\n value.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n }\n const data: IVersionedValueWithEpoch = {\n value,\n version: persistedCacheValueVersion,\n fluidEpoch: this._fluidEpoch,\n };\n return this.cache.put(this.fileEntryFromEntry(entry), data)\n .catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n throw error;\n });\n }\n\n public async removeEntries(): Promise<void> {\n try {\n return await this.cache.removeEntries(this.fileEntry);\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n }\n }\n\n public get fluidEpoch() {\n return this._fluidEpoch;\n }\n\n public async validateEpochFromPush(details: IConnected) {\n const epoch = details.epoch;\n assert(epoch !== undefined, 0x09d /* \"Connection details should contain epoch\" */);\n try {\n this.validateEpochFromResponse(epoch, \"push\");\n } catch (error) {\n await this.checkForEpochError(error, epoch, \"push\");\n throw error;\n }\n }\n\n /**\n * Api to fetch the response for given request and parse it as json.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n */\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: RequestInit,\n fetchType: FetchType,\n addInBody: boolean = false,\n ): Promise<IOdspResponse<T>> {\n const clientCorrelationId = this.formatClientCorrelationId();\n // Add epoch in fetch request.\n this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n let epochFromResponse: string | undefined;\n return this.rateLimiter.schedule(\n async () => fetchAndParseAsJSONHelper<T>(url, fetchOptions),\n ).then((response) => {\n epochFromResponse = response.headers.get(\"x-fluid-epoch\");\n this.validateEpochFromResponse(epochFromResponse, fetchType);\n response.commonSpoHeaders = {\n ...response.commonSpoHeaders,\n \"X-RequestStats\": clientCorrelationId,\n };\n return response;\n }).catch(async (error) => {\n // Get the server epoch from error in case we don't have it as if undefined we won't be able\n // to mark it as epoch error.\n if (epochFromResponse === undefined) {\n epochFromResponse = (error as IOdspError).serverEpoch;\n }\n await this.checkForEpochError(error, epochFromResponse, fetchType);\n throw error;\n }).catch((error) => {\n const fluidError = normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId }});\n throw fluidError;\n });\n }\n\n /**\n * Api to fetch the response as it is for given request.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n */\n public async fetchArray(\n url: string,\n fetchOptions: {[index: string]: any},\n fetchType: FetchType,\n addInBody: boolean = false,\n ) {\n const clientCorrelationId = this.formatClientCorrelationId();\n // Add epoch in fetch request.\n this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n let epochFromResponse: string | undefined;\n return this.rateLimiter.schedule(\n async () => fetchArray(url, fetchOptions),\n ).then((response) => {\n epochFromResponse = response.headers.get(\"x-fluid-epoch\");\n this.validateEpochFromResponse(epochFromResponse, fetchType);\n response.commonSpoHeaders = {\n ...response.commonSpoHeaders,\n \"X-RequestStats\": clientCorrelationId,\n };\n return response;\n }).catch(async (error) => {\n // Get the server epoch from error in case we don't have it as if undefined we won't be able\n // to mark it as epoch error.\n if (epochFromResponse === undefined) {\n epochFromResponse = (error as IOdspError).serverEpoch;\n }\n await this.checkForEpochError(error, epochFromResponse, fetchType);\n throw error;\n }).catch((error) => {\n const fluidError = normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId }});\n throw fluidError;\n });\n }\n\n private addEpochInRequest(\n fetchOptions: RequestInit,\n addInBody: boolean,\n clientCorrelationId: string,\n ) {\n if (addInBody) {\n const headers: {[key: string]: string} = {};\n headers[\"X-RequestStats\"] = clientCorrelationId;\n if (this.fluidEpoch !== undefined) {\n headers[\"x-fluid-epoch\"] = this.fluidEpoch;\n }\n this.addParamInBody(fetchOptions, headers);\n } else {\n const addHeader = (key: string, val: string) => {\n fetchOptions.headers = {\n ...fetchOptions.headers,\n };\n assert(fetchOptions.headers !== undefined, 0x282 /* \"Headers should be present now\" */);\n fetchOptions.headers[key] = val;\n };\n addHeader(\"X-RequestStats\", clientCorrelationId);\n if (this.fluidEpoch !== undefined) {\n addHeader(\"x-fluid-epoch\", this.fluidEpoch);\n }\n }\n }\n\n private addParamInBody(fetchOptions: RequestInit, headers: {[key: string]: string}) {\n // We use multi part form request for post body where we want to use this.\n // So extract the form boundary to mark the end of form.\n const body = fetchOptions.body;\n assert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n const splitBody = body.split(\"\\r\\n\");\n const firstLine = splitBody.shift();\n assert(firstLine !== undefined && firstLine.startsWith(\"--\"), 0x21e /* \"improper boundary format\" */);\n const formParams = [firstLine];\n Object.entries(headers).forEach(([key, value]) => {\n formParams.push(`${key}: ${value}`);\n });\n splitBody.forEach((value: string) => {\n formParams.push(value);\n });\n fetchOptions.body = formParams.join(\"\\r\\n\");\n }\n\n private formatClientCorrelationId() {\n return `driverId=${this.driverId}, RequestNumber=${this.networkCallNumber++}`;\n }\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n const error = this.checkForEpochErrorCore(epochFromResponse);\n if (error !== undefined) {\n throw error;\n }\n if (epochFromResponse !== undefined) {\n if (this._fluidEpoch === undefined) {\n this.setEpoch(epochFromResponse, fromCache, fetchType);\n }\n }\n }\n\n private async checkForEpochError(\n error: unknown,\n epochFromResponse: string | null | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n if (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {\n const epochError = this.checkForEpochErrorCore(epochFromResponse);\n if (epochError !== undefined) {\n assert(isFluidError(epochError),\n 0x21f /* \"epochError expected to be thrown by throwOdspNetworkError and of known type\" */);\n epochError.addTelemetryProperties({\n fromCache,\n clientEpoch: this.fluidEpoch,\n fetchType,\n });\n this.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n // If the epoch mismatches, then clear all entries for such file entry from cache.\n await this.removeEntries();\n throw epochError;\n }\n // If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n // then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n // time is 1s.\n throw new ThrottlingError(\"coherency409\", error.message, 1, { [Odsp409Error]: true });\n }\n }\n\n private checkForEpochErrorCore(epochFromResponse: string | null | undefined) {\n // If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n // initializes this value. Sometimes response does not contain epoch as it is still in\n // implementation phase at server side. In that case also, don't compare it with our epoch value.\n if (this.fluidEpoch && epochFromResponse && (this.fluidEpoch !== epochFromResponse)) {\n // This is similar in nature to how fluidEpochMismatchError (409) is handled.\n // Difference - client detected mismatch, instead of server detecting it.\n return new NonRetryableError(\"epochMismatch\", \"Epoch mismatch\", DriverErrorType.fileOverwrittenInStorage);\n }\n }\n\n private fileEntryFromEntry(entry: IEntry): ICacheEntry {\n return { ...entry, file: this.fileEntry };\n }\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n private readonly treesLatestDeferral = new Deferred<void>();\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchType,\n fromCache: boolean = false,\n ) {\n super.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n // Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n // That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n // exploring a file.\n this.treesLatestDeferral.resolve();\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n let result = super.get(entry);\n\n // equivalence of what happens in fetchAndParseAsJSON()\n if (entry.type === snapshotKey) {\n result = result\n .then((value) => {\n // If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n // Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n if (value !== undefined) {\n this.treesLatestDeferral.resolve();\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value;\n })\n .catch((error) => {\n this.treesLatestDeferral.reject(error);\n throw error;\n });\n }\n return result;\n }\n\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: {[index: string]: any},\n fetchType: FetchType,\n addInBody: boolean = false,\n ): Promise<IOdspResponse<T>> {\n // Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n // joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n const completed = this.treesLatestDeferral.isCompleted;\n\n try {\n return await super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n } catch (error) {\n // Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n // Similar, if getVersions failed, we should not do any further storage calls.\n // So treesLatest is the only call that can have parallel joinSession request.\n if (fetchType === \"treesLatest\") {\n this.treesLatestDeferral.reject(error);\n }\n if (fetchType !== \"joinSession\" || error.statusCode < 401 || error.statusCode > 404 || completed) {\n throw error;\n }\n }\n\n // It is joinSession failing with 401..404 error\n // Repeat after waiting for treeLatest succeeding (or fail if it failed).\n // No special handling after first call - if file has been deleted, then it's game over.\n\n // Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n // If we waited too long, we will log error event and proceed with call.\n // It may result in failure for user, but refreshing document would address it.\n // Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n // to unblock the process.\n await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"JoinSessionSyncWait\" },\n async (event) => {\n const timeoutRes = 51; // anything will work here\n let timer: ReturnType<typeof setTimeout>;\n const timeoutP = new Promise<number>((resolve) => {\n timer = setTimeout(() => { resolve(timeoutRes); }, 15000);\n });\n const res = await Promise.race([\n timeoutP,\n // cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n this.treesLatestDeferral.promise.finally(() => clearTimeout(timer))]);\n if (res === timeoutRes) {\n event.cancel();\n }\n },\n { start: true, end: true, cancel: \"generic\" });\n return super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n }\n}\n\nexport interface ICacheAndTracker {\n cache: IOdspCache;\n epochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n persistedCacheArg: IPersistedCache,\n nonpersistentCache: INonPersistentCache,\n fileEntry: IFileEntry,\n logger: ITelemetryLogger): ICacheAndTracker\n{\n const epochTracker = new EpochTrackerWithRedemption(persistedCacheArg, fileEntry, logger);\n return {\n cache: {\n ...nonpersistentCache,\n persistedCache: epochTracker,\n },\n epochTracker,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"epochTracker.js","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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","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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ThrottlingError, RateLimiter, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { IConnected } from \"@fluidframework/protocol-definitions\";\nimport {\n snapshotKey,\n ICacheEntry,\n IEntry,\n IFileEntry,\n IPersistedCache,\n IOdspError,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { PerformanceEvent, isFluidError, normalizeError } from \"@fluidframework/telemetry-utils\";\nimport { fetchAndParseAsJSONHelper, fetchArray, getOdspResolvedUrl, IOdspResponse } from \"./odspUtils\";\nimport {\n IOdspCache,\n INonPersistentCache,\n IPersistedFileCache,\n } from \"./odspCache\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic\";\n\nexport type FetchType = \"blob\" | \"createBlob\" | \"createFile\" | \"joinSession\" | \"ops\" | \"test\" | \"snapshotTree\" |\n \"treesLatest\" | \"uploadSummary\" | \"push\" | \"versions\";\n\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n// Please update the README file in odsp-driver-definitions if you change the defaultCacheExpiryTimeoutMs.\nexport const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000;\n\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 private _fluidEpoch: string | undefined;\n\n public readonly rateLimiter: RateLimiter;\n private readonly driverId = uuid();\n // This tracks the request number made by the driver instance.\n private networkCallNumber = 1;\n constructor(\n protected readonly cache: IPersistedCache,\n protected readonly fileEntry: IFileEntry,\n protected readonly logger: ITelemetryLogger,\n ) {\n // Limits the max number of concurrent requests to 24.\n this.rateLimiter = new RateLimiter(24);\n }\n\n // public for UT purposes only!\n public setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {\n assert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n this._fluidEpoch = epoch;\n\n this.logger.sendTelemetryEvent(\n {\n eventName: \"EpochLearnedFirstTime\",\n epoch,\n fetchType,\n fromCache,\n },\n );\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n try {\n // Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n const value: IVersionedValueWithEpoch = await this.cache.get(this.fileEntryFromEntry(entry));\n // Version mismatch between what the runtime expects and what it recieved.\n // The cached value should not be used\n if (value === undefined || value.version !== persistedCacheValueVersion) {\n return undefined;\n }\n assert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n if (this._fluidEpoch === undefined) {\n this.setEpoch(value.fluidEpoch, true, \"cache\");\n // Epoch mismatch, the cached value is considerably different from what the current state of\n // the runtime and should not be used\n } else if (this._fluidEpoch !== value.fluidEpoch) {\n return undefined;\n }\n // Expire the cached snapshot if it's older than the defaultCacheExpiryTimeoutMs and immediately\n // expire all old caches that do not have cacheEntryTime\n if (entry.type === snapshotKey) {\n const cacheTime = value.value?.cacheEntryTime;\n const currentTime = Date.now();\n if (cacheTime === undefined || currentTime - cacheTime >= defaultCacheExpiryTimeoutMs) {\n this.logger.sendTelemetryEvent(\n {\n eventName: \"odspVersionsCacheExpired\",\n duration: currentTime - cacheTime,\n maxCacheAgeMs: defaultCacheExpiryTimeoutMs,\n });\n await this.removeEntries();\n return undefined;\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value.value;\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n return undefined;\n }\n }\n\n public async put(entry: IEntry, value: any) {\n assert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n // For snapshots, the value should have the cacheEntryTime. This will be used to expire snapshots older\n // than the defaultCacheExpiryTimeoutMs.\n if (entry.type === snapshotKey) {\n value.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n }\n const data: IVersionedValueWithEpoch = {\n value,\n version: persistedCacheValueVersion,\n fluidEpoch: this._fluidEpoch,\n };\n return this.cache.put(this.fileEntryFromEntry(entry), data)\n .catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n throw error;\n });\n }\n\n public async removeEntries(): Promise<void> {\n try {\n return await this.cache.removeEntries(this.fileEntry);\n } catch (error) {\n this.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n }\n }\n\n public get fluidEpoch() {\n return this._fluidEpoch;\n }\n\n public async validateEpochFromPush(details: IConnected) {\n const epoch = details.epoch;\n assert(epoch !== undefined, 0x09d /* \"Connection details should contain epoch\" */);\n try {\n this.validateEpochFromResponse(epoch, \"push\");\n } catch (error) {\n await this.checkForEpochError(error, epoch, \"push\");\n throw error;\n }\n }\n\n /**\n * Api to fetch the response for given request and parse it as json.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n */\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: RequestInit,\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ): Promise<IOdspResponse<T>> {\n const clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n // Add epoch in fetch request.\n this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n let epochFromResponse: string | undefined;\n return this.rateLimiter.schedule(\n async () => fetchAndParseAsJSONHelper<T>(url, fetchOptions),\n ).then((response) => {\n epochFromResponse = response.headers.get(\"x-fluid-epoch\");\n this.validateEpochFromResponse(epochFromResponse, fetchType);\n response.commonSpoHeaders = {\n ...response.commonSpoHeaders,\n \"X-RequestStats\": clientCorrelationId,\n };\n return response;\n }).catch(async (error) => {\n // Get the server epoch from error in case we don't have it as if undefined we won't be able\n // to mark it as epoch error.\n if (epochFromResponse === undefined) {\n epochFromResponse = (error as IOdspError).serverEpoch;\n }\n await this.checkForEpochError(error, epochFromResponse, fetchType);\n throw error;\n }).catch((error) => {\n const fluidError = normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId }});\n throw fluidError;\n });\n }\n\n /**\n * Api to fetch the response as it is for given request.\n * @param url - url of the request\n * @param fetchOptions - fetch options for request containing body, headers etc.\n * @param fetchType - method for which fetch is called.\n * @param addInBody - Pass True if caller wants to add epoch in post body.\n */\n public async fetchArray(\n url: string,\n fetchOptions: {[index: string]: any},\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ) {\n const clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n // Add epoch in fetch request.\n this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n let epochFromResponse: string | undefined;\n return this.rateLimiter.schedule(\n async () => fetchArray(url, fetchOptions),\n ).then((response) => {\n epochFromResponse = response.headers.get(\"x-fluid-epoch\");\n this.validateEpochFromResponse(epochFromResponse, fetchType);\n response.commonSpoHeaders = {\n ...response.commonSpoHeaders,\n \"X-RequestStats\": clientCorrelationId,\n };\n return response;\n }).catch(async (error) => {\n // Get the server epoch from error in case we don't have it as if undefined we won't be able\n // to mark it as epoch error.\n if (epochFromResponse === undefined) {\n epochFromResponse = (error as IOdspError).serverEpoch;\n }\n await this.checkForEpochError(error, epochFromResponse, fetchType);\n throw error;\n }).catch((error) => {\n const fluidError = normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId }});\n throw fluidError;\n });\n }\n\n private addEpochInRequest(\n fetchOptions: RequestInit,\n addInBody: boolean,\n clientCorrelationId: string,\n ) {\n const isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;\n if (addInBody) {\n const headers: {[key: string]: string} = {};\n headers[\"X-RequestStats\"] = clientCorrelationId;\n if (this.fluidEpoch !== undefined) {\n headers[\"x-fluid-epoch\"] = this.fluidEpoch;\n }\n if (isClpCompliantApp) {\n headers[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();\n }\n this.addParamInBody(fetchOptions, headers);\n } else {\n const addHeader = (key: string, val: string) => {\n fetchOptions.headers = {\n ...fetchOptions.headers,\n };\n assert(fetchOptions.headers !== undefined, 0x282 /* \"Headers should be present now\" */);\n fetchOptions.headers[key] = val;\n };\n addHeader(\"X-RequestStats\", clientCorrelationId);\n if (this.fluidEpoch !== undefined) {\n addHeader(\"x-fluid-epoch\", this.fluidEpoch);\n }\n if (isClpCompliantApp) {\n addHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());\n }\n }\n }\n\n private addParamInBody(fetchOptions: RequestInit, headers: {[key: string]: string}) {\n // We use multi part form request for post body where we want to use this.\n // So extract the form boundary to mark the end of form.\n const body = fetchOptions.body;\n assert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n const splitBody = body.split(\"\\r\\n\");\n const firstLine = splitBody.shift();\n assert(firstLine !== undefined && firstLine.startsWith(\"--\"), 0x21e /* \"improper boundary format\" */);\n const formParams = [firstLine];\n Object.entries(headers).forEach(([key, value]) => {\n formParams.push(`${key}: ${value}`);\n });\n splitBody.forEach((value: string) => {\n formParams.push(value);\n });\n fetchOptions.body = formParams.join(\"\\r\\n\");\n }\n\n private formatClientCorrelationId(fetchReason?: string) {\n const items: string[] = [`driverId=${this.driverId}`, `RequestNumber=${this.networkCallNumber++}`];\n if (fetchReason !== undefined) {\n items.push(`fetchReason=${fetchReason}`);\n }\n return items.join(\", \");\n }\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n const error = this.checkForEpochErrorCore(epochFromResponse);\n if (error !== undefined) {\n throw error;\n }\n if (epochFromResponse !== undefined) {\n if (this._fluidEpoch === undefined) {\n this.setEpoch(epochFromResponse, fromCache, fetchType);\n }\n }\n }\n\n private async checkForEpochError(\n error: unknown,\n epochFromResponse: string | null | undefined,\n fetchType: FetchTypeInternal,\n fromCache: boolean = false,\n ) {\n if (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {\n const epochError = this.checkForEpochErrorCore(epochFromResponse);\n if (epochError !== undefined) {\n assert(isFluidError(epochError),\n 0x21f /* \"epochError expected to be thrown by throwOdspNetworkError and of known type\" */);\n epochError.addTelemetryProperties({\n fromCache,\n clientEpoch: this.fluidEpoch,\n fetchType,\n });\n this.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n // If the epoch mismatches, then clear all entries for such file entry from cache.\n await this.removeEntries();\n throw epochError;\n }\n // If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n // then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n // time is 1s.\n throw new ThrottlingError(\"coherency409\", error.message, 1, { [Odsp409Error]: true });\n }\n }\n\n private checkForEpochErrorCore(epochFromResponse: string | null | undefined) {\n // If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n // initializes this value. Sometimes response does not contain epoch as it is still in\n // implementation phase at server side. In that case also, don't compare it with our epoch value.\n if (this.fluidEpoch && epochFromResponse && (this.fluidEpoch !== epochFromResponse)) {\n // This is similar in nature to how fluidEpochMismatchError (409) is handled.\n // Difference - client detected mismatch, instead of server detecting it.\n return new NonRetryableError(\"epochMismatch\", \"Epoch mismatch\", DriverErrorType.fileOverwrittenInStorage);\n }\n }\n\n private fileEntryFromEntry(entry: IEntry): ICacheEntry {\n return { ...entry, file: this.fileEntry };\n }\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n private readonly treesLatestDeferral = new Deferred<void>();\n\n protected validateEpochFromResponse(\n epochFromResponse: string | undefined,\n fetchType: FetchType,\n fromCache: boolean = false,\n ) {\n super.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n // Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n // That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n // exploring a file.\n this.treesLatestDeferral.resolve();\n }\n\n public async get(\n entry: IEntry,\n ): Promise<any> {\n let result = super.get(entry);\n\n // equivalence of what happens in fetchAndParseAsJSON()\n if (entry.type === snapshotKey) {\n result = result\n .then((value) => {\n // If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n // Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n if (value !== undefined) {\n this.treesLatestDeferral.resolve();\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return value;\n })\n .catch((error) => {\n this.treesLatestDeferral.reject(error);\n throw error;\n });\n }\n return result;\n }\n\n public async fetchAndParseAsJSON<T>(\n url: string,\n fetchOptions: {[index: string]: any},\n fetchType: FetchType,\n addInBody: boolean = false,\n fetchReason?: string,\n ): Promise<IOdspResponse<T>> {\n // Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n // joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n const completed = this.treesLatestDeferral.isCompleted;\n\n try {\n return await super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody, fetchReason);\n } catch (error) {\n // Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n // Similar, if getVersions failed, we should not do any further storage calls.\n // So treesLatest is the only call that can have parallel joinSession request.\n if (fetchType === \"treesLatest\") {\n this.treesLatestDeferral.reject(error);\n }\n if (fetchType !== \"joinSession\" || error.statusCode < 401 || error.statusCode > 404 || completed) {\n throw error;\n }\n }\n\n // It is joinSession failing with 401..404 error\n // Repeat after waiting for treeLatest succeeding (or fail if it failed).\n // No special handling after first call - if file has been deleted, then it's game over.\n\n // Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n // If we waited too long, we will log error event and proceed with call.\n // It may result in failure for user, but refreshing document would address it.\n // Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n // to unblock the process.\n await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"JoinSessionSyncWait\" },\n async (event) => {\n const timeoutRes = 51; // anything will work here\n let timer: ReturnType<typeof setTimeout>;\n const timeoutP = new Promise<number>((resolve) => {\n timer = setTimeout(() => { resolve(timeoutRes); }, 15000);\n });\n const res = await Promise.race([\n timeoutP,\n // cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n this.treesLatestDeferral.promise.finally(() => clearTimeout(timer))]);\n if (res === timeoutRes) {\n event.cancel();\n }\n },\n { start: true, end: true, cancel: \"generic\" });\n return super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n }\n}\n\nexport interface ICacheAndTracker {\n cache: IOdspCache;\n epochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n persistedCacheArg: IPersistedCache,\n nonpersistentCache: INonPersistentCache,\n fileEntry: IFileEntry,\n logger: ITelemetryLogger): ICacheAndTracker\n{\n const epochTracker = new EpochTrackerWithRedemption(persistedCacheArg, fileEntry, logger);\n return {\n cache: {\n ...nonpersistentCache,\n persistedCache: epochTracker,\n },\n epochTracker,\n };\n}\n"]}
|
package/dist/fetchSnapshot.d.ts
CHANGED
|
@@ -15,12 +15,13 @@ import { EpochTracker } from "./epochTracker";
|
|
|
15
15
|
* @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot
|
|
16
16
|
* @param versionId - id of specific snapshot to be fetched
|
|
17
17
|
* @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)
|
|
18
|
+
* @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header
|
|
18
19
|
* @returns A promise of the snapshot and the status code of the response
|
|
19
20
|
*/
|
|
20
|
-
export declare function fetchSnapshot(snapshotUrl: string, token: string | null, versionId: string, fetchFullSnapshot: boolean, logger: ITelemetryLogger, snapshotDownloader: (url: string, fetchOptions: {
|
|
21
|
+
export declare function fetchSnapshot(snapshotUrl: string, token: string | null, versionId: string, fetchFullSnapshot: boolean, forceAccessTokenViaAuthorizationHeader: boolean, logger: ITelemetryLogger, snapshotDownloader: (url: string, fetchOptions: {
|
|
21
22
|
[index: string]: any;
|
|
22
23
|
}) => Promise<IOdspResponse<unknown>>): Promise<ISnapshotContents>;
|
|
23
|
-
export declare function fetchSnapshotWithRedeem(odspResolvedUrl: IOdspResolvedUrl, storageTokenFetcher: InstrumentedStorageTokenFetcher, snapshotOptions: ISnapshotOptions | undefined, logger: ITelemetryLogger, snapshotDownloader: (finalOdspResolvedUrl: IOdspResolvedUrl, storageToken: string, snapshotOptions: ISnapshotOptions | undefined, controller?: AbortController) => Promise<ISnapshotRequestAndResponseOptions>, putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>, removeEntries: () => Promise<void>, enableRedeemFallback?: boolean): Promise<ISnapshotContents>;
|
|
24
|
+
export declare function fetchSnapshotWithRedeem(odspResolvedUrl: IOdspResolvedUrl, storageTokenFetcher: InstrumentedStorageTokenFetcher, snapshotOptions: ISnapshotOptions | undefined, forceAccessTokenViaAuthorizationHeader: boolean, logger: ITelemetryLogger, snapshotDownloader: (finalOdspResolvedUrl: IOdspResolvedUrl, storageToken: string, snapshotOptions: ISnapshotOptions | undefined, controller?: AbortController) => Promise<ISnapshotRequestAndResponseOptions>, putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>, removeEntries: () => Promise<void>, enableRedeemFallback?: boolean): Promise<ISnapshotContents>;
|
|
24
25
|
interface ISnapshotRequestAndResponseOptions {
|
|
25
26
|
odspSnapshotResponse: IOdspResponse<ISnapshotContents>;
|
|
26
27
|
requestUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAItE,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAEhB,+BAA+B,EAClC,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EAAuC,wBAAwB,EAA8B,MAAM,aAAa,CAAC;AAGxH,OAAO,EAKH,aAAa,EACb,iBAAiB,EACpB,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C
|
|
1
|
+
{"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAItE,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAEhB,+BAA+B,EAClC,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EAAuC,wBAAwB,EAA8B,MAAM,aAAa,CAAC;AAGxH,OAAO,EAKH,aAAa,EACb,iBAAiB,EACpB,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAC/B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,gBAAgB,EACxB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE;IAAC,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAC3G,OAAO,CAAC,iBAAiB,CAAC,CAwB5B;AAED,wBAAsB,uBAAuB,CACzC,eAAe,EAAE,gBAAgB,EACjC,mBAAmB,EAAE,+BAA+B,EACpD,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,gBAAgB,EACxB,kBAAkB,EAAE,CACZ,oBAAoB,EAAE,gBAAgB,EACtC,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,UAAU,CAAC,EAAE,eAAe,KAC3B,OAAO,CAAC,kCAAkC,CAAC,EACpD,UAAU,EAAE,CAAC,cAAc,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,EACvE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAClC,oBAAoB,CAAC,EAAE,OAAO,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAqD5B;AA+LD,UAAU,kCAAkC;IACxC,oBAAoB,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QAAC,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC,CAAC;CAC1C;AAkID,wBAAsB,gBAAgB,CAClC,eAAe,EAAE,gBAAgB,EACjC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,yBAAyB,CAAC,EAAE,OAAO,EACnC,UAAU,CAAC,EAAE,eAAe,EAC5B,YAAY,CAAC,EAAE,YAAY,GAC5B,OAAO,CAAC,kCAAkC,CAAC,CAc7C"}
|