@fluidframework/odsp-driver 2.0.0-internal.5.3.4 → 2.0.0-internal.5.4.2

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/fetchSnapshot.d.ts +0 -1
  3. package/dist/fetchSnapshot.d.ts.map +1 -1
  4. package/dist/fetchSnapshot.js +1 -5
  5. package/dist/fetchSnapshot.js.map +1 -1
  6. package/dist/odspDeltaStorageService.d.ts +4 -2
  7. package/dist/odspDeltaStorageService.d.ts.map +1 -1
  8. package/dist/odspDeltaStorageService.js +12 -10
  9. package/dist/odspDeltaStorageService.js.map +1 -1
  10. package/dist/odspDocumentService.d.ts.map +1 -1
  11. package/dist/odspDocumentService.js +8 -5
  12. package/dist/odspDocumentService.js.map +1 -1
  13. package/dist/odspDocumentStorageManager.d.ts +2 -0
  14. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  15. package/dist/odspDocumentStorageManager.js +6 -0
  16. package/dist/odspDocumentStorageManager.js.map +1 -1
  17. package/dist/packageVersion.d.ts +1 -1
  18. package/dist/packageVersion.js +1 -1
  19. package/dist/packageVersion.js.map +1 -1
  20. package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
  21. package/dist/prefetchLatestSnapshot.js +1 -1
  22. package/dist/prefetchLatestSnapshot.js.map +1 -1
  23. package/lib/fetchSnapshot.d.ts +0 -1
  24. package/lib/fetchSnapshot.d.ts.map +1 -1
  25. package/lib/fetchSnapshot.js +0 -1
  26. package/lib/fetchSnapshot.js.map +1 -1
  27. package/lib/odspDeltaStorageService.d.ts +4 -2
  28. package/lib/odspDeltaStorageService.d.ts.map +1 -1
  29. package/lib/odspDeltaStorageService.js +11 -6
  30. package/lib/odspDeltaStorageService.js.map +1 -1
  31. package/lib/odspDocumentService.d.ts.map +1 -1
  32. package/lib/odspDocumentService.js +9 -6
  33. package/lib/odspDocumentService.js.map +1 -1
  34. package/lib/odspDocumentStorageManager.d.ts +2 -0
  35. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  36. package/lib/odspDocumentStorageManager.js +6 -0
  37. package/lib/odspDocumentStorageManager.js.map +1 -1
  38. package/lib/packageVersion.d.ts +1 -1
  39. package/lib/packageVersion.js +1 -1
  40. package/lib/packageVersion.js.map +1 -1
  41. package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
  42. package/lib/prefetchLatestSnapshot.js +2 -2
  43. package/lib/prefetchLatestSnapshot.js.map +1 -1
  44. package/package.json +12 -13
  45. package/src/fetchSnapshot.ts +0 -1
  46. package/src/odspDeltaStorageService.ts +10 -5
  47. package/src/odspDocumentService.ts +7 -6
  48. package/src/odspDocumentStorageManager.ts +8 -2
  49. package/src/packageVersion.ts +1 -1
  50. package/src/prefetchLatestSnapshot.ts +4 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @fluidframework/odsp-driver
2
2
 
3
+ ## 2.0.0-internal.5.4.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.0.0-internal.5.3.0
4
8
 
5
9
  ### Minor Changes
@@ -2,7 +2,6 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { default as AbortController } from "abort-controller";
6
5
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
7
6
  import { IOdspResolvedUrl, ISnapshotOptions, InstrumentedStorageTokenFetcher } from "@fluidframework/odsp-driver-definitions";
8
7
  import { IOdspSnapshot, IVersionedValueWithEpoch } from "./contracts";
@@ -1 +1 @@
1
- {"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EACN,mBAAmB,EAInB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAEhB,+BAA+B,EAC/B,MAAM,yCAAyC,CAAC;AAOjD,OAAO,EACN,aAAa,EAEb,wBAAwB,EAExB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAKN,aAAa,EAGb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,oBAAY,yBAAyB;IACpC,IAAI,IAAI;IACR,MAAM,IAAI;IACV,aAAa,IAAI;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAClC,WAAW,EAAE,MAAM,EAEnB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,CACnB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,KAClC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAuB5B;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,YAAY,EAAE,MAAM,EACpB,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,oBAAoB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAwE5B;AA0RD,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,GAAG,CAAA;KAAE,CAAC;CACzC;AAuCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB;;;;EAQ5D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,QAS5D;AAWD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACrC,eAAe,EAAE,gBAAgB,EACjC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,mBAAmB,EAC3B,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,CAiD7C"}
1
+ {"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,mBAAmB,EAInB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAEhB,+BAA+B,EAC/B,MAAM,yCAAyC,CAAC;AAOjD,OAAO,EACN,aAAa,EAEb,wBAAwB,EAExB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAKN,aAAa,EAGb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,oBAAY,yBAAyB;IACpC,IAAI,IAAI;IACR,MAAM,IAAI;IACV,aAAa,IAAI;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAClC,WAAW,EAAE,MAAM,EAEnB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,mBAAmB,EAC3B,kBAAkB,EAAE,CACnB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,KAClC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAClC,OAAO,CAAC,iBAAiB,CAAC,CAuB5B;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,YAAY,EAAE,MAAM,EACpB,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,oBAAoB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAwE5B;AA0RD,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,GAAG,CAAA;KAAE,CAAC;CACzC;AAuCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB;;;;EAQ5D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,QAS5D;AAWD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACrC,eAAe,EAAE,gBAAgB,EACjC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,mBAAmB,EAC3B,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,CAiD7C"}
@@ -3,12 +3,8 @@
3
3
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
4
  * Licensed under the MIT License.
5
5
  */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
6
  Object.defineProperty(exports, "__esModule", { value: true });
10
7
  exports.downloadSnapshot = exports.validateBlobsAndTrees = exports.evalBlobsAndTrees = exports.fetchSnapshotWithRedeem = exports.fetchSnapshot = exports.SnapshotFormatSupportType = void 0;
11
- const abort_controller_1 = __importDefault(require("abort-controller"));
12
8
  const uuid_1 = require("uuid");
13
9
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
14
10
  const common_utils_1 = require("@fluidframework/common-utils");
@@ -138,7 +134,7 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, storageTokenFetcher, sna
138
134
  let controller;
139
135
  let fetchTimeout;
140
136
  if ((snapshotOptions === null || snapshotOptions === void 0 ? void 0 : snapshotOptions.timeout) !== undefined) {
141
- controller = new abort_controller_1.default();
137
+ controller = new AbortController();
142
138
  fetchTimeout = setTimeout(() => controller.abort(), snapshotOptions.timeout);
143
139
  }
144
140
  const [response, fetchTime] = await (0, odspUtils_1.measureP)(async () => snapshotDownloader(odspResolvedUrl, storageToken, snapshotOptions, controller)).finally(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"fetchSnapshot.js","sourceRoot":"","sources":["../src/fetchSnapshot.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 { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n\tITelemetryLoggerExt,\n\tisFluidError,\n\tPerformanceEvent,\n\twrapError,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert, fromUtf8ToBase64 } from \"@fluidframework/common-utils\";\nimport { getW3CData } from \"@fluidframework/driver-base\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n\tIOdspResolvedUrl,\n\tISnapshotOptions,\n\tOdspErrorType,\n\tInstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tDriverErrorTelemetryProps,\n\tisRuntimeMessage,\n\tNonRetryableError,\n} from \"@fluidframework/driver-utils\";\nimport {\n\tIOdspSnapshot,\n\tISnapshotCachedEntry,\n\tIVersionedValueWithEpoch,\n\tpersistedCacheValueVersion,\n} from \"./contracts\";\nimport { getQueryString } from \"./getQueryString\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n\tfetchAndParseAsJSONHelper,\n\tfetchHelper,\n\tgetWithRetryForTokenRefresh,\n\tgetWithRetryForTokenRefreshRepeat,\n\tIOdspResponse,\n\tmeasure,\n\tmeasureP,\n} from \"./odspUtils\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"./odspSnapshotParser\";\nimport {\n\tcurrentReadVersion,\n\tISnapshotContentsWithProps,\n\tparseCompactSnapshotResponse,\n} from \"./compactSnapshotParser\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { pkgVersion } from \"./packageVersion\";\n\n/**\n * Enum to support different types of snapshot formats.\n */\nexport enum SnapshotFormatSupportType {\n\tJson = 0,\n\tBinary = 1,\n\tJsonAndBinary = 2,\n}\n\n/**\n * Fetches a snapshot from the server with a given version id.\n * @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched\n * @param token - token used for authorization in the request\n * @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot\n * @param versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n\tsnapshotUrl: string,\n\t// eslint-disable-next-line @rushstack/no-new-null\n\ttoken: string | null,\n\tversionId: string,\n\tfetchFullSnapshot: boolean,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshotContents> {\n\tconst path = `/trees/${versionId}`;\n\tlet queryParams: ISnapshotOptions = {};\n\n\tif (fetchFullSnapshot) {\n\t\tqueryParams = versionId !== \"latest\" ? { blobs: 2 } : { deltas: 1, blobs: 2 };\n\t}\n\n\tconst queryString = getQueryString(queryParams);\n\tconst { url, headers } = getUrlAndHeadersWithAuth(\n\t\t`${snapshotUrl}${path}${queryString}`,\n\t\ttoken,\n\t\tforceAccessTokenViaAuthorizationHeader,\n\t);\n\tconst response = (await PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"fetchSnapshot\",\n\t\t\theaders: Object.keys(headers).length !== 0 ? true : undefined,\n\t\t},\n\t\tasync () => snapshotDownloader(url, { headers }),\n\t)) as IOdspResponse<IOdspSnapshot>;\n\treturn convertOdspSnapshotToSnapshotTreeAndBlobs(response.content);\n}\n\nexport async function fetchSnapshotWithRedeem(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageTokenFetcher: InstrumentedStorageTokenFetcher,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tstorageToken: string,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tremoveEntries: () => Promise<void>,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\tif (sharingLinkToRedeem) {\n\t\todspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n\t}\n\n\treturn fetchLatestSnapshotCore(\n\t\todspResolvedUrl,\n\t\tstorageTokenFetcher,\n\t\tsnapshotOptions,\n\t\tlogger,\n\t\tsnapshotDownloader,\n\t\tputInCache,\n\t\tenableRedeemFallback,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tif (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n\t\t\t\t// Execute the redeem fallback\n\n\t\t\t\tawait redeemSharingLink(\n\t\t\t\t\todspResolvedUrl,\n\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\tlogger,\n\t\t\t\t\tforceAccessTokenViaAuthorizationHeader,\n\t\t\t\t);\n\t\t\t\tconst odspResolvedUrlWithoutShareLink: IOdspResolvedUrl = {\n\t\t\t\t\t...odspResolvedUrl,\n\t\t\t\t\tshareLinkInfo: {\n\t\t\t\t\t\t...odspResolvedUrl.shareLinkInfo,\n\t\t\t\t\t\tsharingLinkToRedeem: undefined,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\t// Log initial failure only if redeem succeeded - it points out to some bug somewhere\n\t\t\t\t// If redeem failed, that most likely means user has no permissions to access a file,\n\t\t\t\t// and thus it's not worth it logging extra errors - same error will be logged by end-to-end\n\t\t\t\t// flow (container open) based on a failure above.\n\t\t\t\tlogger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"RedeemFallback\",\n\t\t\t\t\t\terrorType: error.errorType,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\n\t\t\t\treturn fetchLatestSnapshotCore(\n\t\t\t\t\todspResolvedUrlWithoutShareLink,\n\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\tsnapshotOptions,\n\t\t\t\t\tlogger,\n\t\t\t\t\tsnapshotDownloader,\n\t\t\t\t\tputInCache,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t})\n\t\t.catch(async (error) => {\n\t\t\t// Clear the cache on 401/403/404 on snapshot fetch from network because this means either the user doesn't\n\t\t\t// have permissions for the file or it was deleted. So, if we do not clear cache, we will continue fetching\n\t\t\t// snapshot from cache in the future.\n\t\t\tif (\n\t\t\t\t(typeof error === \"object\" &&\n\t\t\t\t\terror !== null &&\n\t\t\t\t\terror.errorType === DriverErrorType.authorizationError) ||\n\t\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError\n\t\t\t) {\n\t\t\t\tawait removeEntries();\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n}\n\nasync function redeemSharingLink(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageTokenFetcher: InstrumentedStorageTokenFetcher,\n\tlogger: ITelemetryLoggerExt,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n) {\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"RedeemShareLink\",\n\t\t},\n\t\tasync () =>\n\t\t\tgetWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\t\t\tassert(\n\t\t\t\t\t!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t\t\t0x1ed /* \"Share link should be present\" */,\n\t\t\t\t);\n\t\t\t\tconst storageToken = await storageTokenFetcher(\n\t\t\t\t\ttokenFetchOptions,\n\t\t\t\t\t\"RedeemShareLink\",\n\t\t\t\t);\n\t\t\t\tconst encodedShareUrl = getEncodedShareUrl(\n\t\t\t\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t\t);\n\t\t\t\tconst redeemUrl = `${odspResolvedUrl.siteUrl}/_api/v2.0/shares/${encodedShareUrl}`;\n\t\t\t\tconst { url, headers } = getUrlAndHeadersWithAuth(\n\t\t\t\t\tredeemUrl,\n\t\t\t\t\tstorageToken,\n\t\t\t\t\tforceAccessTokenViaAuthorizationHeader,\n\t\t\t\t);\n\t\t\t\theaders.prefer = \"redeemSharingLink\";\n\t\t\t\treturn fetchAndParseAsJSONHelper(url, { headers });\n\t\t\t}),\n\t);\n}\n\nasync function fetchLatestSnapshotCore(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageTokenFetcher: InstrumentedStorageTokenFetcher,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tstorageToken: string,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n\treturn getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\tconst storageToken = await storageTokenFetcher(tokenFetchOptions, \"TreesLatest\", true);\n\t\tassert(storageToken !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\n\t\tconst perfEvent = {\n\t\t\teventName: \"TreesLatest\",\n\t\t\tattempts: tokenFetchOptions.refresh ? 2 : 1,\n\t\t\tshareLinkPresent: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined,\n\t\t\tisSummarizer: odspResolvedUrl.summarizer,\n\t\t\tredeemFallbackEnabled: enableRedeemFallback,\n\t\t};\n\t\tif (snapshotOptions !== undefined) {\n\t\t\tObject.entries(snapshotOptions).forEach(([key, value]) => {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tperfEvent[`snapshotOption_${key}`] = value;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t// This event measures only successful cases of getLatest call (no tokens, no retries).\n\t\treturn PerformanceEvent.timedExecAsync(logger, perfEvent, async (event) => {\n\t\t\tlet controller: AbortController | undefined;\n\t\t\tlet fetchTimeout: ReturnType<typeof setTimeout> | undefined;\n\t\t\tif (snapshotOptions?.timeout !== undefined) {\n\t\t\t\tcontroller = new AbortController();\n\t\t\t\tfetchTimeout = setTimeout(() => controller!.abort(), snapshotOptions.timeout);\n\t\t\t}\n\n\t\t\tconst [response, fetchTime] = await measureP(async () =>\n\t\t\t\tsnapshotDownloader(odspResolvedUrl, storageToken, snapshotOptions, controller),\n\t\t\t).finally(() => {\n\t\t\t\t// Clear the fetchTimeout once the response is fetched.\n\t\t\t\tif (fetchTimeout !== undefined) {\n\t\t\t\t\tclearTimeout(fetchTimeout);\n\t\t\t\t\tfetchTimeout = undefined;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst odspResponse = response.odspResponse;\n\t\t\tconst contentType = odspResponse.headers.get(\"content-type\");\n\n\t\t\tconst propsToLog: DriverErrorTelemetryProps = {\n\t\t\t\t...odspResponse.propsToLog,\n\t\t\t\tcontentType,\n\t\t\t\taccept: response.requestHeaders.accept,\n\t\t\t\tdriverVersion: pkgVersion,\n\t\t\t};\n\n\t\t\tlet parsedSnapshotContents: IOdspResponse<ISnapshotContentsWithProps> | undefined;\n\t\t\tlet contentTypeToRead: string | undefined;\n\t\t\tif (contentType?.includes(\"application/ms-fluid\")) {\n\t\t\t\tcontentTypeToRead = \"application/ms-fluid\";\n\t\t\t} else if (contentType?.includes(\"application/json\")) {\n\t\t\t\tcontentTypeToRead = \"application/json\";\n\t\t\t}\n\n\t\t\tlet parseTime: number;\n\t\t\tlet receiveContentTime: number;\n\t\t\ttry {\n\t\t\t\tswitch (contentTypeToRead) {\n\t\t\t\t\tcase \"application/json\": {\n\t\t\t\t\t\tlet text: string;\n\t\t\t\t\t\t[text, receiveContentTime] = await measureP(async () =>\n\t\t\t\t\t\t\todspResponse.content.text(),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tpropsToLog.bodySize = text.length;\n\t\t\t\t\t\tlet content: IOdspSnapshot;\n\t\t\t\t\t\t[content, parseTime] = measure(() => JSON.parse(text) as IOdspSnapshot);\n\t\t\t\t\t\tvalidateBlobsAndTrees(content);\n\t\t\t\t\t\tconst snapshotContents: ISnapshotContents =\n\t\t\t\t\t\t\tconvertOdspSnapshotToSnapshotTreeAndBlobs(content);\n\t\t\t\t\t\tparsedSnapshotContents = {\n\t\t\t\t\t\t\t...odspResponse,\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t...snapshotContents,\n\t\t\t\t\t\t\t\ttelemetryProps: {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"application/ms-fluid\": {\n\t\t\t\t\t\tlet content: ArrayBuffer;\n\t\t\t\t\t\t[content, receiveContentTime] = await measureP(async () =>\n\t\t\t\t\t\t\todspResponse.content.arrayBuffer(),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tpropsToLog.bodySize = content.byteLength;\n\t\t\t\t\t\tlet snapshotContents: ISnapshotContentsWithProps;\n\t\t\t\t\t\t[snapshotContents, parseTime] = measure(() =>\n\t\t\t\t\t\t\tparseCompactSnapshotResponse(new Uint8Array(content), logger),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tsnapshotContents.snapshotTree.trees === undefined ||\n\t\t\t\t\t\t\tsnapshotContents.snapshotTree.blobs === undefined\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\t\t\"Returned odsp snapshot is malformed. No trees or blobs!\",\n\t\t\t\t\t\t\t\tDriverErrorType.incorrectServerResponse,\n\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst props = snapshotContents.telemetryProps;\n\t\t\t\t\t\tconst slowTreeParseCodePaths = props.slowTreeStructureCount ?? 0;\n\t\t\t\t\t\tconst slowBlobParseCodePaths = props.slowBlobStructureCount ?? 0;\n\t\t\t\t\t\tif (slowTreeParseCodePaths > 10 || slowBlobParseCodePaths > 10) {\n\t\t\t\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\t\t\t\teventName: \"SlowSnapshotParseCodePaths\",\n\t\t\t\t\t\t\t\tslowTreeStructureCount: slowTreeParseCodePaths,\n\t\t\t\t\t\t\t\tslowBlobStructureCount: slowBlobParseCodePaths,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparsedSnapshotContents = { ...odspResponse, content: snapshotContents };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\t\"Unknown snapshot content type\",\n\t\t\t\t\t\t\tDriverErrorType.incorrectServerResponse,\n\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isFluidError(error)) {\n\t\t\t\t\terror.addTelemetryProperties(propsToLog);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst enhancedError = wrapError(\n\t\t\t\t\terror,\n\t\t\t\t\t(errorMessage) =>\n\t\t\t\t\t\tnew NonRetryableError(\n\t\t\t\t\t\t\t`Error parsing snapshot response: ${errorMessage}`,\n\t\t\t\t\t\t\tDriverErrorType.genericError,\n\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tthrow enhancedError;\n\t\t\t}\n\n\t\t\tassert(parsedSnapshotContents !== undefined, 0x312 /* snapshot should be parsed */);\n\t\t\tconst snapshot = parsedSnapshotContents.content;\n\t\t\tconst { trees, numBlobs, encodedBlobsSize } = evalBlobsAndTrees(snapshot);\n\n\t\t\t// There are some scenarios in ODSP where we cannot cache, trees/latest will explicitly tell us when we\n\t\t\t// cannot cache using an HTTP response header.\n\t\t\tconst canCache =\n\t\t\t\todspResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\";\n\t\t\tconst sequenceNumber: number = snapshot.sequenceNumber ?? 0;\n\t\t\tconst seqNumberFromOps =\n\t\t\t\tsnapshot.ops && snapshot.ops.length > 0\n\t\t\t\t\t? snapshot.ops[0].sequenceNumber - 1\n\t\t\t\t\t: undefined;\n\n\t\t\tif (\n\t\t\t\t!Number.isInteger(sequenceNumber) ||\n\t\t\t\t(seqNumberFromOps !== undefined && seqNumberFromOps !== sequenceNumber)\n\t\t\t) {\n\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\teventName: \"fetchSnapshotError\",\n\t\t\t\t\tsequenceNumber,\n\t\t\t\t\tseqNumberFromOps,\n\t\t\t\t});\n\t\t\t\tsnapshot.sequenceNumber = undefined;\n\t\t\t} else if (canCache) {\n\t\t\t\tconst fluidEpoch = odspResponse.headers.get(\"x-fluid-epoch\");\n\t\t\t\tassert(\n\t\t\t\t\tfluidEpoch !== undefined,\n\t\t\t\t\t0x1e6 /* \"Epoch should be present in response\" */,\n\t\t\t\t);\n\t\t\t\tconst value: ISnapshotCachedEntry = {\n\t\t\t\t\t...snapshot,\n\t\t\t\t\tcacheEntryTime: Date.now(),\n\t\t\t\t};\n\t\t\t\tconst valueWithEpoch: IVersionedValueWithEpoch = {\n\t\t\t\t\tvalue,\n\t\t\t\t\tfluidEpoch,\n\t\t\t\t\tversion: persistedCacheValueVersion,\n\t\t\t\t};\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\t\tputInCache(valueWithEpoch);\n\t\t\t}\n\n\t\t\tevent.end({\n\t\t\t\ttrees,\n\t\t\t\tblobs: snapshot.blobs?.size ?? 0,\n\t\t\t\tleafNodes: numBlobs,\n\t\t\t\tencodedBlobsSize,\n\t\t\t\tsequenceNumber,\n\t\t\t\tops: snapshot.ops?.length ?? 0,\n\t\t\t\tuserOps: snapshot.ops?.filter((op) => isRuntimeMessage(op)).length ?? 0,\n\t\t\t\theaders: Object.keys(response.requestHeaders).length !== 0 ? true : undefined,\n\t\t\t\t// Measures time to make fetch call. Should be similar to\n\t\t\t\t// fetchStartToResponseEndTime - receiveContentTime, i.e. it looks like it's time till first byte /\n\t\t\t\t// end of response headers\n\t\t\t\tfetchTime,\n\t\t\t\t// time it takes client to parse payload. Same payload as in \"SnapshotParse\" event, here for\n\t\t\t\t// easier analyzes.\n\t\t\t\tparseTime,\n\t\t\t\t// Time it takes to receive content (text of buffer) from Response object.\n\t\t\t\t// This time likely is very closely correlated with networkTime, i.e. time it takes to receive\n\t\t\t\t// actual content (starting measuring from first bite / end of response header)\n\t\t\t\treceiveContentTime,\n\t\t\t\t...getW3CData(response.requestUrl, \"fetch\"),\n\t\t\t\t// Sharing link telemetry regarding sharing link redeem status and performance. Ex: FRL; dur=100,\n\t\t\t\t// Azure Fluid Relay service; desc=S, FRP; desc=False. Here, FRL is the duration taken for redeem,\n\t\t\t\t// Azure Fluid Relay service is the redeem status (S means success), and FRP is a flag to indicate\n\t\t\t\t// if the permission has changed.\n\t\t\t\tsltelemetry: odspResponse.headers.get(\"x-fluid-sltelemetry\"),\n\t\t\t\t// All other props\n\t\t\t\t...propsToLog,\n\t\t\t\t// Various perf counters and measures collected by binary parsing code:\n\t\t\t\t// slowTreeStructureCount, slowBlobStructureCount, durationStructure, durationStrings,\n\t\t\t\t// durationSnapshotTree, durationBlobs, etc.\n\t\t\t\t...parsedSnapshotContents.content.telemetryProps,\n\t\t\t});\n\t\t\treturn snapshot;\n\t\t}).catch((error) => {\n\t\t\t// We hit these errors in stress tests, under load\n\t\t\t// It's useful to try one more time in such case.\n\t\t\tif (\n\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\terror !== null &&\n\t\t\t\t(error.errorType === DriverErrorType.fetchFailure ||\n\t\t\t\t\terror.errorType === OdspErrorType.fetchTimeout)\n\t\t\t) {\n\t\t\t\terror[getWithRetryForTokenRefreshRepeat] = true;\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t});\n}\n\nexport interface ISnapshotRequestAndResponseOptions {\n\todspResponse: IOdspResponse<Response>;\n\trequestUrl: string;\n\trequestHeaders: { [index: string]: any };\n}\n\nfunction getFormBodyAndHeaders(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageToken: string,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\theaders?: { [index: string]: string },\n) {\n\tconst formBoundary = uuid();\n\tconst formParams: string[] = [];\n\tformParams.push(`--${formBoundary}`);\n\tformParams.push(`Authorization: Bearer ${storageToken}`);\n\tformParams.push(`X-HTTP-Method-Override: GET`);\n\tif (snapshotOptions !== undefined) {\n\t\tObject.entries(snapshotOptions).forEach(([key, value]) => {\n\t\t\tif (value !== undefined) {\n\t\t\t\tformParams.push(`${key}: ${value}`);\n\t\t\t}\n\t\t});\n\t}\n\tif (headers !== undefined) {\n\t\tObject.entries(headers).forEach(([key, value]) => {\n\t\t\tif (value !== undefined) {\n\t\t\t\tformParams.push(`${key}: ${value}`);\n\t\t\t}\n\t\t});\n\t}\n\tif (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem) {\n\t\tformParams.push(`sl: ${odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem}`);\n\t}\n\tformParams.push(`_post: 1`);\n\tformParams.push(`\\r\\n--${formBoundary}--`);\n\tconst postBody = formParams.join(\"\\r\\n\");\n\tconst header: { [index: string]: any } = {\n\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t};\n\treturn { body: postBody, headers: header };\n}\n\nexport function evalBlobsAndTrees(snapshot: ISnapshotContents) {\n\tconst trees = countTreesInSnapshotTree(snapshot.snapshotTree);\n\tconst numBlobs = snapshot.blobs.size;\n\tlet encodedBlobsSize = 0;\n\tfor (const [_, blobContent] of snapshot.blobs) {\n\t\tencodedBlobsSize += blobContent.byteLength;\n\t}\n\treturn { trees, numBlobs, encodedBlobsSize };\n}\n\nexport function validateBlobsAndTrees(snapshot: IOdspSnapshot) {\n\tassert(\n\t\tsnapshot.trees !== undefined,\n\t\t0x200 /* \"Returned odsp snapshot is malformed. No trees!\" */,\n\t);\n\tassert(\n\t\tsnapshot.blobs !== undefined,\n\t\t0x201 /* \"Returned odsp snapshot is malformed. No blobs!\" */,\n\t);\n}\n\nfunction countTreesInSnapshotTree(snapshotTree: ISnapshotTree): number {\n\tlet numTrees = 0;\n\tfor (const [_, tree] of Object.entries(snapshotTree.trees)) {\n\t\tnumTrees += 1;\n\t\tnumTrees += countTreesInSnapshotTree(tree);\n\t}\n\treturn numTrees;\n}\n\n/**\n * This function fetches the snapshot and parse it according to what is mentioned in response headers.\n * @param odspResolvedUrl - resolved odsp url.\n * @param storageToken - token to do the auth for network request.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param controller - abort controller if caller needs to abort the network call.\n * @param epochTracker - epoch tracker used to add/validate epoch in the network call.\n * @returns fetched snapshot.\n */\nexport async function downloadSnapshot(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageToken: string,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tsnapshotFormatFetchType?: SnapshotFormatSupportType,\n\tcontroller?: AbortController,\n\tepochTracker?: EpochTracker,\n\tscenarioName?: string,\n): Promise<ISnapshotRequestAndResponseOptions> {\n\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\tif (sharingLinkToRedeem) {\n\t\todspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n\t}\n\n\tconst snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n\tconst url = `${snapshotUrl}/trees/latest?ump=1`;\n\t// The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n\t// Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n\t// This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n\t// for futher reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n\tconst header = { prefer: \"manualredirect\" };\n\tconst { body, headers } = getFormBodyAndHeaders(\n\t\todspResolvedUrl,\n\t\tstorageToken,\n\t\tsnapshotOptions,\n\t\theader,\n\t);\n\tconst fetchOptions = {\n\t\tbody,\n\t\theaders,\n\t\tsignal: controller?.signal,\n\t\tmethod: \"POST\",\n\t};\n\t// Decide what snapshot format to fetch as per the feature gate.\n\tswitch (snapshotFormatFetchType) {\n\t\tcase SnapshotFormatSupportType.Binary:\n\t\t\theaders.accept = `application/ms-fluid; v=${currentReadVersion}`;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// By default ask both versions and let the server decide the format.\n\t\t\theaders.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n\t}\n\n\tconst odspResponse = await (epochTracker?.fetch(\n\t\turl,\n\t\tfetchOptions,\n\t\t\"treesLatest\",\n\t\ttrue,\n\t\tscenarioName,\n\t) ?? fetchHelper(url, fetchOptions));\n\n\treturn {\n\t\todspResponse,\n\t\trequestHeaders: headers,\n\t\trequestUrl: url,\n\t};\n}\n\nfunction isRedeemSharingLinkError(odspResolvedUrl: IOdspResolvedUrl, error: any) {\n\tif (\n\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined &&\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error.errorType === DriverErrorType.authorizationError ||\n\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError)\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nfunction getEncodedShareUrl(url: string): string {\n\t/**\n\t * Encode the url to accepted format by Sharepoint\n\t * https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get\n\t */\n\tlet encodedUrl = fromUtf8ToBase64(encodeURI(url));\n\tencodedUrl = encodedUrl.replace(/=+$/g, \"\").replace(/\\//g, \"_\").replace(/\\+/g, \"-\");\n\tencodedUrl = \"u!\".concat(encodedUrl);\n\treturn encodedUrl;\n}\n"]}
1
+ {"version":3,"file":"fetchSnapshot.js","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport {\n\tITelemetryLoggerExt,\n\tisFluidError,\n\tPerformanceEvent,\n\twrapError,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert, fromUtf8ToBase64 } from \"@fluidframework/common-utils\";\nimport { getW3CData } from \"@fluidframework/driver-base\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n\tIOdspResolvedUrl,\n\tISnapshotOptions,\n\tOdspErrorType,\n\tInstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tDriverErrorTelemetryProps,\n\tisRuntimeMessage,\n\tNonRetryableError,\n} from \"@fluidframework/driver-utils\";\nimport {\n\tIOdspSnapshot,\n\tISnapshotCachedEntry,\n\tIVersionedValueWithEpoch,\n\tpersistedCacheValueVersion,\n} from \"./contracts\";\nimport { getQueryString } from \"./getQueryString\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n\tfetchAndParseAsJSONHelper,\n\tfetchHelper,\n\tgetWithRetryForTokenRefresh,\n\tgetWithRetryForTokenRefreshRepeat,\n\tIOdspResponse,\n\tmeasure,\n\tmeasureP,\n} from \"./odspUtils\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"./odspSnapshotParser\";\nimport {\n\tcurrentReadVersion,\n\tISnapshotContentsWithProps,\n\tparseCompactSnapshotResponse,\n} from \"./compactSnapshotParser\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { pkgVersion } from \"./packageVersion\";\n\n/**\n * Enum to support different types of snapshot formats.\n */\nexport enum SnapshotFormatSupportType {\n\tJson = 0,\n\tBinary = 1,\n\tJsonAndBinary = 2,\n}\n\n/**\n * Fetches a snapshot from the server with a given version id.\n * @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched\n * @param token - token used for authorization in the request\n * @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot\n * @param versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n\tsnapshotUrl: string,\n\t// eslint-disable-next-line @rushstack/no-new-null\n\ttoken: string | null,\n\tversionId: string,\n\tfetchFullSnapshot: boolean,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\turl: string,\n\t\tfetchOptions: { [index: string]: any },\n\t) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshotContents> {\n\tconst path = `/trees/${versionId}`;\n\tlet queryParams: ISnapshotOptions = {};\n\n\tif (fetchFullSnapshot) {\n\t\tqueryParams = versionId !== \"latest\" ? { blobs: 2 } : { deltas: 1, blobs: 2 };\n\t}\n\n\tconst queryString = getQueryString(queryParams);\n\tconst { url, headers } = getUrlAndHeadersWithAuth(\n\t\t`${snapshotUrl}${path}${queryString}`,\n\t\ttoken,\n\t\tforceAccessTokenViaAuthorizationHeader,\n\t);\n\tconst response = (await PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"fetchSnapshot\",\n\t\t\theaders: Object.keys(headers).length !== 0 ? true : undefined,\n\t\t},\n\t\tasync () => snapshotDownloader(url, { headers }),\n\t)) as IOdspResponse<IOdspSnapshot>;\n\treturn convertOdspSnapshotToSnapshotTreeAndBlobs(response.content);\n}\n\nexport async function fetchSnapshotWithRedeem(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageTokenFetcher: InstrumentedStorageTokenFetcher,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tstorageToken: string,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tremoveEntries: () => Promise<void>,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\tif (sharingLinkToRedeem) {\n\t\todspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n\t}\n\n\treturn fetchLatestSnapshotCore(\n\t\todspResolvedUrl,\n\t\tstorageTokenFetcher,\n\t\tsnapshotOptions,\n\t\tlogger,\n\t\tsnapshotDownloader,\n\t\tputInCache,\n\t\tenableRedeemFallback,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tif (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n\t\t\t\t// Execute the redeem fallback\n\n\t\t\t\tawait redeemSharingLink(\n\t\t\t\t\todspResolvedUrl,\n\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\tlogger,\n\t\t\t\t\tforceAccessTokenViaAuthorizationHeader,\n\t\t\t\t);\n\t\t\t\tconst odspResolvedUrlWithoutShareLink: IOdspResolvedUrl = {\n\t\t\t\t\t...odspResolvedUrl,\n\t\t\t\t\tshareLinkInfo: {\n\t\t\t\t\t\t...odspResolvedUrl.shareLinkInfo,\n\t\t\t\t\t\tsharingLinkToRedeem: undefined,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\t// Log initial failure only if redeem succeeded - it points out to some bug somewhere\n\t\t\t\t// If redeem failed, that most likely means user has no permissions to access a file,\n\t\t\t\t// and thus it's not worth it logging extra errors - same error will be logged by end-to-end\n\t\t\t\t// flow (container open) based on a failure above.\n\t\t\t\tlogger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"RedeemFallback\",\n\t\t\t\t\t\terrorType: error.errorType,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\n\t\t\t\treturn fetchLatestSnapshotCore(\n\t\t\t\t\todspResolvedUrlWithoutShareLink,\n\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\tsnapshotOptions,\n\t\t\t\t\tlogger,\n\t\t\t\t\tsnapshotDownloader,\n\t\t\t\t\tputInCache,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t})\n\t\t.catch(async (error) => {\n\t\t\t// Clear the cache on 401/403/404 on snapshot fetch from network because this means either the user doesn't\n\t\t\t// have permissions for the file or it was deleted. So, if we do not clear cache, we will continue fetching\n\t\t\t// snapshot from cache in the future.\n\t\t\tif (\n\t\t\t\t(typeof error === \"object\" &&\n\t\t\t\t\terror !== null &&\n\t\t\t\t\terror.errorType === DriverErrorType.authorizationError) ||\n\t\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError\n\t\t\t) {\n\t\t\t\tawait removeEntries();\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n}\n\nasync function redeemSharingLink(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageTokenFetcher: InstrumentedStorageTokenFetcher,\n\tlogger: ITelemetryLoggerExt,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n) {\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"RedeemShareLink\",\n\t\t},\n\t\tasync () =>\n\t\t\tgetWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\t\t\tassert(\n\t\t\t\t\t!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t\t\t0x1ed /* \"Share link should be present\" */,\n\t\t\t\t);\n\t\t\t\tconst storageToken = await storageTokenFetcher(\n\t\t\t\t\ttokenFetchOptions,\n\t\t\t\t\t\"RedeemShareLink\",\n\t\t\t\t);\n\t\t\t\tconst encodedShareUrl = getEncodedShareUrl(\n\t\t\t\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t\t);\n\t\t\t\tconst redeemUrl = `${odspResolvedUrl.siteUrl}/_api/v2.0/shares/${encodedShareUrl}`;\n\t\t\t\tconst { url, headers } = getUrlAndHeadersWithAuth(\n\t\t\t\t\tredeemUrl,\n\t\t\t\t\tstorageToken,\n\t\t\t\t\tforceAccessTokenViaAuthorizationHeader,\n\t\t\t\t);\n\t\t\t\theaders.prefer = \"redeemSharingLink\";\n\t\t\t\treturn fetchAndParseAsJSONHelper(url, { headers });\n\t\t\t}),\n\t);\n}\n\nasync function fetchLatestSnapshotCore(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageTokenFetcher: InstrumentedStorageTokenFetcher,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tstorageToken: string,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n\treturn getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\tconst storageToken = await storageTokenFetcher(tokenFetchOptions, \"TreesLatest\", true);\n\t\tassert(storageToken !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\n\t\tconst perfEvent = {\n\t\t\teventName: \"TreesLatest\",\n\t\t\tattempts: tokenFetchOptions.refresh ? 2 : 1,\n\t\t\tshareLinkPresent: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined,\n\t\t\tisSummarizer: odspResolvedUrl.summarizer,\n\t\t\tredeemFallbackEnabled: enableRedeemFallback,\n\t\t};\n\t\tif (snapshotOptions !== undefined) {\n\t\t\tObject.entries(snapshotOptions).forEach(([key, value]) => {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tperfEvent[`snapshotOption_${key}`] = value;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t// This event measures only successful cases of getLatest call (no tokens, no retries).\n\t\treturn PerformanceEvent.timedExecAsync(logger, perfEvent, async (event) => {\n\t\t\tlet controller: AbortController | undefined;\n\t\t\tlet fetchTimeout: ReturnType<typeof setTimeout> | undefined;\n\t\t\tif (snapshotOptions?.timeout !== undefined) {\n\t\t\t\tcontroller = new AbortController();\n\t\t\t\tfetchTimeout = setTimeout(() => controller!.abort(), snapshotOptions.timeout);\n\t\t\t}\n\n\t\t\tconst [response, fetchTime] = await measureP(async () =>\n\t\t\t\tsnapshotDownloader(odspResolvedUrl, storageToken, snapshotOptions, controller),\n\t\t\t).finally(() => {\n\t\t\t\t// Clear the fetchTimeout once the response is fetched.\n\t\t\t\tif (fetchTimeout !== undefined) {\n\t\t\t\t\tclearTimeout(fetchTimeout);\n\t\t\t\t\tfetchTimeout = undefined;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst odspResponse = response.odspResponse;\n\t\t\tconst contentType = odspResponse.headers.get(\"content-type\");\n\n\t\t\tconst propsToLog: DriverErrorTelemetryProps = {\n\t\t\t\t...odspResponse.propsToLog,\n\t\t\t\tcontentType,\n\t\t\t\taccept: response.requestHeaders.accept,\n\t\t\t\tdriverVersion: pkgVersion,\n\t\t\t};\n\n\t\t\tlet parsedSnapshotContents: IOdspResponse<ISnapshotContentsWithProps> | undefined;\n\t\t\tlet contentTypeToRead: string | undefined;\n\t\t\tif (contentType?.includes(\"application/ms-fluid\")) {\n\t\t\t\tcontentTypeToRead = \"application/ms-fluid\";\n\t\t\t} else if (contentType?.includes(\"application/json\")) {\n\t\t\t\tcontentTypeToRead = \"application/json\";\n\t\t\t}\n\n\t\t\tlet parseTime: number;\n\t\t\tlet receiveContentTime: number;\n\t\t\ttry {\n\t\t\t\tswitch (contentTypeToRead) {\n\t\t\t\t\tcase \"application/json\": {\n\t\t\t\t\t\tlet text: string;\n\t\t\t\t\t\t[text, receiveContentTime] = await measureP(async () =>\n\t\t\t\t\t\t\todspResponse.content.text(),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tpropsToLog.bodySize = text.length;\n\t\t\t\t\t\tlet content: IOdspSnapshot;\n\t\t\t\t\t\t[content, parseTime] = measure(() => JSON.parse(text) as IOdspSnapshot);\n\t\t\t\t\t\tvalidateBlobsAndTrees(content);\n\t\t\t\t\t\tconst snapshotContents: ISnapshotContents =\n\t\t\t\t\t\t\tconvertOdspSnapshotToSnapshotTreeAndBlobs(content);\n\t\t\t\t\t\tparsedSnapshotContents = {\n\t\t\t\t\t\t\t...odspResponse,\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t...snapshotContents,\n\t\t\t\t\t\t\t\ttelemetryProps: {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"application/ms-fluid\": {\n\t\t\t\t\t\tlet content: ArrayBuffer;\n\t\t\t\t\t\t[content, receiveContentTime] = await measureP(async () =>\n\t\t\t\t\t\t\todspResponse.content.arrayBuffer(),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tpropsToLog.bodySize = content.byteLength;\n\t\t\t\t\t\tlet snapshotContents: ISnapshotContentsWithProps;\n\t\t\t\t\t\t[snapshotContents, parseTime] = measure(() =>\n\t\t\t\t\t\t\tparseCompactSnapshotResponse(new Uint8Array(content), logger),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tsnapshotContents.snapshotTree.trees === undefined ||\n\t\t\t\t\t\t\tsnapshotContents.snapshotTree.blobs === undefined\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\t\t\"Returned odsp snapshot is malformed. No trees or blobs!\",\n\t\t\t\t\t\t\t\tDriverErrorType.incorrectServerResponse,\n\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst props = snapshotContents.telemetryProps;\n\t\t\t\t\t\tconst slowTreeParseCodePaths = props.slowTreeStructureCount ?? 0;\n\t\t\t\t\t\tconst slowBlobParseCodePaths = props.slowBlobStructureCount ?? 0;\n\t\t\t\t\t\tif (slowTreeParseCodePaths > 10 || slowBlobParseCodePaths > 10) {\n\t\t\t\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\t\t\t\teventName: \"SlowSnapshotParseCodePaths\",\n\t\t\t\t\t\t\t\tslowTreeStructureCount: slowTreeParseCodePaths,\n\t\t\t\t\t\t\t\tslowBlobStructureCount: slowBlobParseCodePaths,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparsedSnapshotContents = { ...odspResponse, content: snapshotContents };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\t\"Unknown snapshot content type\",\n\t\t\t\t\t\t\tDriverErrorType.incorrectServerResponse,\n\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isFluidError(error)) {\n\t\t\t\t\terror.addTelemetryProperties(propsToLog);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst enhancedError = wrapError(\n\t\t\t\t\terror,\n\t\t\t\t\t(errorMessage) =>\n\t\t\t\t\t\tnew NonRetryableError(\n\t\t\t\t\t\t\t`Error parsing snapshot response: ${errorMessage}`,\n\t\t\t\t\t\t\tDriverErrorType.genericError,\n\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tthrow enhancedError;\n\t\t\t}\n\n\t\t\tassert(parsedSnapshotContents !== undefined, 0x312 /* snapshot should be parsed */);\n\t\t\tconst snapshot = parsedSnapshotContents.content;\n\t\t\tconst { trees, numBlobs, encodedBlobsSize } = evalBlobsAndTrees(snapshot);\n\n\t\t\t// There are some scenarios in ODSP where we cannot cache, trees/latest will explicitly tell us when we\n\t\t\t// cannot cache using an HTTP response header.\n\t\t\tconst canCache =\n\t\t\t\todspResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\";\n\t\t\tconst sequenceNumber: number = snapshot.sequenceNumber ?? 0;\n\t\t\tconst seqNumberFromOps =\n\t\t\t\tsnapshot.ops && snapshot.ops.length > 0\n\t\t\t\t\t? snapshot.ops[0].sequenceNumber - 1\n\t\t\t\t\t: undefined;\n\n\t\t\tif (\n\t\t\t\t!Number.isInteger(sequenceNumber) ||\n\t\t\t\t(seqNumberFromOps !== undefined && seqNumberFromOps !== sequenceNumber)\n\t\t\t) {\n\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\teventName: \"fetchSnapshotError\",\n\t\t\t\t\tsequenceNumber,\n\t\t\t\t\tseqNumberFromOps,\n\t\t\t\t});\n\t\t\t\tsnapshot.sequenceNumber = undefined;\n\t\t\t} else if (canCache) {\n\t\t\t\tconst fluidEpoch = odspResponse.headers.get(\"x-fluid-epoch\");\n\t\t\t\tassert(\n\t\t\t\t\tfluidEpoch !== undefined,\n\t\t\t\t\t0x1e6 /* \"Epoch should be present in response\" */,\n\t\t\t\t);\n\t\t\t\tconst value: ISnapshotCachedEntry = {\n\t\t\t\t\t...snapshot,\n\t\t\t\t\tcacheEntryTime: Date.now(),\n\t\t\t\t};\n\t\t\t\tconst valueWithEpoch: IVersionedValueWithEpoch = {\n\t\t\t\t\tvalue,\n\t\t\t\t\tfluidEpoch,\n\t\t\t\t\tversion: persistedCacheValueVersion,\n\t\t\t\t};\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\t\tputInCache(valueWithEpoch);\n\t\t\t}\n\n\t\t\tevent.end({\n\t\t\t\ttrees,\n\t\t\t\tblobs: snapshot.blobs?.size ?? 0,\n\t\t\t\tleafNodes: numBlobs,\n\t\t\t\tencodedBlobsSize,\n\t\t\t\tsequenceNumber,\n\t\t\t\tops: snapshot.ops?.length ?? 0,\n\t\t\t\tuserOps: snapshot.ops?.filter((op) => isRuntimeMessage(op)).length ?? 0,\n\t\t\t\theaders: Object.keys(response.requestHeaders).length !== 0 ? true : undefined,\n\t\t\t\t// Measures time to make fetch call. Should be similar to\n\t\t\t\t// fetchStartToResponseEndTime - receiveContentTime, i.e. it looks like it's time till first byte /\n\t\t\t\t// end of response headers\n\t\t\t\tfetchTime,\n\t\t\t\t// time it takes client to parse payload. Same payload as in \"SnapshotParse\" event, here for\n\t\t\t\t// easier analyzes.\n\t\t\t\tparseTime,\n\t\t\t\t// Time it takes to receive content (text of buffer) from Response object.\n\t\t\t\t// This time likely is very closely correlated with networkTime, i.e. time it takes to receive\n\t\t\t\t// actual content (starting measuring from first bite / end of response header)\n\t\t\t\treceiveContentTime,\n\t\t\t\t...getW3CData(response.requestUrl, \"fetch\"),\n\t\t\t\t// Sharing link telemetry regarding sharing link redeem status and performance. Ex: FRL; dur=100,\n\t\t\t\t// Azure Fluid Relay service; desc=S, FRP; desc=False. Here, FRL is the duration taken for redeem,\n\t\t\t\t// Azure Fluid Relay service is the redeem status (S means success), and FRP is a flag to indicate\n\t\t\t\t// if the permission has changed.\n\t\t\t\tsltelemetry: odspResponse.headers.get(\"x-fluid-sltelemetry\"),\n\t\t\t\t// All other props\n\t\t\t\t...propsToLog,\n\t\t\t\t// Various perf counters and measures collected by binary parsing code:\n\t\t\t\t// slowTreeStructureCount, slowBlobStructureCount, durationStructure, durationStrings,\n\t\t\t\t// durationSnapshotTree, durationBlobs, etc.\n\t\t\t\t...parsedSnapshotContents.content.telemetryProps,\n\t\t\t});\n\t\t\treturn snapshot;\n\t\t}).catch((error) => {\n\t\t\t// We hit these errors in stress tests, under load\n\t\t\t// It's useful to try one more time in such case.\n\t\t\tif (\n\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\terror !== null &&\n\t\t\t\t(error.errorType === DriverErrorType.fetchFailure ||\n\t\t\t\t\terror.errorType === OdspErrorType.fetchTimeout)\n\t\t\t) {\n\t\t\t\terror[getWithRetryForTokenRefreshRepeat] = true;\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t});\n}\n\nexport interface ISnapshotRequestAndResponseOptions {\n\todspResponse: IOdspResponse<Response>;\n\trequestUrl: string;\n\trequestHeaders: { [index: string]: any };\n}\n\nfunction getFormBodyAndHeaders(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageToken: string,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\theaders?: { [index: string]: string },\n) {\n\tconst formBoundary = uuid();\n\tconst formParams: string[] = [];\n\tformParams.push(`--${formBoundary}`);\n\tformParams.push(`Authorization: Bearer ${storageToken}`);\n\tformParams.push(`X-HTTP-Method-Override: GET`);\n\tif (snapshotOptions !== undefined) {\n\t\tObject.entries(snapshotOptions).forEach(([key, value]) => {\n\t\t\tif (value !== undefined) {\n\t\t\t\tformParams.push(`${key}: ${value}`);\n\t\t\t}\n\t\t});\n\t}\n\tif (headers !== undefined) {\n\t\tObject.entries(headers).forEach(([key, value]) => {\n\t\t\tif (value !== undefined) {\n\t\t\t\tformParams.push(`${key}: ${value}`);\n\t\t\t}\n\t\t});\n\t}\n\tif (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem) {\n\t\tformParams.push(`sl: ${odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem}`);\n\t}\n\tformParams.push(`_post: 1`);\n\tformParams.push(`\\r\\n--${formBoundary}--`);\n\tconst postBody = formParams.join(\"\\r\\n\");\n\tconst header: { [index: string]: any } = {\n\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t};\n\treturn { body: postBody, headers: header };\n}\n\nexport function evalBlobsAndTrees(snapshot: ISnapshotContents) {\n\tconst trees = countTreesInSnapshotTree(snapshot.snapshotTree);\n\tconst numBlobs = snapshot.blobs.size;\n\tlet encodedBlobsSize = 0;\n\tfor (const [_, blobContent] of snapshot.blobs) {\n\t\tencodedBlobsSize += blobContent.byteLength;\n\t}\n\treturn { trees, numBlobs, encodedBlobsSize };\n}\n\nexport function validateBlobsAndTrees(snapshot: IOdspSnapshot) {\n\tassert(\n\t\tsnapshot.trees !== undefined,\n\t\t0x200 /* \"Returned odsp snapshot is malformed. No trees!\" */,\n\t);\n\tassert(\n\t\tsnapshot.blobs !== undefined,\n\t\t0x201 /* \"Returned odsp snapshot is malformed. No blobs!\" */,\n\t);\n}\n\nfunction countTreesInSnapshotTree(snapshotTree: ISnapshotTree): number {\n\tlet numTrees = 0;\n\tfor (const [_, tree] of Object.entries(snapshotTree.trees)) {\n\t\tnumTrees += 1;\n\t\tnumTrees += countTreesInSnapshotTree(tree);\n\t}\n\treturn numTrees;\n}\n\n/**\n * This function fetches the snapshot and parse it according to what is mentioned in response headers.\n * @param odspResolvedUrl - resolved odsp url.\n * @param storageToken - token to do the auth for network request.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param controller - abort controller if caller needs to abort the network call.\n * @param epochTracker - epoch tracker used to add/validate epoch in the network call.\n * @returns fetched snapshot.\n */\nexport async function downloadSnapshot(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tstorageToken: string,\n\tlogger: ITelemetryLoggerExt,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tsnapshotFormatFetchType?: SnapshotFormatSupportType,\n\tcontroller?: AbortController,\n\tepochTracker?: EpochTracker,\n\tscenarioName?: string,\n): Promise<ISnapshotRequestAndResponseOptions> {\n\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\tif (sharingLinkToRedeem) {\n\t\todspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n\t}\n\n\tconst snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n\tconst url = `${snapshotUrl}/trees/latest?ump=1`;\n\t// The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n\t// Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n\t// This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n\t// for futher reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n\tconst header = { prefer: \"manualredirect\" };\n\tconst { body, headers } = getFormBodyAndHeaders(\n\t\todspResolvedUrl,\n\t\tstorageToken,\n\t\tsnapshotOptions,\n\t\theader,\n\t);\n\tconst fetchOptions = {\n\t\tbody,\n\t\theaders,\n\t\tsignal: controller?.signal,\n\t\tmethod: \"POST\",\n\t};\n\t// Decide what snapshot format to fetch as per the feature gate.\n\tswitch (snapshotFormatFetchType) {\n\t\tcase SnapshotFormatSupportType.Binary:\n\t\t\theaders.accept = `application/ms-fluid; v=${currentReadVersion}`;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// By default ask both versions and let the server decide the format.\n\t\t\theaders.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n\t}\n\n\tconst odspResponse = await (epochTracker?.fetch(\n\t\turl,\n\t\tfetchOptions,\n\t\t\"treesLatest\",\n\t\ttrue,\n\t\tscenarioName,\n\t) ?? fetchHelper(url, fetchOptions));\n\n\treturn {\n\t\todspResponse,\n\t\trequestHeaders: headers,\n\t\trequestUrl: url,\n\t};\n}\n\nfunction isRedeemSharingLinkError(odspResolvedUrl: IOdspResolvedUrl, error: any) {\n\tif (\n\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined &&\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error.errorType === DriverErrorType.authorizationError ||\n\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError)\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nfunction getEncodedShareUrl(url: string): string {\n\t/**\n\t * Encode the url to accepted format by Sharepoint\n\t * https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get\n\t */\n\tlet encodedUrl = fromUtf8ToBase64(encodeURI(url));\n\tencodedUrl = encodedUrl.replace(/=+$/g, \"\").replace(/\\//g, \"_\").replace(/\\+/g, \"-\");\n\tencodedUrl = \"u!\".concat(encodedUrl);\n\treturn encodedUrl;\n}\n"]}
@@ -8,6 +8,7 @@ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions"
8
8
  import { InstrumentedStorageTokenFetcher } from "@fluidframework/odsp-driver-definitions";
9
9
  import { IDeltasFetchResult, IDocumentDeltaStorageService } from "@fluidframework/driver-definitions";
10
10
  import { EpochTracker } from "./epochTracker";
11
+ import { OdspDocumentStorageService } from "./odspDocumentStorageManager";
11
12
  /**
12
13
  * Provides access to the underlying delta storage on the server for sharepoint driver.
13
14
  */
@@ -37,8 +38,9 @@ export declare class OdspDeltaStorageWithCache implements IDocumentDeltaStorageS
37
38
  private readonly getCached;
38
39
  private readonly requestFromSocket;
39
40
  private readonly opsReceived;
40
- private firstCacheMiss;
41
- constructor(snapshotOps: ISequencedDocumentMessage[] | undefined, logger: ITelemetryLoggerExt, batchSize: number, concurrency: number, getFromStorage: (from: number, to: number, telemetryProps: ITelemetryProperties, fetchReason?: string) => Promise<IDeltasFetchResult>, getCached: (from: number, to: number) => Promise<ISequencedDocumentMessage[]>, requestFromSocket: (from: number, to: number) => void, opsReceived: (ops: ISequencedDocumentMessage[]) => void);
41
+ private readonly storageManagerGetter;
42
+ private useCacheForOps;
43
+ constructor(snapshotOps: ISequencedDocumentMessage[] | undefined, logger: ITelemetryLoggerExt, batchSize: number, concurrency: number, getFromStorage: (from: number, to: number, telemetryProps: ITelemetryProperties, fetchReason?: string) => Promise<IDeltasFetchResult>, getCached: (from: number, to: number) => Promise<ISequencedDocumentMessage[]>, requestFromSocket: (from: number, to: number) => void, opsReceived: (ops: ISequencedDocumentMessage[]) => void, storageManagerGetter: () => OdspDocumentStorageService | undefined);
42
44
  fetchMessages(fromTotal: number, toTotal: number | undefined, abortSignal?: AbortSignal, cachedOnly?: boolean, fetchReason?: string): import("@fluidframework/driver-definitions").IStream<ISequencedDocumentMessage[]>;
43
45
  }
44
46
  //# sourceMappingURL=odspDeltaStorageService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"odspDeltaStorageService.d.ts","sourceRoot":"","sources":["../src/odspDeltaStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAoB,MAAM,iCAAiC,CAAC;AAExF,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC1F,OAAO,EACN,kBAAkB,EAClB,4BAA4B,EAC5B,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,qBAAa,uBAAuB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAHN,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,+BAA+B,EAChD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,mBAAmB;IAG7C;;;;;;;OAOG;IACU,GAAG,CACf,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,YAAY,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC;IA0EvB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAOxC;AAED,qBAAa,yBAA0B,YAAW,4BAA4B;IAI5E,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAM/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAI1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAlB7B,OAAO,CAAC,cAAc,CAAS;gBAGtB,WAAW,EAAE,yBAAyB,EAAE,GAAG,SAAS,EAC3C,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,CAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,WAAW,CAAC,EAAE,MAAM,KAChB,OAAO,CAAC,kBAAkB,CAAC,EACf,SAAS,EAAE,CAC3B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,KACN,OAAO,CAAC,yBAAyB,EAAE,CAAC,EACxB,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,EACrD,WAAW,EAAE,CAAC,GAAG,EAAE,yBAAyB,EAAE,KAAK,IAAI;IAGlE,aAAa,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,CAAC,EAAE,OAAO,EACpB,WAAW,CAAC,EAAE,MAAM;CA2FrB"}
1
+ {"version":3,"file":"odspDeltaStorageService.d.ts","sourceRoot":"","sources":["../src/odspDeltaStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAoB,MAAM,iCAAiC,CAAC;AAExF,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC1F,OAAO,EACN,kBAAkB,EAClB,4BAA4B,EAC5B,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E;;GAEG;AACH,qBAAa,uBAAuB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAHN,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,+BAA+B,EAChD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,mBAAmB;IAG7C;;;;;;;OAOG;IACU,GAAG,CACf,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,YAAY,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,CAAC;IA0EvB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAOxC;AAED,qBAAa,yBAA0B,YAAW,4BAA4B;IAI5E,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAM/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAI1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAnBtC,OAAO,CAAC,cAAc,CAAQ;gBAGrB,WAAW,EAAE,yBAAyB,EAAE,GAAG,SAAS,EAC3C,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,CAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,WAAW,CAAC,EAAE,MAAM,KAChB,OAAO,CAAC,kBAAkB,CAAC,EACf,SAAS,EAAE,CAC3B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,KACN,OAAO,CAAC,yBAAyB,EAAE,CAAC,EACxB,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,EACrD,WAAW,EAAE,CAAC,GAAG,EAAE,yBAAyB,EAAE,KAAK,IAAI,EACvD,oBAAoB,EAAE,MAAM,0BAA0B,GAAG,SAAS;IAG7E,aAAa,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,CAAC,EAAE,OAAO,EACpB,WAAW,CAAC,EAAE,MAAM;CA+FrB"}
@@ -3,12 +3,8 @@
3
3
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
4
  * Licensed under the MIT License.
5
5
  */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
6
  Object.defineProperty(exports, "__esModule", { value: true });
10
7
  exports.OdspDeltaStorageWithCache = exports.OdspDeltaStorageService = void 0;
11
- const abort_controller_1 = __importDefault(require("abort-controller"));
12
8
  const uuid_1 = require("uuid");
13
9
  const driver_base_1 = require("@fluidframework/driver-base");
14
10
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
@@ -55,7 +51,7 @@ class OdspDeltaStorageService {
55
51
  // networking. Even bigger problem - a lot of requests timeout (based on cursory look - after 1-2 minutes)
56
52
  // So adding some timeout to ensure we retry again in hope of faster success.
57
53
  // Please see https://github.com/microsoft/FluidFramework/issues/6997 for details.
58
- const abort = new abort_controller_1.default();
54
+ const abort = new AbortController();
59
55
  const timer = setTimeout(() => abort.abort(), 30000);
60
56
  const response = await this.epochTracker.fetchAndParseAsJSON(baseUrl, {
61
57
  headers,
@@ -84,7 +80,7 @@ class OdspDeltaStorageService {
84
80
  }
85
81
  exports.OdspDeltaStorageService = OdspDeltaStorageService;
86
82
  class OdspDeltaStorageWithCache {
87
- constructor(snapshotOps, logger, batchSize, concurrency, getFromStorage, getCached, requestFromSocket, opsReceived) {
83
+ constructor(snapshotOps, logger, batchSize, concurrency, getFromStorage, getCached, requestFromSocket, opsReceived, storageManagerGetter) {
88
84
  this.snapshotOps = snapshotOps;
89
85
  this.logger = logger;
90
86
  this.batchSize = batchSize;
@@ -93,14 +89,20 @@ class OdspDeltaStorageWithCache {
93
89
  this.getCached = getCached;
94
90
  this.requestFromSocket = requestFromSocket;
95
91
  this.opsReceived = opsReceived;
96
- this.firstCacheMiss = false;
92
+ this.storageManagerGetter = storageManagerGetter;
93
+ this.useCacheForOps = true;
97
94
  }
98
95
  fetchMessages(fromTotal, toTotal, abortSignal, cachedOnly, fetchReason) {
96
+ var _a;
99
97
  // We do not control what's in the cache. Current API assumes that fetchMessages() keeps banging on
100
98
  // storage / cache until it gets ops it needs. This would result in deadlock if fixed range is asked from
101
99
  // cache and it's not there.
102
100
  // Better implementation would be to return only what we have in cache, but that also breaks API
103
101
  (0, common_utils_1.assert)(!cachedOnly || toTotal === undefined, 0x1e3);
102
+ // Don't use cache for ops is snapshot is fetched from network or if it was not fetched at all.
103
+ this.useCacheForOps =
104
+ this.useCacheForOps &&
105
+ ((_a = this.storageManagerGetter()) === null || _a === void 0 ? void 0 : _a.isFirstSnapshotFromNetwork) === false;
104
106
  let opsFromSnapshot = 0;
105
107
  let opsFromCache = 0;
106
108
  let opsFromStorage = 0;
@@ -118,13 +120,13 @@ class OdspDeltaStorageWithCache {
118
120
  // Kick out request to PUSH for ops if it has them
119
121
  this.requestFromSocket(from, to);
120
122
  // Cache in normal flow is continuous. Once there is a miss, stop consulting cache.
121
- // This saves a bit of processing time
122
- if (!this.firstCacheMiss) {
123
+ // This saves a bit of processing time.
124
+ if (this.useCacheForOps) {
123
125
  const messagesFromCache = await this.getCached(from, to);
124
126
  (0, driver_base_1.validateMessages)("cached", messagesFromCache, from, this.logger);
125
127
  // Set the firstCacheMiss as true in case we didn't get all the ops.
126
128
  // This will save an extra cache read on "DocumentOpen" or "PostDocumentOpen".
127
- this.firstCacheMiss = from + messagesFromCache.length < to;
129
+ this.useCacheForOps = from + messagesFromCache.length >= to;
128
130
  if (messagesFromCache.length !== 0) {
129
131
  opsFromCache += messagesFromCache.length;
130
132
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"odspDeltaStorageService.js","sourceRoot":"","sources":["../src/odspDeltaStorageService.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 { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryProperties } from \"@fluidframework/core-interfaces\";\nimport { validateMessages } from \"@fluidframework/driver-base\";\nimport { ITelemetryLoggerExt, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { InstrumentedStorageTokenFetcher } from \"@fluidframework/odsp-driver-definitions\";\nimport {\n\tIDeltasFetchResult,\n\tIDocumentDeltaStorageService,\n} from \"@fluidframework/driver-definitions\";\nimport { requestOps, streamObserver } from \"@fluidframework/driver-utils\";\nimport { IDeltaStorageGetResponse, ISequencedDeltaOpMessage } from \"./contracts\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { getWithRetryForTokenRefresh } from \"./odspUtils\";\n\n/**\n * Provides access to the underlying delta storage on the server for sharepoint driver.\n */\nexport class OdspDeltaStorageService {\n\tconstructor(\n\t\tprivate readonly deltaFeedUrl: string,\n\t\tprivate readonly getStorageToken: InstrumentedStorageTokenFetcher,\n\t\tprivate readonly epochTracker: EpochTracker,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {}\n\n\t/**\n\t * Retrieves ops from storage\n\t * @param from - inclusive\n\t * @param to - exclusive\n\t * @param telemetryProps - properties to add when issuing telemetry events\n\t * @param scenarioName - reason for fetching ops\n\t * @returns ops retrieved & info if result was partial (i.e. more is available)\n\t */\n\tpublic async get(\n\t\tfrom: number,\n\t\tto: number,\n\t\ttelemetryProps: ITelemetryProperties,\n\t\tscenarioName?: string,\n\t): Promise<IDeltasFetchResult> {\n\t\treturn getWithRetryForTokenRefresh(async (options) => {\n\t\t\t// Note - this call ends up in getSocketStorageDiscovery() and can refresh token\n\t\t\t// Thus it needs to be done before we call getStorageToken() to reduce extra calls\n\t\t\tconst baseUrl = this.buildUrl(from, to);\n\t\t\tconst storageToken = await this.getStorageToken(options, \"DeltaStorage\");\n\n\t\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"OpsFetch\",\n\t\t\t\t\tattempts: options.refresh ? 2 : 1,\n\t\t\t\t\tfrom,\n\t\t\t\t\tto,\n\t\t\t\t\t...telemetryProps,\n\t\t\t\t\treason: scenarioName,\n\t\t\t\t},\n\t\t\t\tasync (event) => {\n\t\t\t\t\tconst formBoundary = uuid();\n\t\t\t\t\tlet postBody = `--${formBoundary}\\r\\n`;\n\t\t\t\t\tpostBody += `Authorization: Bearer ${storageToken}\\r\\n`;\n\t\t\t\t\tpostBody += `X-HTTP-Method-Override: GET\\r\\n`;\n\n\t\t\t\t\tpostBody += `_post: 1\\r\\n`;\n\t\t\t\t\tpostBody += `\\r\\n--${formBoundary}--`;\n\t\t\t\t\tconst headers: { [index: string]: any } = {\n\t\t\t\t\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t\t\t\t\t};\n\n\t\t\t\t\t// Some request take a long time (1-2 minutes) to complete, where telemetry shows very small amount\n\t\t\t\t\t// of time spent on server, and usually small payload sizes. I.e. all the time is spent somewhere in\n\t\t\t\t\t// networking. Even bigger problem - a lot of requests timeout (based on cursory look - after 1-2 minutes)\n\t\t\t\t\t// So adding some timeout to ensure we retry again in hope of faster success.\n\t\t\t\t\t// Please see https://github.com/microsoft/FluidFramework/issues/6997 for details.\n\t\t\t\t\tconst abort = new AbortController();\n\t\t\t\t\tconst timer = setTimeout(() => abort.abort(), 30000);\n\n\t\t\t\t\tconst response =\n\t\t\t\t\t\tawait this.epochTracker.fetchAndParseAsJSON<IDeltaStorageGetResponse>(\n\t\t\t\t\t\t\tbaseUrl,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\tbody: postBody,\n\t\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\t\tsignal: abort.signal,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"ops\",\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\tscenarioName,\n\t\t\t\t\t\t);\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tconst deltaStorageResponse = response.content;\n\t\t\t\t\tconst messages =\n\t\t\t\t\t\tdeltaStorageResponse.value.length > 0 &&\n\t\t\t\t\t\t\"op\" in deltaStorageResponse.value[0]\n\t\t\t\t\t\t\t? (deltaStorageResponse.value as ISequencedDeltaOpMessage[]).map(\n\t\t\t\t\t\t\t\t\t(operation) => operation.op,\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: (deltaStorageResponse.value as ISequencedDocumentMessage[]);\n\n\t\t\t\t\tevent.end({\n\t\t\t\t\t\theaders: Object.keys(headers).length !== 0 ? true : undefined,\n\t\t\t\t\t\tlength: messages.length,\n\t\t\t\t\t\t...response.propsToLog,\n\t\t\t\t\t});\n\n\t\t\t\t\t// It is assumed that server always returns all the ops that it has in the range that was requested.\n\t\t\t\t\t// This may change in the future, if so, we need to adjust and receive \"end\" value from server in such case.\n\t\t\t\t\treturn { messages, partialResult: false };\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic buildUrl(from: number, to: number) {\n\t\tconst filter = encodeURIComponent(\n\t\t\t`sequenceNumber ge ${from} and sequenceNumber le ${to - 1}`,\n\t\t);\n\t\tconst queryString = `?ump=1&filter=${filter}`;\n\t\treturn `${this.deltaFeedUrl}${queryString}`;\n\t}\n}\n\nexport class OdspDeltaStorageWithCache implements IDocumentDeltaStorageService {\n\tprivate firstCacheMiss = false;\n\n\tpublic constructor(\n\t\tprivate snapshotOps: ISequencedDocumentMessage[] | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate readonly batchSize: number,\n\t\tprivate readonly concurrency: number,\n\t\tprivate readonly getFromStorage: (\n\t\t\tfrom: number,\n\t\t\tto: number,\n\t\t\ttelemetryProps: ITelemetryProperties,\n\t\t\tfetchReason?: string,\n\t\t) => Promise<IDeltasFetchResult>,\n\t\tprivate readonly getCached: (\n\t\t\tfrom: number,\n\t\t\tto: number,\n\t\t) => Promise<ISequencedDocumentMessage[]>,\n\t\tprivate readonly requestFromSocket: (from: number, to: number) => void,\n\t\tprivate readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,\n\t) {}\n\n\tpublic fetchMessages(\n\t\tfromTotal: number,\n\t\ttoTotal: number | undefined,\n\t\tabortSignal?: AbortSignal,\n\t\tcachedOnly?: boolean,\n\t\tfetchReason?: string,\n\t) {\n\t\t// We do not control what's in the cache. Current API assumes that fetchMessages() keeps banging on\n\t\t// storage / cache until it gets ops it needs. This would result in deadlock if fixed range is asked from\n\t\t// cache and it's not there.\n\t\t// Better implementation would be to return only what we have in cache, but that also breaks API\n\t\tassert(!cachedOnly || toTotal === undefined, 0x1e3);\n\n\t\tlet opsFromSnapshot = 0;\n\t\tlet opsFromCache = 0;\n\t\tlet opsFromStorage = 0;\n\n\t\tconst requestCallback = async (\n\t\t\tfrom: number,\n\t\t\tto: number,\n\t\t\ttelemetryProps: ITelemetryProperties,\n\t\t) => {\n\t\t\tif (this.snapshotOps !== undefined && this.snapshotOps.length !== 0) {\n\t\t\t\tconst messages = this.snapshotOps.filter(\n\t\t\t\t\t(op) => op.sequenceNumber >= from && op.sequenceNumber < to,\n\t\t\t\t);\n\t\t\t\tvalidateMessages(\"cached\", messages, from, this.logger);\n\t\t\t\tif (messages.length > 0 && messages[0].sequenceNumber === from) {\n\t\t\t\t\tthis.snapshotOps = this.snapshotOps.filter((op) => op.sequenceNumber >= to);\n\t\t\t\t\topsFromSnapshot += messages.length;\n\t\t\t\t\treturn { messages, partialResult: true };\n\t\t\t\t}\n\t\t\t\tthis.snapshotOps = undefined;\n\t\t\t}\n\n\t\t\t// Kick out request to PUSH for ops if it has them\n\t\t\tthis.requestFromSocket(from, to);\n\n\t\t\t// Cache in normal flow is continuous. Once there is a miss, stop consulting cache.\n\t\t\t// This saves a bit of processing time\n\t\t\tif (!this.firstCacheMiss) {\n\t\t\t\tconst messagesFromCache = await this.getCached(from, to);\n\t\t\t\tvalidateMessages(\"cached\", messagesFromCache, from, this.logger);\n\t\t\t\t// Set the firstCacheMiss as true in case we didn't get all the ops.\n\t\t\t\t// This will save an extra cache read on \"DocumentOpen\" or \"PostDocumentOpen\".\n\t\t\t\tthis.firstCacheMiss = from + messagesFromCache.length < to;\n\t\t\t\tif (messagesFromCache.length !== 0) {\n\t\t\t\t\topsFromCache += messagesFromCache.length;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tmessages: messagesFromCache,\n\t\t\t\t\t\tpartialResult: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (cachedOnly) {\n\t\t\t\treturn { messages: [], partialResult: false };\n\t\t\t}\n\n\t\t\tconst ops = await this.getFromStorage(from, to, telemetryProps, fetchReason);\n\t\t\tvalidateMessages(\"storage\", ops.messages, from, this.logger);\n\t\t\topsFromStorage += ops.messages.length;\n\t\t\tthis.opsReceived(ops.messages);\n\t\t\treturn ops;\n\t\t};\n\n\t\tconst stream = requestOps(\n\t\t\tasync (from: number, to: number, telemetryProps: ITelemetryProperties) => {\n\t\t\t\tconst result = await requestCallback(from, to, telemetryProps);\n\t\t\t\t// Catch all case, just in case\n\t\t\t\tvalidateMessages(\"catch all\", result.messages, from, this.logger);\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\t// Staging: starting with no concurrency, listening for feedback first.\n\t\t\t// In future releases we will switch to actual concurrency\n\t\t\tthis.concurrency,\n\t\t\tfromTotal, // inclusive\n\t\t\ttoTotal, // exclusive\n\t\t\tthis.batchSize,\n\t\t\tthis.logger,\n\t\t\tabortSignal,\n\t\t\tfetchReason,\n\t\t);\n\n\t\treturn streamObserver(stream, (result) => {\n\t\t\tif (result.done && opsFromSnapshot + opsFromCache + opsFromStorage !== 0) {\n\t\t\t\tthis.logger.sendPerformanceEvent({\n\t\t\t\t\teventName: \"CacheOpsRetrieved\",\n\t\t\t\t\topsFromSnapshot,\n\t\t\t\t\topsFromCache,\n\t\t\t\t\topsFromStorage,\n\t\t\t\t\treason: fetchReason,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"odspDeltaStorageService.js","sourceRoot":"","sources":["../src/odspDeltaStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryProperties } from \"@fluidframework/core-interfaces\";\nimport { validateMessages } from \"@fluidframework/driver-base\";\nimport { ITelemetryLoggerExt, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { InstrumentedStorageTokenFetcher } from \"@fluidframework/odsp-driver-definitions\";\nimport {\n\tIDeltasFetchResult,\n\tIDocumentDeltaStorageService,\n} from \"@fluidframework/driver-definitions\";\nimport { requestOps, streamObserver } from \"@fluidframework/driver-utils\";\nimport { IDeltaStorageGetResponse, ISequencedDeltaOpMessage } from \"./contracts\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { getWithRetryForTokenRefresh } from \"./odspUtils\";\nimport { OdspDocumentStorageService } from \"./odspDocumentStorageManager\";\n\n/**\n * Provides access to the underlying delta storage on the server for sharepoint driver.\n */\nexport class OdspDeltaStorageService {\n\tconstructor(\n\t\tprivate readonly deltaFeedUrl: string,\n\t\tprivate readonly getStorageToken: InstrumentedStorageTokenFetcher,\n\t\tprivate readonly epochTracker: EpochTracker,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {}\n\n\t/**\n\t * Retrieves ops from storage\n\t * @param from - inclusive\n\t * @param to - exclusive\n\t * @param telemetryProps - properties to add when issuing telemetry events\n\t * @param scenarioName - reason for fetching ops\n\t * @returns ops retrieved & info if result was partial (i.e. more is available)\n\t */\n\tpublic async get(\n\t\tfrom: number,\n\t\tto: number,\n\t\ttelemetryProps: ITelemetryProperties,\n\t\tscenarioName?: string,\n\t): Promise<IDeltasFetchResult> {\n\t\treturn getWithRetryForTokenRefresh(async (options) => {\n\t\t\t// Note - this call ends up in getSocketStorageDiscovery() and can refresh token\n\t\t\t// Thus it needs to be done before we call getStorageToken() to reduce extra calls\n\t\t\tconst baseUrl = this.buildUrl(from, to);\n\t\t\tconst storageToken = await this.getStorageToken(options, \"DeltaStorage\");\n\n\t\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\t\tthis.logger,\n\t\t\t\t{\n\t\t\t\t\teventName: \"OpsFetch\",\n\t\t\t\t\tattempts: options.refresh ? 2 : 1,\n\t\t\t\t\tfrom,\n\t\t\t\t\tto,\n\t\t\t\t\t...telemetryProps,\n\t\t\t\t\treason: scenarioName,\n\t\t\t\t},\n\t\t\t\tasync (event) => {\n\t\t\t\t\tconst formBoundary = uuid();\n\t\t\t\t\tlet postBody = `--${formBoundary}\\r\\n`;\n\t\t\t\t\tpostBody += `Authorization: Bearer ${storageToken}\\r\\n`;\n\t\t\t\t\tpostBody += `X-HTTP-Method-Override: GET\\r\\n`;\n\n\t\t\t\t\tpostBody += `_post: 1\\r\\n`;\n\t\t\t\t\tpostBody += `\\r\\n--${formBoundary}--`;\n\t\t\t\t\tconst headers: { [index: string]: any } = {\n\t\t\t\t\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t\t\t\t\t};\n\n\t\t\t\t\t// Some request take a long time (1-2 minutes) to complete, where telemetry shows very small amount\n\t\t\t\t\t// of time spent on server, and usually small payload sizes. I.e. all the time is spent somewhere in\n\t\t\t\t\t// networking. Even bigger problem - a lot of requests timeout (based on cursory look - after 1-2 minutes)\n\t\t\t\t\t// So adding some timeout to ensure we retry again in hope of faster success.\n\t\t\t\t\t// Please see https://github.com/microsoft/FluidFramework/issues/6997 for details.\n\t\t\t\t\tconst abort = new AbortController();\n\t\t\t\t\tconst timer = setTimeout(() => abort.abort(), 30000);\n\n\t\t\t\t\tconst response =\n\t\t\t\t\t\tawait this.epochTracker.fetchAndParseAsJSON<IDeltaStorageGetResponse>(\n\t\t\t\t\t\t\tbaseUrl,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\tbody: postBody,\n\t\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\t\tsignal: abort.signal,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"ops\",\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\tscenarioName,\n\t\t\t\t\t\t);\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tconst deltaStorageResponse = response.content;\n\t\t\t\t\tconst messages =\n\t\t\t\t\t\tdeltaStorageResponse.value.length > 0 &&\n\t\t\t\t\t\t\"op\" in deltaStorageResponse.value[0]\n\t\t\t\t\t\t\t? (deltaStorageResponse.value as ISequencedDeltaOpMessage[]).map(\n\t\t\t\t\t\t\t\t\t(operation) => operation.op,\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: (deltaStorageResponse.value as ISequencedDocumentMessage[]);\n\n\t\t\t\t\tevent.end({\n\t\t\t\t\t\theaders: Object.keys(headers).length !== 0 ? true : undefined,\n\t\t\t\t\t\tlength: messages.length,\n\t\t\t\t\t\t...response.propsToLog,\n\t\t\t\t\t});\n\n\t\t\t\t\t// It is assumed that server always returns all the ops that it has in the range that was requested.\n\t\t\t\t\t// This may change in the future, if so, we need to adjust and receive \"end\" value from server in such case.\n\t\t\t\t\treturn { messages, partialResult: false };\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tpublic buildUrl(from: number, to: number) {\n\t\tconst filter = encodeURIComponent(\n\t\t\t`sequenceNumber ge ${from} and sequenceNumber le ${to - 1}`,\n\t\t);\n\t\tconst queryString = `?ump=1&filter=${filter}`;\n\t\treturn `${this.deltaFeedUrl}${queryString}`;\n\t}\n}\n\nexport class OdspDeltaStorageWithCache implements IDocumentDeltaStorageService {\n\tprivate useCacheForOps = true;\n\n\tpublic constructor(\n\t\tprivate snapshotOps: ISequencedDocumentMessage[] | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate readonly batchSize: number,\n\t\tprivate readonly concurrency: number,\n\t\tprivate readonly getFromStorage: (\n\t\t\tfrom: number,\n\t\t\tto: number,\n\t\t\ttelemetryProps: ITelemetryProperties,\n\t\t\tfetchReason?: string,\n\t\t) => Promise<IDeltasFetchResult>,\n\t\tprivate readonly getCached: (\n\t\t\tfrom: number,\n\t\t\tto: number,\n\t\t) => Promise<ISequencedDocumentMessage[]>,\n\t\tprivate readonly requestFromSocket: (from: number, to: number) => void,\n\t\tprivate readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,\n\t\tprivate readonly storageManagerGetter: () => OdspDocumentStorageService | undefined,\n\t) {}\n\n\tpublic fetchMessages(\n\t\tfromTotal: number,\n\t\ttoTotal: number | undefined,\n\t\tabortSignal?: AbortSignal,\n\t\tcachedOnly?: boolean,\n\t\tfetchReason?: string,\n\t) {\n\t\t// We do not control what's in the cache. Current API assumes that fetchMessages() keeps banging on\n\t\t// storage / cache until it gets ops it needs. This would result in deadlock if fixed range is asked from\n\t\t// cache and it's not there.\n\t\t// Better implementation would be to return only what we have in cache, but that also breaks API\n\t\tassert(!cachedOnly || toTotal === undefined, 0x1e3);\n\n\t\t// Don't use cache for ops is snapshot is fetched from network or if it was not fetched at all.\n\t\tthis.useCacheForOps =\n\t\t\tthis.useCacheForOps &&\n\t\t\tthis.storageManagerGetter()?.isFirstSnapshotFromNetwork === false;\n\t\tlet opsFromSnapshot = 0;\n\t\tlet opsFromCache = 0;\n\t\tlet opsFromStorage = 0;\n\n\t\tconst requestCallback = async (\n\t\t\tfrom: number,\n\t\t\tto: number,\n\t\t\ttelemetryProps: ITelemetryProperties,\n\t\t) => {\n\t\t\tif (this.snapshotOps !== undefined && this.snapshotOps.length !== 0) {\n\t\t\t\tconst messages = this.snapshotOps.filter(\n\t\t\t\t\t(op) => op.sequenceNumber >= from && op.sequenceNumber < to,\n\t\t\t\t);\n\t\t\t\tvalidateMessages(\"cached\", messages, from, this.logger);\n\t\t\t\tif (messages.length > 0 && messages[0].sequenceNumber === from) {\n\t\t\t\t\tthis.snapshotOps = this.snapshotOps.filter((op) => op.sequenceNumber >= to);\n\t\t\t\t\topsFromSnapshot += messages.length;\n\t\t\t\t\treturn { messages, partialResult: true };\n\t\t\t\t}\n\t\t\t\tthis.snapshotOps = undefined;\n\t\t\t}\n\n\t\t\t// Kick out request to PUSH for ops if it has them\n\t\t\tthis.requestFromSocket(from, to);\n\n\t\t\t// Cache in normal flow is continuous. Once there is a miss, stop consulting cache.\n\t\t\t// This saves a bit of processing time.\n\t\t\tif (this.useCacheForOps) {\n\t\t\t\tconst messagesFromCache = await this.getCached(from, to);\n\t\t\t\tvalidateMessages(\"cached\", messagesFromCache, from, this.logger);\n\t\t\t\t// Set the firstCacheMiss as true in case we didn't get all the ops.\n\t\t\t\t// This will save an extra cache read on \"DocumentOpen\" or \"PostDocumentOpen\".\n\t\t\t\tthis.useCacheForOps = from + messagesFromCache.length >= to;\n\t\t\t\tif (messagesFromCache.length !== 0) {\n\t\t\t\t\topsFromCache += messagesFromCache.length;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tmessages: messagesFromCache,\n\t\t\t\t\t\tpartialResult: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (cachedOnly) {\n\t\t\t\treturn { messages: [], partialResult: false };\n\t\t\t}\n\n\t\t\tconst ops = await this.getFromStorage(from, to, telemetryProps, fetchReason);\n\t\t\tvalidateMessages(\"storage\", ops.messages, from, this.logger);\n\t\t\topsFromStorage += ops.messages.length;\n\t\t\tthis.opsReceived(ops.messages);\n\t\t\treturn ops;\n\t\t};\n\n\t\tconst stream = requestOps(\n\t\t\tasync (from: number, to: number, telemetryProps: ITelemetryProperties) => {\n\t\t\t\tconst result = await requestCallback(from, to, telemetryProps);\n\t\t\t\t// Catch all case, just in case\n\t\t\t\tvalidateMessages(\"catch all\", result.messages, from, this.logger);\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\t// Staging: starting with no concurrency, listening for feedback first.\n\t\t\t// In future releases we will switch to actual concurrency\n\t\t\tthis.concurrency,\n\t\t\tfromTotal, // inclusive\n\t\t\ttoTotal, // exclusive\n\t\t\tthis.batchSize,\n\t\t\tthis.logger,\n\t\t\tabortSignal,\n\t\t\tfetchReason,\n\t\t);\n\n\t\treturn streamObserver(stream, (result) => {\n\t\t\tif (result.done && opsFromSnapshot + opsFromCache + opsFromStorage !== 0) {\n\t\t\t\tthis.logger.sendPerformanceEvent({\n\t\t\t\t\teventName: \"CacheOpsRetrieved\",\n\t\t\t\t\topsFromSnapshot,\n\t\t\t\t\topsFromCache,\n\t\t\t\t\topsFromStorage,\n\t\t\t\t\treason: fetchReason,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentService.d.ts","sourceRoot":"","sources":["../src/odspDocumentService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,mBAAmB,EAInB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACN,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,EACvB,wBAAwB,EACxB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EACN,gBAAgB,EAChB,iBAAiB,EAEjB,iBAAiB,EACjB,+BAA+B,EAC/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAKzC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIxC;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,gBAAgB;aAuE1C,eAAe,EAAE,gBAAgB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAhFrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;IAGrD,OAAO,CAAC,aAAa,CAAkD;IAEvE,OAAO,CAAC,0BAA0B,CAAyC;IAE3E,OAAO,CAAC,sBAAsB,CAAkB;IAEhD;;;;;;;;;;;;OAYG;WACiB,MAAM,CACzB,WAAW,EAAE,YAAY,EACzB,eAAe,EAAE,+BAA+B,EAEhD,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,SAAS,EACvF,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,iBAAiB,EAC7B,YAAY,EAAE,YAAY,EAC1B,wBAAwB,CAAC,EAAE,MAAM,EACjC,kBAAkB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IAc5B,OAAO,CAAC,cAAc,CAAC,CAA6B;IAEpD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IAEvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IAEvD,OAAO,CAAC,SAAS,CAAC,CAAW;IAE7B;;;;;;;;;;;;;OAaG;IACH,OAAO;IAmCP,IAAW,WAAW,IAAI,YAAY,CAErC;IACD,IAAW,QAAQ,6BAElB;IAED;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,uBAAuB,CAAC;IA+BjE;;;;OAIG;IACU,qBAAqB,IAAI,OAAO,CAAC,4BAA4B,CAAC;IAoC3E;;;;OAIG;IACU,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAiBrF;;;;;OAKG;YACW,yBAAyB;IA4BhC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG;IAe1B,SAAS,KAAK,QAAQ,yBAgCrB;IAID,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,yBAAyB,EAAE;CAQtD"}
1
+ {"version":3,"file":"odspDocumentService.d.ts","sourceRoot":"","sources":["../src/odspDocumentService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,mBAAmB,EAGnB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACN,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,EACvB,wBAAwB,EACxB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EACN,gBAAgB,EAChB,iBAAiB,EAEjB,iBAAiB,EACjB,+BAA+B,EAC/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAKzC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIxC;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,gBAAgB;aAuE1C,eAAe,EAAE,gBAAgB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAhFrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;IAGrD,OAAO,CAAC,aAAa,CAAkD;IAEvE,OAAO,CAAC,0BAA0B,CAAyC;IAE3E,OAAO,CAAC,sBAAsB,CAAkB;IAEhD;;;;;;;;;;;;OAYG;WACiB,MAAM,CACzB,WAAW,EAAE,YAAY,EACzB,eAAe,EAAE,+BAA+B,EAEhD,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,SAAS,EACvF,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,iBAAiB,EAC7B,YAAY,EAAE,YAAY,EAC1B,wBAAwB,CAAC,EAAE,MAAM,EACjC,kBAAkB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IAc5B,OAAO,CAAC,cAAc,CAAC,CAA6B;IAEpD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IAEvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IAEvD,OAAO,CAAC,SAAS,CAAC,CAAW;IAE7B;;;;;;;;;;;;;OAaG;IACH,OAAO;IAoCP,IAAW,WAAW,IAAI,YAAY,CAErC;IACD,IAAW,QAAQ,6BAElB;IAED;;;;OAIG;IACU,gBAAgB,IAAI,OAAO,CAAC,uBAAuB,CAAC;IA+BjE;;;;OAIG;IACU,qBAAqB,IAAI,OAAO,CAAC,4BAA4B,CAAC;IAqC3E;;;;OAIG;IACU,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAiBrF;;;;;OAKG;YACW,yBAAyB;IA4BhC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG;IAe1B,SAAS,KAAK,QAAQ,yBAgCrB;IAID,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,yBAAyB,EAAE;CAQtD"}
@@ -65,11 +65,14 @@ class OdspDocumentService {
65
65
  storageOnly: odspResolvedUrl.fileVersion !== undefined,
66
66
  summarizeProtocolTree: true,
67
67
  };
68
- this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(logger, undefined, {
69
- all: {
70
- odc: (0, odspUrlHelper_1.isOdcOrigin)(new URL(this.odspResolvedUrl.endpoints.snapshotStorageUrl).origin),
68
+ this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
69
+ logger,
70
+ properties: {
71
+ all: {
72
+ odc: (0, odspUrlHelper_1.isOdcOrigin)(new URL(this.odspResolvedUrl.endpoints.snapshotStorageUrl).origin),
73
+ },
71
74
  },
72
- }));
75
+ });
73
76
  this.hostPolicy = hostPolicy;
74
77
  if (this.clientIsSummarizer) {
75
78
  this.hostPolicy = Object.assign(Object.assign({}, this.hostPolicy), { summarizerClient: true });
@@ -150,7 +153,7 @@ class OdspDocumentService {
150
153
  if (currentConnection !== undefined && !currentConnection.disposed) {
151
154
  currentConnection.requestOps(from, to);
152
155
  }
153
- }, (ops) => this.opsReceived(ops));
156
+ }, (ops) => this.opsReceived(ops), () => this.storageManager);
154
157
  }
155
158
  /**
156
159
  * Connects to a delta stream endpoint for emitting ops.
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentService.js","sourceRoot":"","sources":["../src/odspDocumentService.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 {\n\tITelemetryLoggerExt,\n\tChildLogger,\n\tloggerToMonitoringContext,\n\tMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIResolvedUrl,\n\tIDocumentStorageService,\n\tIDocumentServicePolicies,\n} from \"@fluidframework/driver-definitions\";\nimport { IClient, ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIOdspResolvedUrl,\n\tTokenFetchOptions,\n\tIEntry,\n\tHostStoragePolicy,\n\tInstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { HostStoragePolicyInternal } from \"./contracts\";\nimport { IOdspCache } from \"./odspCache\";\nimport { OdspDeltaStorageService, OdspDeltaStorageWithCache } from \"./odspDeltaStorageService\";\nimport { OdspDocumentStorageService } from \"./odspDocumentStorageManager\";\nimport { getOdspResolvedUrl } from \"./odspUtils\";\nimport { isOdcOrigin } from \"./odspUrlHelper\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { OpsCache } from \"./opsCaching\";\nimport { RetryErrorsStorageAdapter } from \"./retryErrorsStorageAdapter\";\nimport type { OdspDelayLoadedDeltaStream } from \"./odspDelayLoadedDeltaStream\";\n\n/**\n * The DocumentService manages the Socket.IO connection and manages routing requests to connected\n * clients\n */\nexport class OdspDocumentService implements IDocumentService {\n\tprivate readonly _policies: IDocumentServicePolicies;\n\n\t// Promise to load socket module only once.\n\tprivate socketModuleP: Promise<OdspDelayLoadedDeltaStream> | undefined;\n\n\tprivate odspDelayLoadedDeltaStream: OdspDelayLoadedDeltaStream | undefined;\n\n\tprivate odspSocketModuleLoaded: boolean = false;\n\n\t/**\n\t * @param resolvedUrl - resolved url identifying document that will be managed by returned service instance.\n\t * @param getStorageToken - function that can provide the storage token. This is is also referred to as\n\t * the \"Vroom\" token in SPO.\n\t * @param getWebsocketToken - function that can provide a token for accessing the web socket. This is also referred\n\t * to as the \"Push\" token in SPO. If undefined then websocket token is expected to be returned with joinSession\n\t * response payload.\n\t * @param logger - a logger that can capture performance and diagnostic information\n\t * @param cache - This caches response for joinSession.\n\t * @param hostPolicy - This host constructed policy which customizes service behavior.\n\t * @param epochTracker - This helper class which adds epoch to backend calls made by returned service instance.\n\t * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n\t */\n\tpublic static async create(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tgetStorageToken: InstrumentedStorageTokenFetcher,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tgetWebsocketToken: ((options: TokenFetchOptions) => Promise<string | null>) | undefined,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tcache: IOdspCache,\n\t\thostPolicy: HostStoragePolicy,\n\t\tepochTracker: EpochTracker,\n\t\tsocketReferenceKeyPrefix?: string,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\treturn new OdspDocumentService(\n\t\t\tgetOdspResolvedUrl(resolvedUrl),\n\t\t\tgetStorageToken,\n\t\t\tgetWebsocketToken,\n\t\t\tlogger,\n\t\t\tcache,\n\t\t\thostPolicy,\n\t\t\tepochTracker,\n\t\t\tsocketReferenceKeyPrefix,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t}\n\n\tprivate storageManager?: OdspDocumentStorageService;\n\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate readonly hostPolicy: HostStoragePolicyInternal;\n\n\tprivate _opsCache?: OpsCache;\n\n\t/**\n\t * @param odspResolvedUrl - resolved url identifying document that will be managed by this service instance.\n\t * @param getStorageToken - function that can provide the storage token. This is is also referred to as\n\t * the \"Vroom\" token in SPO.\n\t * @param getWebsocketToken - function that can provide a token for accessing the web socket. This is also referred\n\t * to as the \"Push\" token in SPO. If undefined then websocket token is expected to be returned with joinSession\n\t * response payload.\n\t * @param logger - a logger that can capture performance and diagnostic information\n\t * @param socketIoClientFactory - A factory that returns a promise to the socket io library required by the driver\n\t * @param cache - This caches response for joinSession.\n\t * @param hostPolicy - host constructed policy which customizes service behavior.\n\t * @param epochTracker - This helper class which adds epoch to backend calls made by this service instance.\n\t * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n\t */\n\tprivate constructor(\n\t\tpublic readonly odspResolvedUrl: IOdspResolvedUrl,\n\t\tprivate readonly getStorageToken: InstrumentedStorageTokenFetcher,\n\t\tprivate readonly getWebsocketToken:\n\t\t\t| ((options: TokenFetchOptions) => Promise<string | null>)\n\t\t\t| undefined,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly cache: IOdspCache,\n\t\thostPolicy: HostStoragePolicy,\n\t\tprivate readonly epochTracker: EpochTracker,\n\t\tprivate readonly socketReferenceKeyPrefix?: string,\n\t\tprivate readonly clientIsSummarizer?: boolean,\n\t) {\n\t\tthis._policies = {\n\t\t\t// load in storage-only mode if a file version is specified\n\t\t\tstorageOnly: odspResolvedUrl.fileVersion !== undefined,\n\t\t\tsummarizeProtocolTree: true,\n\t\t};\n\n\t\tthis.mc = loggerToMonitoringContext(\n\t\t\tChildLogger.create(logger, undefined, {\n\t\t\t\tall: {\n\t\t\t\t\todc: isOdcOrigin(\n\t\t\t\t\t\tnew URL(this.odspResolvedUrl.endpoints.snapshotStorageUrl).origin,\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\n\t\tthis.hostPolicy = hostPolicy;\n\t\tif (this.clientIsSummarizer) {\n\t\t\tthis.hostPolicy = { ...this.hostPolicy, summarizerClient: true };\n\t\t}\n\t}\n\n\tpublic get resolvedUrl(): IResolvedUrl {\n\t\treturn this.odspResolvedUrl;\n\t}\n\tpublic get policies() {\n\t\treturn this._policies;\n\t}\n\n\t/**\n\t * Connects to a storage endpoint for snapshot service.\n\t *\n\t * @returns returns the document storage service for sharepoint driver.\n\t */\n\tpublic async connectToStorage(): Promise<IDocumentStorageService> {\n\t\tif (!this.storageManager) {\n\t\t\tthis.storageManager = new OdspDocumentStorageService(\n\t\t\t\tthis.odspResolvedUrl,\n\t\t\t\tthis.getStorageToken,\n\t\t\t\tthis.mc.logger,\n\t\t\t\ttrue,\n\t\t\t\tthis.cache,\n\t\t\t\tthis.hostPolicy,\n\t\t\t\tthis.epochTracker,\n\t\t\t\t// flushCallback\n\t\t\t\tasync () => {\n\t\t\t\t\tconst currentConnection =\n\t\t\t\t\t\tthis.odspDelayLoadedDeltaStream?.currentDeltaConnection;\n\t\t\t\t\tif (currentConnection !== undefined && !currentConnection.disposed) {\n\t\t\t\t\t\treturn currentConnection.flush();\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Disconnected while uploading summary (attempt to perform flush())\",\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\treturn this.odspDelayLoadedDeltaStream?.relayServiceTenantAndSessionId;\n\t\t\t\t},\n\t\t\t\tthis.mc.config.getNumber(\"Fluid.Driver.Odsp.snapshotFormatFetchType\"),\n\t\t\t);\n\t\t}\n\n\t\treturn new RetryErrorsStorageAdapter(this.storageManager, this.mc.logger);\n\t}\n\n\t/**\n\t * Connects to a delta storage endpoint for getting ops between a range.\n\t *\n\t * @returns returns the document delta storage service for sharepoint driver.\n\t */\n\tpublic async connectToDeltaStorage(): Promise<IDocumentDeltaStorageService> {\n\t\tconst snapshotOps = this.storageManager?.ops ?? [];\n\t\tconst service = new OdspDeltaStorageService(\n\t\t\tthis.odspResolvedUrl.endpoints.deltaStorageUrl,\n\t\t\tthis.getStorageToken,\n\t\t\tthis.epochTracker,\n\t\t\tthis.mc.logger,\n\t\t);\n\n\t\t// batch size, please see issue #5211 for data around batch sizing\n\t\tconst batchSize = this.hostPolicy.opsBatchSize ?? 5000;\n\t\tconst concurrency = this.hostPolicy.concurrentOpsBatches ?? 1;\n\t\treturn new OdspDeltaStorageWithCache(\n\t\t\tsnapshotOps,\n\t\t\tthis.mc.logger,\n\t\t\tbatchSize,\n\t\t\tconcurrency,\n\t\t\t// Get Ops from storage callback.\n\t\t\tasync (from, to, telemetryProps, fetchReason) =>\n\t\t\t\tservice.get(from, to, telemetryProps, fetchReason),\n\t\t\t// Get cachedOps Callback.\n\t\t\tasync (from, to) => {\n\t\t\t\tconst res = await this.opsCache?.get(from, to);\n\t\t\t\treturn (res as ISequencedDocumentMessage[]) ?? [];\n\t\t\t},\n\t\t\t// Ops requestFromSocket Callback.\n\t\t\t(from, to) => {\n\t\t\t\tconst currentConnection = this.odspDelayLoadedDeltaStream?.currentDeltaConnection;\n\t\t\t\tif (currentConnection !== undefined && !currentConnection.disposed) {\n\t\t\t\t\tcurrentConnection.requestOps(from, to);\n\t\t\t\t}\n\t\t\t},\n\t\t\t(ops: ISequencedDocumentMessage[]) => this.opsReceived(ops),\n\t\t);\n\t}\n\n\t/**\n\t * Connects to a delta stream endpoint for emitting ops.\n\t *\n\t * @returns returns the document delta stream service for onedrive/sharepoint driver.\n\t */\n\tpublic async connectToDeltaStream(client: IClient): Promise<IDocumentDeltaConnection> {\n\t\tif (this.socketModuleP === undefined) {\n\t\t\tthis.socketModuleP = this.getDelayLoadedDeltaStream();\n\t\t}\n\t\treturn this.socketModuleP\n\t\t\t.then(async (m) => {\n\t\t\t\tthis.odspSocketModuleLoaded = true;\n\t\t\t\treturn m.connectToDeltaStream(client);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// Setting undefined in case someone tries to recover from module failure by calling again.\n\t\t\t\tthis.socketModuleP = undefined;\n\t\t\t\tthis.odspSocketModuleLoaded = false;\n\t\t\t\tthrow error;\n\t\t\t});\n\t}\n\n\t/**\n\t * This dynamically imports the module for loading the delta connection. In many cases the delta stream, is not\n\t * required during the critical load flow. So this way we don't have to bundle this in the initial bundle and can\n\t * import this later on when required.\n\t * @returns - delta stream object.\n\t */\n\tprivate async getDelayLoadedDeltaStream() {\n\t\tassert(this.odspSocketModuleLoaded === false, 0x507 /* Should be loaded only once */);\n\t\tconst module = await import(\n\t\t\t/* webpackChunkName: \"socketModule\" */ \"./odspDelayLoadedDeltaStream\"\n\t\t)\n\t\t\t.then((m) => {\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({ eventName: \"SocketModuleLoaded\" });\n\t\t\t\treturn m;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"SocketModuleLoadFailed\" }, error);\n\t\t\t\tthrow error;\n\t\t\t});\n\t\tthis.odspDelayLoadedDeltaStream = new module.OdspDelayLoadedDeltaStream(\n\t\t\tthis.odspResolvedUrl,\n\t\t\tthis._policies,\n\t\t\tthis.getStorageToken,\n\t\t\tthis.getWebsocketToken,\n\t\t\tthis.mc,\n\t\t\tthis.cache,\n\t\t\tthis.hostPolicy,\n\t\t\tthis.epochTracker,\n\t\t\t(ops: ISequencedDocumentMessage[]) => this.opsReceived(ops),\n\t\t\tthis.socketReferenceKeyPrefix,\n\t\t);\n\t\treturn this.odspDelayLoadedDeltaStream;\n\t}\n\n\tpublic dispose(error?: any) {\n\t\t// Error might indicate mismatch between client & server knowledge about file\n\t\t// (DriverErrorType.fileOverwrittenInStorage).\n\t\t// For example, file might have been overwritten in storage without generating new epoch\n\t\t// In such case client cached info is stale and has to be removed.\n\t\tif (error !== undefined) {\n\t\t\tthis.epochTracker.removeEntries().catch(() => {});\n\t\t} else {\n\t\t\tthis._opsCache?.flushOps();\n\t\t}\n\t\tthis._opsCache?.dispose();\n\t\t// Only need to dipose this, if it is already loaded.\n\t\tthis.odspDelayLoadedDeltaStream?.dispose();\n\t}\n\n\tprotected get opsCache() {\n\t\tif (this._opsCache) {\n\t\t\treturn this._opsCache;\n\t\t}\n\n\t\tconst seqNumber = this.storageManager?.snapshotSequenceNumber;\n\t\tconst batchSize = this.hostPolicy.opsCaching?.batchSize ?? 100;\n\t\tif (seqNumber === undefined || batchSize < 1) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst opsKey: Omit<IEntry, \"key\"> = {\n\t\t\ttype: \"ops\",\n\t\t};\n\t\tthis._opsCache = new OpsCache(\n\t\t\tseqNumber,\n\t\t\tthis.mc.logger,\n\t\t\t// ICache\n\t\t\t{\n\t\t\t\twrite: async (key: string, opsData: string) => {\n\t\t\t\t\treturn this.cache.persistedCache.put({ ...opsKey, key }, opsData);\n\t\t\t\t},\n\t\t\t\tread: async (key: string) => this.cache.persistedCache.get({ ...opsKey, key }),\n\t\t\t\tremove: () => {\n\t\t\t\t\tthis.cache.persistedCache.removeEntries().catch(() => {});\n\t\t\t\t},\n\t\t\t},\n\t\t\tbatchSize,\n\t\t\tthis.hostPolicy.opsCaching?.timerGranularity ?? 5000,\n\t\t\tthis.hostPolicy.opsCaching?.totalOpsToCache ?? 5000,\n\t\t);\n\t\treturn this._opsCache;\n\t}\n\n\t// Called whenever re receive ops through any channel for this document (snapshot, delta connection, delta storage)\n\t// We use it to notify caching layer of how stale is snapshot stored in cache.\n\tprotected opsReceived(ops: ISequencedDocumentMessage[]) {\n\t\t// No need for two clients to save same ops\n\t\tif (ops.length === 0 || this.odspResolvedUrl.summarizer) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.opsCache?.addOps(ops);\n\t}\n}\n"]}
1
+ {"version":3,"file":"odspDocumentService.js","sourceRoot":"","sources":["../src/odspDocumentService.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 {\n\tITelemetryLoggerExt,\n\tcreateChildMonitoringContext,\n\tMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n\tIDocumentDeltaConnection,\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIResolvedUrl,\n\tIDocumentStorageService,\n\tIDocumentServicePolicies,\n} from \"@fluidframework/driver-definitions\";\nimport { IClient, ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIOdspResolvedUrl,\n\tTokenFetchOptions,\n\tIEntry,\n\tHostStoragePolicy,\n\tInstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { HostStoragePolicyInternal } from \"./contracts\";\nimport { IOdspCache } from \"./odspCache\";\nimport { OdspDeltaStorageService, OdspDeltaStorageWithCache } from \"./odspDeltaStorageService\";\nimport { OdspDocumentStorageService } from \"./odspDocumentStorageManager\";\nimport { getOdspResolvedUrl } from \"./odspUtils\";\nimport { isOdcOrigin } from \"./odspUrlHelper\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { OpsCache } from \"./opsCaching\";\nimport { RetryErrorsStorageAdapter } from \"./retryErrorsStorageAdapter\";\nimport type { OdspDelayLoadedDeltaStream } from \"./odspDelayLoadedDeltaStream\";\n\n/**\n * The DocumentService manages the Socket.IO connection and manages routing requests to connected\n * clients\n */\nexport class OdspDocumentService implements IDocumentService {\n\tprivate readonly _policies: IDocumentServicePolicies;\n\n\t// Promise to load socket module only once.\n\tprivate socketModuleP: Promise<OdspDelayLoadedDeltaStream> | undefined;\n\n\tprivate odspDelayLoadedDeltaStream: OdspDelayLoadedDeltaStream | undefined;\n\n\tprivate odspSocketModuleLoaded: boolean = false;\n\n\t/**\n\t * @param resolvedUrl - resolved url identifying document that will be managed by returned service instance.\n\t * @param getStorageToken - function that can provide the storage token. This is is also referred to as\n\t * the \"Vroom\" token in SPO.\n\t * @param getWebsocketToken - function that can provide a token for accessing the web socket. This is also referred\n\t * to as the \"Push\" token in SPO. If undefined then websocket token is expected to be returned with joinSession\n\t * response payload.\n\t * @param logger - a logger that can capture performance and diagnostic information\n\t * @param cache - This caches response for joinSession.\n\t * @param hostPolicy - This host constructed policy which customizes service behavior.\n\t * @param epochTracker - This helper class which adds epoch to backend calls made by returned service instance.\n\t * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n\t */\n\tpublic static async create(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tgetStorageToken: InstrumentedStorageTokenFetcher,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tgetWebsocketToken: ((options: TokenFetchOptions) => Promise<string | null>) | undefined,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tcache: IOdspCache,\n\t\thostPolicy: HostStoragePolicy,\n\t\tepochTracker: EpochTracker,\n\t\tsocketReferenceKeyPrefix?: string,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\treturn new OdspDocumentService(\n\t\t\tgetOdspResolvedUrl(resolvedUrl),\n\t\t\tgetStorageToken,\n\t\t\tgetWebsocketToken,\n\t\t\tlogger,\n\t\t\tcache,\n\t\t\thostPolicy,\n\t\t\tepochTracker,\n\t\t\tsocketReferenceKeyPrefix,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t}\n\n\tprivate storageManager?: OdspDocumentStorageService;\n\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate readonly hostPolicy: HostStoragePolicyInternal;\n\n\tprivate _opsCache?: OpsCache;\n\n\t/**\n\t * @param odspResolvedUrl - resolved url identifying document that will be managed by this service instance.\n\t * @param getStorageToken - function that can provide the storage token. This is is also referred to as\n\t * the \"Vroom\" token in SPO.\n\t * @param getWebsocketToken - function that can provide a token for accessing the web socket. This is also referred\n\t * to as the \"Push\" token in SPO. If undefined then websocket token is expected to be returned with joinSession\n\t * response payload.\n\t * @param logger - a logger that can capture performance and diagnostic information\n\t * @param socketIoClientFactory - A factory that returns a promise to the socket io library required by the driver\n\t * @param cache - This caches response for joinSession.\n\t * @param hostPolicy - host constructed policy which customizes service behavior.\n\t * @param epochTracker - This helper class which adds epoch to backend calls made by this service instance.\n\t * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n\t */\n\tprivate constructor(\n\t\tpublic readonly odspResolvedUrl: IOdspResolvedUrl,\n\t\tprivate readonly getStorageToken: InstrumentedStorageTokenFetcher,\n\t\tprivate readonly getWebsocketToken:\n\t\t\t| ((options: TokenFetchOptions) => Promise<string | null>)\n\t\t\t| undefined,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly cache: IOdspCache,\n\t\thostPolicy: HostStoragePolicy,\n\t\tprivate readonly epochTracker: EpochTracker,\n\t\tprivate readonly socketReferenceKeyPrefix?: string,\n\t\tprivate readonly clientIsSummarizer?: boolean,\n\t) {\n\t\tthis._policies = {\n\t\t\t// load in storage-only mode if a file version is specified\n\t\t\tstorageOnly: odspResolvedUrl.fileVersion !== undefined,\n\t\t\tsummarizeProtocolTree: true,\n\t\t};\n\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger,\n\t\t\tproperties: {\n\t\t\t\tall: {\n\t\t\t\t\todc: isOdcOrigin(\n\t\t\t\t\t\tnew URL(this.odspResolvedUrl.endpoints.snapshotStorageUrl).origin,\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\n\t\tthis.hostPolicy = hostPolicy;\n\t\tif (this.clientIsSummarizer) {\n\t\t\tthis.hostPolicy = { ...this.hostPolicy, summarizerClient: true };\n\t\t}\n\t}\n\n\tpublic get resolvedUrl(): IResolvedUrl {\n\t\treturn this.odspResolvedUrl;\n\t}\n\tpublic get policies() {\n\t\treturn this._policies;\n\t}\n\n\t/**\n\t * Connects to a storage endpoint for snapshot service.\n\t *\n\t * @returns returns the document storage service for sharepoint driver.\n\t */\n\tpublic async connectToStorage(): Promise<IDocumentStorageService> {\n\t\tif (!this.storageManager) {\n\t\t\tthis.storageManager = new OdspDocumentStorageService(\n\t\t\t\tthis.odspResolvedUrl,\n\t\t\t\tthis.getStorageToken,\n\t\t\t\tthis.mc.logger,\n\t\t\t\ttrue,\n\t\t\t\tthis.cache,\n\t\t\t\tthis.hostPolicy,\n\t\t\t\tthis.epochTracker,\n\t\t\t\t// flushCallback\n\t\t\t\tasync () => {\n\t\t\t\t\tconst currentConnection =\n\t\t\t\t\t\tthis.odspDelayLoadedDeltaStream?.currentDeltaConnection;\n\t\t\t\t\tif (currentConnection !== undefined && !currentConnection.disposed) {\n\t\t\t\t\t\treturn currentConnection.flush();\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Disconnected while uploading summary (attempt to perform flush())\",\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\treturn this.odspDelayLoadedDeltaStream?.relayServiceTenantAndSessionId;\n\t\t\t\t},\n\t\t\t\tthis.mc.config.getNumber(\"Fluid.Driver.Odsp.snapshotFormatFetchType\"),\n\t\t\t);\n\t\t}\n\n\t\treturn new RetryErrorsStorageAdapter(this.storageManager, this.mc.logger);\n\t}\n\n\t/**\n\t * Connects to a delta storage endpoint for getting ops between a range.\n\t *\n\t * @returns returns the document delta storage service for sharepoint driver.\n\t */\n\tpublic async connectToDeltaStorage(): Promise<IDocumentDeltaStorageService> {\n\t\tconst snapshotOps = this.storageManager?.ops ?? [];\n\t\tconst service = new OdspDeltaStorageService(\n\t\t\tthis.odspResolvedUrl.endpoints.deltaStorageUrl,\n\t\t\tthis.getStorageToken,\n\t\t\tthis.epochTracker,\n\t\t\tthis.mc.logger,\n\t\t);\n\n\t\t// batch size, please see issue #5211 for data around batch sizing\n\t\tconst batchSize = this.hostPolicy.opsBatchSize ?? 5000;\n\t\tconst concurrency = this.hostPolicy.concurrentOpsBatches ?? 1;\n\t\treturn new OdspDeltaStorageWithCache(\n\t\t\tsnapshotOps,\n\t\t\tthis.mc.logger,\n\t\t\tbatchSize,\n\t\t\tconcurrency,\n\t\t\t// Get Ops from storage callback.\n\t\t\tasync (from, to, telemetryProps, fetchReason) =>\n\t\t\t\tservice.get(from, to, telemetryProps, fetchReason),\n\t\t\t// Get cachedOps Callback.\n\t\t\tasync (from, to) => {\n\t\t\t\tconst res = await this.opsCache?.get(from, to);\n\t\t\t\treturn (res as ISequencedDocumentMessage[]) ?? [];\n\t\t\t},\n\t\t\t// Ops requestFromSocket Callback.\n\t\t\t(from, to) => {\n\t\t\t\tconst currentConnection = this.odspDelayLoadedDeltaStream?.currentDeltaConnection;\n\t\t\t\tif (currentConnection !== undefined && !currentConnection.disposed) {\n\t\t\t\t\tcurrentConnection.requestOps(from, to);\n\t\t\t\t}\n\t\t\t},\n\t\t\t(ops: ISequencedDocumentMessage[]) => this.opsReceived(ops),\n\t\t\t() => this.storageManager,\n\t\t);\n\t}\n\n\t/**\n\t * Connects to a delta stream endpoint for emitting ops.\n\t *\n\t * @returns returns the document delta stream service for onedrive/sharepoint driver.\n\t */\n\tpublic async connectToDeltaStream(client: IClient): Promise<IDocumentDeltaConnection> {\n\t\tif (this.socketModuleP === undefined) {\n\t\t\tthis.socketModuleP = this.getDelayLoadedDeltaStream();\n\t\t}\n\t\treturn this.socketModuleP\n\t\t\t.then(async (m) => {\n\t\t\t\tthis.odspSocketModuleLoaded = true;\n\t\t\t\treturn m.connectToDeltaStream(client);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// Setting undefined in case someone tries to recover from module failure by calling again.\n\t\t\t\tthis.socketModuleP = undefined;\n\t\t\t\tthis.odspSocketModuleLoaded = false;\n\t\t\t\tthrow error;\n\t\t\t});\n\t}\n\n\t/**\n\t * This dynamically imports the module for loading the delta connection. In many cases the delta stream, is not\n\t * required during the critical load flow. So this way we don't have to bundle this in the initial bundle and can\n\t * import this later on when required.\n\t * @returns - delta stream object.\n\t */\n\tprivate async getDelayLoadedDeltaStream() {\n\t\tassert(this.odspSocketModuleLoaded === false, 0x507 /* Should be loaded only once */);\n\t\tconst module = await import(\n\t\t\t/* webpackChunkName: \"socketModule\" */ \"./odspDelayLoadedDeltaStream\"\n\t\t)\n\t\t\t.then((m) => {\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({ eventName: \"SocketModuleLoaded\" });\n\t\t\t\treturn m;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"SocketModuleLoadFailed\" }, error);\n\t\t\t\tthrow error;\n\t\t\t});\n\t\tthis.odspDelayLoadedDeltaStream = new module.OdspDelayLoadedDeltaStream(\n\t\t\tthis.odspResolvedUrl,\n\t\t\tthis._policies,\n\t\t\tthis.getStorageToken,\n\t\t\tthis.getWebsocketToken,\n\t\t\tthis.mc,\n\t\t\tthis.cache,\n\t\t\tthis.hostPolicy,\n\t\t\tthis.epochTracker,\n\t\t\t(ops: ISequencedDocumentMessage[]) => this.opsReceived(ops),\n\t\t\tthis.socketReferenceKeyPrefix,\n\t\t);\n\t\treturn this.odspDelayLoadedDeltaStream;\n\t}\n\n\tpublic dispose(error?: any) {\n\t\t// Error might indicate mismatch between client & server knowledge about file\n\t\t// (DriverErrorType.fileOverwrittenInStorage).\n\t\t// For example, file might have been overwritten in storage without generating new epoch\n\t\t// In such case client cached info is stale and has to be removed.\n\t\tif (error !== undefined) {\n\t\t\tthis.epochTracker.removeEntries().catch(() => {});\n\t\t} else {\n\t\t\tthis._opsCache?.flushOps();\n\t\t}\n\t\tthis._opsCache?.dispose();\n\t\t// Only need to dipose this, if it is already loaded.\n\t\tthis.odspDelayLoadedDeltaStream?.dispose();\n\t}\n\n\tprotected get opsCache() {\n\t\tif (this._opsCache) {\n\t\t\treturn this._opsCache;\n\t\t}\n\n\t\tconst seqNumber = this.storageManager?.snapshotSequenceNumber;\n\t\tconst batchSize = this.hostPolicy.opsCaching?.batchSize ?? 100;\n\t\tif (seqNumber === undefined || batchSize < 1) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst opsKey: Omit<IEntry, \"key\"> = {\n\t\t\ttype: \"ops\",\n\t\t};\n\t\tthis._opsCache = new OpsCache(\n\t\t\tseqNumber,\n\t\t\tthis.mc.logger,\n\t\t\t// ICache\n\t\t\t{\n\t\t\t\twrite: async (key: string, opsData: string) => {\n\t\t\t\t\treturn this.cache.persistedCache.put({ ...opsKey, key }, opsData);\n\t\t\t\t},\n\t\t\t\tread: async (key: string) => this.cache.persistedCache.get({ ...opsKey, key }),\n\t\t\t\tremove: () => {\n\t\t\t\t\tthis.cache.persistedCache.removeEntries().catch(() => {});\n\t\t\t\t},\n\t\t\t},\n\t\t\tbatchSize,\n\t\t\tthis.hostPolicy.opsCaching?.timerGranularity ?? 5000,\n\t\t\tthis.hostPolicy.opsCaching?.totalOpsToCache ?? 5000,\n\t\t);\n\t\treturn this._opsCache;\n\t}\n\n\t// Called whenever re receive ops through any channel for this document (snapshot, delta connection, delta storage)\n\t// We use it to notify caching layer of how stale is snapshot stored in cache.\n\tprotected opsReceived(ops: ISequencedDocumentMessage[]) {\n\t\t// No need for two clients to save same ops\n\t\tif (ops.length === 0 || this.odspResolvedUrl.summarizer) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.opsCache?.addOps(ops);\n\t}\n}\n"]}
@@ -28,6 +28,7 @@ export declare class OdspDocumentStorageService extends OdspDocumentStorageServi
28
28
  private summaryModuleP;
29
29
  private odspSummaryUploadManager;
30
30
  private firstVersionCall;
31
+ private _isFirstSnapshotFromNetwork;
31
32
  private readonly documentId;
32
33
  private readonly snapshotUrl;
33
34
  private readonly attachmentPOSTUrl;
@@ -41,6 +42,7 @@ export declare class OdspDocumentStorageService extends OdspDocumentStorageServi
41
42
  private readonly maxSnapshotFetchTimeout;
42
43
  private readonly createBlobRateLimiter;
43
44
  constructor(odspResolvedUrl: IOdspResolvedUrl, getStorageToken: InstrumentedStorageTokenFetcher, logger: ITelemetryLoggerExt, fetchFullSnapshot: boolean, cache: IOdspCache, hostPolicy: HostStoragePolicyInternal, epochTracker: EpochTracker, flushCallback: () => Promise<FlushResult>, relayServiceTenantAndSessionId: () => string | undefined, snapshotFormatFetchType?: SnapshotFormatSupportType | undefined);
45
+ get isFirstSnapshotFromNetwork(): boolean | undefined;
44
46
  createBlob(file: ArrayBufferLike): Promise<api.ICreateBlobResponse>;
45
47
  protected fetchBlobFromStorage(blobId: string, evicted: boolean): Promise<ArrayBuffer>;
46
48
  getSnapshotTree(version?: api.IVersion, scenarioName?: string): Promise<api.ISnapshotTree | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentStorageManager.d.ts","sourceRoot":"","sources":["../src/odspDocumentStorageManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"odspDocumentStorageManager.d.ts","sourceRoot":"","sources":["../src/odspDocumentStorageManager.ts"],"names":[],"mappings":"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"}