@fluidframework/odsp-driver 2.103.0 → 2.110.0

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 (106) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/api-report/odsp-driver.legacy.beta.api.md +4 -4
  3. package/dist/contractsPublic.d.ts +4 -4
  4. package/dist/contractsPublic.d.ts.map +1 -1
  5. package/dist/contractsPublic.js.map +1 -1
  6. package/dist/createFile/createFile.d.ts.map +1 -1
  7. package/dist/createFile/createFile.js.map +1 -1
  8. package/dist/createFile/createNewContainerOnExistingFile.d.ts.map +1 -1
  9. package/dist/createFile/createNewContainerOnExistingFile.js.map +1 -1
  10. package/dist/createFile/createNewUtils.d.ts.map +1 -1
  11. package/dist/createFile/createNewUtils.js.map +1 -1
  12. package/dist/fetchSnapshot.d.ts.map +1 -1
  13. package/dist/fetchSnapshot.js +3 -4
  14. package/dist/fetchSnapshot.js.map +1 -1
  15. package/dist/getFileLink.d.ts.map +1 -1
  16. package/dist/getFileLink.js.map +1 -1
  17. package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
  18. package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
  19. package/dist/odspDelayLoadedDeltaStream.js +1 -1
  20. package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
  21. package/dist/odspDeltaStorageService.d.ts.map +1 -1
  22. package/dist/odspDeltaStorageService.js.map +1 -1
  23. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  24. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  25. package/dist/odspDocumentService.d.ts.map +1 -1
  26. package/dist/odspDocumentService.js.map +1 -1
  27. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  28. package/dist/odspDocumentStorageManager.js.map +1 -1
  29. package/dist/odspSummaryUploadManager.d.ts.map +1 -1
  30. package/dist/odspSummaryUploadManager.js.map +1 -1
  31. package/dist/odspUtils.d.ts.map +1 -1
  32. package/dist/odspUtils.js.map +1 -1
  33. package/dist/packageVersion.d.ts +1 -1
  34. package/dist/packageVersion.js +1 -1
  35. package/dist/packageVersion.js.map +1 -1
  36. package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
  37. package/dist/retryErrorsStorageAdapter.js.map +1 -1
  38. package/dist/vroom.d.ts.map +1 -1
  39. package/dist/vroom.js.map +1 -1
  40. package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
  41. package/dist/zipItDataRepresentationUtils.js +2 -1
  42. package/dist/zipItDataRepresentationUtils.js.map +1 -1
  43. package/lib/contractsPublic.d.ts +4 -4
  44. package/lib/contractsPublic.d.ts.map +1 -1
  45. package/lib/contractsPublic.js.map +1 -1
  46. package/lib/createFile/createFile.d.ts.map +1 -1
  47. package/lib/createFile/createFile.js.map +1 -1
  48. package/lib/createFile/createNewContainerOnExistingFile.d.ts.map +1 -1
  49. package/lib/createFile/createNewContainerOnExistingFile.js.map +1 -1
  50. package/lib/createFile/createNewUtils.d.ts.map +1 -1
  51. package/lib/createFile/createNewUtils.js.map +1 -1
  52. package/lib/fetchSnapshot.d.ts.map +1 -1
  53. package/lib/fetchSnapshot.js +3 -4
  54. package/lib/fetchSnapshot.js.map +1 -1
  55. package/lib/getFileLink.d.ts.map +1 -1
  56. package/lib/getFileLink.js +1 -1
  57. package/lib/getFileLink.js.map +1 -1
  58. package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
  59. package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
  60. package/lib/odspDelayLoadedDeltaStream.js +1 -1
  61. package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
  62. package/lib/odspDeltaStorageService.d.ts.map +1 -1
  63. package/lib/odspDeltaStorageService.js.map +1 -1
  64. package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
  65. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  66. package/lib/odspDocumentService.d.ts.map +1 -1
  67. package/lib/odspDocumentService.js.map +1 -1
  68. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  69. package/lib/odspDocumentStorageManager.js +1 -1
  70. package/lib/odspDocumentStorageManager.js.map +1 -1
  71. package/lib/odspSummaryUploadManager.d.ts.map +1 -1
  72. package/lib/odspSummaryUploadManager.js +1 -1
  73. package/lib/odspSummaryUploadManager.js.map +1 -1
  74. package/lib/odspUtils.d.ts.map +1 -1
  75. package/lib/odspUtils.js +1 -1
  76. package/lib/odspUtils.js.map +1 -1
  77. package/lib/packageVersion.d.ts +1 -1
  78. package/lib/packageVersion.js +1 -1
  79. package/lib/packageVersion.js.map +1 -1
  80. package/lib/retryErrorsStorageAdapter.d.ts.map +1 -1
  81. package/lib/retryErrorsStorageAdapter.js.map +1 -1
  82. package/lib/vroom.d.ts.map +1 -1
  83. package/lib/vroom.js.map +1 -1
  84. package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
  85. package/lib/zipItDataRepresentationUtils.js +2 -1
  86. package/lib/zipItDataRepresentationUtils.js.map +1 -1
  87. package/package.json +18 -14
  88. package/src/contractsPublic.ts +4 -4
  89. package/src/createFile/createFile.ts +1 -1
  90. package/src/createFile/createNewContainerOnExistingFile.ts +1 -1
  91. package/src/createFile/createNewUtils.ts +1 -1
  92. package/src/fetchSnapshot.ts +3 -4
  93. package/src/getFileLink.ts +2 -2
  94. package/src/localOdspDriver/localOdspDocumentStorageManager.ts +1 -1
  95. package/src/odspDelayLoadedDeltaStream.ts +1 -1
  96. package/src/odspDeltaStorageService.ts +1 -1
  97. package/src/odspDocumentDeltaConnection.ts +1 -1
  98. package/src/odspDocumentService.ts +2 -2
  99. package/src/odspDocumentStorageManager.ts +3 -3
  100. package/src/odspSummaryUploadManager.ts +2 -2
  101. package/src/odspUtils.ts +2 -2
  102. package/src/packageVersion.ts +1 -1
  103. package/src/retryErrorsStorageAdapter.ts +1 -1
  104. package/src/vroom.ts +1 -1
  105. package/src/zipItDataRepresentationUtils.ts +2 -1
  106. package/tsconfig.json +1 -0
@@ -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 { fromUtf8ToBase64 } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { getW3CData } from \"@fluidframework/driver-base/internal\";\nimport {\n\tDriverErrorTypes,\n\ttype ILocationRedirectionError,\n\ttype ISnapshot,\n\ttype ISnapshotTree,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype DriverErrorTelemetryProps,\n\tNonRetryableError,\n\tisRuntimeMessage,\n} from \"@fluidframework/driver-utils/internal\";\nimport {\n\tfetchIncorrectResponse,\n\tthrowOdspNetworkError,\n} from \"@fluidframework/odsp-doclib-utils/internal\";\nimport {\n\ttype IOdspError,\n\ttype IOdspResolvedUrl,\n\ttype ISnapshotOptions,\n\ttype InstrumentedStorageTokenFetcher,\n\tOdspErrorTypes,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport type { TelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\nimport {\n\tPerformanceEvent,\n\tisFluidError,\n\twrapError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\ttype ISnapshotContentsWithProps,\n\tcurrentReadVersion,\n\tparseCompactSnapshotResponse,\n} from \"./compactSnapshotParser.js\";\nimport {\n\ttype IOdspSnapshot,\n\ttype ISnapshotCachedEntry2,\n\ttype IVersionedValueWithEpoch,\n\tpersistedCacheValueVersion,\n} from \"./contracts.js\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic.js\";\nimport type { EpochTracker } from \"./epochTracker.js\";\nimport { getQueryString } from \"./getQueryString.js\";\nimport { getHeadersWithAuth } from \"./getUrlAndHeadersWithAuth.js\";\nimport { mockify } from \"./mockify.js\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"./odspSnapshotParser.js\";\nimport { checkForKnownServerFarmType } from \"./odspUrlHelper.js\";\nimport {\n\ttype IOdspResponse,\n\tfetchAndParseAsJSONHelper,\n\tfetchHelper,\n\tgetWithRetryForTokenRefresh,\n\tgetOdspResolvedUrl,\n\tgetWithRetryForTokenRefreshRepeat,\n\tisSnapshotFetchForLoadingGroup,\n\tmeasure,\n\tmeasureP,\n\tuseLegacyFlowWithoutGroupsForSnapshotFetch,\n\ttype TokenFetchOptionsEx,\n} from \"./odspUtils.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Enum to support different types of snapshot formats.\n * @legacy\n * @beta\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 versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - Deprecated and not used, true value always used instead. Whether to force passing given token via authorization header\n * @param snapshotDownloader - Implementation of the get/post methods used to fetch the snapshot. snapshotDownloader is responsible for generating the appropriate headers (including Authorization header) as well as handling any token refreshes before retrying.\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n\tsnapshotUrl: string,\n\tversionId: string,\n\tfetchFullSnapshot: boolean,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: TelemetryLoggerExt,\n\tsnapshotDownloader: (url: string) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshot> {\n\tconst path = `/trees/${versionId}`;\n\tlet queryParams: ISnapshotOptions = {};\n\n\tif (fetchFullSnapshot) {\n\t\tqueryParams = versionId === \"latest\" ? { deltas: 1, blobs: 2 } : { blobs: 2 };\n\t}\n\n\tconst queryString = getQueryString(queryParams);\n\tconst url = `${snapshotUrl}${path}${queryString}`;\n\tconst response = (await PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"fetchSnapshot\",\n\t\t},\n\t\tasync () => snapshotDownloader(url),\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: TelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\t\ttokenFetchOptions: TokenFetchOptionsEx,\n\t\tloadingGroupIds: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tremoveEntries: () => Promise<void>,\n\tloadingGroupIds: string[] | undefined,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshot> {\n\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\tif (sharingLinkToRedeem) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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\tloadingGroupIds,\n\t\tenableRedeemFallback,\n\t)\n\t\t.catch(async (error) => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tif (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n\t\t\t\t// Execute the redeem fallback\n\t\t\t\tawait redeemSharingLink(odspResolvedUrl, storageTokenFetcher, logger);\n\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.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"RedeemFallback\",\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\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\tloadingGroupIds,\n\t\t\t\t);\n\t\t\t} else if (\n\t\t\t\tisLocationRedirectionError(error) &&\n\t\t\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\t// The redirect itself is handled earlier, but we need to redeem the sharing link\n\t\t\t\t\t// now against the redirected URL rather than waiting until the error reaches the\n\t\t\t\t\t// resolveWithLocationRedirectionHandling handler as it will call getAbsoluteURL\n\t\t\t\t\t// and would fail due to permission issues since it will not attempt to redeem.\n\t\t\t\t\tlogger.sendTelemetryEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"RedirectRedeemFallback\",\n\t\t\t\t\t\t\terrorType: error.errorType,\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t\tconst redirectedResolvedUrl: IOdspResolvedUrl = {\n\t\t\t\t\t\t...getOdspResolvedUrl(error.redirectUrl),\n\t\t\t\t\t\tshareLinkInfo: odspResolvedUrl.shareLinkInfo,\n\t\t\t\t\t};\n\t\t\t\t\tawait redeemSharingLink(redirectedResolvedUrl, storageTokenFetcher, logger);\n\t\t\t\t} catch (redeemError) {\n\t\t\t\t\tlogger.sendErrorEvent({ eventName: \"RedirectRedeemFallbackError\" }, redeemError);\n\t\t\t\t}\n\t\t\t\tthrow error;\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\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\terror.errorType === OdspErrorTypes.authorizationError) ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\terror.errorType === OdspErrorTypes.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\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\tlogger: TelemetryLoggerExt,\n): Promise<void> {\n\tawait PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"RedeemShareLink\",\n\t\t},\n\t\tasync (event) => {\n\t\t\tassert(\n\t\t\t\t!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t\t0x1ed /* \"Share link should be present\" */,\n\t\t\t);\n\n\t\t\tconst encodedShareUrl = getEncodedShareUrl(\n\t\t\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t);\n\n\t\t\tconst isRedemptionNonDurable: boolean =\n\t\t\t\todspResolvedUrl.shareLinkInfo?.isRedemptionNonDurable === true;\n\n\t\t\tlet redeemUrl: string | undefined;\n\t\t\tasync function callSharesAPI(baseUrl: string): Promise<void> {\n\t\t\t\tawait getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\t\t\t\t// IMPORTANT: Note that redeemUrl has '/driveItem' in it. Technically it is not required for executing redeem operation.\n\t\t\t\t\t// However, we have other cases that use '/shares' API and do require to specify '/driveItem' in order to get specific\n\t\t\t\t\t// drive item properties. The reason this matters is when caller of this API must possess logical permissions to call\n\t\t\t\t\t// this API (for instance, this will be the case when call is made with app-only token) then two separate logical\n\t\t\t\t\t// permissions are needed for the '/shares' call with and without '/driveItem'.\n\t\t\t\t\tredeemUrl = `${baseUrl}/_api/v2.0/shares/${encodedShareUrl}/driveItem`;\n\t\t\t\t\tconst url = redeemUrl;\n\t\t\t\t\tconst method = \"GET\";\n\t\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t\t{ ...tokenFetchOptions, request: { url, method } },\n\t\t\t\t\t\t\"RedeemShareLink\",\n\t\t\t\t\t);\n\t\t\t\t\tconst headers = getHeadersWithAuth(authHeader);\n\t\t\t\t\theaders.prefer = isRedemptionNonDurable ? \"nonDurableRedeem\" : \"redeemSharingLink\";\n\t\t\t\t\tawait fetchAndParseAsJSONHelper(url, { headers, method });\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst details = JSON.stringify({\n\t\t\t\tlength: redeemUrl?.length,\n\t\t\t\tshareLinkUrlLength: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem.length,\n\t\t\t\tqueryParamsLength: new URL(odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem).search\n\t\t\t\t\t.length,\n\t\t\t\tuseHeaders: true,\n\t\t\t\tisRedemptionNonDurable,\n\t\t\t});\n\t\t\t// There is an issue where if we use the siteUrl in /shares, then the allowed length of url is just a few hundred characters(300-400)\n\t\t\t// and we fail to do the redeem. But if we use the tenant domain in the url, then the allowed length becomes 2048. So,\n\t\t\t// construct the url for /shares using tenant domain. We get tenant domain by getting origin of the siteUrl.\n\t\t\ttry {\n\t\t\t\tawait callSharesAPI(new URL(odspResolvedUrl.siteUrl).origin);\n\t\t\t\tevent.end({ details });\n\t\t\t} catch (error) {\n\t\t\t\tevent.cancel({ details }, error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t);\n}\n\nasync function fetchLatestSnapshotCore(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tlogger: TelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\t\ttokenFetchOptions: TokenFetchOptionsEx,\n\t\tloadingGroupIds: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tloadingGroupIds: string[] | undefined,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshot> {\n\treturn getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\tconst fetchSnapshotForLoadingGroup = isSnapshotFetchForLoadingGroup(loadingGroupIds);\n\t\tconst eventName = fetchSnapshotForLoadingGroup ? \"TreesLatestForGroup\" : \"TreesLatest\";\n\t\tconst internalFarmType = checkForKnownServerFarmType(odspResolvedUrl.siteUrl);\n\t\tconst isRedemptionNonDurable: boolean =\n\t\t\todspResolvedUrl.shareLinkInfo?.isRedemptionNonDurable === true;\n\t\tconst fileVersion = odspResolvedUrl.fileVersion ?? undefined;\n\n\t\tconst perfEvent = {\n\t\t\teventName,\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\tdetails: {\n\t\t\t\tinternalFarmType,\n\t\t\t\t// Whether the redemption used is non-durable or not.\n\t\t\t\tisRedemptionNonDurable,\n\t\t\t},\n\t\t};\n\t\tif (snapshotOptions !== undefined) {\n\t\t\tfor (const [key, value] of Object.entries(snapshotOptions)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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(\n\t\t\t\t\todspResolvedUrl,\n\t\t\t\t\tgetAuthHeader,\n\t\t\t\t\ttokenFetchOptions,\n\t\t\t\t\tloadingGroupIds,\n\t\t\t\t\tsnapshotOptions,\n\t\t\t\t\tcontroller,\n\t\t\t\t),\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\n\t\t\t\t\t\t\t\t.text()\n\t\t\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\t\t\tif (res.length === 0) {\n\t\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\t\"Response from browser is empty\",\n\t\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn res;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.catch((error) =>\n\t\t\t\t\t\t\t\t\t// Parsing can fail and message could contain full request URI, including\n\t\t\t\t\t\t\t\t\t// tokens, etc. So do not log error object itself.\n\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\"Error while parsing fetch response\",\n\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\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: ISnapshot =\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\n\t\t\t\t\t\t\t\t.arrayBuffer()\n\t\t\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\t\t\tif (res.byteLength === 0) {\n\t\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\t\"Response from browser is empty\",\n\t\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn res;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.catch((error) =>\n\t\t\t\t\t\t\t\t\t// Parsing can fail and message could contain full request URI, including\n\t\t\t\t\t\t\t\t\t// tokens, etc. So do not log error object itself.\n\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\"Error while parsing fetch response\",\n\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\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\tOdspErrorTypes.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\tconst treeStructureCountWithGroupId = props.treeStructureCountWithGroupId ?? 0;\n\t\t\t\t\t\t// As trees with groupId go through normal parsing, so exclude them.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tslowTreeParseCodePaths - treeStructureCountWithGroupId > 10 ||\n\t\t\t\t\t\t\tslowBlobParseCodePaths > 10\n\t\t\t\t\t\t) {\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\ttreeStructureCountWithGroupId,\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\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t);\n\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\tOdspErrorTypes.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\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. Only cache snapshot if it is not for a loading group.\n\t\t\tconst canCache =\n\t\t\t\todspResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\" &&\n\t\t\t\t!fetchSnapshotForLoadingGroup;\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(fluidEpoch !== undefined, 0x1e6 /* \"Epoch should be present in response\" */);\n\t\t\t\tconst value: ISnapshotCachedEntry2 = {\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\t// trees, leafTrees, blobNodes, encodedBlobsSize,\n\t\t\t\t// blobNodes - blobs tells us (roughly) how many blobs are deduped by service.\n\t\t\t\t...getTreeStats(snapshot),\n\t\t\t\tblobs: snapshot.blobContents?.size ?? 0,\n\t\t\t\tsequenceNumber,\n\t\t\t\tops: snapshot.ops?.length ?? 0,\n\t\t\t\tfetchSnapshotForLoadingGroup,\n\t\t\t\tuseLegacyFlowWithoutGroups:\n\t\t\t\t\tuseLegacyFlowWithoutGroupsForSnapshotFetch(loadingGroupIds),\n\t\t\t\tuserOps: snapshot.ops?.filter((op) => isRuntimeMessage(op)).length ?? 0,\n\t\t\t\tfileVersion,\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 as Partial<IOdspError>).errorType === OdspErrorTypes.fetchFailure ||\n\t\t\t\t\t(error as Partial<IOdspError>).errorType === OdspErrorTypes.fetchTimeout)\n\t\t\t) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\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]: string };\n}\n\nfunction getFormBodyAndHeaders(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tauthHeader: string,\n\theaders?: { [index: string]: string },\n): {\n\tbody: string;\n\theaders: {\n\t\t[index: string]: string;\n\t};\n} {\n\tconst formBoundary = uuid();\n\tconst formParams: string[] = [];\n\tformParams.push(\n\t\t`--${formBoundary}`,\n\t\t`Authorization: ${authHeader}`,\n\t\t`X-HTTP-Method-Override: GET`,\n\t);\n\n\tif (headers !== undefined) {\n\t\tfor (const [key, value] of Object.entries(headers)) {\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`, `\\r\\n--${formBoundary}--`);\n\tconst postBody = formParams.join(\"\\r\\n\");\n\tconst header: { [index: string]: string } = {\n\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t};\n\treturn { body: postBody, headers: header };\n}\n\ninterface ITreeStats {\n\ttrees: number;\n\tleafTrees: number;\n\tblobNodes: number;\n}\n\nexport function getTreeStats(snapshot: ISnapshot): ITreeStats & { encodedBlobsSize: number } {\n\tconst stats: ITreeStats = {\n\t\ttrees: 0,\n\t\tleafTrees: 0,\n\t\tblobNodes: 0,\n\t};\n\tgetTreeStatsCore(snapshot.snapshotTree, stats);\n\tlet encodedBlobsSize = 0;\n\tfor (const [_, blobContent] of snapshot.blobContents) {\n\t\tencodedBlobsSize += blobContent.byteLength;\n\t}\n\treturn { ...stats, encodedBlobsSize };\n}\n\nexport function validateBlobsAndTrees(snapshot: IOdspSnapshot): void {\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 getTreeStatsCore(snapshotTree: ISnapshotTree, stats: ITreeStats): void {\n\tstats.blobNodes += Object.entries(snapshotTree.blobs).length;\n\tstats.trees++;\n\n\tconst entries = Object.entries(snapshotTree.trees);\n\tif (entries.length === 0) {\n\t\tstats.leafTrees++;\n\t} else {\n\t\tfor (const [_, tree] of entries) {\n\t\t\tstats.trees++;\n\t\t\tgetTreeStatsCore(tree, stats);\n\t\t}\n\t}\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 getAuthHeader - function to fetch the auth header for the network request.\n * @param tokenFetchOptions - options for fetching the token.\n * @param loadingGroupIds - loadingGroupIds for which snapshot needs to be downloaded. Note:\n * 1.) If undefined, then legacy trees latest call will be used where no groupId query param would be specified.\n * 2.) If [] is passed, then snapshot with all ungrouped data will be fetched.\n * 3.) If any groupId is specified like [\"g1\"], then snapshot for g1 group will be fetched.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger for sending telemetry events.\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 * @param scenarioName - scenario name for telemetry.\n * @returns fetched snapshot.\n */\nexport const downloadSnapshot = mockify(\n\tasync (\n\t\todspResolvedUrl: IOdspResolvedUrl,\n\t\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\t\ttokenFetchOptions: TokenFetchOptionsEx,\n\t\tloadingGroupIds: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tlogger?: TelemetryLoggerExt,\n\t\tsnapshotFormatFetchType?: SnapshotFormatSupportType,\n\t\tcontroller?: AbortController,\n\t\tepochTracker?: EpochTracker,\n\t\tscenarioName?: string,\n\t): Promise<ISnapshotRequestAndResponseOptions> => {\n\t\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\t\tif (sharingLinkToRedeem) {\n\t\t\todspResolvedUrl.shareLinkInfo = {\n\t\t\t\t...odspResolvedUrl.shareLinkInfo,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tsharingLinkToRedeem,\n\t\t\t};\n\t\t}\n\n\t\tconst snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n\n\t\tconst queryParams: Record<string, unknown> = { ump: 1 };\n\t\tif (snapshotOptions !== undefined) {\n\t\t\tfor (const [key, value] of Object.entries(snapshotOptions)) {\n\t\t\t\t// Exclude \"timeout\" from query string\n\t\t\t\tif (value !== undefined && key !== \"timeout\") {\n\t\t\t\t\tqueryParams[key] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (loadingGroupIds !== undefined) {\n\t\t\tqueryParams.groupId = loadingGroupIds.join(\",\");\n\t\t}\n\n\t\tconst queryString = getQueryString(queryParams);\n\t\tconst url = `${snapshotUrl}/trees/latest${queryString}`;\n\t\tconst method = \"POST\";\n\t\tconst isRedemptionNonDurable: boolean =\n\t\t\todspResolvedUrl.shareLinkInfo?.isRedemptionNonDurable === true;\n\t\t// The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n\t\t// Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n\t\t// This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n\t\t// for further reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n\t\t// If the share link is non-durable, we will add the nonDurableRedeem header to the header.prefer.\n\t\tconst header: { [key: string]: string } = isRedemptionNonDurable\n\t\t\t? { prefer: \"manualredirect, nonDurableRedeem\" }\n\t\t\t: { prefer: \"manualredirect\" };\n\t\t// Epoch tracker is handling adding the CLP Compliant App header, so only when a flow does not\n\t\t// use epoch tracker, we add the header.\n\t\tif (epochTracker === undefined && odspResolvedUrl.isClpCompliantApp !== undefined) {\n\t\t\theader[ClpCompliantAppHeader.isClpCompliantApp] =\n\t\t\t\todspResolvedUrl.isClpCompliantApp.toString();\n\t\t}\n\t\tconst authHeader = await getAuthHeader(\n\t\t\t{ ...tokenFetchOptions, request: { url, method } },\n\t\t\t\"downloadSnapshot\",\n\t\t);\n\t\tassert(authHeader !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\t\tlogger?.sendTelemetryEvent({ eventName: \"SnapshotAuthHeaderObtained\" });\n\t\tconst { body, headers } = getFormBodyAndHeaders(odspResolvedUrl, authHeader, header);\n\t\tconst fetchOptions = {\n\t\t\tbody,\n\t\t\theaders,\n\t\t\tsignal: controller?.signal,\n\t\t\tmethod,\n\t\t};\n\t\t// Decide what snapshot format to fetch as per the feature gate.\n\t\tswitch (snapshotFormatFetchType) {\n\t\t\tcase SnapshotFormatSupportType.Binary: {\n\t\t\t\theaders.accept = `application/ms-fluid; v=${currentReadVersion}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// By default ask both versions and let the server decide the format.\n\t\t\t\theaders.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n\t\t\t}\n\t\t}\n\n\t\tconst odspResponse = await (epochTracker?.fetch(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\t\"treesLatest\",\n\t\t\ttrue,\n\t\t\tscenarioName,\n\t\t) ?? fetchHelper(url, fetchOptions));\n\t\tlogger?.sendTelemetryEvent({ eventName: \"SnapshotFetchResponseReceived\" });\n\n\t\treturn {\n\t\t\todspResponse,\n\t\t\trequestHeaders: headers,\n\t\t\trequestUrl: url,\n\t\t};\n\t},\n);\n\nfunction isLocationRedirectionError(error: unknown): error is ILocationRedirectionError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error as Partial<IOdspError>).errorType === DriverErrorTypes.locationRedirection\n\t);\n}\n\nfunction isRedeemSharingLinkError(\n\todspResolvedUrl: IOdspResolvedUrl,\n\terror: Partial<IOdspError>,\n): boolean {\n\tif (\n\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined &&\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error.errorType === OdspErrorTypes.authorizationError ||\n\t\t\terror.errorType === OdspErrorTypes.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 { fromUtf8ToBase64 } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { getW3CData } from \"@fluidframework/driver-base/internal\";\nimport {\n\tDriverErrorTypes,\n\ttype ILocationRedirectionError,\n\ttype ISnapshot,\n\ttype ISnapshotTree,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype DriverErrorTelemetryProps,\n\tNonRetryableError,\n\tisRuntimeMessage,\n} from \"@fluidframework/driver-utils/internal\";\nimport {\n\tfetchIncorrectResponse,\n\tthrowOdspNetworkError,\n} from \"@fluidframework/odsp-doclib-utils/internal\";\nimport {\n\ttype IOdspError,\n\ttype IOdspResolvedUrl,\n\ttype ISnapshotOptions,\n\ttype InstrumentedStorageTokenFetcher,\n\tOdspErrorTypes,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport type { TelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\nimport {\n\tPerformanceEvent,\n\tisFluidError,\n\twrapError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\ttype ISnapshotContentsWithProps,\n\tcurrentReadVersion,\n\tparseCompactSnapshotResponse,\n} from \"./compactSnapshotParser.js\";\nimport {\n\ttype IOdspSnapshot,\n\ttype ISnapshotCachedEntry2,\n\ttype IVersionedValueWithEpoch,\n\tpersistedCacheValueVersion,\n} from \"./contracts.js\";\nimport { ClpCompliantAppHeader } from \"./contractsPublic.js\";\nimport type { EpochTracker } from \"./epochTracker.js\";\nimport { getQueryString } from \"./getQueryString.js\";\nimport { getHeadersWithAuth } from \"./getUrlAndHeadersWithAuth.js\";\nimport { mockify } from \"./mockify.js\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"./odspSnapshotParser.js\";\nimport { checkForKnownServerFarmType } from \"./odspUrlHelper.js\";\nimport {\n\ttype IOdspResponse,\n\tfetchAndParseAsJSONHelper,\n\tfetchHelper,\n\tgetWithRetryForTokenRefresh,\n\tgetOdspResolvedUrl,\n\tgetWithRetryForTokenRefreshRepeat,\n\tisSnapshotFetchForLoadingGroup,\n\tmeasure,\n\tmeasureP,\n\tuseLegacyFlowWithoutGroupsForSnapshotFetch,\n\ttype TokenFetchOptionsEx,\n} from \"./odspUtils.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * Enum to support different types of snapshot formats.\n * @legacy\n * @beta\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 versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - Deprecated and not used, true value always used instead. Whether to force passing given token via authorization header\n * @param snapshotDownloader - Implementation of the get/post methods used to fetch the snapshot. snapshotDownloader is responsible for generating the appropriate headers (including Authorization header) as well as handling any token refreshes before retrying.\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n\tsnapshotUrl: string,\n\tversionId: string,\n\tfetchFullSnapshot: boolean,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: TelemetryLoggerExt,\n\tsnapshotDownloader: (url: string) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshot> {\n\tconst path = `/trees/${versionId}`;\n\tlet queryParams: ISnapshotOptions = {};\n\n\tif (fetchFullSnapshot) {\n\t\tqueryParams = versionId === \"latest\" ? { deltas: 1, blobs: 2 } : { blobs: 2 };\n\t}\n\n\tconst queryString = getQueryString(queryParams);\n\tconst url = `${snapshotUrl}${path}${queryString}`;\n\tconst response = (await PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"fetchSnapshot\",\n\t\t},\n\t\tasync () => snapshotDownloader(url),\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: TelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\t\ttokenFetchOptions: TokenFetchOptionsEx,\n\t\tloadingGroupIds: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tremoveEntries: () => Promise<void>,\n\tloadingGroupIds: string[] | undefined,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshot> {\n\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\tif (sharingLinkToRedeem) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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\tloadingGroupIds,\n\t\tenableRedeemFallback,\n\t)\n\t\t.catch(async (error) => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tif (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n\t\t\t\t// Execute the redeem fallback\n\t\t\t\tawait redeemSharingLink(odspResolvedUrl, storageTokenFetcher, logger);\n\n\t\t\t\tconst shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo };\n\t\t\t\tdelete shareLinkInfo.sharingLinkToRedeem;\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};\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.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"RedeemFallback\",\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\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\tloadingGroupIds,\n\t\t\t\t);\n\t\t\t} else if (\n\t\t\t\tisLocationRedirectionError(error) &&\n\t\t\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined\n\t\t\t) {\n\t\t\t\ttry {\n\t\t\t\t\t// The redirect itself is handled earlier, but we need to redeem the sharing link\n\t\t\t\t\t// now against the redirected URL rather than waiting until the error reaches the\n\t\t\t\t\t// resolveWithLocationRedirectionHandling handler as it will call getAbsoluteURL\n\t\t\t\t\t// and would fail due to permission issues since it will not attempt to redeem.\n\t\t\t\t\tlogger.sendTelemetryEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"RedirectRedeemFallback\",\n\t\t\t\t\t\t\terrorType: error.errorType,\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t\tconst redirectedResolvedUrl: IOdspResolvedUrl = {\n\t\t\t\t\t\t...getOdspResolvedUrl(error.redirectUrl),\n\t\t\t\t\t\tshareLinkInfo: odspResolvedUrl.shareLinkInfo,\n\t\t\t\t\t};\n\t\t\t\t\tawait redeemSharingLink(redirectedResolvedUrl, storageTokenFetcher, logger);\n\t\t\t\t} catch (redeemError) {\n\t\t\t\t\tlogger.sendErrorEvent({ eventName: \"RedirectRedeemFallbackError\" }, redeemError);\n\t\t\t\t}\n\t\t\t\tthrow error;\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\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\terror.errorType === OdspErrorTypes.authorizationError) ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\terror.errorType === OdspErrorTypes.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\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\tlogger: TelemetryLoggerExt,\n): Promise<void> {\n\tawait PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"RedeemShareLink\",\n\t\t},\n\t\tasync (event) => {\n\t\t\tassert(\n\t\t\t\t!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t\t0x1ed /* \"Share link should be present\" */,\n\t\t\t);\n\n\t\t\tconst encodedShareUrl = getEncodedShareUrl(\n\t\t\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n\t\t\t);\n\n\t\t\tconst isRedemptionNonDurable: boolean =\n\t\t\t\todspResolvedUrl.shareLinkInfo?.isRedemptionNonDurable === true;\n\n\t\t\tlet redeemUrl: string | undefined;\n\t\t\tasync function callSharesAPI(baseUrl: string): Promise<void> {\n\t\t\t\tawait getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\t\t\t\t// IMPORTANT: Note that redeemUrl has '/driveItem' in it. Technically it is not required for executing redeem operation.\n\t\t\t\t\t// However, we have other cases that use '/shares' API and do require to specify '/driveItem' in order to get specific\n\t\t\t\t\t// drive item properties. The reason this matters is when caller of this API must possess logical permissions to call\n\t\t\t\t\t// this API (for instance, this will be the case when call is made with app-only token) then two separate logical\n\t\t\t\t\t// permissions are needed for the '/shares' call with and without '/driveItem'.\n\t\t\t\t\tredeemUrl = `${baseUrl}/_api/v2.0/shares/${encodedShareUrl}/driveItem`;\n\t\t\t\t\tconst url = redeemUrl;\n\t\t\t\t\tconst method = \"GET\";\n\t\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t\t{ ...tokenFetchOptions, request: { url, method } },\n\t\t\t\t\t\t\"RedeemShareLink\",\n\t\t\t\t\t);\n\t\t\t\t\tconst headers = getHeadersWithAuth(authHeader);\n\t\t\t\t\theaders.prefer = isRedemptionNonDurable ? \"nonDurableRedeem\" : \"redeemSharingLink\";\n\t\t\t\t\tawait fetchAndParseAsJSONHelper(url, { headers, method });\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst details = JSON.stringify({\n\t\t\t\tlength: redeemUrl?.length,\n\t\t\t\tshareLinkUrlLength: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem.length,\n\t\t\t\tqueryParamsLength: new URL(odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem).search\n\t\t\t\t\t.length,\n\t\t\t\tuseHeaders: true,\n\t\t\t\tisRedemptionNonDurable,\n\t\t\t});\n\t\t\t// There is an issue where if we use the siteUrl in /shares, then the allowed length of url is just a few hundred characters(300-400)\n\t\t\t// and we fail to do the redeem. But if we use the tenant domain in the url, then the allowed length becomes 2048. So,\n\t\t\t// construct the url for /shares using tenant domain. We get tenant domain by getting origin of the siteUrl.\n\t\t\ttry {\n\t\t\t\tawait callSharesAPI(new URL(odspResolvedUrl.siteUrl).origin);\n\t\t\t\tevent.end({ details });\n\t\t\t} catch (error) {\n\t\t\t\tevent.cancel({ details }, error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t);\n}\n\nasync function fetchLatestSnapshotCore(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\tsnapshotOptions: ISnapshotOptions | undefined,\n\tlogger: TelemetryLoggerExt,\n\tsnapshotDownloader: (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\t\ttokenFetchOptions: TokenFetchOptionsEx,\n\t\tloadingGroupIds: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t) => Promise<ISnapshotRequestAndResponseOptions>,\n\tputInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n\tloadingGroupIds: string[] | undefined,\n\tenableRedeemFallback?: boolean,\n): Promise<ISnapshot> {\n\treturn getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n\t\tconst fetchSnapshotForLoadingGroup = isSnapshotFetchForLoadingGroup(loadingGroupIds);\n\t\tconst eventName = fetchSnapshotForLoadingGroup ? \"TreesLatestForGroup\" : \"TreesLatest\";\n\t\tconst internalFarmType = checkForKnownServerFarmType(odspResolvedUrl.siteUrl);\n\t\tconst isRedemptionNonDurable: boolean =\n\t\t\todspResolvedUrl.shareLinkInfo?.isRedemptionNonDurable === true;\n\t\tconst fileVersion = odspResolvedUrl.fileVersion ?? undefined;\n\n\t\tconst perfEvent = {\n\t\t\teventName,\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\tdetails: {\n\t\t\t\tinternalFarmType,\n\t\t\t\t// Whether the redemption used is non-durable or not.\n\t\t\t\tisRedemptionNonDurable,\n\t\t\t},\n\t\t};\n\t\tif (snapshotOptions !== undefined) {\n\t\t\tfor (const [key, value] of Object.entries(snapshotOptions)) {\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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(\n\t\t\t\t\todspResolvedUrl,\n\t\t\t\t\tgetAuthHeader,\n\t\t\t\t\ttokenFetchOptions,\n\t\t\t\t\tloadingGroupIds,\n\t\t\t\t\tsnapshotOptions,\n\t\t\t\t\tcontroller,\n\t\t\t\t),\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\n\t\t\t\t\t\t\t\t.text()\n\t\t\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\t\t\tif (res.length === 0) {\n\t\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\t\"Response from browser is empty\",\n\t\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn res;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.catch((error) =>\n\t\t\t\t\t\t\t\t\t// Parsing can fail and message could contain full request URI, including\n\t\t\t\t\t\t\t\t\t// tokens, etc. So do not log error object itself.\n\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\"Error while parsing fetch response\",\n\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\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: ISnapshot =\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\n\t\t\t\t\t\t\t\t.arrayBuffer()\n\t\t\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\t\t\tif (res.byteLength === 0) {\n\t\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\t\"Response from browser is empty\",\n\t\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn res;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.catch((error) =>\n\t\t\t\t\t\t\t\t\t// Parsing can fail and message could contain full request URI, including\n\t\t\t\t\t\t\t\t\t// tokens, etc. So do not log error object itself.\n\t\t\t\t\t\t\t\t\tthrowOdspNetworkError(\n\t\t\t\t\t\t\t\t\t\t\"Error while parsing fetch response\",\n\t\t\t\t\t\t\t\t\t\tfetchIncorrectResponse,\n\t\t\t\t\t\t\t\t\t\todspResponse.content, // response\n\t\t\t\t\t\t\t\t\t\tundefined, // response text\n\t\t\t\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\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\tOdspErrorTypes.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\tconst treeStructureCountWithGroupId = props.treeStructureCountWithGroupId ?? 0;\n\t\t\t\t\t\t// As trees with groupId go through normal parsing, so exclude them.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tslowTreeParseCodePaths - treeStructureCountWithGroupId > 10 ||\n\t\t\t\t\t\t\tslowBlobParseCodePaths > 10\n\t\t\t\t\t\t) {\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\ttreeStructureCountWithGroupId,\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\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\t\t\tpropsToLog,\n\t\t\t\t\t\t);\n\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\tOdspErrorTypes.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\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. Only cache snapshot if it is not for a loading group.\n\t\t\tconst canCache =\n\t\t\t\todspResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\" &&\n\t\t\t\t!fetchSnapshotForLoadingGroup;\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(fluidEpoch !== undefined, 0x1e6 /* \"Epoch should be present in response\" */);\n\t\t\t\tconst value: ISnapshotCachedEntry2 = {\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\t// trees, leafTrees, blobNodes, encodedBlobsSize,\n\t\t\t\t// blobNodes - blobs tells us (roughly) how many blobs are deduped by service.\n\t\t\t\t...getTreeStats(snapshot),\n\t\t\t\tblobs: snapshot.blobContents?.size ?? 0,\n\t\t\t\tsequenceNumber,\n\t\t\t\tops: snapshot.ops?.length ?? 0,\n\t\t\t\tfetchSnapshotForLoadingGroup,\n\t\t\t\tuseLegacyFlowWithoutGroups:\n\t\t\t\t\tuseLegacyFlowWithoutGroupsForSnapshotFetch(loadingGroupIds),\n\t\t\t\tuserOps: snapshot.ops?.filter((op) => isRuntimeMessage(op)).length ?? 0,\n\t\t\t\tfileVersion,\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 as Partial<IOdspError>).errorType === OdspErrorTypes.fetchFailure ||\n\t\t\t\t\t(error as Partial<IOdspError>).errorType === OdspErrorTypes.fetchTimeout)\n\t\t\t) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\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]: string };\n}\n\nfunction getFormBodyAndHeaders(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tauthHeader: string,\n\theaders?: { [index: string]: string },\n): {\n\tbody: string;\n\theaders: {\n\t\t[index: string]: string;\n\t};\n} {\n\tconst formBoundary = uuid();\n\tconst formParams: string[] = [];\n\tformParams.push(\n\t\t`--${formBoundary}`,\n\t\t`Authorization: ${authHeader}`,\n\t\t`X-HTTP-Method-Override: GET`,\n\t);\n\n\tif (headers !== undefined) {\n\t\tfor (const [key, value] of Object.entries(headers)) {\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`, `\\r\\n--${formBoundary}--`);\n\tconst postBody = formParams.join(\"\\r\\n\");\n\tconst header: { [index: string]: string } = {\n\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t};\n\treturn { body: postBody, headers: header };\n}\n\ninterface ITreeStats {\n\ttrees: number;\n\tleafTrees: number;\n\tblobNodes: number;\n}\n\nexport function getTreeStats(snapshot: ISnapshot): ITreeStats & { encodedBlobsSize: number } {\n\tconst stats: ITreeStats = {\n\t\ttrees: 0,\n\t\tleafTrees: 0,\n\t\tblobNodes: 0,\n\t};\n\tgetTreeStatsCore(snapshot.snapshotTree, stats);\n\tlet encodedBlobsSize = 0;\n\tfor (const [_, blobContent] of snapshot.blobContents) {\n\t\tencodedBlobsSize += blobContent.byteLength;\n\t}\n\treturn { ...stats, encodedBlobsSize };\n}\n\nexport function validateBlobsAndTrees(snapshot: IOdspSnapshot): void {\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 getTreeStatsCore(snapshotTree: ISnapshotTree, stats: ITreeStats): void {\n\tstats.blobNodes += Object.entries(snapshotTree.blobs).length;\n\tstats.trees++;\n\n\tconst entries = Object.entries(snapshotTree.trees);\n\tif (entries.length === 0) {\n\t\tstats.leafTrees++;\n\t} else {\n\t\tfor (const [_, tree] of entries) {\n\t\t\tstats.trees++;\n\t\t\tgetTreeStatsCore(tree, stats);\n\t\t}\n\t}\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 getAuthHeader - function to fetch the auth header for the network request.\n * @param tokenFetchOptions - options for fetching the token.\n * @param loadingGroupIds - loadingGroupIds for which snapshot needs to be downloaded. Note:\n * 1.) If undefined, then legacy trees latest call will be used where no groupId query param would be specified.\n * 2.) If [] is passed, then snapshot with all ungrouped data will be fetched.\n * 3.) If any groupId is specified like [\"g1\"], then snapshot for g1 group will be fetched.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger for sending telemetry events.\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 * @param scenarioName - scenario name for telemetry.\n * @returns fetched snapshot.\n */\nexport const downloadSnapshot = mockify(\n\tasync (\n\t\todspResolvedUrl: IOdspResolvedUrl,\n\t\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\t\ttokenFetchOptions: TokenFetchOptionsEx,\n\t\tloadingGroupIds: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tlogger?: TelemetryLoggerExt,\n\t\tsnapshotFormatFetchType?: SnapshotFormatSupportType,\n\t\tcontroller?: AbortController,\n\t\tepochTracker?: EpochTracker,\n\t\tscenarioName?: string,\n\t): Promise<ISnapshotRequestAndResponseOptions> => {\n\t\t// back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\tconst sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n\t\tif (sharingLinkToRedeem) {\n\t\t\todspResolvedUrl.shareLinkInfo = {\n\t\t\t\t...odspResolvedUrl.shareLinkInfo,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tsharingLinkToRedeem,\n\t\t\t};\n\t\t}\n\n\t\tconst snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n\n\t\tconst queryParams: Record<string, unknown> = { ump: 1 };\n\t\tif (snapshotOptions !== undefined) {\n\t\t\tfor (const [key, value] of Object.entries(snapshotOptions)) {\n\t\t\t\t// Exclude \"timeout\" from query string\n\t\t\t\tif (value !== undefined && key !== \"timeout\") {\n\t\t\t\t\tqueryParams[key] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (loadingGroupIds !== undefined) {\n\t\t\tqueryParams.groupId = loadingGroupIds.join(\",\");\n\t\t}\n\n\t\tconst queryString = getQueryString(queryParams);\n\t\tconst url = `${snapshotUrl}/trees/latest${queryString}`;\n\t\tconst method = \"POST\";\n\t\tconst isRedemptionNonDurable: boolean =\n\t\t\todspResolvedUrl.shareLinkInfo?.isRedemptionNonDurable === true;\n\t\t// The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n\t\t// Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n\t\t// This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n\t\t// for further reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n\t\t// If the share link is non-durable, we will add the nonDurableRedeem header to the header.prefer.\n\t\tconst header: { [key: string]: string } = isRedemptionNonDurable\n\t\t\t? { prefer: \"manualredirect, nonDurableRedeem\" }\n\t\t\t: { prefer: \"manualredirect\" };\n\t\t// Epoch tracker is handling adding the CLP Compliant App header, so only when a flow does not\n\t\t// use epoch tracker, we add the header.\n\t\tif (epochTracker === undefined && odspResolvedUrl.isClpCompliantApp !== undefined) {\n\t\t\theader[ClpCompliantAppHeader.isClpCompliantApp] =\n\t\t\t\todspResolvedUrl.isClpCompliantApp.toString();\n\t\t}\n\t\tconst authHeader = await getAuthHeader(\n\t\t\t{ ...tokenFetchOptions, request: { url, method } },\n\t\t\t\"downloadSnapshot\",\n\t\t);\n\t\tassert(authHeader !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\t\tlogger?.sendTelemetryEvent({ eventName: \"SnapshotAuthHeaderObtained\" });\n\t\tconst { body, headers } = getFormBodyAndHeaders(odspResolvedUrl, authHeader, header);\n\t\tconst fetchOptions = {\n\t\t\tbody,\n\t\t\theaders,\n\t\t\tsignal: controller?.signal,\n\t\t\tmethod,\n\t\t};\n\t\t// Decide what snapshot format to fetch as per the feature gate.\n\t\tswitch (snapshotFormatFetchType) {\n\t\t\tcase SnapshotFormatSupportType.Binary: {\n\t\t\t\theaders.accept = `application/ms-fluid; v=${currentReadVersion}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// By default ask both versions and let the server decide the format.\n\t\t\t\theaders.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n\t\t\t}\n\t\t}\n\n\t\tconst odspResponse = await (epochTracker?.fetch(\n\t\t\turl,\n\t\t\tfetchOptions,\n\t\t\t\"treesLatest\",\n\t\t\ttrue,\n\t\t\tscenarioName,\n\t\t) ?? fetchHelper(url, fetchOptions));\n\t\tlogger?.sendTelemetryEvent({ eventName: \"SnapshotFetchResponseReceived\" });\n\n\t\treturn {\n\t\t\todspResponse,\n\t\t\trequestHeaders: headers,\n\t\t\trequestUrl: url,\n\t\t};\n\t},\n);\n\nfunction isLocationRedirectionError(error: unknown): error is ILocationRedirectionError {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error as Partial<IOdspError>).errorType === DriverErrorTypes.locationRedirection\n\t);\n}\n\nfunction isRedeemSharingLinkError(\n\todspResolvedUrl: IOdspResolvedUrl,\n\terror: Partial<IOdspError>,\n): boolean {\n\tif (\n\t\todspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined &&\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t(error.errorType === OdspErrorTypes.authorizationError ||\n\t\t\terror.errorType === OdspErrorTypes.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 +1 @@
1
- {"version":3,"file":"getFileLink.d.ts","sourceRoot":"","sources":["../src/getFileLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAGN,KAAK,6BAA6B,EAClC,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EACN,KAAK,kBAAkB,EAGvB,MAAM,0CAA0C,CAAC;AAelD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,6CAEZ,aAAa,6BAA6B,CAAC,eACxC,gBAAgB,UACrB,kBAAkB,KACxB,QAAQ,MAAM,CAAC,CAsDlB,CAAC"}
1
+ {"version":3,"file":"getFileLink.d.ts","sourceRoot":"","sources":["../src/getFileLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAGN,KAAK,6BAA6B,EAClC,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EAGN,KAAK,kBAAkB,EACvB,MAAM,0CAA0C,CAAC;AAelD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,6CAEZ,aAAa,6BAA6B,CAAC,eACxC,gBAAgB,UACrB,kBAAkB,KACxB,QAAQ,MAAM,CAAC,CAsDlB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getFileLink.js","sourceRoot":"","sources":["../src/getFileLink.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 type { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { NonRetryableError, runWithRetry } from \"@fluidframework/driver-utils/internal\";\nimport {\n\ttype IOdspUrlParts,\n\tOdspErrorTypes,\n\ttype OdspResourceTokenFetchOptions,\n\ttype TokenFetcher,\n\ttype IOdspResolvedUrl,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\ttype TelemetryLoggerExt,\n\tPerformanceEvent,\n\tisFluidError,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { getHeadersWithAuth } from \"./getUrlAndHeadersWithAuth.js\";\nimport { mockify } from \"./mockify.js\";\nimport {\n\tfetchHelper,\n\tgetWithRetryForTokenRefresh,\n\ttoInstrumentedOdspStorageTokenFetcher,\n} from \"./odspUtils.js\";\nimport { pkgVersion as driverVersion } from \"./packageVersion.js\";\nimport { runWithRetry as runWithRetryForCoherencyAndServiceReadOnlyErrors } from \"./retryUtils.js\";\n\n// Store cached responses for the lifetime of web session as file link remains the same for given file item\nconst fileLinkCache = new Map<string, Promise<string>>();\n\n/**\n * Returns file link for a file with given drive and item ids.\n * Scope needed: files.readwrite.all.\n * This function keeps retrying if it gets a retriable error or wait for some delay if it gets a\n * throttling error. In future, we are thinking of app allowing to pass some cancel token, with which\n * we would be able to stop retrying.\n * @param getToken - used to fetch access tokens needed to execute operation\n * @param odspUrlParts - object describing file storage identity\n * @param logger - used to log results of operation, including any error\n * @returns Promise which resolves to file link url when successful; otherwise, undefined.\n */\nexport const getFileLink = mockify(\n\tasync (\n\t\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\t\tresolvedUrl: IOdspResolvedUrl,\n\t\tlogger: TelemetryLoggerExt,\n\t): Promise<string> => {\n\t\tconst cacheKey = `${resolvedUrl.siteUrl}_${resolvedUrl.driveId}_${resolvedUrl.itemId}`;\n\t\tconst maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n\t\tif (maybeFileLinkCacheEntry !== undefined) {\n\t\t\treturn maybeFileLinkCacheEntry;\n\t\t}\n\n\t\tconst fileLinkGenerator = async function (): Promise<string> {\n\t\t\tlet fileLinkCore: string;\n\t\t\ttry {\n\t\t\t\tlet retryCount = 0;\n\t\t\t\tfileLinkCore = await runWithRetry(\n\t\t\t\t\tasync () =>\n\t\t\t\t\t\trunWithRetryForCoherencyAndServiceReadOnlyErrors(\n\t\t\t\t\t\t\tasync () =>\n\t\t\t\t\t\t\t\tgetFileLinkWithLocationRedirectionHandling(getToken, resolvedUrl, logger),\n\t\t\t\t\t\t\t\"getFileLinkCore\",\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t),\n\t\t\t\t\t\"getShareLink\",\n\t\t\t\t\tlogger,\n\t\t\t\t\t{\n\t\t\t\t\t\t// TODO: use a stronger type\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t\t\tonRetry(delayInMs: number, error: any) {\n\t\t\t\t\t\t\tretryCount++;\n\t\t\t\t\t\t\tif (retryCount === 5) {\n\t\t\t\t\t\t\t\tif (error !== undefined && typeof error === \"object\") {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\t\t\t\terror.canRetry = false;\n\t\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\t// Delete from the cache to permit retrying later.\n\t\t\t\tfileLinkCache.delete(cacheKey);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n\t\t\tassert(\n\t\t\t\tfileLinkCore !== undefined,\n\t\t\t\t0x292 /* \"Unexpected undefined result from getFileLinkCore\" */,\n\t\t\t);\n\t\t\treturn fileLinkCore;\n\t\t};\n\t\tconst fileLink = fileLinkGenerator();\n\t\tfileLinkCache.set(cacheKey, fileLink);\n\t\treturn fileLink;\n\t},\n);\n\n/**\n * Handles location redirection while fulfilling the getFileLink call. We don't want browser to handle\n * the redirection as the browser will retry with same auth token which will not work as we need app\n * to regenerate tokens for the new site domain. So when we will make the network calls below we will set\n * the redirect:manual header to manually handle these redirects.\n * Refer: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308\n * @param getToken - token fetcher to fetch the token.\n * @param odspUrlParts - parts of odsp resolved url.\n * @param logger - logger to send events.\n * @returns Response from the API call.\n * @legacy\n * @beta\n */\nasync function getFileLinkWithLocationRedirectionHandling(\n\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\tresolvedUrl: IOdspResolvedUrl,\n\tlogger: TelemetryLoggerExt,\n): Promise<string> {\n\t// We can have chains of location redirection one after the other, so have a for loop\n\t// so that we can keep handling the same type of error. Set max number of redirection to 5.\n\tlet lastError: unknown;\n\tlet locationRedirected = false;\n\tfor (let count = 1; count <= 5; count++) {\n\t\ttry {\n\t\t\tconst fileItem = await getFileItemLite(getToken, resolvedUrl, logger);\n\t\t\t// Sometimes the siteUrl in the actual file is different from the siteUrl in the resolvedUrl due to location\n\t\t\t// redirection. This creates issues in the getSharingInformation call. So we need to update the siteUrl in the\n\t\t\t// resolvedUrl to the siteUrl in the fileItem which is the updated siteUrl.\n\t\t\tconst oldSiteDomain = new URL(resolvedUrl.siteUrl).origin;\n\t\t\tconst newSiteDomain = new URL(fileItem.sharepointIds.siteUrl).origin;\n\t\t\tif (oldSiteDomain !== newSiteDomain) {\n\t\t\t\tlocationRedirected = true;\n\t\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"LocationRedirectionErrorForGetOdspFileLink\",\n\t\t\t\t\tretryCount: count,\n\t\t\t\t});\n\t\t\t\trenameTenantInOdspResolvedUrl(resolvedUrl, newSiteDomain);\n\t\t\t}\n\t\t\treturn await getFileLinkCore(getToken, resolvedUrl, logger, fileItem);\n\t\t} catch (error: unknown) {\n\t\t\tlastError = error;\n\t\t\t// If the getSharingLink call fails with the 401/403/404 error, then it could be due to that the file has moved\n\t\t\t// to another location. This could occur in case we have more than 1 tenant rename. In that case, we should retry\n\t\t\t// the getFileItemLite call to get the updated fileItem.\n\t\t\tif (\n\t\t\t\tisFluidError(error) &&\n\t\t\t\tlocationRedirected &&\n\t\t\t\t(error.errorType === OdspErrorTypes.fileNotFoundOrAccessDeniedError ||\n\t\t\t\t\terror.errorType === OdspErrorTypes.authorizationError)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\tthrow lastError;\n}\n\nasync function getFileLinkCore(\n\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\todspUrlParts: IOdspUrlParts,\n\tlogger: TelemetryLoggerExt,\n\tfileItem: FileItemLite,\n): Promise<string> {\n\t// ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{ eventName: \"odspFileLink\", requestName: \"getSharingInformation\" },\n\t\tasync (event) => {\n\t\t\tlet attempts = 0;\n\t\t\tlet additionalProps;\n\t\t\tconst fileLink = await getWithRetryForTokenRefresh(async (options) => {\n\t\t\t\tattempts++;\n\t\t\t\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\t\t\t\tlogger,\n\t\t\t\t\todspUrlParts,\n\t\t\t\t\tgetToken,\n\t\t\t\t);\n\n\t\t\t\t// IMPORTANT: In past we were using GetFileByUrl() API to get to the list item that was corresponding\n\t\t\t\t// to the file. This was intentionally replaced with GetFileById() to solve the following issue:\n\t\t\t\t// GetFileByUrl() uses webDavUrl to locate list item. This API does not work for Consumer scenarios\n\t\t\t\t// where webDavUrl is constructed using legacy ODC format for backward compatibility reasons.\n\t\t\t\t// GetFileByUrl() does not understand that format and thus fails. GetFileById() relies on file item\n\t\t\t\t// unique guid (sharepointIds.listItemUniqueId) and it works uniformly across Consumer and Commercial.\n\t\t\t\tconst url = `${\n\t\t\t\t\todspUrlParts.siteUrl\n\t\t\t\t}/_api/web/GetFileById(@a1)/ListItemAllFields/GetSharingInformation?@a1=guid${encodeURIComponent(\n\t\t\t\t\t`'${fileItem.sharepointIds.listItemUniqueId}'`,\n\t\t\t\t)}`;\n\t\t\t\tconst method = \"GET\";\n\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t{ ...options, request: { url, method } },\n\t\t\t\t\t\"GetFileLinkCore\",\n\t\t\t\t);\n\t\t\t\tconst headers = getHeadersWithAuth(authHeader);\n\t\t\t\tconst requestInit = {\n\t\t\t\t\tmethod,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": \"application/json;odata=verbose\",\n\t\t\t\t\t\t\"Accept\": \"application/json;odata=verbose\",\n\t\t\t\t\t\t...headers,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tconst response = await fetchHelper(url, requestInit);\n\t\t\t\tadditionalProps = response.propsToLog;\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tconst sharingInfo = await response.content.json();\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\t\tconst directUrl = sharingInfo?.d?.directUrl;\n\t\t\t\tif (typeof directUrl !== \"string\") {\n\t\t\t\t\t// This will retry once in getWithRetryForTokenRefresh\n\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\"Malformed GetSharingInformation response\",\n\t\t\t\t\t\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\t\t{ driverVersion },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn directUrl;\n\t\t\t});\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tevent.end({ ...additionalProps, attempts });\n\t\t\treturn fileLink;\n\t\t},\n\t);\n}\n\n/**\n * Sharepoint Ids Interface\n */\ninterface IGraphSharepointIds {\n\tlistId: string;\n\tlistItemId: string;\n\tlistItemUniqueId: string;\n\tsiteId: string;\n\tsiteUrl: string;\n\twebId: string;\n}\n\n/**\n * This represents a lite version of file item containing only select file properties\n */\ninterface FileItemLite {\n\twebUrl: string;\n\twebDavUrl: string;\n\tsharepointIds: IGraphSharepointIds;\n}\n\nconst isFileItemLite = (maybeFileItemLite: unknown): maybeFileItemLite is FileItemLite =>\n\ttypeof (maybeFileItemLite as Partial<FileItemLite>).webUrl === \"string\" &&\n\ttypeof (maybeFileItemLite as Partial<FileItemLite>).webDavUrl === \"string\" &&\n\t// TODO: stronger check\n\ttypeof (maybeFileItemLite as Partial<FileItemLite>).sharepointIds === \"object\";\n\nasync function getFileItemLite(\n\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\todspUrlParts: IOdspUrlParts,\n\tlogger: TelemetryLoggerExt,\n): Promise<FileItemLite> {\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{ eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n\t\tasync (event) => {\n\t\t\tlet attempts = 0;\n\t\t\tlet additionalProps: ITelemetryBaseProperties | undefined;\n\t\t\tconst fileItem = await getWithRetryForTokenRefresh(async (options) => {\n\t\t\t\tattempts++;\n\t\t\t\tconst { siteUrl, driveId, itemId } = odspUrlParts;\n\t\t\t\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\t\t\t\tlogger,\n\t\t\t\t\todspUrlParts,\n\t\t\t\t\tgetToken,\n\t\t\t\t);\n\t\t\t\tconst url = `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl,sharepointIds`;\n\t\t\t\tconst method = \"GET\";\n\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t{ ...options, request: { url, method } },\n\t\t\t\t\t\"GetFileItemLite\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tauthHeader !== null,\n\t\t\t\t\t0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */,\n\t\t\t\t);\n\n\t\t\t\tconst headers = getHeadersWithAuth(authHeader);\n\t\t\t\tconst requestInit = { method, headers };\n\t\t\t\tconst response = await fetchHelper(url, requestInit);\n\t\t\t\tadditionalProps = response.propsToLog;\n\n\t\t\t\tconst responseJson: unknown = await response.content.json();\n\t\t\t\tif (!isFileItemLite(responseJson)) {\n\t\t\t\t\t// This will retry once in getWithRetryForTokenRefresh\n\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\"Malformed getFileItemLite response\",\n\t\t\t\t\t\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\t\t{ driverVersion },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn responseJson;\n\t\t\t});\n\t\t\tevent.end({ ...additionalProps, attempts });\n\t\t\treturn fileItem;\n\t\t},\n\t);\n}\n\n/**\n * It takes a resolved url with old siteUrl and patches resolved url with updated site url domain.\n * @param odspResolvedUrl - Previous odsp resolved url with older site url.\n * @param newSiteDomain - New site domain after the tenant rename.\n */\nfunction renameTenantInOdspResolvedUrl(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tnewSiteDomain: string,\n): void {\n\tconst newSiteUrl = `${newSiteDomain}${new URL(odspResolvedUrl.siteUrl).pathname}`;\n\todspResolvedUrl.siteUrl = newSiteUrl;\n\n\tif (odspResolvedUrl.endpoints.attachmentGETStorageUrl) {\n\t\todspResolvedUrl.endpoints.attachmentGETStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.attachmentGETStorageUrl).pathname}`;\n\t}\n\tif (odspResolvedUrl.endpoints.attachmentPOSTStorageUrl) {\n\t\todspResolvedUrl.endpoints.attachmentPOSTStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.attachmentPOSTStorageUrl).pathname}`;\n\t}\n\tif (odspResolvedUrl.endpoints.deltaStorageUrl) {\n\t\todspResolvedUrl.endpoints.deltaStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.deltaStorageUrl).pathname}`;\n\t}\n\tif (odspResolvedUrl.endpoints.snapshotStorageUrl) {\n\t\todspResolvedUrl.endpoints.snapshotStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.snapshotStorageUrl).pathname}`;\n\t}\n}\n"]}
1
+ {"version":3,"file":"getFileLink.js","sourceRoot":"","sources":["../src/getFileLink.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 type { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { NonRetryableError, runWithRetry } from \"@fluidframework/driver-utils/internal\";\nimport {\n\ttype IOdspUrlParts,\n\tOdspErrorTypes,\n\ttype OdspResourceTokenFetchOptions,\n\ttype TokenFetcher,\n\ttype IOdspResolvedUrl,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tisFluidError,\n\tPerformanceEvent,\n\ttype TelemetryLoggerExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { getHeadersWithAuth } from \"./getUrlAndHeadersWithAuth.js\";\nimport { mockify } from \"./mockify.js\";\nimport {\n\tfetchHelper,\n\tgetWithRetryForTokenRefresh,\n\ttoInstrumentedOdspStorageTokenFetcher,\n} from \"./odspUtils.js\";\nimport { pkgVersion as driverVersion } from \"./packageVersion.js\";\nimport { runWithRetry as runWithRetryForCoherencyAndServiceReadOnlyErrors } from \"./retryUtils.js\";\n\n// Store cached responses for the lifetime of web session as file link remains the same for given file item\nconst fileLinkCache = new Map<string, Promise<string>>();\n\n/**\n * Returns file link for a file with given drive and item ids.\n * Scope needed: files.readwrite.all.\n * This function keeps retrying if it gets a retriable error or wait for some delay if it gets a\n * throttling error. In future, we are thinking of app allowing to pass some cancel token, with which\n * we would be able to stop retrying.\n * @param getToken - used to fetch access tokens needed to execute operation\n * @param odspUrlParts - object describing file storage identity\n * @param logger - used to log results of operation, including any error\n * @returns Promise which resolves to file link url when successful; otherwise, undefined.\n */\nexport const getFileLink = mockify(\n\tasync (\n\t\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\t\tresolvedUrl: IOdspResolvedUrl,\n\t\tlogger: TelemetryLoggerExt,\n\t): Promise<string> => {\n\t\tconst cacheKey = `${resolvedUrl.siteUrl}_${resolvedUrl.driveId}_${resolvedUrl.itemId}`;\n\t\tconst maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n\t\tif (maybeFileLinkCacheEntry !== undefined) {\n\t\t\treturn maybeFileLinkCacheEntry;\n\t\t}\n\n\t\tconst fileLinkGenerator = async function (): Promise<string> {\n\t\t\tlet fileLinkCore: string;\n\t\t\ttry {\n\t\t\t\tlet retryCount = 0;\n\t\t\t\tfileLinkCore = await runWithRetry(\n\t\t\t\t\tasync () =>\n\t\t\t\t\t\trunWithRetryForCoherencyAndServiceReadOnlyErrors(\n\t\t\t\t\t\t\tasync () =>\n\t\t\t\t\t\t\t\tgetFileLinkWithLocationRedirectionHandling(getToken, resolvedUrl, logger),\n\t\t\t\t\t\t\t\"getFileLinkCore\",\n\t\t\t\t\t\t\tlogger,\n\t\t\t\t\t\t),\n\t\t\t\t\t\"getShareLink\",\n\t\t\t\t\tlogger,\n\t\t\t\t\t{\n\t\t\t\t\t\t// TODO: use a stronger type\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t\t\tonRetry(delayInMs: number, error: any) {\n\t\t\t\t\t\t\tretryCount++;\n\t\t\t\t\t\t\tif (retryCount === 5) {\n\t\t\t\t\t\t\t\tif (error !== undefined && typeof error === \"object\") {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\t\t\t\terror.canRetry = false;\n\t\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\t// Delete from the cache to permit retrying later.\n\t\t\t\tfileLinkCache.delete(cacheKey);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n\t\t\tassert(\n\t\t\t\tfileLinkCore !== undefined,\n\t\t\t\t0x292 /* \"Unexpected undefined result from getFileLinkCore\" */,\n\t\t\t);\n\t\t\treturn fileLinkCore;\n\t\t};\n\t\tconst fileLink = fileLinkGenerator();\n\t\tfileLinkCache.set(cacheKey, fileLink);\n\t\treturn fileLink;\n\t},\n);\n\n/**\n * Handles location redirection while fulfilling the getFileLink call. We don't want browser to handle\n * the redirection as the browser will retry with same auth token which will not work as we need app\n * to regenerate tokens for the new site domain. So when we will make the network calls below we will set\n * the redirect:manual header to manually handle these redirects.\n * Refer: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308\n * @param getToken - token fetcher to fetch the token.\n * @param odspUrlParts - parts of odsp resolved url.\n * @param logger - logger to send events.\n * @returns Response from the API call.\n * @legacy\n * @beta\n */\nasync function getFileLinkWithLocationRedirectionHandling(\n\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\tresolvedUrl: IOdspResolvedUrl,\n\tlogger: TelemetryLoggerExt,\n): Promise<string> {\n\t// We can have chains of location redirection one after the other, so have a for loop\n\t// so that we can keep handling the same type of error. Set max number of redirection to 5.\n\tlet lastError: unknown;\n\tlet locationRedirected = false;\n\tfor (let count = 1; count <= 5; count++) {\n\t\ttry {\n\t\t\tconst fileItem = await getFileItemLite(getToken, resolvedUrl, logger);\n\t\t\t// Sometimes the siteUrl in the actual file is different from the siteUrl in the resolvedUrl due to location\n\t\t\t// redirection. This creates issues in the getSharingInformation call. So we need to update the siteUrl in the\n\t\t\t// resolvedUrl to the siteUrl in the fileItem which is the updated siteUrl.\n\t\t\tconst oldSiteDomain = new URL(resolvedUrl.siteUrl).origin;\n\t\t\tconst newSiteDomain = new URL(fileItem.sharepointIds.siteUrl).origin;\n\t\t\tif (oldSiteDomain !== newSiteDomain) {\n\t\t\t\tlocationRedirected = true;\n\t\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"LocationRedirectionErrorForGetOdspFileLink\",\n\t\t\t\t\tretryCount: count,\n\t\t\t\t});\n\t\t\t\trenameTenantInOdspResolvedUrl(resolvedUrl, newSiteDomain);\n\t\t\t}\n\t\t\treturn await getFileLinkCore(getToken, resolvedUrl, logger, fileItem);\n\t\t} catch (error: unknown) {\n\t\t\tlastError = error;\n\t\t\t// If the getSharingLink call fails with the 401/403/404 error, then it could be due to that the file has moved\n\t\t\t// to another location. This could occur in case we have more than 1 tenant rename. In that case, we should retry\n\t\t\t// the getFileItemLite call to get the updated fileItem.\n\t\t\tif (\n\t\t\t\tisFluidError(error) &&\n\t\t\t\tlocationRedirected &&\n\t\t\t\t(error.errorType === OdspErrorTypes.fileNotFoundOrAccessDeniedError ||\n\t\t\t\t\terror.errorType === OdspErrorTypes.authorizationError)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\tthrow lastError;\n}\n\nasync function getFileLinkCore(\n\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\todspUrlParts: IOdspUrlParts,\n\tlogger: TelemetryLoggerExt,\n\tfileItem: FileItemLite,\n): Promise<string> {\n\t// ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{ eventName: \"odspFileLink\", requestName: \"getSharingInformation\" },\n\t\tasync (event) => {\n\t\t\tlet attempts = 0;\n\t\t\tlet additionalProps;\n\t\t\tconst fileLink = await getWithRetryForTokenRefresh(async (options) => {\n\t\t\t\tattempts++;\n\t\t\t\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\t\t\t\tlogger,\n\t\t\t\t\todspUrlParts,\n\t\t\t\t\tgetToken,\n\t\t\t\t);\n\n\t\t\t\t// IMPORTANT: In past we were using GetFileByUrl() API to get to the list item that was corresponding\n\t\t\t\t// to the file. This was intentionally replaced with GetFileById() to solve the following issue:\n\t\t\t\t// GetFileByUrl() uses webDavUrl to locate list item. This API does not work for Consumer scenarios\n\t\t\t\t// where webDavUrl is constructed using legacy ODC format for backward compatibility reasons.\n\t\t\t\t// GetFileByUrl() does not understand that format and thus fails. GetFileById() relies on file item\n\t\t\t\t// unique guid (sharepointIds.listItemUniqueId) and it works uniformly across Consumer and Commercial.\n\t\t\t\tconst url = `${\n\t\t\t\t\todspUrlParts.siteUrl\n\t\t\t\t}/_api/web/GetFileById(@a1)/ListItemAllFields/GetSharingInformation?@a1=guid${encodeURIComponent(\n\t\t\t\t\t`'${fileItem.sharepointIds.listItemUniqueId}'`,\n\t\t\t\t)}`;\n\t\t\t\tconst method = \"GET\";\n\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t{ ...options, request: { url, method } },\n\t\t\t\t\t\"GetFileLinkCore\",\n\t\t\t\t);\n\t\t\t\tconst headers = getHeadersWithAuth(authHeader);\n\t\t\t\tconst requestInit = {\n\t\t\t\t\tmethod,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": \"application/json;odata=verbose\",\n\t\t\t\t\t\t\"Accept\": \"application/json;odata=verbose\",\n\t\t\t\t\t\t...headers,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tconst response = await fetchHelper(url, requestInit);\n\t\t\t\tadditionalProps = response.propsToLog;\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tconst sharingInfo = await response.content.json();\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n\t\t\t\tconst directUrl = sharingInfo?.d?.directUrl;\n\t\t\t\tif (typeof directUrl !== \"string\") {\n\t\t\t\t\t// This will retry once in getWithRetryForTokenRefresh\n\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\"Malformed GetSharingInformation response\",\n\t\t\t\t\t\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\t\t{ driverVersion },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn directUrl;\n\t\t\t});\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tevent.end({ ...additionalProps, attempts });\n\t\t\treturn fileLink;\n\t\t},\n\t);\n}\n\n/**\n * Sharepoint Ids Interface\n */\ninterface IGraphSharepointIds {\n\tlistId: string;\n\tlistItemId: string;\n\tlistItemUniqueId: string;\n\tsiteId: string;\n\tsiteUrl: string;\n\twebId: string;\n}\n\n/**\n * This represents a lite version of file item containing only select file properties\n */\ninterface FileItemLite {\n\twebUrl: string;\n\twebDavUrl: string;\n\tsharepointIds: IGraphSharepointIds;\n}\n\nconst isFileItemLite = (maybeFileItemLite: unknown): maybeFileItemLite is FileItemLite =>\n\ttypeof (maybeFileItemLite as Partial<FileItemLite>).webUrl === \"string\" &&\n\ttypeof (maybeFileItemLite as Partial<FileItemLite>).webDavUrl === \"string\" &&\n\t// TODO: stronger check\n\ttypeof (maybeFileItemLite as Partial<FileItemLite>).sharepointIds === \"object\";\n\nasync function getFileItemLite(\n\tgetToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\todspUrlParts: IOdspUrlParts,\n\tlogger: TelemetryLoggerExt,\n): Promise<FileItemLite> {\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{ eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n\t\tasync (event) => {\n\t\t\tlet attempts = 0;\n\t\t\tlet additionalProps: ITelemetryBaseProperties | undefined;\n\t\t\tconst fileItem = await getWithRetryForTokenRefresh(async (options) => {\n\t\t\t\tattempts++;\n\t\t\t\tconst { siteUrl, driveId, itemId } = odspUrlParts;\n\t\t\t\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\t\t\t\tlogger,\n\t\t\t\t\todspUrlParts,\n\t\t\t\t\tgetToken,\n\t\t\t\t);\n\t\t\t\tconst url = `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl,sharepointIds`;\n\t\t\t\tconst method = \"GET\";\n\t\t\t\tconst authHeader = await getAuthHeader(\n\t\t\t\t\t{ ...options, request: { url, method } },\n\t\t\t\t\t\"GetFileItemLite\",\n\t\t\t\t);\n\t\t\t\tassert(\n\t\t\t\t\tauthHeader !== null,\n\t\t\t\t\t0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */,\n\t\t\t\t);\n\n\t\t\t\tconst headers = getHeadersWithAuth(authHeader);\n\t\t\t\tconst requestInit = { method, headers };\n\t\t\t\tconst response = await fetchHelper(url, requestInit);\n\t\t\t\tadditionalProps = response.propsToLog;\n\n\t\t\t\tconst responseJson: unknown = await response.content.json();\n\t\t\t\tif (!isFileItemLite(responseJson)) {\n\t\t\t\t\t// This will retry once in getWithRetryForTokenRefresh\n\t\t\t\t\tthrow new NonRetryableError(\n\t\t\t\t\t\t\"Malformed getFileItemLite response\",\n\t\t\t\t\t\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\t\t{ driverVersion },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn responseJson;\n\t\t\t});\n\t\t\tevent.end({ ...additionalProps, attempts });\n\t\t\treturn fileItem;\n\t\t},\n\t);\n}\n\n/**\n * It takes a resolved url with old siteUrl and patches resolved url with updated site url domain.\n * @param odspResolvedUrl - Previous odsp resolved url with older site url.\n * @param newSiteDomain - New site domain after the tenant rename.\n */\nfunction renameTenantInOdspResolvedUrl(\n\todspResolvedUrl: IOdspResolvedUrl,\n\tnewSiteDomain: string,\n): void {\n\tconst newSiteUrl = `${newSiteDomain}${new URL(odspResolvedUrl.siteUrl).pathname}`;\n\todspResolvedUrl.siteUrl = newSiteUrl;\n\n\tif (odspResolvedUrl.endpoints.attachmentGETStorageUrl) {\n\t\todspResolvedUrl.endpoints.attachmentGETStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.attachmentGETStorageUrl).pathname}`;\n\t}\n\tif (odspResolvedUrl.endpoints.attachmentPOSTStorageUrl) {\n\t\todspResolvedUrl.endpoints.attachmentPOSTStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.attachmentPOSTStorageUrl).pathname}`;\n\t}\n\tif (odspResolvedUrl.endpoints.deltaStorageUrl) {\n\t\todspResolvedUrl.endpoints.deltaStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.deltaStorageUrl).pathname}`;\n\t}\n\tif (odspResolvedUrl.endpoints.snapshotStorageUrl) {\n\t\todspResolvedUrl.endpoints.snapshotStorageUrl = `${newSiteDomain}${new URL(odspResolvedUrl.endpoints.snapshotStorageUrl).pathname}`;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"localOdspDocumentStorageManager.d.ts","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentStorageManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,KAAK,EACX,SAAS,EACT,qBAAqB,EACrB,eAAe,EACf,QAAQ,EACR,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACN,KAAK,kBAAkB,EAEvB,MAAM,0CAA0C,CAAC;AAIlD,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAGtF;;;GAGG;AACH,qBAAa,+BAAgC,SAAQ,8BAA8B;IAIjF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJ/B,OAAO,CAAC,cAAc,CAAqB;gBAGzB,MAAM,EAAE,kBAAkB,EAC1B,aAAa,EAAE,UAAU,GAAG,MAAM;IAKpD,OAAO,CAAC,iBAAiB,CAAS;IAErB,WAAW,CAEvB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAuBT,WAAW,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC;IAI1F,OAAO,CAAC,kBAAkB;IAI1B,SAAS,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,KAAK;IAI3E,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,KAAK;IAIlE,wBAAwB,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,GAAG,KAAK;IAIlF,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK;IAIhD,OAAO,CAAC,eAAe;CAOvB"}
1
+ {"version":3,"file":"localOdspDocumentStorageManager.d.ts","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentStorageManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,KAAK,EACX,SAAS,EACT,qBAAqB,EACrB,eAAe,EACf,QAAQ,EACR,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAEN,KAAK,kBAAkB,EACvB,MAAM,0CAA0C,CAAC;AAIlD,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAGtF;;;GAGG;AACH,qBAAa,+BAAgC,SAAQ,8BAA8B;IAIjF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJ/B,OAAO,CAAC,cAAc,CAAqB;gBAGzB,MAAM,EAAE,kBAAkB,EAC1B,aAAa,EAAE,UAAU,GAAG,MAAM;IAKpD,OAAO,CAAC,iBAAiB,CAAS;IAErB,WAAW,CAEvB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAuBT,WAAW,CAAC,oBAAoB,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC;IAI1F,OAAO,CAAC,kBAAkB;IAI1B,SAAS,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,KAAK;IAI3E,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,KAAK;IAIlE,wBAAwB,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,GAAG,KAAK;IAIlF,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK;IAIhD,OAAO,CAAC,eAAe;CAOvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"localOdspDocumentStorageManager.js","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentStorageManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAQ7D,oEAAmE;AACnE,uEAGkD;AAElD,0EAA2E;AAE3E,4FAAsF;AACtF,oEAAqF;AAErF;;;GAGG;AACH,MAAa,+BAAgC,SAAQ,kEAA8B;IAGlF,YACkB,MAA0B,EAC1B,aAAkC;QAEnD,KAAK,CAAC,IAAA,oCAAyB,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;QAH/B,WAAM,GAAN,MAAM,CAAoB;QAC1B,kBAAa,GAAb,aAAa,CAAqB;QAK5C,sBAAiB,GAAG,KAAK,CAAC;IAFlC,CAAC;IAIM,KAAK,CAAC,WAAW;IACvB,kDAAkD;IAClD,MAAqB,EACrB,KAAa,EACb,aAAsB;QAEtB,IAAA,iBAAM,EAAC,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnF,IAAA,iBAAM,EAAC,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAE3E,4DAA4D;QAC5D,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAE9B,IAAI,gBAA2B,CAAC;QAEhC,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAkB,CAAC;YAC/E,gBAAgB,GAAG,IAAA,iEAAyC,EAAC,OAAO,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACP,gBAAgB,GAAG,IAAA,uDAA4B,EAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAClF,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,oBAA4C;QACpE,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IAEO,kBAAkB;QACzB,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,SAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,CAAC;IAES,qBAAqB,CAAC,GAAW,EAAE,aAAsB;QAClE,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;IAC/C,CAAC;IAES,oBAAoB,CAAC,OAAe,EAAE,QAAiB;QAChE,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC9C,CAAC;IAEM,wBAAwB,CAAC,QAAsB,EAAE,QAAyB;QAChF,IAAI,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC;IAClD,CAAC;IAEM,UAAU,CAAC,KAAsB;QACvC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC;IAEO,eAAe,CAAC,UAAkB;QACzC,MAAM,OAAO,GAAG,IAAI,qBAAU,CAC7B,IAAI,UAAU,uDAAuD,CACrE,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;QACvE,MAAM,OAAO,CAAC;IACf,CAAC;CACD;AAvED,0EAuEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport type {\n\tISnapshot,\n\tISnapshotFetchOptions,\n\tISummaryContext,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { UsageError } from \"@fluidframework/driver-utils/internal\";\nimport {\n\ttype TelemetryLoggerExt,\n\tloggerToMonitoringContext,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { parseCompactSnapshotResponse } from \"../compactSnapshotParser.js\";\nimport type { IOdspSnapshot } from \"../contracts.js\";\nimport { OdspDocumentStorageServiceBase } from \"../odspDocumentStorageServiceBase.js\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"../odspSnapshotParser.js\";\n\n/**\n * ODSP document storage service that works on a provided snapshot for all its processing.\n * Attempting to use unsupported actions/methods will result in errors being thrown.\n */\nexport class LocalOdspDocumentStorageService extends OdspDocumentStorageServiceBase {\n\tprivate snapshotTreeId: string | undefined;\n\n\tconstructor(\n\t\tprivate readonly logger: TelemetryLoggerExt,\n\t\tprivate readonly localSnapshot: Uint8Array | string,\n\t) {\n\t\tsuper(loggerToMonitoringContext(logger).config);\n\t}\n\n\tprivate calledGetVersions = false;\n\n\tpublic async getVersions(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tblobid: string | null,\n\t\tcount: number,\n\t\t_scenarioName?: string,\n\t): Promise<IVersion[]> {\n\t\tassert(blobid === null, 0x342 /* Invalid usage. \"blobid\" should always be null */);\n\t\tassert(count === 1, 0x343 /* Invalid usage. \"count\" should always be 1 */);\n\n\t\t// No reason to re-parse the data since it will never change\n\t\tif (this.calledGetVersions) {\n\t\t\treturn this.getSnapshotVersion();\n\t\t}\n\t\tthis.calledGetVersions = true;\n\n\t\tlet snapshotContents: ISnapshot;\n\n\t\tif (typeof this.localSnapshot === \"string\") {\n\t\t\tconst content: IOdspSnapshot = JSON.parse(this.localSnapshot) as IOdspSnapshot;\n\t\t\tsnapshotContents = convertOdspSnapshotToSnapshotTreeAndBlobs(content);\n\t\t} else {\n\t\t\tsnapshotContents = parseCompactSnapshotResponse(this.localSnapshot, this.logger);\n\t\t}\n\n\t\tthis.snapshotTreeId = this.initializeFromSnapshot(snapshotContents);\n\t\treturn this.getSnapshotVersion();\n\t}\n\n\tpublic async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {\n\t\tthis.throwUsageError(\"getSnapshot\");\n\t}\n\n\tprivate getSnapshotVersion(): IVersion[] {\n\t\treturn this.snapshotTreeId ? [{ id: this.snapshotTreeId, treeId: undefined! }] : [];\n\t}\n\n\tprotected fetchTreeFromSnapshot(_id: string, _scenarioName?: string): never {\n\t\tthis.throwUsageError(\"fetchTreeFromSnapshot\");\n\t}\n\n\tprotected fetchBlobFromStorage(_blobId: string, _evicted: boolean): never {\n\t\tthis.throwUsageError(\"fetchBlobFromStorage\");\n\t}\n\n\tpublic uploadSummaryWithContext(_summary: ISummaryTree, _context: ISummaryContext): never {\n\t\tthis.throwUsageError(\"uploadSummaryWithContext\");\n\t}\n\n\tpublic createBlob(_file: ArrayBufferLike): never {\n\t\tthis.throwUsageError(\"createBlob\");\n\t}\n\n\tprivate throwUsageError(methodName: string): never {\n\t\tconst toThrow = new UsageError(\n\t\t\t`\"${methodName}\" is not supported by LocalOdspDocumentStorageService`,\n\t\t);\n\t\tthis.logger.sendErrorEvent({ eventName: \"UnsupportedUsage\" }, toThrow);\n\t\tthrow toThrow;\n\t}\n}\n"]}
1
+ {"version":3,"file":"localOdspDocumentStorageManager.js","sourceRoot":"","sources":["../../src/localOdspDriver/localOdspDocumentStorageManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAQ7D,oEAAmE;AACnE,uEAGkD;AAElD,0EAA2E;AAE3E,4FAAsF;AACtF,oEAAqF;AAErF;;;GAGG;AACH,MAAa,+BAAgC,SAAQ,kEAA8B;IAGlF,YACkB,MAA0B,EAC1B,aAAkC;QAEnD,KAAK,CAAC,IAAA,oCAAyB,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;QAH/B,WAAM,GAAN,MAAM,CAAoB;QAC1B,kBAAa,GAAb,aAAa,CAAqB;QAK5C,sBAAiB,GAAG,KAAK,CAAC;IAFlC,CAAC;IAIM,KAAK,CAAC,WAAW;IACvB,kDAAkD;IAClD,MAAqB,EACrB,KAAa,EACb,aAAsB;QAEtB,IAAA,iBAAM,EAAC,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnF,IAAA,iBAAM,EAAC,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAE3E,4DAA4D;QAC5D,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAE9B,IAAI,gBAA2B,CAAC;QAEhC,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAkB,CAAC;YAC/E,gBAAgB,GAAG,IAAA,iEAAyC,EAAC,OAAO,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACP,gBAAgB,GAAG,IAAA,uDAA4B,EAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAClF,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAClC,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,oBAA4C;QACpE,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IAEO,kBAAkB;QACzB,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,SAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,CAAC;IAES,qBAAqB,CAAC,GAAW,EAAE,aAAsB;QAClE,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC;IAC/C,CAAC;IAES,oBAAoB,CAAC,OAAe,EAAE,QAAiB;QAChE,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC9C,CAAC;IAEM,wBAAwB,CAAC,QAAsB,EAAE,QAAyB;QAChF,IAAI,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAAC;IAClD,CAAC;IAEM,UAAU,CAAC,KAAsB;QACvC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC;IAEO,eAAe,CAAC,UAAkB;QACzC,MAAM,OAAO,GAAG,IAAI,qBAAU,CAC7B,IAAI,UAAU,uDAAuD,CACrE,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;QACvE,MAAM,OAAO,CAAC;IACf,CAAC;CACD;AAvED,0EAuEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport type {\n\tISnapshot,\n\tISnapshotFetchOptions,\n\tISummaryContext,\n\tIVersion,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { UsageError } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tloggerToMonitoringContext,\n\ttype TelemetryLoggerExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { parseCompactSnapshotResponse } from \"../compactSnapshotParser.js\";\nimport type { IOdspSnapshot } from \"../contracts.js\";\nimport { OdspDocumentStorageServiceBase } from \"../odspDocumentStorageServiceBase.js\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"../odspSnapshotParser.js\";\n\n/**\n * ODSP document storage service that works on a provided snapshot for all its processing.\n * Attempting to use unsupported actions/methods will result in errors being thrown.\n */\nexport class LocalOdspDocumentStorageService extends OdspDocumentStorageServiceBase {\n\tprivate snapshotTreeId: string | undefined;\n\n\tconstructor(\n\t\tprivate readonly logger: TelemetryLoggerExt,\n\t\tprivate readonly localSnapshot: Uint8Array | string,\n\t) {\n\t\tsuper(loggerToMonitoringContext(logger).config);\n\t}\n\n\tprivate calledGetVersions = false;\n\n\tpublic async getVersions(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tblobid: string | null,\n\t\tcount: number,\n\t\t_scenarioName?: string,\n\t): Promise<IVersion[]> {\n\t\tassert(blobid === null, 0x342 /* Invalid usage. \"blobid\" should always be null */);\n\t\tassert(count === 1, 0x343 /* Invalid usage. \"count\" should always be 1 */);\n\n\t\t// No reason to re-parse the data since it will never change\n\t\tif (this.calledGetVersions) {\n\t\t\treturn this.getSnapshotVersion();\n\t\t}\n\t\tthis.calledGetVersions = true;\n\n\t\tlet snapshotContents: ISnapshot;\n\n\t\tif (typeof this.localSnapshot === \"string\") {\n\t\t\tconst content: IOdspSnapshot = JSON.parse(this.localSnapshot) as IOdspSnapshot;\n\t\t\tsnapshotContents = convertOdspSnapshotToSnapshotTreeAndBlobs(content);\n\t\t} else {\n\t\t\tsnapshotContents = parseCompactSnapshotResponse(this.localSnapshot, this.logger);\n\t\t}\n\n\t\tthis.snapshotTreeId = this.initializeFromSnapshot(snapshotContents);\n\t\treturn this.getSnapshotVersion();\n\t}\n\n\tpublic async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {\n\t\tthis.throwUsageError(\"getSnapshot\");\n\t}\n\n\tprivate getSnapshotVersion(): IVersion[] {\n\t\treturn this.snapshotTreeId ? [{ id: this.snapshotTreeId, treeId: undefined! }] : [];\n\t}\n\n\tprotected fetchTreeFromSnapshot(_id: string, _scenarioName?: string): never {\n\t\tthis.throwUsageError(\"fetchTreeFromSnapshot\");\n\t}\n\n\tprotected fetchBlobFromStorage(_blobId: string, _evicted: boolean): never {\n\t\tthis.throwUsageError(\"fetchBlobFromStorage\");\n\t}\n\n\tpublic uploadSummaryWithContext(_summary: ISummaryTree, _context: ISummaryContext): never {\n\t\tthis.throwUsageError(\"uploadSummaryWithContext\");\n\t}\n\n\tpublic createBlob(_file: ArrayBufferLike): never {\n\t\tthis.throwUsageError(\"createBlob\");\n\t}\n\n\tprivate throwUsageError(methodName: string): never {\n\t\tconst toThrow = new UsageError(\n\t\t\t`\"${methodName}\" is not supported by LocalOdspDocumentStorageService`,\n\t\t);\n\t\tthis.logger.sendErrorEvent({ eventName: \"UnsupportedUsage\" }, toThrow);\n\t\tthrow toThrow;\n\t}\n}\n"]}
@@ -376,7 +376,7 @@ class OdspDelayLoadedDeltaStream {
376
376
  dispose(error) {
377
377
  this.clearJoinSessionTimer();
378
378
  this.currentConnection?.dispose();
379
- this.currentConnection = undefined;
379
+ delete this.currentConnection;
380
380
  }
381
381
  }
382
382
  exports.OdspDelayLoadedDeltaStream = OdspDelayLoadedDeltaStream;
@@ -1 +1 @@
1
- {"version":3,"file":"odspDelayLoadedDeltaStream.js","sourceRoot":"","sources":["../src/odspDelayLoadedDeltaStream.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 { performanceNow } from \"@fluid-internal/client-utils\";\nimport type { ISignalEnvelope } from \"@fluidframework/core-interfaces/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IClient } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentDeltaConnection,\n\tIDocumentServicePolicies,\n\tIResolvedUrl,\n\tIAnyDriverError,\n\tISequencedDocumentMessage,\n\tISignalMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tDeltaStreamConnectionForbiddenError,\n\tNonRetryableError,\n} from \"@fluidframework/driver-utils/internal\";\nimport { hasFacetCodes } from \"@fluidframework/odsp-doclib-utils/internal\";\nimport {\n\ttype HostStoragePolicy,\n\ttype IOdspError,\n\ttype IOdspResolvedUrl,\n\ttype ISocketStorageDiscovery,\n\ttype ISensitivityLabelsInfo,\n\ttype InstrumentedStorageTokenFetcher,\n\tOdspErrorTypes,\n\ttype TokenFetchOptions,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\ttype IFluidErrorBase,\n\ttype MonitoringContext,\n\tnormalizeError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { policyLabelsUpdatesSignalType } from \"./contracts.js\";\nimport type { EpochTracker } from \"./epochTracker.js\";\nimport type { IOdspCache } from \"./odspCache.js\";\nimport { OdspDocumentDeltaConnection } from \"./odspDocumentDeltaConnection.js\";\nimport {\n\ttype TokenFetchOptionsEx,\n\tgetJoinSessionCacheKey,\n\tgetWithRetryForTokenRefresh,\n} from \"./odspUtils.js\";\nimport { pkgVersion as driverVersion } from \"./packageVersion.js\";\nimport { fetchJoinSession } from \"./vroom.js\";\n\n/**\n * This OdspDelayLoadedDeltaStream is used by OdspDocumentService.ts to delay load the delta connection\n * as they are not on critical path of loading a container.\n */\nexport class OdspDelayLoadedDeltaStream {\n\t// Timer which runs and executes the join session call after intervals.\n\tprivate joinSessionRefreshTimer: ReturnType<typeof setTimeout> | undefined;\n\n\tprivate readonly joinSessionKey: string;\n\n\tprivate currentConnection?: OdspDocumentDeltaConnection;\n\n\tprivate _relayServiceTenantAndSessionId: string | undefined;\n\n\tprivate firstConnectionAttempt = true;\n\n\t// Tracks the time at which the Policy Labels were updated the last time. This is used to resolve race conditions\n\t// between label updates from the join session and the Fluid signals and they could have same or different timestamps.\n\t// So this timestamp is updated with timestamp from the service/signals with the most recent timestamp. We could also\n\t// receive stale data from join session as that call is made at intervals, so we need to update with only most recent data.\n\tprivate labelUpdateTimestamp: number = -1;\n\n\t/**\n\t * @param odspResolvedUrl - resolved url identifying document that will be managed by this service instance.\n\t * @param policies - Document service policies.\n\t * @param getAuthHeader - function that can provide the Authentication header value. 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 mc - a logger that can capture performance and diagnostic information\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 opsReceived - To register the ops received through socket.\n\t * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n\t */\n\tpublic constructor(\n\t\tpublic readonly odspResolvedUrl: IOdspResolvedUrl,\n\t\tpublic policies: IDocumentServicePolicies,\n\t\tprivate readonly getAuthHeader: InstrumentedStorageTokenFetcher,\n\t\tprivate readonly getWebsocketToken:\n\t\t\t| ((options: TokenFetchOptions) => Promise<string | null>)\n\t\t\t| undefined,\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly cache: IOdspCache,\n\t\tprivate readonly hostPolicy: HostStoragePolicy,\n\t\tprivate readonly epochTracker: EpochTracker,\n\t\tprivate readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,\n\t\tprivate readonly metadataUpdateHandler: (metadata: Record<string, string>) => void,\n\t\tprivate readonly socketReferenceKeyPrefix?: string,\n\t) {\n\t\tthis.joinSessionKey = getJoinSessionCacheKey(this.odspResolvedUrl);\n\t}\n\n\tpublic get resolvedUrl(): IResolvedUrl {\n\t\treturn this.odspResolvedUrl;\n\t}\n\n\tpublic get currentDeltaConnection(): OdspDocumentDeltaConnection | undefined {\n\t\treturn this.currentConnection;\n\t}\n\n\tpublic get relayServiceTenantAndSessionId(): string | undefined {\n\t\treturn this._relayServiceTenantAndSessionId;\n\t}\n\n\t/**\n\t * Annotate the given error indicating which connection step failed\n\t */\n\tprivate annotateConnectionError(\n\t\terror: unknown,\n\t\tfailedConnectionStep: string,\n\t\tseparateTokenRequest: boolean,\n\t): IFluidErrorBase {\n\t\treturn normalizeError(error, {\n\t\t\tprops: {\n\t\t\t\tfailedConnectionStep,\n\t\t\t\tseparateTokenRequest,\n\t\t\t},\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\tassert(\n\t\t\tthis.currentConnection === undefined,\n\t\t\t0x4ad /* Should not be called when connection is already present! */,\n\t\t);\n\t\t// Attempt to connect twice, in case we used expired token.\n\t\treturn getWithRetryForTokenRefresh<IDocumentDeltaConnection>(async (options) => {\n\t\t\t// Presence of getWebsocketToken callback dictates whether callback is used for fetching\n\t\t\t// websocket token or whether it is returned with joinSession response payload\n\t\t\tconst requestWebsocketTokenFromJoinSession = this.getWebsocketToken === undefined;\n\t\t\tconst websocketTokenPromise = requestWebsocketTokenFromJoinSession\n\t\t\t\t? // eslint-disable-next-line unicorn/no-null\n\t\t\t\t\tPromise.resolve(null)\n\t\t\t\t: this.getWebsocketToken(options);\n\n\t\t\tconst annotateAndRethrowConnectionError = (step: string) => (error: unknown) => {\n\t\t\t\tthrow this.annotateConnectionError(error, step, !requestWebsocketTokenFromJoinSession);\n\t\t\t};\n\n\t\t\t// Log telemetry for join session attempt\n\t\t\tif (this.firstConnectionAttempt) {\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"FirstJoinSessionAttemptDetails\",\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\trequestWebsocketToken: requestWebsocketTokenFromJoinSession,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst joinSessionPromise = this.joinSession(\n\t\t\t\trequestWebsocketTokenFromJoinSession,\n\t\t\t\toptions,\n\t\t\t\tfalse /* isRefreshingJoinSession */,\n\t\t\t\tundefined /* clientId */,\n\t\t\t\tthis.hostPolicy.sessionOptions?.displayName,\n\t\t\t);\n\t\t\tconst [websocketEndpoint, websocketToken] = await Promise.all([\n\t\t\t\tjoinSessionPromise.catch(annotateAndRethrowConnectionError(\"joinSession\")),\n\t\t\t\twebsocketTokenPromise.catch(annotateAndRethrowConnectionError(\"getWebsocketToken\")),\n\t\t\t]);\n\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tconst finalWebsocketToken = websocketToken ?? websocketEndpoint.socketToken ?? null;\n\t\t\tif (finalWebsocketToken === null) {\n\t\t\t\tthrow this.annotateConnectionError(\n\t\t\t\t\tnew NonRetryableError(\"Websocket token is null\", OdspErrorTypes.fetchTokenError, {\n\t\t\t\t\t\tdriverVersion,\n\t\t\t\t\t}),\n\t\t\t\t\t\"getWebsocketToken\",\n\t\t\t\t\t!requestWebsocketTokenFromJoinSession,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (websocketEndpoint.sensitivityLabelsInfo !== undefined) {\n\t\t\t\tthis.emitSensitivityLabelUpdateEvent(websocketEndpoint.sensitivityLabelsInfo);\n\t\t\t}\n\n\t\t\tconst connectionId = uuid();\n\t\t\tif (this.firstConnectionAttempt) {\n\t\t\t\tthis.firstConnectionAttempt = false;\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"FirstConnectionAttemptDetails\",\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tconnectionId,\n\t\t\t\t\t\ttenantId: websocketEndpoint.tenantId,\n\t\t\t\t\t\tdocumentId: websocketEndpoint.id,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst connection = await this.createDeltaConnection(\n\t\t\t\t\twebsocketEndpoint.tenantId,\n\t\t\t\t\twebsocketEndpoint.id,\n\t\t\t\t\tfinalWebsocketToken,\n\t\t\t\t\tclient,\n\t\t\t\t\twebsocketEndpoint.deltaStreamSocketUrl,\n\t\t\t\t\tconnectionId,\n\t\t\t\t);\n\t\t\t\tconnection.on(\"op\", (documentId, ops: ISequencedDocumentMessage[]) => {\n\t\t\t\t\tthis.opsReceived(ops);\n\t\t\t\t});\n\t\t\t\tconnection.on(\"signal\", this.signalHandler);\n\t\t\t\t// Also process the initial signals\n\t\t\t\tthis.signalHandler(connection.initialSignals);\n\t\t\t\t// On disconnect with 401/403 error code, we can just clear the joinSession cache as we will again\n\t\t\t\t// get the auth error on reconnecting and face latency.\n\t\t\t\tconnection.once(\"disconnect\", (error: unknown) => {\n\t\t\t\t\t// Clear the join session refresh timer so that it can be restarted on reconnection.\n\t\t\t\t\tthis.clearJoinSessionTimer();\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\t\t\terror !== null &&\n\t\t\t\t\t\t(error as Partial<IOdspError>).errorType === OdspErrorTypes.authorizationError\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.cache.sessionJoinCache.remove(this.joinSessionKey);\n\t\t\t\t\t}\n\t\t\t\t\t// If we hit this assert, it means that \"disconnect\" event is emitted before the connection went through\n\t\t\t\t\t// dispose flow which is not correct and could lead to a bunch of errors.\n\t\t\t\t\tassert(connection.disposed, 0x4ae /* Connection should be disposed by now */);\n\t\t\t\t\tthis.currentConnection = undefined;\n\t\t\t\t});\n\t\t\t\tthis.currentConnection = connection;\n\t\t\t\treturn connection;\n\t\t\t} catch (error) {\n\t\t\t\t// Remove join session information from cache only if it is an error is from socket event connect_document_error.\n\t\t\t\t// Otherwise keep it in cache so that this session can be re-used after disconnection.\n\t\t\t\t// Also keeping an undefined check here to account for any unknown code path that is unable to stamp the value as in that case also\n\t\t\t\t// it is safer to clear join session cache and start over.\n\t\t\t\tif (\n\t\t\t\t\terror &&\n\t\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\t\t((error as IAnyDriverError).scenarioName === \"connect_document_error\" ||\n\t\t\t\t\t\t(error as IAnyDriverError).scenarioName === undefined)\n\t\t\t\t) {\n\t\t\t\t\tthis.clearJoinSessionTimer();\n\t\t\t\t\tthis.cache.sessionJoinCache.remove(this.joinSessionKey);\n\t\t\t\t}\n\t\t\t\tconst normalizedError = this.annotateConnectionError(\n\t\t\t\t\terror,\n\t\t\t\t\t\"createDeltaConnection\",\n\t\t\t\t\t!requestWebsocketTokenFromJoinSession,\n\t\t\t\t);\n\t\t\t\tif (typeof error === \"object\" && error !== null) {\n\t\t\t\t\tnormalizedError.addTelemetryProperties({\n\t\t\t\t\t\tsocketDocumentId: websocketEndpoint.id,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthrow normalizedError;\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate readonly signalHandler = (signalsArg: ISignalMessage | ISignalMessage[]): void => {\n\t\tconst signals = Array.isArray(signalsArg) ? signalsArg : [signalsArg];\n\t\tfor (const signal of signals) {\n\t\t\t// Make sure it is not for a specific client as `PolicyLabelsUpdate` is meant for all clients.\n\t\t\tif (signal.clientId === null) {\n\t\t\t\t// We could have some issues/irregularities in parsing signals, so put it in try/catch block\n\t\t\t\t// and ignore the error as we can have labels update later on through join session response.\n\t\t\t\tlet envelope: ISignalEnvelope | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tenvelope = JSON.parse(signal.content as string) as ISignalEnvelope;\n\t\t\t\t} catch {\n\t\t\t\t\t// Drop error\n\t\t\t\t}\n\t\t\t\tif (envelope?.contents?.type === policyLabelsUpdatesSignalType) {\n\t\t\t\t\tthis.emitSensitivityLabelUpdateEvent(\n\t\t\t\t\t\tenvelope.contents.content as ISensitivityLabelsInfo,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate clearJoinSessionTimer(): void {\n\t\tif (this.joinSessionRefreshTimer !== undefined) {\n\t\t\tclearTimeout(this.joinSessionRefreshTimer);\n\t\t\tthis.joinSessionRefreshTimer = undefined;\n\t\t}\n\t}\n\n\tprivate async scheduleJoinSessionRefresh(\n\t\tdelta: number,\n\t\trequestSocketToken: boolean,\n\t\tclientId: string | undefined,\n\t\tdisplayName: string | undefined,\n\t): Promise<void> {\n\t\tif (this.joinSessionRefreshTimer !== undefined) {\n\t\t\tthis.clearJoinSessionTimer();\n\t\t\t// TODO: use a stronger type\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"DuplicateJoinSessionRefresh\",\n\t\t\t\t},\n\t\t\t\tnew Error(\"DuplicateJoinSessionRefresh\"),\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tthis.joinSessionRefreshTimer = setTimeout(() => {\n\t\t\t\tthis.clearJoinSessionTimer();\n\t\t\t\t// Clear the timer as it is going to be scheduled again as part of refreshing join session.\n\t\t\t\tgetWithRetryForTokenRefresh(async (options) => {\n\t\t\t\t\tawait this.joinSession(\n\t\t\t\t\t\trequestSocketToken,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\ttrue /* isRefreshingJoinSession */,\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t\tdisplayName,\n\t\t\t\t\t);\n\t\t\t\t\tresolve();\n\t\t\t\t}).catch((error) => {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n\t\t\t\t\treject(error);\n\t\t\t\t});\n\t\t\t}, delta);\n\t\t});\n\t}\n\n\tprivate async joinSession(\n\t\trequestSocketToken: boolean,\n\t\toptions: TokenFetchOptionsEx,\n\t\tisRefreshingJoinSession: boolean,\n\t\tclientId: string | undefined,\n\t\tdisplayName: string | undefined,\n\t): Promise<ISocketStorageDiscovery> {\n\t\t// If this call is to refresh the join session for the current connection but we are already disconnected in\n\t\t// the meantime or disconnected and then reconnected then do not make the call. However, we should not have\n\t\t// come here if that is the case because timer should have been disposed, but due to race condition with the\n\t\t// timer we should not make the call and throw error.\n\t\tif (\n\t\t\tisRefreshingJoinSession &&\n\t\t\t(this.currentConnection === undefined ||\n\t\t\t\t(clientId !== undefined && this.currentConnection.clientId !== clientId))\n\t\t) {\n\t\t\tthis.clearJoinSessionTimer();\n\t\t\tthrow new NonRetryableError(\n\t\t\t\t\"JoinSessionRefreshTimerNotCancelled\",\n\t\t\t\tOdspErrorTypes.genericError,\n\t\t\t\t{\n\t\t\t\t\tdriverVersion,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tschedulerClientId: clientId,\n\t\t\t\t\t\tcurrentClientId: this.currentConnection?.clientId,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tconst response = await this.joinSessionCore(\n\t\t\trequestSocketToken,\n\t\t\toptions,\n\t\t\tisRefreshingJoinSession,\n\t\t\tdisplayName,\n\t\t).catch((error) => {\n\t\t\tif (hasFacetCodes(error) && error.facetCodes !== undefined) {\n\t\t\t\tfor (const code of error.facetCodes) {\n\t\t\t\t\tswitch (code) {\n\t\t\t\t\t\tcase \"sessionForbidden\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnPreservedFiles\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnModerationEnabledLibrary\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnRequireCheckout\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnCheckoutFile\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnInvisibleMinorVersion\": {\n\t\t\t\t\t\t\t// This document can only be opened in storage-only mode.\n\t\t\t\t\t\t\t// DeltaManager will recognize this error\n\t\t\t\t\t\t\t// and load without a delta stream connection.\n\t\t\t\t\t\t\tthis.policies = { ...this.policies, storageOnly: true };\n\t\t\t\t\t\t\tthrow new DeltaStreamConnectionForbiddenError(\n\t\t\t\t\t\t\t\t`Storage-only due to ${code}`,\n\t\t\t\t\t\t\t\t{ driverVersion },\n\t\t\t\t\t\t\t\tcode,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t\tthis._relayServiceTenantAndSessionId = `${response.tenantId}/${response.id}`;\n\t\treturn response;\n\t}\n\n\tprivate async joinSessionCore(\n\t\trequestSocketToken: boolean,\n\t\toptions: TokenFetchOptionsEx,\n\t\tisRefreshingJoinSession: boolean,\n\t\tdisplayName: string | undefined,\n\t): Promise<ISocketStorageDiscovery> {\n\t\tconst disableJoinSessionRefresh = this.mc.config.getBoolean(\n\t\t\t\"Fluid.Driver.Odsp.disableJoinSessionRefresh\",\n\t\t);\n\t\tconst executeFetch = async (): Promise<{\n\t\t\tentryTime: number;\n\t\t\tjoinSessionResponse: ISocketStorageDiscovery;\n\t\t}> => {\n\t\t\tconst joinSessionResponse = await fetchJoinSession(\n\t\t\t\tthis.odspResolvedUrl,\n\t\t\t\t\"opStream/joinSession\",\n\t\t\t\t\"POST\",\n\t\t\t\tthis.mc.logger,\n\t\t\t\tthis.getAuthHeader,\n\t\t\t\tthis.epochTracker,\n\t\t\t\trequestSocketToken,\n\t\t\t\toptions,\n\t\t\t\tdisableJoinSessionRefresh,\n\t\t\t\tisRefreshingJoinSession,\n\t\t\t\tdisplayName,\n\t\t\t);\n\t\t\t// Emit event only in case it is fetched from the network.\n\t\t\tif (joinSessionResponse.sensitivityLabelsInfo !== undefined) {\n\t\t\t\tthis.emitSensitivityLabelUpdateEvent(joinSessionResponse.sensitivityLabelsInfo);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tentryTime: Date.now(),\n\t\t\t\tjoinSessionResponse,\n\t\t\t};\n\t\t};\n\n\t\tconst getResponseAndRefreshAfterDeltaMs = async (): Promise<{\n\t\t\trefreshAfterDeltaMs: number;\n\t\t\tentryTime: number;\n\t\t\tjoinSessionResponse: ISocketStorageDiscovery;\n\t\t}> => {\n\t\t\tconst _response = await this.cache.sessionJoinCache.addOrGet(\n\t\t\t\tthis.joinSessionKey,\n\t\t\t\texecuteFetch,\n\t\t\t);\n\t\t\t// If the response does not contain refreshSessionDurationSeconds, then treat it as old flow and let the\n\t\t\t// cache entry to be treated as expired after 1 hour.\n\t\t\t_response.joinSessionResponse.refreshSessionDurationSeconds =\n\t\t\t\t_response.joinSessionResponse.refreshSessionDurationSeconds ?? 3600;\n\t\t\treturn {\n\t\t\t\t..._response,\n\t\t\t\trefreshAfterDeltaMs: this.calculateJoinSessionRefreshDelta(\n\t\t\t\t\t_response.entryTime,\n\t\t\t\t\t_response.joinSessionResponse.refreshSessionDurationSeconds,\n\t\t\t\t),\n\t\t\t};\n\t\t};\n\t\tlet response = await getResponseAndRefreshAfterDeltaMs();\n\t\t// This means that the cached entry has expired(This should not be possible if the response is fetched\n\t\t// from the network call). In this case we remove the cached entry and fetch the new response.\n\t\tif (response.refreshAfterDeltaMs <= 0) {\n\t\t\tthis.cache.sessionJoinCache.remove(this.joinSessionKey);\n\t\t\tresponse = await getResponseAndRefreshAfterDeltaMs();\n\t\t}\n\t\tif (!disableJoinSessionRefresh) {\n\t\t\tconst props = {\n\t\t\t\tentryTime: response.entryTime,\n\t\t\t\trefreshSessionDurationSeconds:\n\t\t\t\t\tresponse.joinSessionResponse.refreshSessionDurationSeconds,\n\t\t\t\trefreshAfterDeltaMs: response.refreshAfterDeltaMs,\n\t\t\t};\n\t\t\tif (response.refreshAfterDeltaMs > 0) {\n\t\t\t\tthis.scheduleJoinSessionRefresh(\n\t\t\t\t\tresponse.refreshAfterDeltaMs,\n\t\t\t\t\trequestSocketToken,\n\t\t\t\t\tthis.currentConnection?.clientId,\n\t\t\t\t\tdisplayName,\n\t\t\t\t).catch((error) => {\n\t\t\t\t\t// Log the error and do nothing as the reconnection would fetch the join session.\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"JoinSessionRefreshError\",\n\t\t\t\t\t\t\tdetails: JSON.stringify(props),\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Logging just for informational purposes to help with debugging as this is a new feature.\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"JoinSessionRefreshNotScheduled\",\n\t\t\t\t\tdetails: JSON.stringify(props),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn response.joinSessionResponse;\n\t}\n\n\tprivate emitSensitivityLabelUpdateEvent(\n\t\tsensitivityLabelsInfo: ISensitivityLabelsInfo,\n\t): void {\n\t\tconst createdTimestamp = sensitivityLabelsInfo.timestamp;\n\t\tassert(\n\t\t\ttypeof createdTimestamp === \"number\" && createdTimestamp > 0,\n\t\t\t0x8e0 /* time should be a positive number */,\n\t\t);\n\t\tif (createdTimestamp > this.labelUpdateTimestamp) {\n\t\t\tthis.labelUpdateTimestamp = createdTimestamp;\n\t\t\tthis.metadataUpdateHandler({\n\t\t\t\tsensitivityLabelsInfo: JSON.stringify(sensitivityLabelsInfo),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate calculateJoinSessionRefreshDelta(\n\t\tresponseFetchTime: number,\n\t\trefreshSessionDurationSeconds: number,\n\t): number {\n\t\t// 30 seconds is buffer time to refresh the session.\n\t\treturn responseFetchTime + (refreshSessionDurationSeconds * 1000 - 30000) - Date.now();\n\t}\n\n\t/**\n\t * Creates a connection to the given delta stream endpoint\n\t *\n\t * @param tenantId - the ID of the tenant\n\t * @param documentId - document ID\n\t * @param token - authorization token for delta service\n\t * @param client - information about the client\n\t * @param webSocketUrl - websocket URL\n\t * @param connectionId - connection ID for the connection\n\t */\n\tprivate async createDeltaConnection(\n\t\ttenantId: string,\n\t\tdocumentId: string,\n\t\ttoken: string | null,\n\t\tclient: IClient,\n\t\twebSocketUrl: string,\n\t\tconnectionId: string,\n\t): Promise<OdspDocumentDeltaConnection> {\n\t\tconst startTime = performanceNow();\n\t\tconst connection = await OdspDocumentDeltaConnection.create(\n\t\t\ttenantId,\n\t\t\tdocumentId,\n\t\t\ttoken,\n\t\t\tclient,\n\t\t\twebSocketUrl,\n\t\t\tthis.mc.logger,\n\t\t\t60000,\n\t\t\tthis.epochTracker,\n\t\t\tthis.socketReferenceKeyPrefix,\n\t\t\tconnectionId,\n\t\t);\n\t\tconst duration = performanceNow() - startTime;\n\t\t// This event happens rather often, so it adds up to cost of telemetry.\n\t\t// Given that most reconnects result in reusing socket and happen very quickly,\n\t\t// report event only if it took longer than threshold.\n\t\tif (duration >= 2000) {\n\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"ConnectionSuccess\",\n\t\t\t\tduration,\n\t\t\t});\n\t\t}\n\t\treturn connection;\n\t}\n\n\tpublic dispose(error?: unknown): void {\n\t\tthis.clearJoinSessionTimer();\n\t\tthis.currentConnection?.dispose();\n\t\tthis.currentConnection = undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"odspDelayLoadedDeltaStream.js","sourceRoot":"","sources":["../src/odspDelayLoadedDeltaStream.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 { performanceNow } from \"@fluid-internal/client-utils\";\nimport type { ISignalEnvelope } from \"@fluidframework/core-interfaces/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IClient } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIDocumentDeltaConnection,\n\tIDocumentServicePolicies,\n\tIResolvedUrl,\n\tIAnyDriverError,\n\tISequencedDocumentMessage,\n\tISignalMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tDeltaStreamConnectionForbiddenError,\n\tNonRetryableError,\n} from \"@fluidframework/driver-utils/internal\";\nimport { hasFacetCodes } from \"@fluidframework/odsp-doclib-utils/internal\";\nimport {\n\ttype HostStoragePolicy,\n\ttype IOdspError,\n\ttype IOdspResolvedUrl,\n\ttype ISocketStorageDiscovery,\n\ttype ISensitivityLabelsInfo,\n\ttype InstrumentedStorageTokenFetcher,\n\tOdspErrorTypes,\n\ttype TokenFetchOptions,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\ttype IFluidErrorBase,\n\ttype MonitoringContext,\n\tnormalizeError,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { policyLabelsUpdatesSignalType } from \"./contracts.js\";\nimport type { EpochTracker } from \"./epochTracker.js\";\nimport type { IOdspCache } from \"./odspCache.js\";\nimport { OdspDocumentDeltaConnection } from \"./odspDocumentDeltaConnection.js\";\nimport {\n\ttype TokenFetchOptionsEx,\n\tgetJoinSessionCacheKey,\n\tgetWithRetryForTokenRefresh,\n} from \"./odspUtils.js\";\nimport { pkgVersion as driverVersion } from \"./packageVersion.js\";\nimport { fetchJoinSession } from \"./vroom.js\";\n\n/**\n * This OdspDelayLoadedDeltaStream is used by OdspDocumentService.ts to delay load the delta connection\n * as they are not on critical path of loading a container.\n */\nexport class OdspDelayLoadedDeltaStream {\n\t// Timer which runs and executes the join session call after intervals.\n\tprivate joinSessionRefreshTimer: ReturnType<typeof setTimeout> | undefined;\n\n\tprivate readonly joinSessionKey: string;\n\n\tprivate currentConnection?: OdspDocumentDeltaConnection;\n\n\tprivate _relayServiceTenantAndSessionId: string | undefined;\n\n\tprivate firstConnectionAttempt = true;\n\n\t// Tracks the time at which the Policy Labels were updated the last time. This is used to resolve race conditions\n\t// between label updates from the join session and the Fluid signals and they could have same or different timestamps.\n\t// So this timestamp is updated with timestamp from the service/signals with the most recent timestamp. We could also\n\t// receive stale data from join session as that call is made at intervals, so we need to update with only most recent data.\n\tprivate labelUpdateTimestamp: number = -1;\n\n\t/**\n\t * @param odspResolvedUrl - resolved url identifying document that will be managed by this service instance.\n\t * @param policies - Document service policies.\n\t * @param getAuthHeader - function that can provide the Authentication header value. 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 mc - a logger that can capture performance and diagnostic information\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 opsReceived - To register the ops received through socket.\n\t * @param socketReferenceKeyPrefix - (optional) prefix to isolate socket reuse cache\n\t */\n\tpublic constructor(\n\t\tpublic readonly odspResolvedUrl: IOdspResolvedUrl,\n\t\tpublic policies: IDocumentServicePolicies,\n\t\tprivate readonly getAuthHeader: InstrumentedStorageTokenFetcher,\n\t\tprivate readonly getWebsocketToken:\n\t\t\t| ((options: TokenFetchOptions) => Promise<string | null>)\n\t\t\t| undefined,\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly cache: IOdspCache,\n\t\tprivate readonly hostPolicy: HostStoragePolicy,\n\t\tprivate readonly epochTracker: EpochTracker,\n\t\tprivate readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,\n\t\tprivate readonly metadataUpdateHandler: (metadata: Record<string, string>) => void,\n\t\tprivate readonly socketReferenceKeyPrefix?: string,\n\t) {\n\t\tthis.joinSessionKey = getJoinSessionCacheKey(this.odspResolvedUrl);\n\t}\n\n\tpublic get resolvedUrl(): IResolvedUrl {\n\t\treturn this.odspResolvedUrl;\n\t}\n\n\tpublic get currentDeltaConnection(): OdspDocumentDeltaConnection | undefined {\n\t\treturn this.currentConnection;\n\t}\n\n\tpublic get relayServiceTenantAndSessionId(): string | undefined {\n\t\treturn this._relayServiceTenantAndSessionId;\n\t}\n\n\t/**\n\t * Annotate the given error indicating which connection step failed\n\t */\n\tprivate annotateConnectionError(\n\t\terror: unknown,\n\t\tfailedConnectionStep: string,\n\t\tseparateTokenRequest: boolean,\n\t): IFluidErrorBase {\n\t\treturn normalizeError(error, {\n\t\t\tprops: {\n\t\t\t\tfailedConnectionStep,\n\t\t\t\tseparateTokenRequest,\n\t\t\t},\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\tassert(\n\t\t\tthis.currentConnection === undefined,\n\t\t\t0x4ad /* Should not be called when connection is already present! */,\n\t\t);\n\t\t// Attempt to connect twice, in case we used expired token.\n\t\treturn getWithRetryForTokenRefresh<IDocumentDeltaConnection>(async (options) => {\n\t\t\t// Presence of getWebsocketToken callback dictates whether callback is used for fetching\n\t\t\t// websocket token or whether it is returned with joinSession response payload\n\t\t\tconst requestWebsocketTokenFromJoinSession = this.getWebsocketToken === undefined;\n\t\t\tconst websocketTokenPromise = requestWebsocketTokenFromJoinSession\n\t\t\t\t? // eslint-disable-next-line unicorn/no-null\n\t\t\t\t\tPromise.resolve(null)\n\t\t\t\t: this.getWebsocketToken(options);\n\n\t\t\tconst annotateAndRethrowConnectionError = (step: string) => (error: unknown) => {\n\t\t\t\tthrow this.annotateConnectionError(error, step, !requestWebsocketTokenFromJoinSession);\n\t\t\t};\n\n\t\t\t// Log telemetry for join session attempt\n\t\t\tif (this.firstConnectionAttempt) {\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"FirstJoinSessionAttemptDetails\",\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\trequestWebsocketToken: requestWebsocketTokenFromJoinSession,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst joinSessionPromise = this.joinSession(\n\t\t\t\trequestWebsocketTokenFromJoinSession,\n\t\t\t\toptions,\n\t\t\t\tfalse /* isRefreshingJoinSession */,\n\t\t\t\tundefined /* clientId */,\n\t\t\t\tthis.hostPolicy.sessionOptions?.displayName,\n\t\t\t);\n\t\t\tconst [websocketEndpoint, websocketToken] = await Promise.all([\n\t\t\t\tjoinSessionPromise.catch(annotateAndRethrowConnectionError(\"joinSession\")),\n\t\t\t\twebsocketTokenPromise.catch(annotateAndRethrowConnectionError(\"getWebsocketToken\")),\n\t\t\t]);\n\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tconst finalWebsocketToken = websocketToken ?? websocketEndpoint.socketToken ?? null;\n\t\t\tif (finalWebsocketToken === null) {\n\t\t\t\tthrow this.annotateConnectionError(\n\t\t\t\t\tnew NonRetryableError(\"Websocket token is null\", OdspErrorTypes.fetchTokenError, {\n\t\t\t\t\t\tdriverVersion,\n\t\t\t\t\t}),\n\t\t\t\t\t\"getWebsocketToken\",\n\t\t\t\t\t!requestWebsocketTokenFromJoinSession,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (websocketEndpoint.sensitivityLabelsInfo !== undefined) {\n\t\t\t\tthis.emitSensitivityLabelUpdateEvent(websocketEndpoint.sensitivityLabelsInfo);\n\t\t\t}\n\n\t\t\tconst connectionId = uuid();\n\t\t\tif (this.firstConnectionAttempt) {\n\t\t\t\tthis.firstConnectionAttempt = false;\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"FirstConnectionAttemptDetails\",\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tconnectionId,\n\t\t\t\t\t\ttenantId: websocketEndpoint.tenantId,\n\t\t\t\t\t\tdocumentId: websocketEndpoint.id,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst connection = await this.createDeltaConnection(\n\t\t\t\t\twebsocketEndpoint.tenantId,\n\t\t\t\t\twebsocketEndpoint.id,\n\t\t\t\t\tfinalWebsocketToken,\n\t\t\t\t\tclient,\n\t\t\t\t\twebsocketEndpoint.deltaStreamSocketUrl,\n\t\t\t\t\tconnectionId,\n\t\t\t\t);\n\t\t\t\tconnection.on(\"op\", (documentId, ops: ISequencedDocumentMessage[]) => {\n\t\t\t\t\tthis.opsReceived(ops);\n\t\t\t\t});\n\t\t\t\tconnection.on(\"signal\", this.signalHandler);\n\t\t\t\t// Also process the initial signals\n\t\t\t\tthis.signalHandler(connection.initialSignals);\n\t\t\t\t// On disconnect with 401/403 error code, we can just clear the joinSession cache as we will again\n\t\t\t\t// get the auth error on reconnecting and face latency.\n\t\t\t\tconnection.once(\"disconnect\", (error: unknown) => {\n\t\t\t\t\t// Clear the join session refresh timer so that it can be restarted on reconnection.\n\t\t\t\t\tthis.clearJoinSessionTimer();\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\t\t\terror !== null &&\n\t\t\t\t\t\t(error as Partial<IOdspError>).errorType === OdspErrorTypes.authorizationError\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.cache.sessionJoinCache.remove(this.joinSessionKey);\n\t\t\t\t\t}\n\t\t\t\t\t// If we hit this assert, it means that \"disconnect\" event is emitted before the connection went through\n\t\t\t\t\t// dispose flow which is not correct and could lead to a bunch of errors.\n\t\t\t\t\tassert(connection.disposed, 0x4ae /* Connection should be disposed by now */);\n\t\t\t\t\tthis.currentConnection = undefined;\n\t\t\t\t});\n\t\t\t\tthis.currentConnection = connection;\n\t\t\t\treturn connection;\n\t\t\t} catch (error) {\n\t\t\t\t// Remove join session information from cache only if it is an error is from socket event connect_document_error.\n\t\t\t\t// Otherwise keep it in cache so that this session can be re-used after disconnection.\n\t\t\t\t// Also keeping an undefined check here to account for any unknown code path that is unable to stamp the value as in that case also\n\t\t\t\t// it is safer to clear join session cache and start over.\n\t\t\t\tif (\n\t\t\t\t\terror &&\n\t\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\t\t((error as IAnyDriverError).scenarioName === \"connect_document_error\" ||\n\t\t\t\t\t\t(error as IAnyDriverError).scenarioName === undefined)\n\t\t\t\t) {\n\t\t\t\t\tthis.clearJoinSessionTimer();\n\t\t\t\t\tthis.cache.sessionJoinCache.remove(this.joinSessionKey);\n\t\t\t\t}\n\t\t\t\tconst normalizedError = this.annotateConnectionError(\n\t\t\t\t\terror,\n\t\t\t\t\t\"createDeltaConnection\",\n\t\t\t\t\t!requestWebsocketTokenFromJoinSession,\n\t\t\t\t);\n\t\t\t\tif (typeof error === \"object\" && error !== null) {\n\t\t\t\t\tnormalizedError.addTelemetryProperties({\n\t\t\t\t\t\tsocketDocumentId: websocketEndpoint.id,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthrow normalizedError;\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate readonly signalHandler = (signalsArg: ISignalMessage | ISignalMessage[]): void => {\n\t\tconst signals = Array.isArray(signalsArg) ? signalsArg : [signalsArg];\n\t\tfor (const signal of signals) {\n\t\t\t// Make sure it is not for a specific client as `PolicyLabelsUpdate` is meant for all clients.\n\t\t\tif (signal.clientId === null) {\n\t\t\t\t// We could have some issues/irregularities in parsing signals, so put it in try/catch block\n\t\t\t\t// and ignore the error as we can have labels update later on through join session response.\n\t\t\t\tlet envelope: ISignalEnvelope | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tenvelope = JSON.parse(signal.content as string) as ISignalEnvelope;\n\t\t\t\t} catch {\n\t\t\t\t\t// Drop error\n\t\t\t\t}\n\t\t\t\tif (envelope?.contents?.type === policyLabelsUpdatesSignalType) {\n\t\t\t\t\tthis.emitSensitivityLabelUpdateEvent(\n\t\t\t\t\t\tenvelope.contents.content as ISensitivityLabelsInfo,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate clearJoinSessionTimer(): void {\n\t\tif (this.joinSessionRefreshTimer !== undefined) {\n\t\t\tclearTimeout(this.joinSessionRefreshTimer);\n\t\t\tthis.joinSessionRefreshTimer = undefined;\n\t\t}\n\t}\n\n\tprivate async scheduleJoinSessionRefresh(\n\t\tdelta: number,\n\t\trequestSocketToken: boolean,\n\t\tclientId: string | undefined,\n\t\tdisplayName: string | undefined,\n\t): Promise<void> {\n\t\tif (this.joinSessionRefreshTimer !== undefined) {\n\t\t\tthis.clearJoinSessionTimer();\n\t\t\t// TODO: use a stronger type\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(Error as any).stackTraceLimit = 50;\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"DuplicateJoinSessionRefresh\",\n\t\t\t\t},\n\t\t\t\tnew Error(\"DuplicateJoinSessionRefresh\"),\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\t}\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tthis.joinSessionRefreshTimer = setTimeout(() => {\n\t\t\t\tthis.clearJoinSessionTimer();\n\t\t\t\t// Clear the timer as it is going to be scheduled again as part of refreshing join session.\n\t\t\t\tgetWithRetryForTokenRefresh(async (options) => {\n\t\t\t\t\tawait this.joinSession(\n\t\t\t\t\t\trequestSocketToken,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\ttrue /* isRefreshingJoinSession */,\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t\tdisplayName,\n\t\t\t\t\t);\n\t\t\t\t\tresolve();\n\t\t\t\t}).catch((error) => {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n\t\t\t\t\treject(error);\n\t\t\t\t});\n\t\t\t}, delta);\n\t\t});\n\t}\n\n\tprivate async joinSession(\n\t\trequestSocketToken: boolean,\n\t\toptions: TokenFetchOptionsEx,\n\t\tisRefreshingJoinSession: boolean,\n\t\tclientId: string | undefined,\n\t\tdisplayName: string | undefined,\n\t): Promise<ISocketStorageDiscovery> {\n\t\t// If this call is to refresh the join session for the current connection but we are already disconnected in\n\t\t// the meantime or disconnected and then reconnected then do not make the call. However, we should not have\n\t\t// come here if that is the case because timer should have been disposed, but due to race condition with the\n\t\t// timer we should not make the call and throw error.\n\t\tif (\n\t\t\tisRefreshingJoinSession &&\n\t\t\t(this.currentConnection === undefined ||\n\t\t\t\t(clientId !== undefined && this.currentConnection.clientId !== clientId))\n\t\t) {\n\t\t\tthis.clearJoinSessionTimer();\n\t\t\tthrow new NonRetryableError(\n\t\t\t\t\"JoinSessionRefreshTimerNotCancelled\",\n\t\t\t\tOdspErrorTypes.genericError,\n\t\t\t\t{\n\t\t\t\t\tdriverVersion,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tschedulerClientId: clientId,\n\t\t\t\t\t\tcurrentClientId: this.currentConnection?.clientId,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tconst response = await this.joinSessionCore(\n\t\t\trequestSocketToken,\n\t\t\toptions,\n\t\t\tisRefreshingJoinSession,\n\t\t\tdisplayName,\n\t\t).catch((error) => {\n\t\t\tif (hasFacetCodes(error) && error.facetCodes !== undefined) {\n\t\t\t\tfor (const code of error.facetCodes) {\n\t\t\t\t\tswitch (code) {\n\t\t\t\t\t\tcase \"sessionForbidden\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnPreservedFiles\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnModerationEnabledLibrary\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnRequireCheckout\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnCheckoutFile\":\n\t\t\t\t\t\tcase \"sessionForbiddenOnInvisibleMinorVersion\": {\n\t\t\t\t\t\t\t// This document can only be opened in storage-only mode.\n\t\t\t\t\t\t\t// DeltaManager will recognize this error\n\t\t\t\t\t\t\t// and load without a delta stream connection.\n\t\t\t\t\t\t\tthis.policies = { ...this.policies, storageOnly: true };\n\t\t\t\t\t\t\tthrow new DeltaStreamConnectionForbiddenError(\n\t\t\t\t\t\t\t\t`Storage-only due to ${code}`,\n\t\t\t\t\t\t\t\t{ driverVersion },\n\t\t\t\t\t\t\t\tcode,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\t\tthis._relayServiceTenantAndSessionId = `${response.tenantId}/${response.id}`;\n\t\treturn response;\n\t}\n\n\tprivate async joinSessionCore(\n\t\trequestSocketToken: boolean,\n\t\toptions: TokenFetchOptionsEx,\n\t\tisRefreshingJoinSession: boolean,\n\t\tdisplayName: string | undefined,\n\t): Promise<ISocketStorageDiscovery> {\n\t\tconst disableJoinSessionRefresh = this.mc.config.getBoolean(\n\t\t\t\"Fluid.Driver.Odsp.disableJoinSessionRefresh\",\n\t\t);\n\t\tconst executeFetch = async (): Promise<{\n\t\t\tentryTime: number;\n\t\t\tjoinSessionResponse: ISocketStorageDiscovery;\n\t\t}> => {\n\t\t\tconst joinSessionResponse = await fetchJoinSession(\n\t\t\t\tthis.odspResolvedUrl,\n\t\t\t\t\"opStream/joinSession\",\n\t\t\t\t\"POST\",\n\t\t\t\tthis.mc.logger,\n\t\t\t\tthis.getAuthHeader,\n\t\t\t\tthis.epochTracker,\n\t\t\t\trequestSocketToken,\n\t\t\t\toptions,\n\t\t\t\tdisableJoinSessionRefresh,\n\t\t\t\tisRefreshingJoinSession,\n\t\t\t\tdisplayName,\n\t\t\t);\n\t\t\t// Emit event only in case it is fetched from the network.\n\t\t\tif (joinSessionResponse.sensitivityLabelsInfo !== undefined) {\n\t\t\t\tthis.emitSensitivityLabelUpdateEvent(joinSessionResponse.sensitivityLabelsInfo);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tentryTime: Date.now(),\n\t\t\t\tjoinSessionResponse,\n\t\t\t};\n\t\t};\n\n\t\tconst getResponseAndRefreshAfterDeltaMs = async (): Promise<{\n\t\t\trefreshAfterDeltaMs: number;\n\t\t\tentryTime: number;\n\t\t\tjoinSessionResponse: ISocketStorageDiscovery;\n\t\t}> => {\n\t\t\tconst _response = await this.cache.sessionJoinCache.addOrGet(\n\t\t\t\tthis.joinSessionKey,\n\t\t\t\texecuteFetch,\n\t\t\t);\n\t\t\t// If the response does not contain refreshSessionDurationSeconds, then treat it as old flow and let the\n\t\t\t// cache entry to be treated as expired after 1 hour.\n\t\t\t_response.joinSessionResponse.refreshSessionDurationSeconds =\n\t\t\t\t_response.joinSessionResponse.refreshSessionDurationSeconds ?? 3600;\n\t\t\treturn {\n\t\t\t\t..._response,\n\t\t\t\trefreshAfterDeltaMs: this.calculateJoinSessionRefreshDelta(\n\t\t\t\t\t_response.entryTime,\n\t\t\t\t\t_response.joinSessionResponse.refreshSessionDurationSeconds,\n\t\t\t\t),\n\t\t\t};\n\t\t};\n\t\tlet response = await getResponseAndRefreshAfterDeltaMs();\n\t\t// This means that the cached entry has expired(This should not be possible if the response is fetched\n\t\t// from the network call). In this case we remove the cached entry and fetch the new response.\n\t\tif (response.refreshAfterDeltaMs <= 0) {\n\t\t\tthis.cache.sessionJoinCache.remove(this.joinSessionKey);\n\t\t\tresponse = await getResponseAndRefreshAfterDeltaMs();\n\t\t}\n\t\tif (!disableJoinSessionRefresh) {\n\t\t\tconst props = {\n\t\t\t\tentryTime: response.entryTime,\n\t\t\t\trefreshSessionDurationSeconds:\n\t\t\t\t\tresponse.joinSessionResponse.refreshSessionDurationSeconds,\n\t\t\t\trefreshAfterDeltaMs: response.refreshAfterDeltaMs,\n\t\t\t};\n\t\t\tif (response.refreshAfterDeltaMs > 0) {\n\t\t\t\tthis.scheduleJoinSessionRefresh(\n\t\t\t\t\tresponse.refreshAfterDeltaMs,\n\t\t\t\t\trequestSocketToken,\n\t\t\t\t\tthis.currentConnection?.clientId,\n\t\t\t\t\tdisplayName,\n\t\t\t\t).catch((error) => {\n\t\t\t\t\t// Log the error and do nothing as the reconnection would fetch the join session.\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"JoinSessionRefreshError\",\n\t\t\t\t\t\t\tdetails: JSON.stringify(props),\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Logging just for informational purposes to help with debugging as this is a new feature.\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"JoinSessionRefreshNotScheduled\",\n\t\t\t\t\tdetails: JSON.stringify(props),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn response.joinSessionResponse;\n\t}\n\n\tprivate emitSensitivityLabelUpdateEvent(\n\t\tsensitivityLabelsInfo: ISensitivityLabelsInfo,\n\t): void {\n\t\tconst createdTimestamp = sensitivityLabelsInfo.timestamp;\n\t\tassert(\n\t\t\ttypeof createdTimestamp === \"number\" && createdTimestamp > 0,\n\t\t\t0x8e0 /* time should be a positive number */,\n\t\t);\n\t\tif (createdTimestamp > this.labelUpdateTimestamp) {\n\t\t\tthis.labelUpdateTimestamp = createdTimestamp;\n\t\t\tthis.metadataUpdateHandler({\n\t\t\t\tsensitivityLabelsInfo: JSON.stringify(sensitivityLabelsInfo),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate calculateJoinSessionRefreshDelta(\n\t\tresponseFetchTime: number,\n\t\trefreshSessionDurationSeconds: number,\n\t): number {\n\t\t// 30 seconds is buffer time to refresh the session.\n\t\treturn responseFetchTime + (refreshSessionDurationSeconds * 1000 - 30000) - Date.now();\n\t}\n\n\t/**\n\t * Creates a connection to the given delta stream endpoint\n\t *\n\t * @param tenantId - the ID of the tenant\n\t * @param documentId - document ID\n\t * @param token - authorization token for delta service\n\t * @param client - information about the client\n\t * @param webSocketUrl - websocket URL\n\t * @param connectionId - connection ID for the connection\n\t */\n\tprivate async createDeltaConnection(\n\t\ttenantId: string,\n\t\tdocumentId: string,\n\t\ttoken: string | null,\n\t\tclient: IClient,\n\t\twebSocketUrl: string,\n\t\tconnectionId: string,\n\t): Promise<OdspDocumentDeltaConnection> {\n\t\tconst startTime = performanceNow();\n\t\tconst connection = await OdspDocumentDeltaConnection.create(\n\t\t\ttenantId,\n\t\t\tdocumentId,\n\t\t\ttoken,\n\t\t\tclient,\n\t\t\twebSocketUrl,\n\t\t\tthis.mc.logger,\n\t\t\t60000,\n\t\t\tthis.epochTracker,\n\t\t\tthis.socketReferenceKeyPrefix,\n\t\t\tconnectionId,\n\t\t);\n\t\tconst duration = performanceNow() - startTime;\n\t\t// This event happens rather often, so it adds up to cost of telemetry.\n\t\t// Given that most reconnects result in reusing socket and happen very quickly,\n\t\t// report event only if it took longer than threshold.\n\t\tif (duration >= 2000) {\n\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"ConnectionSuccess\",\n\t\t\t\tduration,\n\t\t\t});\n\t\t}\n\t\treturn connection;\n\t}\n\n\tpublic dispose(error?: unknown): void {\n\t\tthis.clearJoinSessionTimer();\n\t\tthis.currentConnection?.dispose();\n\t\tdelete this.currentConnection;\n\t}\n}\n"]}