@fluidframework/odsp-driver 2.1.0-276326 → 2.1.0-281041
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/README.md +3 -1
- package/api-extractor/{api-extractor-lint-beta.cjs.json → api-extractor.current.json} +2 -2
- package/api-extractor/api-extractor.legacy.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/odsp-driver.legacy.public.api.md +9 -0
- package/dist/ReadBufferUtils.d.ts.map +1 -1
- package/dist/ReadBufferUtils.js +1 -0
- package/dist/ReadBufferUtils.js.map +1 -1
- package/dist/WriteBufferUtils.d.ts.map +1 -1
- package/dist/WriteBufferUtils.js +2 -0
- package/dist/WriteBufferUtils.js.map +1 -1
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +28 -5
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +3 -1
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +1 -1
- package/dist/createFile.js.map +1 -1
- package/dist/createNewContainerOnExistingFile.d.ts.map +1 -1
- package/dist/createNewContainerOnExistingFile.js +2 -1
- package/dist/createNewContainerOnExistingFile.js.map +1 -1
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +4 -1
- package/dist/createNewUtils.js.map +1 -1
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +3 -3
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +1 -1
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +8 -3
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/legacy.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.js +1 -0
- package/dist/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.js +2 -0
- package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +4 -1
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +2 -0
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +1 -0
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +4 -3
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js +2 -0
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts +8 -0
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +4 -2
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js +7 -3
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +3 -1
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUrlHelper.d.ts.map +1 -1
- package/dist/odspUrlHelper.js +5 -1
- package/dist/odspUrlHelper.js.map +1 -1
- package/dist/odspUtils.d.ts +3 -2
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +7 -3
- package/dist/odspUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +2 -2
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/public.d.ts +1 -1
- package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/dist/zipItDataRepresentationUtils.js +9 -0
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/internal.d.ts +1 -1
- package/legacy.d.ts +1 -1
- package/lib/ReadBufferUtils.d.ts.map +1 -1
- package/lib/ReadBufferUtils.js +1 -0
- package/lib/ReadBufferUtils.js.map +1 -1
- package/lib/WriteBufferUtils.d.ts.map +1 -1
- package/lib/WriteBufferUtils.js +2 -0
- package/lib/WriteBufferUtils.js.map +1 -1
- package/lib/compactSnapshotParser.d.ts.map +1 -1
- package/lib/compactSnapshotParser.js +28 -5
- package/lib/compactSnapshotParser.js.map +1 -1
- package/lib/compactSnapshotWriter.d.ts.map +1 -1
- package/lib/compactSnapshotWriter.js +3 -1
- package/lib/compactSnapshotWriter.js.map +1 -1
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +3 -3
- package/lib/createFile.js.map +1 -1
- package/lib/createNewContainerOnExistingFile.d.ts.map +1 -1
- package/lib/createNewContainerOnExistingFile.js +3 -2
- package/lib/createNewContainerOnExistingFile.js.map +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +5 -2
- package/lib/createNewUtils.js.map +1 -1
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +4 -4
- package/lib/epochTracker.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +1 -1
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +8 -3
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.js +1 -0
- package/lib/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.js +2 -0
- package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +4 -1
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js +2 -0
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +1 -0
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +5 -4
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/lib/odspDocumentStorageServiceBase.js +2 -0
- package/lib/odspDocumentStorageServiceBase.js.map +1 -1
- package/lib/odspDriverUrlResolver.d.ts +8 -0
- package/lib/odspDriverUrlResolver.d.ts.map +1 -1
- package/lib/odspDriverUrlResolver.js +3 -2
- package/lib/odspDriverUrlResolver.js.map +1 -1
- package/lib/odspSnapshotParser.d.ts.map +1 -1
- package/lib/odspSnapshotParser.js +7 -3
- package/lib/odspSnapshotParser.js.map +1 -1
- package/lib/odspSummaryUploadManager.d.ts.map +1 -1
- package/lib/odspSummaryUploadManager.js +3 -1
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/odspUrlHelper.d.ts.map +1 -1
- package/lib/odspUrlHelper.js +5 -1
- package/lib/odspUrlHelper.js.map +1 -1
- package/lib/odspUtils.d.ts +3 -2
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +6 -3
- package/lib/odspUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +3 -3
- package/lib/prefetchLatestSnapshot.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/lib/zipItDataRepresentationUtils.js +9 -0
- package/lib/zipItDataRepresentationUtils.js.map +1 -1
- package/package.json +25 -35
- package/src/ReadBufferUtils.ts +2 -1
- package/src/WriteBufferUtils.ts +4 -2
- package/src/compactSnapshotParser.ts +41 -17
- package/src/compactSnapshotWriter.ts +4 -2
- package/src/createFile.ts +9 -1
- package/src/createNewContainerOnExistingFile.ts +16 -3
- package/src/createNewUtils.ts +7 -4
- package/src/epochTracker.ts +4 -3
- package/src/fetchSnapshot.ts +10 -3
- package/src/localOdspDriver/localOdspDeltaStorageService.ts +2 -1
- package/src/odspDelayLoadedDeltaStream.ts +4 -2
- package/src/odspDeltaStorageService.ts +4 -2
- package/src/odspDocumentDeltaConnection.ts +4 -2
- package/src/odspDocumentStorageManager.ts +18 -3
- package/src/odspDocumentStorageServiceBase.ts +4 -2
- package/src/odspDriverUrlResolver.ts +3 -2
- package/src/odspSnapshotParser.ts +10 -6
- package/src/odspSummaryUploadManager.ts +4 -2
- package/src/odspUrlHelper.ts +8 -4
- package/src/odspUtils.ts +13 -2
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +3 -4
- package/src/zipItDataRepresentationUtils.ts +18 -9
- package/tsconfig.json +0 -1
- package/api-extractor/api-extractor-lint-beta.esm.json +0 -5
- package/beta.d.ts +0 -11
- package/dist/beta.d.ts +0 -12
- package/lib/beta.d.ts +0 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewContainerOnExistingFile.d.ts","sourceRoot":"","sources":["../src/createNewContainerOnExistingFile.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAGlE,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,+BAA+B,EAC/B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"createNewContainerOnExistingFile.d.ts","sourceRoot":"","sources":["../src/createNewContainerOnExistingFile.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAGlE,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,+BAA+B,EAC/B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EACN,mBAAmB,EAEnB,MAAM,0CAA0C,CAAC;AAUlD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EACN,iBAAiB,EAGjB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;GAUG;AACH,wBAAsB,gCAAgC,CACrD,aAAa,EAAE,+BAA+B,EAC9C,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,mBAAmB,EAC3B,gBAAgB,EAAE,YAAY,GAAG,SAAS,EAC1C,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,UAAU,EACrB,gBAAgB,EAAE,OAAO,EACzB,sCAAsC,EAAE,OAAO,EAC/C,iBAAiB,CAAC,EAAE,OAAO,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAkD3B"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.createNewContainerOnExistingFile = void 0;
|
|
8
8
|
const internal_1 = require("@fluidframework/driver-utils/internal");
|
|
9
|
+
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
9
10
|
const contractsPublic_js_1 = require("./contractsPublic.js");
|
|
10
11
|
const createNewUtils_js_1 = require("./createNewUtils.js");
|
|
11
12
|
const createOdspUrl_js_1 = require("./createOdspUrl.js");
|
|
@@ -52,7 +53,7 @@ async function createNewContainerOnExistingFile(getAuthHeader, fileInfo, logger,
|
|
|
52
53
|
// converting summary and getting sequence number
|
|
53
54
|
const snapshot = (0, createNewUtils_js_1.convertCreateNewSummaryTreeToTreeAndBlobs)(createNewSummary, summaryHandle);
|
|
54
55
|
// caching the converted summary
|
|
55
|
-
await epochTracker.put((0, odspUtils_js_1.createCacheSnapshotKey)(odspResolvedUrl), snapshot);
|
|
56
|
+
await epochTracker.put((0, odspUtils_js_1.createCacheSnapshotKey)(odspResolvedUrl, (0, odspUtils_js_1.snapshotWithLoadingGroupIdSupported)((0, internal_2.loggerToMonitoringContext)(logger).config)), snapshot);
|
|
56
57
|
}
|
|
57
58
|
return odspResolvedUrl;
|
|
58
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewContainerOnExistingFile.js","sourceRoot":"","sources":["../src/createNewContainerOnExistingFile.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,oEAAmE;
|
|
1
|
+
{"version":3,"file":"createNewContainerOnExistingFile.js","sourceRoot":"","sources":["../src/createNewContainerOnExistingFile.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,oEAAmE;AAMnE,uEAGkD;AAGlD,6DAA6D;AAC7D,2DAI6B;AAC7B,yDAAmD;AAEnD,yEAAmE;AACnE,yDAAgD;AAChD,iDAIwB;AAExB;;;;;;;;;;GAUG;AACI,KAAK,UAAU,gCAAgC,CACrD,aAA8C,EAC9C,QAA2B,EAC3B,MAA2B,EAC3B,gBAA0C,EAC1C,YAA0B,EAC1B,SAAqB,EACrB,gBAAyB,EACzB,sCAA+C,EAC/C,iBAA2B;IAE3B,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,qBAAU,CAAC,uDAAuD,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,IAAA,6BAAU,EAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,WAAW,QAAQ,CAAC,OAAO,UAClF,QAAQ,CAAC,MACV,EAAE,CAAC;IAEH,MAAM,iBAAiB,GAAG,IAAA,uDAAmC,EAAC,gBAAgB,CAAC,CAAC;IAEhF,MAAM,UAAU,GAAG,GAAG,OAAO,8BAA8B,CAAC;IAE5D,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,MAAM,IAAA,+CAA2B,EAAwB;QACtF,iBAAiB;QACjB,aAAa;QACb,MAAM;QACN,UAAU;QACV,sCAAsC;QACtC,YAAY;QACZ,aAAa,EAAE,kCAAkC;QACjD,SAAS,EAAE,eAAe;KAC1B,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAA,gCAAa,EAAC,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,IAAI,gDAAqB,EAAE,CAAC;IAC7C,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC;QAC9C,GAAG,EAAE,OAAO;QACZ,OAAO,EAAE,EAAE,CAAC,0CAAqB,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE;KACzE,CAAC,CAAC;IACH,SAAS,CAAC,KAAK,GAAG,eAAe,CAAC,gBAAgB,CAAC;IACnD,SAAS,CAAC,WAAW,GAAG,eAAe,CAAC;IAExC,IAAI,gBAAgB,EAAE,CAAC;QACtB,iDAAiD;QACjD,MAAM,QAAQ,GAAc,IAAA,6DAAyC,EACpE,gBAAgB,EAChB,aAAa,CACb,CAAC;QACF,gCAAgC;QAChC,MAAM,YAAY,CAAC,GAAG,CACrB,IAAA,qCAAsB,EACrB,eAAe,EACf,IAAA,kDAAmC,EAAC,IAAA,oCAAyB,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAC7E,EACD,QAAQ,CACR,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAC;AACxB,CAAC;AA5DD,4EA4DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport { ISnapshot } from \"@fluidframework/driver-definitions/internal\";\nimport { UsageError } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tIFileEntry,\n\tIOdspResolvedUrl,\n\tInstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tloggerToMonitoringContext,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { IWriteSummaryResponse } from \"./contracts.js\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic.js\";\nimport {\n\tconvertCreateNewSummaryTreeToTreeAndBlobs,\n\tconvertSummaryIntoContainerSnapshot,\n\tcreateNewFluidContainerCore,\n} from \"./createNewUtils.js\";\nimport { createOdspUrl } from \"./createOdspUrl.js\";\nimport { EpochTracker } from \"./epochTracker.js\";\nimport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver.js\";\nimport { getApiRoot } from \"./odspUrlHelper.js\";\nimport {\n\tIExistingFileInfo,\n\tcreateCacheSnapshotKey,\n\tsnapshotWithLoadingGroupIdSupported,\n} from \"./odspUtils.js\";\n\n/**\n * Creates a new Fluid container on an existing file.\n *\n * @remarks This requires service's capability to manage Fluid container inside an existing file.\n *\n * @example\n *\n * This enables a scenario where Fluid data is not stored as a standalone file but in a way that is managed\n * by an existing file. For example, SharePoint Pages is able to store Fluid container in an\n * \"alternative file partition\" where the main File stub is an ASPX page.\n */\nexport async function createNewContainerOnExistingFile(\n\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\tfileInfo: IExistingFileInfo,\n\tlogger: ITelemetryLoggerExt,\n\tcreateNewSummary: ISummaryTree | undefined,\n\tepochTracker: EpochTracker,\n\tfileEntry: IFileEntry,\n\tcreateNewCaching: boolean,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tisClpCompliantApp?: boolean,\n): Promise<IOdspResolvedUrl> {\n\tif (createNewSummary === undefined) {\n\t\tthrow new UsageError(\"createNewSummary must exist to create a new container\");\n\t}\n\n\tconst baseUrl = `${getApiRoot(new URL(fileInfo.siteUrl))}/drives/${fileInfo.driveId}/items/${\n\t\tfileInfo.itemId\n\t}`;\n\n\tconst containerSnapshot = convertSummaryIntoContainerSnapshot(createNewSummary);\n\n\tconst initialUrl = `${baseUrl}/opStream/snapshots/snapshot`;\n\n\tconst { id: summaryHandle } = await createNewFluidContainerCore<IWriteSummaryResponse>({\n\t\tcontainerSnapshot,\n\t\tgetAuthHeader,\n\t\tlogger,\n\t\tinitialUrl,\n\t\tforceAccessTokenViaAuthorizationHeader,\n\t\tepochTracker,\n\t\ttelemetryName: \"CreateNewContainerOnExistingFile\",\n\t\tfetchType: \"uploadSummary\",\n\t});\n\n\tconst odspUrl = createOdspUrl({ ...fileInfo, dataStorePath: \"/\" });\n\tconst resolver = new OdspDriverUrlResolver();\n\tconst odspResolvedUrl = await resolver.resolve({\n\t\turl: odspUrl,\n\t\theaders: { [ClpCompliantAppHeader.isClpCompliantApp]: isClpCompliantApp },\n\t});\n\tfileEntry.docId = odspResolvedUrl.hashedDocumentId;\n\tfileEntry.resolvedUrl = odspResolvedUrl;\n\n\tif (createNewCaching) {\n\t\t// converting summary and getting sequence number\n\t\tconst snapshot: ISnapshot = convertCreateNewSummaryTreeToTreeAndBlobs(\n\t\t\tcreateNewSummary,\n\t\t\tsummaryHandle,\n\t\t);\n\t\t// caching the converted summary\n\t\tawait epochTracker.put(\n\t\t\tcreateCacheSnapshotKey(\n\t\t\t\todspResolvedUrl,\n\t\t\t\tsnapshotWithLoadingGroupIdSupported(loggerToMonitoringContext(logger).config),\n\t\t\t),\n\t\t\tsnapshot,\n\t\t);\n\t}\n\n\treturn odspResolvedUrl;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewUtils.d.ts","sourceRoot":"","sources":["../src/createNewUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAEN,YAAY,EAGZ,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAiB,MAAM,6CAA6C,CAAC;AAMvF,OAAO,EAAE,+BAA+B,EAAE,MAAM,kDAAkD,CAAC;AACnG,OAAO,EACN,mBAAmB,EAEnB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EACN,mBAAmB,EAInB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,yCAAyC,CACxD,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,GACZ,SAAS,CAiBX;
|
|
1
|
+
{"version":3,"file":"createNewUtils.d.ts","sourceRoot":"","sources":["../src/createNewUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAEN,YAAY,EAGZ,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAiB,MAAM,6CAA6C,CAAC;AAMvF,OAAO,EAAE,+BAA+B,EAAE,MAAM,kDAAkD,CAAC;AACnG,OAAO,EACN,mBAAmB,EAEnB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EACN,mBAAmB,EAInB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,yCAAyC,CACxD,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,GACZ,SAAS,CAiBX;AAkDD,wBAAgB,mCAAmC,CAClD,gBAAgB,EAAE,YAAY,GAC5B,mBAAmB,CA2BrB;AAkED,wBAAsB,2BAA2B,CAAC,CAAC,EAAE,IAAI,EAAE;IAC1D,iBAAiB,EAAE,mBAAmB,CAAC;IACvC,aAAa,EAAE,+BAA+B,CAAC;IAC/C,MAAM,EAAE,mBAAmB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC,EAAE,OAAO,CAAC;IAChD,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;CAChD,GAAG,OAAO,CAAC,CAAC,CAAC,CA0Fb"}
|
package/dist/createNewUtils.js
CHANGED
|
@@ -44,6 +44,7 @@ function convertCreateNewSummaryTreeToTreeAndBlobsCore(summary, blobs) {
|
|
|
44
44
|
};
|
|
45
45
|
const keys = Object.keys(summary.tree);
|
|
46
46
|
for (const key of keys) {
|
|
47
|
+
// Non null asserting for now this should change to Object.entries
|
|
47
48
|
const summaryObject = summary.tree[key];
|
|
48
49
|
switch (summaryObject.type) {
|
|
49
50
|
case driver_definitions_1.SummaryType.Tree: {
|
|
@@ -109,6 +110,8 @@ function convertSummaryToSnapshotTreeForCreateNew(summary) {
|
|
|
109
110
|
};
|
|
110
111
|
const keys = Object.keys(summary.tree);
|
|
111
112
|
for (const key of keys) {
|
|
113
|
+
(0, internal_1.assert)(!key.includes("/"), "id should not include slashes");
|
|
114
|
+
// Non null asserting for now this should change to Object.entries
|
|
112
115
|
const summaryObject = summary.tree[key];
|
|
113
116
|
let value;
|
|
114
117
|
// Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the
|
|
@@ -143,7 +146,7 @@ function convertSummaryToSnapshotTreeForCreateNew(summary) {
|
|
|
143
146
|
}
|
|
144
147
|
}
|
|
145
148
|
const entry = {
|
|
146
|
-
path:
|
|
149
|
+
path: key,
|
|
147
150
|
type: (0, internal_2.getGitType)(summaryObject),
|
|
148
151
|
value,
|
|
149
152
|
unreferenced,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewUtils.js","sourceRoot":"","sources":["../src/createNewUtils.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 { Uint8ArrayToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport {\n\tISummaryBlob,\n\tISummaryTree,\n\ttype SummaryObject,\n\tSummaryType,\n} from \"@fluidframework/driver-definitions\";\nimport { ISnapshot, ISnapshotTree } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tgetDocAttributesFromProtocolSummary,\n\tgetGitType,\n\tisCombinedAppAndProtocolSummary,\n} from \"@fluidframework/driver-utils/internal\";\nimport { InstrumentedStorageTokenFetcher } from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\tIOdspSummaryPayload,\n\tIOdspSummaryTree,\n\tOdspSummaryTreeEntry,\n\tOdspSummaryTreeValue,\n} from \"./contracts.js\";\nimport { EpochTracker, FetchType } from \"./epochTracker.js\";\nimport { getHeadersWithAuth } from \"./getUrlAndHeadersWithAuth.js\";\nimport { getWithRetryForTokenRefresh, maxUmpPostBodySize } from \"./odspUtils.js\";\nimport { runWithRetry } from \"./retryUtils.js\";\n\n/**\n * Converts a summary(ISummaryTree) taken in detached container to snapshot tree and blobs\n */\nexport function convertCreateNewSummaryTreeToTreeAndBlobs(\n\tsummary: ISummaryTree,\n\ttreeId: string,\n): ISnapshot {\n\tconst protocolSummary = summary.tree[\".protocol\"] as ISummaryTree;\n\tconst documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n\tconst sequenceNumber = documentAttributes.sequenceNumber;\n\tconst blobContents = new Map<string, ArrayBuffer>();\n\tconst snapshotTree = convertCreateNewSummaryTreeToTreeAndBlobsCore(summary, blobContents);\n\tsnapshotTree.id = treeId;\n\tconst snapshotTreeValue: ISnapshot = {\n\t\tsnapshotTree,\n\t\tblobContents,\n\t\tops: [],\n\t\tsequenceNumber,\n\t\tlatestSequenceNumber: sequenceNumber,\n\t\tsnapshotFormatV: 1,\n\t};\n\n\treturn snapshotTreeValue;\n}\n\nfunction convertCreateNewSummaryTreeToTreeAndBlobsCore(\n\tsummary: ISummaryTree,\n\tblobs: Map<string, ArrayBuffer>,\n): ISnapshotTree {\n\tconst treeNode: ISnapshotTree = {\n\t\tblobs: {},\n\t\ttrees: {},\n\t\tunreferenced: summary.unreferenced,\n\t\tgroupId: summary.groupId,\n\t};\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tconst summaryObject = summary.tree[key];\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\ttreeNode.trees[key] = convertCreateNewSummaryTreeToTreeAndBlobsCore(\n\t\t\t\t\tsummaryObject,\n\t\t\t\t\tblobs,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst contentBuffer =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? stringToBuffer(summaryObject.content, \"utf8\")\n\t\t\t\t\t\t: summaryObject.content;\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tblobs.set(blobId, contentBuffer);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle:\n\t\t\tcase SummaryType.Attachment: {\n\t\t\t\tthrow new Error(`No ${summaryObject.type} should be present for detached summary!`);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(\n\t\t\t\t\tsummaryObject,\n\t\t\t\t\t`Unknown tree type ${(summaryObject as SummaryObject).type}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\treturn treeNode;\n}\n\nexport function convertSummaryIntoContainerSnapshot(\n\tcreateNewSummary: ISummaryTree,\n): IOdspSummaryPayload {\n\tif (!isCombinedAppAndProtocolSummary(createNewSummary)) {\n\t\tthrow new Error(\"App and protocol summary required for create new path!!\");\n\t}\n\tconst appSummary = createNewSummary.tree[\".app\"];\n\tconst protocolSummary = createNewSummary.tree[\".protocol\"];\n\tconst documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n\tconst attributesSummaryBlob: ISummaryBlob = {\n\t\ttype: SummaryType.Blob,\n\t\tcontent: JSON.stringify(documentAttributes),\n\t};\n\tprotocolSummary.tree.attributes = attributesSummaryBlob;\n\tconst convertedCreateNewSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\tconst snapshotTree = convertSummaryToSnapshotTreeForCreateNew(convertedCreateNewSummary);\n\tconst snapshot: IOdspSummaryPayload = {\n\t\tentries: snapshotTree.entries ?? [],\n\t\tmessage: \"app\",\n\t\tsequenceNumber: documentAttributes.sequenceNumber,\n\t\ttype: \"container\",\n\t};\n\treturn snapshot;\n}\n\n/**\n * Converts a summary tree to ODSP tree\n */\nfunction convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspSummaryTree {\n\tconst snapshotTree: IOdspSummaryTree = {\n\t\ttype: \"tree\",\n\t\tentries: [],\n\t};\n\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tconst summaryObject = summary.tree[key];\n\n\t\tlet value: OdspSummaryTreeValue;\n\t\t// Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the\n\t\t// property is not present, the tree entry is considered referenced. If the property is present and is true,\n\t\t// the tree entry is considered unreferenced.\n\t\tlet unreferenced: true | undefined;\n\t\tlet groupId: string | undefined;\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\tvalue = convertSummaryToSnapshotTreeForCreateNew(summaryObject);\n\t\t\t\tunreferenced = summaryObject.unreferenced;\n\t\t\t\tgroupId = summaryObject.groupId;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst content =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? summaryObject.content\n\t\t\t\t\t\t: Uint8ArrayToString(summaryObject.content, \"base64\");\n\t\t\t\tconst encoding = typeof summaryObject.content === \"string\" ? \"utf-8\" : \"base64\";\n\n\t\t\t\tvalue = {\n\t\t\t\t\ttype: \"blob\",\n\t\t\t\t\tcontent,\n\t\t\t\t\tencoding,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle: {\n\t\t\t\tthrow new Error(\"No handle should be present for first summary!!\");\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new Error(`Unknown tree type ${summaryObject.type}`);\n\t\t\t}\n\t\t}\n\n\t\tconst entry: OdspSummaryTreeEntry = {\n\t\t\tpath: encodeURIComponent(key),\n\t\t\ttype: getGitType(summaryObject),\n\t\t\tvalue,\n\t\t\tunreferenced,\n\t\t\tgroupId,\n\t\t};\n\t\tsnapshotTree.entries?.push(entry);\n\t}\n\n\treturn snapshotTree;\n}\n\nexport async function createNewFluidContainerCore<T>(args: {\n\tcontainerSnapshot: IOdspSummaryPayload;\n\tgetAuthHeader: InstrumentedStorageTokenFetcher;\n\tlogger: ITelemetryLoggerExt;\n\tinitialUrl: string;\n\tforceAccessTokenViaAuthorizationHeader: boolean;\n\tepochTracker: EpochTracker;\n\ttelemetryName: string;\n\tfetchType: FetchType;\n\tvalidateResponseCallback?: (content: T) => void;\n}): Promise<T> {\n\tconst {\n\t\tcontainerSnapshot,\n\t\tgetAuthHeader,\n\t\tlogger,\n\t\tinitialUrl,\n\t\tepochTracker,\n\t\ttelemetryName,\n\t\tfetchType,\n\t\tvalidateResponseCallback,\n\t} = args;\n\n\treturn getWithRetryForTokenRefresh(async (options) => {\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tlogger,\n\t\t\t{ eventName: telemetryName },\n\t\t\tasync (event) => {\n\t\t\t\tconst snapshotBody = JSON.stringify(containerSnapshot);\n\t\t\t\tlet url: string;\n\t\t\t\tlet headers: { [index: string]: string };\n\t\t\t\tlet addInBody = false;\n\t\t\t\tconst formBoundary = uuid();\n\t\t\t\tconst urlObj = new URL(initialUrl);\n\t\t\t\turlObj.searchParams.set(\"ump\", \"1\");\n\t\t\t\tconst authInBodyUrl = urlObj.href;\n\t\t\t\tconst method = \"POST\";\n\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t{ ...options, request: { url: authInBodyUrl, method } },\n\t\t\t\t\ttelemetryName,\n\t\t\t\t);\n\t\t\t\tconst postBodyWithAuth =\n\t\t\t\t\t`--${formBoundary}\\r\\n` +\n\t\t\t\t\t`Authorization: ${authHeader}\\r\\n` +\n\t\t\t\t\t`X-HTTP-Method-Override: POST\\r\\n` +\n\t\t\t\t\t`Content-Type: application/json\\r\\n` +\n\t\t\t\t\t`_post: 1\\r\\n` +\n\t\t\t\t\t`\\r\\n${snapshotBody}\\r\\n` +\n\t\t\t\t\t`\\r\\n--${formBoundary}--`;\n\n\t\t\t\tlet postBody = snapshotBody;\n\t\t\t\tif (\n\t\t\t\t\tpostBodyWithAuth.length <= maxUmpPostBodySize &&\n\t\t\t\t\tauthHeader?.startsWith(\"Bearer\")\n\t\t\t\t) {\n\t\t\t\t\turl = authInBodyUrl;\n\t\t\t\t\theaders = {\n\t\t\t\t\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t\t\t\t\t};\n\t\t\t\t\taddInBody = true;\n\t\t\t\t\tpostBody = postBodyWithAuth;\n\t\t\t\t} else {\n\t\t\t\t\turl = initialUrl;\n\t\t\t\t\tconst authHeaderNoUmp = await getAuthHeader(\n\t\t\t\t\t\t{ ...options, request: { url, method } },\n\t\t\t\t\t\ttelemetryName,\n\t\t\t\t\t);\n\t\t\t\t\theaders = {\n\t\t\t\t\t\t...getHeadersWithAuth(authHeaderNoUmp),\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t};\n\t\t\t\t\tpostBody = snapshotBody;\n\t\t\t\t}\n\n\t\t\t\tconst fetchResponse = await runWithRetry(\n\t\t\t\t\tasync () =>\n\t\t\t\t\t\tepochTracker.fetchAndParseAsJSON<T>(\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbody: postBody,\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\tmethod,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfetchType,\n\t\t\t\t\t\t\taddInBody,\n\t\t\t\t\t\t),\n\t\t\t\t\ttelemetryName,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\n\t\t\t\tvalidateResponseCallback?.(fetchResponse.content);\n\n\t\t\t\tevent.end({\n\t\t\t\t\tattempts: options.refresh ? 2 : 1,\n\t\t\t\t\t...fetchResponse.propsToLog,\n\t\t\t\t});\n\n\t\t\t\treturn fetchResponse.content;\n\t\t\t},\n\t\t);\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createNewUtils.js","sourceRoot":"","sources":["../src/createNewUtils.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 { Uint8ArrayToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport {\n\tISummaryBlob,\n\tISummaryTree,\n\ttype SummaryObject,\n\tSummaryType,\n} from \"@fluidframework/driver-definitions\";\nimport { ISnapshot, ISnapshotTree } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tgetDocAttributesFromProtocolSummary,\n\tgetGitType,\n\tisCombinedAppAndProtocolSummary,\n} from \"@fluidframework/driver-utils/internal\";\nimport { InstrumentedStorageTokenFetcher } from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\tIOdspSummaryPayload,\n\tIOdspSummaryTree,\n\tOdspSummaryTreeEntry,\n\tOdspSummaryTreeValue,\n} from \"./contracts.js\";\nimport { EpochTracker, FetchType } from \"./epochTracker.js\";\nimport { getHeadersWithAuth } from \"./getUrlAndHeadersWithAuth.js\";\nimport { getWithRetryForTokenRefresh, maxUmpPostBodySize } from \"./odspUtils.js\";\nimport { runWithRetry } from \"./retryUtils.js\";\n\n/**\n * Converts a summary(ISummaryTree) taken in detached container to snapshot tree and blobs\n */\nexport function convertCreateNewSummaryTreeToTreeAndBlobs(\n\tsummary: ISummaryTree,\n\ttreeId: string,\n): ISnapshot {\n\tconst protocolSummary = summary.tree[\".protocol\"] as ISummaryTree;\n\tconst documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n\tconst sequenceNumber = documentAttributes.sequenceNumber;\n\tconst blobContents = new Map<string, ArrayBuffer>();\n\tconst snapshotTree = convertCreateNewSummaryTreeToTreeAndBlobsCore(summary, blobContents);\n\tsnapshotTree.id = treeId;\n\tconst snapshotTreeValue: ISnapshot = {\n\t\tsnapshotTree,\n\t\tblobContents,\n\t\tops: [],\n\t\tsequenceNumber,\n\t\tlatestSequenceNumber: sequenceNumber,\n\t\tsnapshotFormatV: 1,\n\t};\n\n\treturn snapshotTreeValue;\n}\n\nfunction convertCreateNewSummaryTreeToTreeAndBlobsCore(\n\tsummary: ISummaryTree,\n\tblobs: Map<string, ArrayBuffer>,\n): ISnapshotTree {\n\tconst treeNode: ISnapshotTree = {\n\t\tblobs: {},\n\t\ttrees: {},\n\t\tunreferenced: summary.unreferenced,\n\t\tgroupId: summary.groupId,\n\t};\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\t// Non null asserting for now this should change to Object.entries\n\t\tconst summaryObject = summary.tree[key]!;\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\ttreeNode.trees[key] = convertCreateNewSummaryTreeToTreeAndBlobsCore(\n\t\t\t\t\tsummaryObject,\n\t\t\t\t\tblobs,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst contentBuffer =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? stringToBuffer(summaryObject.content, \"utf8\")\n\t\t\t\t\t\t: summaryObject.content;\n\t\t\t\tconst blobId = uuid();\n\t\t\t\ttreeNode.blobs[key] = blobId;\n\t\t\t\tblobs.set(blobId, contentBuffer);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle:\n\t\t\tcase SummaryType.Attachment: {\n\t\t\t\tthrow new Error(`No ${summaryObject.type} should be present for detached summary!`);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(\n\t\t\t\t\tsummaryObject,\n\t\t\t\t\t`Unknown tree type ${(summaryObject as SummaryObject).type}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\treturn treeNode;\n}\n\nexport function convertSummaryIntoContainerSnapshot(\n\tcreateNewSummary: ISummaryTree,\n): IOdspSummaryPayload {\n\tif (!isCombinedAppAndProtocolSummary(createNewSummary)) {\n\t\tthrow new Error(\"App and protocol summary required for create new path!!\");\n\t}\n\tconst appSummary = createNewSummary.tree[\".app\"];\n\tconst protocolSummary = createNewSummary.tree[\".protocol\"];\n\tconst documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);\n\tconst attributesSummaryBlob: ISummaryBlob = {\n\t\ttype: SummaryType.Blob,\n\t\tcontent: JSON.stringify(documentAttributes),\n\t};\n\tprotocolSummary.tree.attributes = attributesSummaryBlob;\n\tconst convertedCreateNewSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\t\".protocol\": protocolSummary,\n\t\t\t\".app\": appSummary,\n\t\t},\n\t};\n\tconst snapshotTree = convertSummaryToSnapshotTreeForCreateNew(convertedCreateNewSummary);\n\tconst snapshot: IOdspSummaryPayload = {\n\t\tentries: snapshotTree.entries ?? [],\n\t\tmessage: \"app\",\n\t\tsequenceNumber: documentAttributes.sequenceNumber,\n\t\ttype: \"container\",\n\t};\n\treturn snapshot;\n}\n\n/**\n * Converts a summary tree to ODSP tree\n */\nfunction convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspSummaryTree {\n\tconst snapshotTree: IOdspSummaryTree = {\n\t\ttype: \"tree\",\n\t\tentries: [],\n\t};\n\n\tconst keys = Object.keys(summary.tree);\n\tfor (const key of keys) {\n\t\tassert(!key.includes(\"/\"), \"id should not include slashes\");\n\t\t// Non null asserting for now this should change to Object.entries\n\t\tconst summaryObject = summary.tree[key]!;\n\n\t\tlet value: OdspSummaryTreeValue;\n\t\t// Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the\n\t\t// property is not present, the tree entry is considered referenced. If the property is present and is true,\n\t\t// the tree entry is considered unreferenced.\n\t\tlet unreferenced: true | undefined;\n\t\tlet groupId: string | undefined;\n\n\t\tswitch (summaryObject.type) {\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\tvalue = convertSummaryToSnapshotTreeForCreateNew(summaryObject);\n\t\t\t\tunreferenced = summaryObject.unreferenced;\n\t\t\t\tgroupId = summaryObject.groupId;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tconst content =\n\t\t\t\t\ttypeof summaryObject.content === \"string\"\n\t\t\t\t\t\t? summaryObject.content\n\t\t\t\t\t\t: Uint8ArrayToString(summaryObject.content, \"base64\");\n\t\t\t\tconst encoding = typeof summaryObject.content === \"string\" ? \"utf-8\" : \"base64\";\n\n\t\t\t\tvalue = {\n\t\t\t\t\ttype: \"blob\",\n\t\t\t\t\tcontent,\n\t\t\t\t\tencoding,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SummaryType.Handle: {\n\t\t\t\tthrow new Error(\"No handle should be present for first summary!!\");\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new Error(`Unknown tree type ${summaryObject.type}`);\n\t\t\t}\n\t\t}\n\n\t\tconst entry: OdspSummaryTreeEntry = {\n\t\t\tpath: key,\n\t\t\ttype: getGitType(summaryObject),\n\t\t\tvalue,\n\t\t\tunreferenced,\n\t\t\tgroupId,\n\t\t};\n\t\tsnapshotTree.entries?.push(entry);\n\t}\n\n\treturn snapshotTree;\n}\n\nexport async function createNewFluidContainerCore<T>(args: {\n\tcontainerSnapshot: IOdspSummaryPayload;\n\tgetAuthHeader: InstrumentedStorageTokenFetcher;\n\tlogger: ITelemetryLoggerExt;\n\tinitialUrl: string;\n\tforceAccessTokenViaAuthorizationHeader: boolean;\n\tepochTracker: EpochTracker;\n\ttelemetryName: string;\n\tfetchType: FetchType;\n\tvalidateResponseCallback?: (content: T) => void;\n}): Promise<T> {\n\tconst {\n\t\tcontainerSnapshot,\n\t\tgetAuthHeader,\n\t\tlogger,\n\t\tinitialUrl,\n\t\tepochTracker,\n\t\ttelemetryName,\n\t\tfetchType,\n\t\tvalidateResponseCallback,\n\t} = args;\n\n\treturn getWithRetryForTokenRefresh(async (options) => {\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tlogger,\n\t\t\t{ eventName: telemetryName },\n\t\t\tasync (event) => {\n\t\t\t\tconst snapshotBody = JSON.stringify(containerSnapshot);\n\t\t\t\tlet url: string;\n\t\t\t\tlet headers: { [index: string]: string };\n\t\t\t\tlet addInBody = false;\n\t\t\t\tconst formBoundary = uuid();\n\t\t\t\tconst urlObj = new URL(initialUrl);\n\t\t\t\turlObj.searchParams.set(\"ump\", \"1\");\n\t\t\t\tconst authInBodyUrl = urlObj.href;\n\t\t\t\tconst method = \"POST\";\n\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t{ ...options, request: { url: authInBodyUrl, method } },\n\t\t\t\t\ttelemetryName,\n\t\t\t\t);\n\t\t\t\tconst postBodyWithAuth =\n\t\t\t\t\t`--${formBoundary}\\r\\n` +\n\t\t\t\t\t`Authorization: ${authHeader}\\r\\n` +\n\t\t\t\t\t`X-HTTP-Method-Override: POST\\r\\n` +\n\t\t\t\t\t`Content-Type: application/json\\r\\n` +\n\t\t\t\t\t`_post: 1\\r\\n` +\n\t\t\t\t\t`\\r\\n${snapshotBody}\\r\\n` +\n\t\t\t\t\t`\\r\\n--${formBoundary}--`;\n\n\t\t\t\tlet postBody = snapshotBody;\n\t\t\t\tif (\n\t\t\t\t\tpostBodyWithAuth.length <= maxUmpPostBodySize &&\n\t\t\t\t\tauthHeader?.startsWith(\"Bearer\")\n\t\t\t\t) {\n\t\t\t\t\turl = authInBodyUrl;\n\t\t\t\t\theaders = {\n\t\t\t\t\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t\t\t\t\t};\n\t\t\t\t\taddInBody = true;\n\t\t\t\t\tpostBody = postBodyWithAuth;\n\t\t\t\t} else {\n\t\t\t\t\turl = initialUrl;\n\t\t\t\t\tconst authHeaderNoUmp = await getAuthHeader(\n\t\t\t\t\t\t{ ...options, request: { url, method } },\n\t\t\t\t\t\ttelemetryName,\n\t\t\t\t\t);\n\t\t\t\t\theaders = {\n\t\t\t\t\t\t...getHeadersWithAuth(authHeaderNoUmp),\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t};\n\t\t\t\t\tpostBody = snapshotBody;\n\t\t\t\t}\n\n\t\t\t\tconst fetchResponse = await runWithRetry(\n\t\t\t\t\tasync () =>\n\t\t\t\t\t\tepochTracker.fetchAndParseAsJSON<T>(\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbody: postBody,\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\tmethod,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfetchType,\n\t\t\t\t\t\t\taddInBody,\n\t\t\t\t\t\t),\n\t\t\t\t\ttelemetryName,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\n\t\t\t\tvalidateResponseCallback?.(fetchResponse.content);\n\n\t\t\t\tevent.end({\n\t\t\t\t\tattempts: options.refresh ? 2 : 1,\n\t\t\t\t\t...fetchResponse.propsToLog,\n\t\t\t\t});\n\n\t\t\t\treturn fetchResponse.content;\n\t\t\t},\n\t\t);\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAGN,WAAW,EAEX,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAEN,MAAM,EACN,UAAU,EAIV,eAAe,
|
|
1
|
+
{"version":3,"file":"epochTracker.d.ts","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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"}
|
package/dist/epochTracker.js
CHANGED
|
@@ -83,7 +83,7 @@ class EpochTracker {
|
|
|
83
83
|
}
|
|
84
84
|
// Expire the cached snapshot if it's older than snapshotCacheExpiryTimeoutMs and immediately
|
|
85
85
|
// expire all old caches that do not have cacheEntryTime
|
|
86
|
-
if (entry.type === internal_3.snapshotKey) {
|
|
86
|
+
if (entry.type === internal_3.snapshotKey || entry.type === internal_3.snapshotWithLoadingGroupIdKey) {
|
|
87
87
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
88
88
|
const cacheTime = value.value?.cacheEntryTime;
|
|
89
89
|
const currentTime = Date.now();
|
|
@@ -112,7 +112,7 @@ class EpochTracker {
|
|
|
112
112
|
(0, internal_1.assert)(this._fluidEpoch !== undefined, 0x1dd /* "no epoch" */);
|
|
113
113
|
// For snapshots, the value should have the cacheEntryTime.
|
|
114
114
|
// This will be used to expire snapshots older than snapshotCacheExpiryTimeoutMs.
|
|
115
|
-
if (entry.type === internal_3.snapshotKey) {
|
|
115
|
+
if (entry.type === internal_3.snapshotKey || entry.type === internal_3.snapshotWithLoadingGroupIdKey) {
|
|
116
116
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
117
117
|
value.cacheEntryTime = value.cacheEntryTime ?? Date.now();
|
|
118
118
|
}
|
|
@@ -360,7 +360,7 @@ class EpochTrackerWithRedemption extends EpochTracker {
|
|
|
360
360
|
async get(entry) {
|
|
361
361
|
let result = super.get(entry);
|
|
362
362
|
// equivalence of what happens in fetchAndParseAsJSON()
|
|
363
|
-
if (entry.type === internal_3.snapshotKey) {
|
|
363
|
+
if (entry.type === internal_3.snapshotKey || entry.type === internal_3.snapshotWithLoadingGroupIdKey) {
|
|
364
364
|
result = result
|
|
365
365
|
.then((value) => {
|
|
366
366
|
// If there is nothing in cache, we need to wait for network call to complete (and do redemption)
|
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 { assert, Deferred } from \"@fluidframework/core-utils/internal\";\nimport {\n\tLocationRedirectionError,\n\tNonRetryableError,\n\tRateLimiter,\n\tThrottlingError,\n} from \"@fluidframework/driver-utils/internal\";\nimport {\n\tICacheEntry,\n\tIEntry,\n\tIFileEntry,\n\tIOdspError,\n\tIOdspErrorAugmentations,\n\tIOdspResolvedUrl,\n\tIPersistedCache,\n\tOdspErrorTypes,\n\tmaximumCacheDurationMs,\n\tsnapshotKey,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n\tisFluidError,\n\tloggerToMonitoringContext,\n\tnormalizeError,\n\twrapError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts.js\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic.js\";\nimport { INonPersistentCache, IOdspCache, IPersistedFileCache } from \"./odspCache.js\";\nimport { patchOdspResolvedUrl } from \"./odspLocationRedirection.js\";\nimport {\n\tIOdspResponse,\n\tfetchAndParseAsJSONHelper,\n\tfetchArray,\n\tfetchHelper,\n\tgetOdspResolvedUrl,\n} from \"./odspUtils.js\";\nimport { pkgVersion as driverVersion } from \"./packageVersion.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type FetchType =\n\t| \"blob\"\n\t| \"createBlob\"\n\t| \"createFile\"\n\t| \"joinSession\"\n\t| \"ops\"\n\t| \"test\"\n\t| \"snapshotTree\"\n\t| \"treesLatest\"\n\t| \"uploadSummary\"\n\t| \"push\"\n\t| \"versions\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n/**\n * In ODSP, the concept of \"epoch\" refers to binary updates to files. For example, this might include using\n * version restore, or if the user downloads a Fluid file and then uploads it again. These result in the epoch\n * value being incremented.\n *\n * The implications of these binary updates is that the Fluid state is disrupted: the sequence number might\n * go backwards, the data might be inconsistent with the latest state of collaboration, etc. As a result, it's\n * not safe to continue collaboration across an epoch change. We need to detect these epoch changes and\n * error out from the collaboration.\n *\n * This class is a wrapper around fetch calls. It adds epoch to the request made so that the\n * server can match it with its epoch value in order to match the version.\n * It also validates the epoch value received in response of fetch calls. If the epoch does not match,\n * then it also clears all the cached entries for the given container.\n * @legacy\n * @alpha\n */\nexport class EpochTracker implements IPersistedFileCache {\n\tprivate _fluidEpoch: string | undefined;\n\n\tprivate readonly snapshotCacheExpiryTimeoutMs: number;\n\tpublic readonly rateLimiter: RateLimiter;\n\tprivate readonly driverId = uuid();\n\t// This tracks the request number made by the driver instance.\n\tprivate networkCallNumber = 1;\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\t// Limits the max number of concurrent requests to 24.\n\t\tthis.rateLimiter = new RateLimiter(24);\n\n\t\t// Matches the TestOverride logic for the policy defined in odspDocumentStorageServiceBase.ts\n\t\tthis.snapshotCacheExpiryTimeoutMs = loggerToMonitoringContext(logger).config.getBoolean(\n\t\t\t\"Fluid.Driver.Odsp.TestOverride.DisableSnapshotCache\",\n\t\t)\n\t\t\t? 0\n\t\t\t: maximumCacheDurationMs;\n\t}\n\n\t// public for UT purposes only!\n\tpublic setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal): void {\n\t\tassert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n\t\tthis._fluidEpoch = epoch;\n\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"EpochLearnedFirstTime\",\n\t\t\tepoch,\n\t\t\tfetchType,\n\t\t\tfromCache,\n\t\t});\n\t}\n\n\t// TODO: return a stronger type\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\ttry {\n\t\t\t// Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tconst value: IVersionedValueWithEpoch = await this.cache.get(\n\t\t\t\tthis.fileEntryFromEntry(entry),\n\t\t\t);\n\t\t\t// Version mismatch between what the runtime expects and what it recieved.\n\t\t\t// The cached value should not be used\n\t\t\tif (value === undefined || value.version !== persistedCacheValueVersion) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tassert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n\t\t\tif (this._fluidEpoch === undefined) {\n\t\t\t\tthis.setEpoch(value.fluidEpoch, true, \"cache\");\n\t\t\t\t// Epoch mismatch, the cached value is considerably different from what the current state of\n\t\t\t\t// the runtime and should not be used\n\t\t\t} else if (this._fluidEpoch !== value.fluidEpoch) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\t// Expire the cached snapshot if it's older than snapshotCacheExpiryTimeoutMs and immediately\n\t\t\t// expire all old caches that do not have cacheEntryTime\n\t\t\tif (entry.type === snapshotKey) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\t\tconst cacheTime = value.value?.cacheEntryTime;\n\t\t\t\tconst currentTime = Date.now();\n\t\t\t\tif (\n\t\t\t\t\tcacheTime === undefined ||\n\t\t\t\t\tcurrentTime - cacheTime >= this.snapshotCacheExpiryTimeoutMs\n\t\t\t\t) {\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"odspVersionsCacheExpired\",\n\t\t\t\t\t\tduration: currentTime - cacheTime,\n\t\t\t\t\t\tmaxCacheAgeMs: this.snapshotCacheExpiryTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t\tawait this.removeEntries();\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn value.value;\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t// TODO: take a stronger type or `unknown`\n\t// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n\tpublic async put(entry: IEntry, value: any): Promise<void> {\n\t\tassert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n\t\t// For snapshots, the value should have the cacheEntryTime.\n\t\t// This will be used to expire snapshots older than snapshotCacheExpiryTimeoutMs.\n\t\tif (entry.type === snapshotKey) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\tvalue.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n\t\t}\n\t\tconst data: IVersionedValueWithEpoch = {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tvalue,\n\t\t\tversion: persistedCacheValueVersion,\n\t\t\tfluidEpoch: this._fluidEpoch,\n\t\t};\n\t\treturn this.cache.put(this.fileEntryFromEntry(entry), data).catch((error) => {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n\t\t\tthrow error;\n\t\t});\n\t}\n\n\tpublic async removeEntries(): Promise<void> {\n\t\ttry {\n\t\t\treturn await this.cache.removeEntries(this.fileEntry);\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n\t\t}\n\t}\n\n\tpublic get fluidEpoch(): string | undefined {\n\t\treturn this._fluidEpoch;\n\t}\n\n\tpublic async validateEpoch(epoch: string | undefined, fetchType: FetchType): Promise<void> {\n\t\tassert(epoch !== undefined, 0x584 /* response should contain epoch */);\n\t\ttry {\n\t\t\tthis.validateEpochFromResponse(epoch, fetchType);\n\t\t} catch (error) {\n\t\t\tawait this.checkForEpochError(error, epoch, fetchType);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\treturn this.fetchCore<T>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchAndParseAsJSONHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetch(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<Response>> {\n\t\treturn this.fetchCore<Response>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate async fetchCore<T>(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetcher: (url: string, fetchOptions: RequestInit) => Promise<IOdspResponse<T>>,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\tconst clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n\t\t// Add epoch in fetch request.\n\t\tthis.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n\t\tlet epochFromResponse: string | undefined;\n\t\treturn this.rateLimiter\n\t\t\t.schedule(async () => fetcher(url, fetchOptions))\n\t\t\t.then((response) => {\n\t\t\t\tepochFromResponse = response.headers.get(\"x-fluid-epoch\");\n\t\t\t\tthis.validateEpochFromResponse(epochFromResponse, fetchType);\n\t\t\t\tresponse.propsToLog.XRequestStatsHeader = clientCorrelationId;\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.catch(async (error) => {\n\t\t\t\t// Get the server epoch from error in case we don't have it as if undefined we won't be able\n\t\t\t\t// to mark it as epoch error.\n\t\t\t\tif (epochFromResponse === undefined) {\n\t\t\t\t\tepochFromResponse = (error as IOdspError).serverEpoch;\n\t\t\t\t}\n\t\t\t\tawait this.checkForEpochError(error, epochFromResponse, fetchType);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// If the error is about location redirection, then we need to generate new resolved url with correct\n\t\t\t\t// location info.\n\t\t\t\tif (\n\t\t\t\t\tisFluidError(error) &&\n\t\t\t\t\terror.errorType === OdspErrorTypes.fileNotFoundOrAccessDeniedError\n\t\t\t\t) {\n\t\t\t\t\tconst redirectLocation = (error as IOdspErrorAugmentations).redirectLocation;\n\t\t\t\t\tif (redirectLocation !== undefined) {\n\t\t\t\t\t\tconst redirectUrl: IOdspResolvedUrl = patchOdspResolvedUrl(\n\t\t\t\t\t\t\tthis.fileEntry.resolvedUrl,\n\t\t\t\t\t\t\tredirectLocation,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst locationRedirectionError = new LocationRedirectionError(\n\t\t\t\t\t\t\terror.message,\n\t\t\t\t\t\t\tredirectUrl,\n\t\t\t\t\t\t\t{ driverVersion, redirectLocation },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlocationRedirectionError.addTelemetryProperties(error.getTelemetryProperties());\n\t\t\t\t\t\tthrow locationRedirectionError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconst fluidError = normalizeError(error, {\n\t\t\t\t\tprops: { XRequestStatsHeader: clientCorrelationId },\n\t\t\t\t});\n\t\t\t\tthrow fluidError;\n\t\t\t});\n\t}\n\n\t/**\n\t * Api to fetch the response as it is for given request.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchArray(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: RequestInit },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<ArrayBuffer>> {\n\t\treturn this.fetchCore<ArrayBuffer>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchArray,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate addEpochInRequest(\n\t\tfetchOptions: RequestInit,\n\t\taddInBody: boolean,\n\t\tclientCorrelationId: string,\n\t): void {\n\t\tconst isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;\n\t\tif (addInBody) {\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\theaders[\"X-RequestStats\"] = clientCorrelationId;\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\theaders[\"x-fluid-epoch\"] = this.fluidEpoch;\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\theaders[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();\n\t\t\t}\n\t\t\tthis.addParamInBody(fetchOptions, headers);\n\t\t} else {\n\t\t\tconst addHeader = (key: string, val: string): void => {\n\t\t\t\tfetchOptions.headers = {\n\t\t\t\t\t...fetchOptions.headers,\n\t\t\t\t};\n\t\t\t\tassert(\n\t\t\t\t\tfetchOptions.headers !== undefined,\n\t\t\t\t\t0x282 /* \"Headers should be present now\" */,\n\t\t\t\t);\n\t\t\t\tfetchOptions.headers[key] = val;\n\t\t\t};\n\t\t\taddHeader(\"X-RequestStats\", clientCorrelationId);\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\taddHeader(\"x-fluid-epoch\", this.fluidEpoch);\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\taddHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string }): void {\n\t\t// We use multi part form request for post body where we want to use this.\n\t\t// So extract the form boundary to mark the end of form.\n\t\tconst body = fetchOptions.body;\n\t\tassert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n\t\tconst splitBody = body.split(\"\\r\\n\");\n\t\tconst firstLine = splitBody.shift();\n\t\tassert(firstLine?.startsWith(\"--\") === true, 0x21e /* \"improper boundary format\" */);\n\t\tconst formParams = [firstLine];\n\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\tformParams.push(`${key}: ${value}`);\n\t\t}\n\t\tfor (const value of splitBody) {\n\t\t\tformParams.push(value);\n\t\t}\n\t\tfetchOptions.body = formParams.join(\"\\r\\n\");\n\t}\n\n\tprivate formatClientCorrelationId(fetchReason?: string): string {\n\t\tconst items: string[] = [\n\t\t\t`driverId=${this.driverId}`,\n\t\t\t`RequestNumber=${this.networkCallNumber++}`,\n\t\t\t`driverVersion=${driverVersion}`,\n\t\t\t`isSummarizer=${this.clientIsSummarizer}`,\n\t\t];\n\t\tif (fetchReason !== undefined) {\n\t\t\titems.push(`fetchReason=${fetchReason}`);\n\t\t}\n\t\treturn items.join(\", \");\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t): void {\n\t\tconst error = this.checkForEpochErrorCore(epochFromResponse);\n\t\tif (error !== undefined) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (epochFromResponse !== undefined && this._fluidEpoch === undefined) {\n\t\t\tthis.setEpoch(epochFromResponse, fromCache, fetchType);\n\t\t}\n\t}\n\n\tprivate async checkForEpochError(\n\t\terror: unknown,\n\t\tepochFromResponse: string | null | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t): Promise<void> {\n\t\tif (isFluidError(error) && error.errorType === OdspErrorTypes.fileOverwrittenInStorage) {\n\t\t\tconst epochError = this.checkForEpochErrorCore(epochFromResponse);\n\t\t\tif (epochError !== undefined) {\n\t\t\t\tepochError.addTelemetryProperties({\n\t\t\t\t\tfromCache,\n\t\t\t\t\tfetchType,\n\t\t\t\t});\n\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n\t\t\t\t// If the epoch mismatches, then clear all entries for such file entry from cache.\n\t\t\t\tawait this.removeEntries();\n\t\t\t\tthrow epochError;\n\t\t\t}\n\t\t\t// If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n\t\t\t// then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n\t\t\t// time is 1s.\n\t\t\tconst newError = wrapError(error, (message: string) => {\n\t\t\t\treturn new ThrottlingError(`Coherency 409: ${message}`, 1 /* retryAfterSeconds */, {\n\t\t\t\t\t[Odsp409Error]: true,\n\t\t\t\t\tdriverVersion,\n\t\t\t\t});\n\t\t\t});\n\t\t\tthrow newError;\n\t\t}\n\t}\n\n\tprivate checkForEpochErrorCore(\n\t\tepochFromResponse: string | null | undefined,\n\t): NonRetryableError<\"fileOverwrittenInStorage\"> | undefined {\n\t\t// If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n\t\t// initializes this value. Sometimes response does not contain epoch as it is still in\n\t\t// implementation phase at server side. In that case also, don't compare it with our epoch value.\n\t\tif (this.fluidEpoch && epochFromResponse && this.fluidEpoch !== epochFromResponse) {\n\t\t\t// This is similar in nature to how fluidEpochMismatchError (409) is handled.\n\t\t\t// Difference - client detected mismatch, instead of server detecting it.\n\t\t\treturn new NonRetryableError(\"Epoch mismatch\", OdspErrorTypes.fileOverwrittenInStorage, {\n\t\t\t\tdriverVersion,\n\t\t\t\tserverEpoch: epochFromResponse,\n\t\t\t\tclientEpoch: this.fluidEpoch,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate fileEntryFromEntry(entry: IEntry): ICacheEntry {\n\t\treturn { ...entry, file: this.fileEntry };\n\t}\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n\tprivate readonly treesLatestDeferral = new Deferred<void>();\n\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\tsuper(cache, fileEntry, logger, clientIsSummarizer);\n\t\t// Handles the rejected promise within treesLatestDeferral.\n\t\tthis.treesLatestDeferral.promise.catch(() => {});\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchType,\n\t\tfromCache: boolean = false,\n\t): void {\n\t\tsuper.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n\t\t// Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n\t\t// That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n\t\t// exploring a file.\n\t\tthis.treesLatestDeferral.resolve();\n\t}\n\n\t// TODO: return a stronger type\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\tlet result = super.get(entry);\n\n\t\t// equivalence of what happens in fetchAndParseAsJSON()\n\t\tif (entry.type === snapshotKey) {\n\t\t\tresult = result\n\t\t\t\t.then((value) => {\n\t\t\t\t\t// If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n\t\t\t\t\t// Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\tthis.treesLatestDeferral.resolve();\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn value;\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t}\n\t\treturn result;\n\t}\n\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: RequestInit },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\t// Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n\t\t// joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n\t\tconst completed = this.treesLatestDeferral.isCompleted;\n\n\t\ttry {\n\t\t\treturn await super.fetchAndParseAsJSON<T>(\n\t\t\t\turl,\n\t\t\t\tfetchOptions,\n\t\t\t\tfetchType,\n\t\t\t\taddInBody,\n\t\t\t\tfetchReason,\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\t// Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n\t\t\t// Similar, if getVersions failed, we should not do any further storage calls.\n\t\t\t// So treesLatest is the only call that can have parallel joinSession request.\n\t\t\tif (fetchType === \"treesLatest\") {\n\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tfetchType !== \"joinSession\" ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\terror.statusCode < 401 ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\terror.statusCode > 404 ||\n\t\t\t\tcompleted\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\t// It is joinSession failing with 401..404 error\n\t\t// Repeat after waiting for treeLatest succeeding (or fail if it failed).\n\t\t// No special handling after first call - if file has been deleted, then it's game over.\n\n\t\t// Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n\t\t// If we waited too long, we will log error event and proceed with call.\n\t\t// It may result in failure for user, but refreshing document would address it.\n\t\t// Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n\t\t// to unblock the process.\n\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\tthis.logger,\n\t\t\t{ eventName: \"JoinSessionSyncWait\" },\n\t\t\tasync (event) => {\n\t\t\t\tconst timeoutRes = 51; // anything will work here\n\t\t\t\tlet timer: ReturnType<typeof setTimeout>;\n\t\t\t\tconst timeoutP = new Promise<number>((resolve) => {\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\tresolve(timeoutRes);\n\t\t\t\t\t}, 15000);\n\t\t\t\t});\n\t\t\t\tconst res = await Promise.race([\n\t\t\t\t\ttimeoutP,\n\t\t\t\t\t// cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n\t\t\t\t\tthis.treesLatestDeferral.promise.finally(() => clearTimeout(timer)),\n\t\t\t\t]);\n\t\t\t\tif (res === timeoutRes) {\n\t\t\t\t\tevent.cancel();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t);\n\t\treturn super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n\t}\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface ICacheAndTracker {\n\tcache: IOdspCache;\n\tepochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n\tpersistedCacheArg: IPersistedCache,\n\tnonpersistentCache: INonPersistentCache,\n\tfileEntry: IFileEntry,\n\tlogger: ITelemetryLoggerExt,\n\tclientIsSummarizer?: boolean,\n): ICacheAndTracker {\n\tconst epochTracker = new EpochTrackerWithRedemption(\n\t\tpersistedCacheArg,\n\t\tfileEntry,\n\t\tlogger,\n\t\tclientIsSummarizer,\n\t);\n\treturn {\n\t\tcache: {\n\t\t\t...nonpersistentCache,\n\t\t\tpersistedCache: epochTracker,\n\t\t},\n\t\tepochTracker,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"epochTracker.js","sourceRoot":"","sources":["../src/epochTracker.ts"],"names":[],"mappings":"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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, Deferred } from \"@fluidframework/core-utils/internal\";\nimport {\n\tLocationRedirectionError,\n\tNonRetryableError,\n\tRateLimiter,\n\tThrottlingError,\n} from \"@fluidframework/driver-utils/internal\";\nimport {\n\tICacheEntry,\n\tIEntry,\n\tIFileEntry,\n\tIOdspError,\n\tIOdspErrorAugmentations,\n\tIOdspResolvedUrl,\n\tIPersistedCache,\n\tOdspErrorTypes,\n\tmaximumCacheDurationMs,\n\tsnapshotKey,\n\tsnapshotWithLoadingGroupIdKey,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n\tisFluidError,\n\tloggerToMonitoringContext,\n\tnormalizeError,\n\twrapError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts.js\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic.js\";\nimport { INonPersistentCache, IOdspCache, IPersistedFileCache } from \"./odspCache.js\";\nimport { patchOdspResolvedUrl } from \"./odspLocationRedirection.js\";\nimport {\n\tIOdspResponse,\n\tfetchAndParseAsJSONHelper,\n\tfetchArray,\n\tfetchHelper,\n\tgetOdspResolvedUrl,\n} from \"./odspUtils.js\";\nimport { pkgVersion as driverVersion } from \"./packageVersion.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type FetchType =\n\t| \"blob\"\n\t| \"createBlob\"\n\t| \"createFile\"\n\t| \"joinSession\"\n\t| \"ops\"\n\t| \"test\"\n\t| \"snapshotTree\"\n\t| \"treesLatest\"\n\t| \"uploadSummary\"\n\t| \"push\"\n\t| \"versions\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type FetchTypeInternal = FetchType | \"cache\";\n\nexport const Odsp409Error = \"Odsp409Error\";\n\n/**\n * In ODSP, the concept of \"epoch\" refers to binary updates to files. For example, this might include using\n * version restore, or if the user downloads a Fluid file and then uploads it again. These result in the epoch\n * value being incremented.\n *\n * The implications of these binary updates is that the Fluid state is disrupted: the sequence number might\n * go backwards, the data might be inconsistent with the latest state of collaboration, etc. As a result, it's\n * not safe to continue collaboration across an epoch change. We need to detect these epoch changes and\n * error out from the collaboration.\n *\n * This class is a wrapper around fetch calls. It adds epoch to the request made so that the\n * server can match it with its epoch value in order to match the version.\n * It also validates the epoch value received in response of fetch calls. If the epoch does not match,\n * then it also clears all the cached entries for the given container.\n * @legacy\n * @alpha\n */\nexport class EpochTracker implements IPersistedFileCache {\n\tprivate _fluidEpoch: string | undefined;\n\n\tprivate readonly snapshotCacheExpiryTimeoutMs: number;\n\tpublic readonly rateLimiter: RateLimiter;\n\tprivate readonly driverId = uuid();\n\t// This tracks the request number made by the driver instance.\n\tprivate networkCallNumber = 1;\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\t// Limits the max number of concurrent requests to 24.\n\t\tthis.rateLimiter = new RateLimiter(24);\n\n\t\t// Matches the TestOverride logic for the policy defined in odspDocumentStorageServiceBase.ts\n\t\tthis.snapshotCacheExpiryTimeoutMs = loggerToMonitoringContext(logger).config.getBoolean(\n\t\t\t\"Fluid.Driver.Odsp.TestOverride.DisableSnapshotCache\",\n\t\t)\n\t\t\t? 0\n\t\t\t: maximumCacheDurationMs;\n\t}\n\n\t// public for UT purposes only!\n\tpublic setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal): void {\n\t\tassert(this._fluidEpoch === undefined, 0x1db /* \"epoch exists\" */);\n\t\tthis._fluidEpoch = epoch;\n\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"EpochLearnedFirstTime\",\n\t\t\tepoch,\n\t\t\tfetchType,\n\t\t\tfromCache,\n\t\t});\n\t}\n\n\t// TODO: return a stronger type\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\ttry {\n\t\t\t// Return undefined so that the ops/snapshots are grabbed from the server instead of the cache\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tconst value: IVersionedValueWithEpoch = await this.cache.get(\n\t\t\t\tthis.fileEntryFromEntry(entry),\n\t\t\t);\n\t\t\t// Version mismatch between what the runtime expects and what it recieved.\n\t\t\t// The cached value should not be used\n\t\t\tif (value === undefined || value.version !== persistedCacheValueVersion) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tassert(value.fluidEpoch !== undefined, 0x1dc /* \"all entries have to have epoch\" */);\n\t\t\tif (this._fluidEpoch === undefined) {\n\t\t\t\tthis.setEpoch(value.fluidEpoch, true, \"cache\");\n\t\t\t\t// Epoch mismatch, the cached value is considerably different from what the current state of\n\t\t\t\t// the runtime and should not be used\n\t\t\t} else if (this._fluidEpoch !== value.fluidEpoch) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\t// Expire the cached snapshot if it's older than snapshotCacheExpiryTimeoutMs and immediately\n\t\t\t// expire all old caches that do not have cacheEntryTime\n\t\t\tif (entry.type === snapshotKey || entry.type === snapshotWithLoadingGroupIdKey) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\t\tconst cacheTime = value.value?.cacheEntryTime;\n\t\t\t\tconst currentTime = Date.now();\n\t\t\t\tif (\n\t\t\t\t\tcacheTime === undefined ||\n\t\t\t\t\tcurrentTime - cacheTime >= this.snapshotCacheExpiryTimeoutMs\n\t\t\t\t) {\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"odspVersionsCacheExpired\",\n\t\t\t\t\t\tduration: currentTime - cacheTime,\n\t\t\t\t\t\tmaxCacheAgeMs: this.snapshotCacheExpiryTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t\tawait this.removeEntries();\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn value.value;\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cacheFetchError\", type: entry.type }, error);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t// TODO: take a stronger type or `unknown`\n\t// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n\tpublic async put(entry: IEntry, value: any): Promise<void> {\n\t\tassert(this._fluidEpoch !== undefined, 0x1dd /* \"no epoch\" */);\n\t\t// For snapshots, the value should have the cacheEntryTime.\n\t\t// This will be used to expire snapshots older than snapshotCacheExpiryTimeoutMs.\n\t\tif (entry.type === snapshotKey || entry.type === snapshotWithLoadingGroupIdKey) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\tvalue.cacheEntryTime = value.cacheEntryTime ?? Date.now();\n\t\t}\n\t\tconst data: IVersionedValueWithEpoch = {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tvalue,\n\t\t\tversion: persistedCacheValueVersion,\n\t\t\tfluidEpoch: this._fluidEpoch,\n\t\t};\n\t\treturn this.cache.put(this.fileEntryFromEntry(entry), data).catch((error) => {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"cachePutError\", type: entry.type }, error);\n\t\t\tthrow error;\n\t\t});\n\t}\n\n\tpublic async removeEntries(): Promise<void> {\n\t\ttry {\n\t\t\treturn await this.cache.removeEntries(this.fileEntry);\n\t\t} catch (error) {\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"removeCacheEntries\" }, error);\n\t\t}\n\t}\n\n\tpublic get fluidEpoch(): string | undefined {\n\t\treturn this._fluidEpoch;\n\t}\n\n\tpublic async validateEpoch(epoch: string | undefined, fetchType: FetchType): Promise<void> {\n\t\tassert(epoch !== undefined, 0x584 /* response should contain epoch */);\n\t\ttry {\n\t\t\tthis.validateEpochFromResponse(epoch, fetchType);\n\t\t} catch (error) {\n\t\t\tawait this.checkForEpochError(error, epoch, fetchType);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\treturn this.fetchCore<T>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchAndParseAsJSONHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\t/**\n\t * Api to fetch the response for given request and parse it as json.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetch(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<Response>> {\n\t\treturn this.fetchCore<Response>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchHelper,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate async fetchCore<T>(\n\t\turl: string,\n\t\tfetchOptions: RequestInit,\n\t\tfetcher: (url: string, fetchOptions: RequestInit) => Promise<IOdspResponse<T>>,\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\tconst clientCorrelationId = this.formatClientCorrelationId(fetchReason);\n\t\t// Add epoch in fetch request.\n\t\tthis.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);\n\t\tlet epochFromResponse: string | undefined;\n\t\treturn this.rateLimiter\n\t\t\t.schedule(async () => fetcher(url, fetchOptions))\n\t\t\t.then((response) => {\n\t\t\t\tepochFromResponse = response.headers.get(\"x-fluid-epoch\");\n\t\t\t\tthis.validateEpochFromResponse(epochFromResponse, fetchType);\n\t\t\t\tresponse.propsToLog.XRequestStatsHeader = clientCorrelationId;\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.catch(async (error) => {\n\t\t\t\t// Get the server epoch from error in case we don't have it as if undefined we won't be able\n\t\t\t\t// to mark it as epoch error.\n\t\t\t\tif (epochFromResponse === undefined) {\n\t\t\t\t\tepochFromResponse = (error as IOdspError).serverEpoch;\n\t\t\t\t}\n\t\t\t\tawait this.checkForEpochError(error, epochFromResponse, fetchType);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// If the error is about location redirection, then we need to generate new resolved url with correct\n\t\t\t\t// location info.\n\t\t\t\tif (\n\t\t\t\t\tisFluidError(error) &&\n\t\t\t\t\terror.errorType === OdspErrorTypes.fileNotFoundOrAccessDeniedError\n\t\t\t\t) {\n\t\t\t\t\tconst redirectLocation = (error as IOdspErrorAugmentations).redirectLocation;\n\t\t\t\t\tif (redirectLocation !== undefined) {\n\t\t\t\t\t\tconst redirectUrl: IOdspResolvedUrl = patchOdspResolvedUrl(\n\t\t\t\t\t\t\tthis.fileEntry.resolvedUrl,\n\t\t\t\t\t\t\tredirectLocation,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst locationRedirectionError = new LocationRedirectionError(\n\t\t\t\t\t\t\terror.message,\n\t\t\t\t\t\t\tredirectUrl,\n\t\t\t\t\t\t\t{ driverVersion, redirectLocation },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlocationRedirectionError.addTelemetryProperties(error.getTelemetryProperties());\n\t\t\t\t\t\tthrow locationRedirectionError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconst fluidError = normalizeError(error, {\n\t\t\t\t\tprops: { XRequestStatsHeader: clientCorrelationId },\n\t\t\t\t});\n\t\t\t\tthrow fluidError;\n\t\t\t});\n\t}\n\n\t/**\n\t * Api to fetch the response as it is for given request.\n\t * @param url - url of the request\n\t * @param fetchOptions - fetch options for request containing body, headers etc.\n\t * @param fetchType - method for which fetch is called.\n\t * @param addInBody - Pass True if caller wants to add epoch in post body.\n\t * @param fetchReason - fetch reason to add to the request.\n\t */\n\tpublic async fetchArray(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: RequestInit },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<ArrayBuffer>> {\n\t\treturn this.fetchCore<ArrayBuffer>(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\tfetchArray,\n\t\t\tfetchType,\n\t\t\taddInBody,\n\t\t\tfetchReason,\n\t\t);\n\t}\n\n\tprivate addEpochInRequest(\n\t\tfetchOptions: RequestInit,\n\t\taddInBody: boolean,\n\t\tclientCorrelationId: string,\n\t): void {\n\t\tconst isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;\n\t\tif (addInBody) {\n\t\t\tconst headers: { [key: string]: string } = {};\n\t\t\theaders[\"X-RequestStats\"] = clientCorrelationId;\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\theaders[\"x-fluid-epoch\"] = this.fluidEpoch;\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\theaders[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();\n\t\t\t}\n\t\t\tthis.addParamInBody(fetchOptions, headers);\n\t\t} else {\n\t\t\tconst addHeader = (key: string, val: string): void => {\n\t\t\t\tfetchOptions.headers = {\n\t\t\t\t\t...fetchOptions.headers,\n\t\t\t\t};\n\t\t\t\tassert(\n\t\t\t\t\tfetchOptions.headers !== undefined,\n\t\t\t\t\t0x282 /* \"Headers should be present now\" */,\n\t\t\t\t);\n\t\t\t\tfetchOptions.headers[key] = val;\n\t\t\t};\n\t\t\taddHeader(\"X-RequestStats\", clientCorrelationId);\n\t\t\tif (this.fluidEpoch !== undefined) {\n\t\t\t\taddHeader(\"x-fluid-epoch\", this.fluidEpoch);\n\t\t\t}\n\t\t\tif (isClpCompliantApp) {\n\t\t\t\taddHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string }): void {\n\t\t// We use multi part form request for post body where we want to use this.\n\t\t// So extract the form boundary to mark the end of form.\n\t\tconst body = fetchOptions.body;\n\t\tassert(typeof body === \"string\", 0x21d /* \"body is not string\" */);\n\t\tconst splitBody = body.split(\"\\r\\n\");\n\t\tconst firstLine = splitBody.shift();\n\t\tassert(firstLine?.startsWith(\"--\") === true, 0x21e /* \"improper boundary format\" */);\n\t\tconst formParams = [firstLine];\n\t\tfor (const [key, value] of Object.entries(headers)) {\n\t\t\tformParams.push(`${key}: ${value}`);\n\t\t}\n\t\tfor (const value of splitBody) {\n\t\t\tformParams.push(value);\n\t\t}\n\t\tfetchOptions.body = formParams.join(\"\\r\\n\");\n\t}\n\n\tprivate formatClientCorrelationId(fetchReason?: string): string {\n\t\tconst items: string[] = [\n\t\t\t`driverId=${this.driverId}`,\n\t\t\t`RequestNumber=${this.networkCallNumber++}`,\n\t\t\t`driverVersion=${driverVersion}`,\n\t\t\t`isSummarizer=${this.clientIsSummarizer}`,\n\t\t];\n\t\tif (fetchReason !== undefined) {\n\t\t\titems.push(`fetchReason=${fetchReason}`);\n\t\t}\n\t\treturn items.join(\", \");\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t): void {\n\t\tconst error = this.checkForEpochErrorCore(epochFromResponse);\n\t\tif (error !== undefined) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (epochFromResponse !== undefined && this._fluidEpoch === undefined) {\n\t\t\tthis.setEpoch(epochFromResponse, fromCache, fetchType);\n\t\t}\n\t}\n\n\tprivate async checkForEpochError(\n\t\terror: unknown,\n\t\tepochFromResponse: string | null | undefined,\n\t\tfetchType: FetchTypeInternal,\n\t\tfromCache: boolean = false,\n\t): Promise<void> {\n\t\tif (isFluidError(error) && error.errorType === OdspErrorTypes.fileOverwrittenInStorage) {\n\t\t\tconst epochError = this.checkForEpochErrorCore(epochFromResponse);\n\t\t\tif (epochError !== undefined) {\n\t\t\t\tepochError.addTelemetryProperties({\n\t\t\t\t\tfromCache,\n\t\t\t\t\tfetchType,\n\t\t\t\t});\n\t\t\t\tthis.logger.sendErrorEvent({ eventName: \"fileOverwrittenInStorage\" }, epochError);\n\t\t\t\t// If the epoch mismatches, then clear all entries for such file entry from cache.\n\t\t\t\tawait this.removeEntries();\n\t\t\t\tthrow epochError;\n\t\t\t}\n\t\t\t// If it was categorized as epoch error but the epoch returned in response matches with the client epoch\n\t\t\t// then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling\n\t\t\t// time is 1s.\n\t\t\tconst newError = wrapError(error, (message: string) => {\n\t\t\t\treturn new ThrottlingError(`Coherency 409: ${message}`, 1 /* retryAfterSeconds */, {\n\t\t\t\t\t[Odsp409Error]: true,\n\t\t\t\t\tdriverVersion,\n\t\t\t\t});\n\t\t\t});\n\t\t\tthrow newError;\n\t\t}\n\t}\n\n\tprivate checkForEpochErrorCore(\n\t\tepochFromResponse: string | null | undefined,\n\t): NonRetryableError<\"fileOverwrittenInStorage\"> | undefined {\n\t\t// If epoch is undefined, then don't compare it because initially for createNew or TreesLatest\n\t\t// initializes this value. Sometimes response does not contain epoch as it is still in\n\t\t// implementation phase at server side. In that case also, don't compare it with our epoch value.\n\t\tif (this.fluidEpoch && epochFromResponse && this.fluidEpoch !== epochFromResponse) {\n\t\t\t// This is similar in nature to how fluidEpochMismatchError (409) is handled.\n\t\t\t// Difference - client detected mismatch, instead of server detecting it.\n\t\t\treturn new NonRetryableError(\"Epoch mismatch\", OdspErrorTypes.fileOverwrittenInStorage, {\n\t\t\t\tdriverVersion,\n\t\t\t\tserverEpoch: epochFromResponse,\n\t\t\t\tclientEpoch: this.fluidEpoch,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate fileEntryFromEntry(entry: IEntry): ICacheEntry {\n\t\treturn { ...entry, file: this.fileEntry };\n\t}\n}\n\nexport class EpochTrackerWithRedemption extends EpochTracker {\n\tprivate readonly treesLatestDeferral = new Deferred<void>();\n\n\tconstructor(\n\t\tprotected readonly cache: IPersistedCache,\n\t\tprotected readonly fileEntry: IFileEntry,\n\t\tprotected readonly logger: ITelemetryLoggerExt,\n\t\tprotected readonly clientIsSummarizer?: boolean,\n\t) {\n\t\tsuper(cache, fileEntry, logger, clientIsSummarizer);\n\t\t// Handles the rejected promise within treesLatestDeferral.\n\t\tthis.treesLatestDeferral.promise.catch(() => {});\n\t}\n\n\tprotected validateEpochFromResponse(\n\t\tepochFromResponse: string | undefined,\n\t\tfetchType: FetchType,\n\t\tfromCache: boolean = false,\n\t): void {\n\t\tsuper.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);\n\n\t\t// Any successful call means we have access to a file, i.e. any redemption that was required already happened.\n\t\t// That covers cases of \"treesLatest\" as well as \"getVersions\" or \"createFile\" - all the ways we can start\n\t\t// exploring a file.\n\t\tthis.treesLatestDeferral.resolve();\n\t}\n\n\t// TODO: return a stronger type\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic async get(entry: IEntry): Promise<any> {\n\t\tlet result = super.get(entry);\n\n\t\t// equivalence of what happens in fetchAndParseAsJSON()\n\t\tif (entry.type === snapshotKey || entry.type === snapshotWithLoadingGroupIdKey) {\n\t\t\tresult = result\n\t\t\t\t.then((value) => {\n\t\t\t\t\t// If there is nothing in cache, we need to wait for network call to complete (and do redemption)\n\t\t\t\t\t// Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry\n\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\tthis.treesLatestDeferral.resolve();\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\t\t\treturn value;\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t}\n\t\treturn result;\n\t}\n\n\tpublic async fetchAndParseAsJSON<T>(\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: RequestInit },\n\t\tfetchType: FetchType,\n\t\taddInBody: boolean = false,\n\t\tfetchReason?: string,\n\t): Promise<IOdspResponse<T>> {\n\t\t// Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started\n\t\t// joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.\n\t\tconst completed = this.treesLatestDeferral.isCompleted;\n\n\t\ttry {\n\t\t\treturn await super.fetchAndParseAsJSON<T>(\n\t\t\t\turl,\n\t\t\t\tfetchOptions,\n\t\t\t\tfetchType,\n\t\t\t\taddInBody,\n\t\t\t\tfetchReason,\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\t// Only handling here treesLatest. If createFile failed, we should never try to do joinSession.\n\t\t\t// Similar, if getVersions failed, we should not do any further storage calls.\n\t\t\t// So treesLatest is the only call that can have parallel joinSession request.\n\t\t\tif (fetchType === \"treesLatest\") {\n\t\t\t\tthis.treesLatestDeferral.reject(error);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tfetchType !== \"joinSession\" ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\terror.statusCode < 401 ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\terror.statusCode > 404 ||\n\t\t\t\tcompleted\n\t\t\t) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\t// It is joinSession failing with 401..404 error\n\t\t// Repeat after waiting for treeLatest succeeding (or fail if it failed).\n\t\t// No special handling after first call - if file has been deleted, then it's game over.\n\n\t\t// Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.\n\t\t// If we waited too long, we will log error event and proceed with call.\n\t\t// It may result in failure for user, but refreshing document would address it.\n\t\t// Thus we use rather long timeout (not to get these failures as much as possible), but not large enough\n\t\t// to unblock the process.\n\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\tthis.logger,\n\t\t\t{ eventName: \"JoinSessionSyncWait\" },\n\t\t\tasync (event) => {\n\t\t\t\tconst timeoutRes = 51; // anything will work here\n\t\t\t\tlet timer: ReturnType<typeof setTimeout>;\n\t\t\t\tconst timeoutP = new Promise<number>((resolve) => {\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\tresolve(timeoutRes);\n\t\t\t\t\t}, 15000);\n\t\t\t\t});\n\t\t\t\tconst res = await Promise.race([\n\t\t\t\t\ttimeoutP,\n\t\t\t\t\t// cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)\n\t\t\t\t\tthis.treesLatestDeferral.promise.finally(() => clearTimeout(timer)),\n\t\t\t\t]);\n\t\t\t\tif (res === timeoutRes) {\n\t\t\t\t\tevent.cancel();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t);\n\t\treturn super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);\n\t}\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface ICacheAndTracker {\n\tcache: IOdspCache;\n\tepochTracker: EpochTracker;\n}\n\nexport function createOdspCacheAndTracker(\n\tpersistedCacheArg: IPersistedCache,\n\tnonpersistentCache: INonPersistentCache,\n\tfileEntry: IFileEntry,\n\tlogger: ITelemetryLoggerExt,\n\tclientIsSummarizer?: boolean,\n): ICacheAndTracker {\n\tconst epochTracker = new EpochTrackerWithRedemption(\n\t\tpersistedCacheArg,\n\t\tfileEntry,\n\t\tlogger,\n\t\tclientIsSummarizer,\n\t);\n\treturn {\n\t\tcache: {\n\t\t\t...nonpersistentCache,\n\t\t\tpersistedCache: epochTracker,\n\t\t},\n\t\tepochTracker,\n\t};\n}\n"]}
|
package/dist/fetchSnapshot.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export declare enum SnapshotFormatSupportType {
|
|
|
23
23
|
* @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched
|
|
24
24
|
* @param versionId - id of specific snapshot to be fetched
|
|
25
25
|
* @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)
|
|
26
|
-
* @param forceAccessTokenViaAuthorizationHeader -
|
|
26
|
+
* @param forceAccessTokenViaAuthorizationHeader - Deprecated and not used, true value always used instead. Whether to force passing given token via authorization header
|
|
27
27
|
* @param snapshotDownloader - Implementation of the get/post methods used to fetch the snapshot. snapshotDownloader is responsible for generating the appropriate headers (including Authorization header) as well as handling any token refreshes before retrying.
|
|
28
28
|
* @returns A promise of the snapshot and the status code of the response
|
|
29
29
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,SAAS,EAAiB,MAAM,6CAA6C,CAAC;AAUvF,OAAO,EAEN,gBAAgB,EAChB,gBAAgB,EAChB,+BAA+B,EAE/B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EACN,mBAAmB,EAKnB,MAAM,0CAA0C,CAAC;AAQlD,OAAO,EACN,aAAa,EAEb,wBAAwB,EAExB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EACN,aAAa,EASb,KAAK,mBAAmB,EACxB,MAAM,gBAAgB,CAAC;AAGxB;;;;GAIG;AACH,oBAAY,yBAAyB;IACpC,IAAI,IAAI;IACR,MAAM,IAAI;IACV,aAAa,IAAI;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAClE,OAAO,CAAC,SAAS,CAAC,CAkBpB;AAED,wBAAsB,uBAAuB,CAC5C,eAAe,EAAE,gBAAgB,EACjC,mBAAmB,EAAE,+BAA+B,EACpD,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,CACnB,oBAAoB,EAAE,gBAAgB,EACtC,aAAa,EAAE,+BAA+B,EAC9C,iBAAiB,EAAE,mBAAmB,EACtC,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,EACrC,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,UAAU,CAAC,EAAE,eAAe,KACxB,OAAO,CAAC,kCAAkC,CAAC,EAChD,UAAU,EAAE,CAAC,cAAc,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,EACvE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAClC,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,EACrC,oBAAoB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC,SAAS,CAAC,CAgFpB;
|
|
1
|
+
{"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,SAAS,EAAiB,MAAM,6CAA6C,CAAC;AAUvF,OAAO,EAEN,gBAAgB,EAChB,gBAAgB,EAChB,+BAA+B,EAE/B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EACN,mBAAmB,EAKnB,MAAM,0CAA0C,CAAC;AAQlD,OAAO,EACN,aAAa,EAEb,wBAAwB,EAExB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EACN,aAAa,EASb,KAAK,mBAAmB,EACxB,MAAM,gBAAgB,CAAC;AAGxB;;;;GAIG;AACH,oBAAY,yBAAyB;IACpC,IAAI,IAAI;IACR,MAAM,IAAI;IACV,aAAa,IAAI;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAClE,OAAO,CAAC,SAAS,CAAC,CAkBpB;AAED,wBAAsB,uBAAuB,CAC5C,eAAe,EAAE,gBAAgB,EACjC,mBAAmB,EAAE,+BAA+B,EACpD,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,CACnB,oBAAoB,EAAE,gBAAgB,EACtC,aAAa,EAAE,+BAA+B,EAC9C,iBAAiB,EAAE,mBAAmB,EACtC,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,EACrC,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,UAAU,CAAC,EAAE,eAAe,KACxB,OAAO,CAAC,kCAAkC,CAAC,EAChD,UAAU,EAAE,CAAC,cAAc,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,EACvE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAClC,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,EACrC,oBAAoB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC,SAAS,CAAC,CAgFpB;AA8XD,MAAM,WAAW,kCAAkC;IAClD,YAAY,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC5C;AAsCD,UAAU,UAAU;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,GAAG,UAAU,GAAG;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAY3F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CASnE;AAiBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACrC,eAAe,EAAE,gBAAgB,EACjC,aAAa,EAAE,+BAA+B,EAC9C,iBAAiB,EAAE,mBAAmB,EACtC,eAAe,EAAE,MAAM,EAAE,GAAG,SAAS,EACrC,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,uBAAuB,CAAC,EAAE,yBAAyB,EACnD,UAAU,CAAC,EAAE,eAAe,EAC5B,YAAY,CAAC,EAAE,YAAY,EAC3B,YAAY,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,kCAAkC,CAAC,CAsE7C"}
|
package/dist/fetchSnapshot.js
CHANGED
|
@@ -36,7 +36,7 @@ var SnapshotFormatSupportType;
|
|
|
36
36
|
* @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched
|
|
37
37
|
* @param versionId - id of specific snapshot to be fetched
|
|
38
38
|
* @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)
|
|
39
|
-
* @param forceAccessTokenViaAuthorizationHeader -
|
|
39
|
+
* @param forceAccessTokenViaAuthorizationHeader - Deprecated and not used, true value always used instead. Whether to force passing given token via authorization header
|
|
40
40
|
* @param snapshotDownloader - Implementation of the get/post methods used to fetch the snapshot. snapshotDownloader is responsible for generating the appropriate headers (including Authorization header) as well as handling any token refreshes before retrying.
|
|
41
41
|
* @returns A promise of the snapshot and the status code of the response
|
|
42
42
|
*/
|
|
@@ -264,11 +264,15 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, getAuthHeader, snapshotO
|
|
|
264
264
|
const props = snapshotContents.telemetryProps;
|
|
265
265
|
const slowTreeParseCodePaths = props.slowTreeStructureCount ?? 0;
|
|
266
266
|
const slowBlobParseCodePaths = props.slowBlobStructureCount ?? 0;
|
|
267
|
-
|
|
267
|
+
const treeStructureCountWithGroupId = props.treeStructureCountWithGroupId ?? 0;
|
|
268
|
+
// As trees with groupId go through normal parsing, so exclude them.
|
|
269
|
+
if (slowTreeParseCodePaths - treeStructureCountWithGroupId > 10 ||
|
|
270
|
+
slowBlobParseCodePaths > 10) {
|
|
268
271
|
logger.sendErrorEvent({
|
|
269
272
|
eventName: "SlowSnapshotParseCodePaths",
|
|
270
273
|
slowTreeStructureCount: slowTreeParseCodePaths,
|
|
271
274
|
slowBlobStructureCount: slowBlobParseCodePaths,
|
|
275
|
+
treeStructureCountWithGroupId,
|
|
272
276
|
});
|
|
273
277
|
}
|
|
274
278
|
parsedSnapshotContents = { ...odspResponse, content: snapshotContents };
|
|
@@ -295,7 +299,8 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, getAuthHeader, snapshotO
|
|
|
295
299
|
!fetchSnapshotForLoadingGroup;
|
|
296
300
|
const sequenceNumber = snapshot.sequenceNumber ?? 0;
|
|
297
301
|
const seqNumberFromOps = snapshot.ops && snapshot.ops.length > 0
|
|
298
|
-
?
|
|
302
|
+
? // Non null asserting here because of the length check above
|
|
303
|
+
snapshot.ops[0].sequenceNumber - 1
|
|
299
304
|
: undefined;
|
|
300
305
|
if (!Number.isInteger(sequenceNumber) ||
|
|
301
306
|
(seqNumberFromOps !== undefined && seqNumberFromOps !== sequenceNumber)) {
|