@fluidframework/odsp-driver 0.59.2001 → 0.59.3000

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 (165) hide show
  1. package/.eslintrc.js +0 -1
  2. package/dist/ReadBufferUtils.js +2 -2
  3. package/dist/ReadBufferUtils.js.map +1 -1
  4. package/dist/WriteBufferUtils.js +14 -14
  5. package/dist/WriteBufferUtils.js.map +1 -1
  6. package/dist/checkUrl.js +1 -1
  7. package/dist/checkUrl.js.map +1 -1
  8. package/dist/compactSnapshotParser.js +27 -27
  9. package/dist/compactSnapshotParser.js.map +1 -1
  10. package/dist/compactSnapshotWriter.js +15 -15
  11. package/dist/compactSnapshotWriter.js.map +1 -1
  12. package/dist/contracts.d.ts +0 -1
  13. package/dist/contracts.d.ts.map +1 -1
  14. package/dist/contracts.js.map +1 -1
  15. package/dist/createFile.js +15 -15
  16. package/dist/createFile.js.map +1 -1
  17. package/dist/createNewUtils.js +4 -4
  18. package/dist/createNewUtils.js.map +1 -1
  19. package/dist/epochTracker.d.ts.map +1 -1
  20. package/dist/epochTracker.js +11 -11
  21. package/dist/epochTracker.js.map +1 -1
  22. package/dist/fetch.js +1 -1
  23. package/dist/fetch.js.map +1 -1
  24. package/dist/fetchSnapshot.d.ts.map +1 -1
  25. package/dist/fetchSnapshot.js +19 -19
  26. package/dist/fetchSnapshot.js.map +1 -1
  27. package/dist/getFileLink.js +19 -19
  28. package/dist/getFileLink.js.map +1 -1
  29. package/dist/getQueryString.d.ts.map +1 -1
  30. package/dist/getQueryString.js.map +1 -1
  31. package/dist/getUrlAndHeadersWithAuth.d.ts.map +1 -1
  32. package/dist/getUrlAndHeadersWithAuth.js.map +1 -1
  33. package/dist/odspCache.d.ts.map +1 -1
  34. package/dist/odspCache.js.map +1 -1
  35. package/dist/odspDeltaStorageService.d.ts.map +1 -1
  36. package/dist/odspDeltaStorageService.js +5 -5
  37. package/dist/odspDeltaStorageService.js.map +1 -1
  38. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  39. package/dist/odspDocumentDeltaConnection.js +12 -12
  40. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  41. package/dist/odspDocumentService.js +9 -8
  42. package/dist/odspDocumentService.js.map +1 -1
  43. package/dist/odspDocumentServiceFactory.js +1 -1
  44. package/dist/odspDocumentServiceFactory.js.map +1 -1
  45. package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  46. package/dist/odspDocumentServiceFactoryCore.js +20 -12
  47. package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
  48. package/dist/odspDocumentStorageManager.d.ts +1 -0
  49. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  50. package/dist/odspDocumentStorageManager.js +34 -32
  51. package/dist/odspDocumentStorageManager.js.map +1 -1
  52. package/dist/odspDriverUrlResolver.js +10 -10
  53. package/dist/odspDriverUrlResolver.js.map +1 -1
  54. package/dist/odspDriverUrlResolverForShareLink.js +10 -10
  55. package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
  56. package/dist/odspError.d.ts +1 -1
  57. package/dist/odspError.d.ts.map +1 -1
  58. package/dist/odspError.js +1 -1
  59. package/dist/odspError.js.map +1 -1
  60. package/dist/odspFluidFileLink.js +2 -2
  61. package/dist/odspFluidFileLink.js.map +1 -1
  62. package/dist/odspPublicUtils.js +1 -1
  63. package/dist/odspPublicUtils.js.map +1 -1
  64. package/dist/odspSnapshotParser.js +3 -3
  65. package/dist/odspSnapshotParser.js.map +1 -1
  66. package/dist/odspSummaryUploadManager.js +7 -7
  67. package/dist/odspSummaryUploadManager.js.map +1 -1
  68. package/dist/odspUtils.js +9 -9
  69. package/dist/odspUtils.js.map +1 -1
  70. package/dist/opsCaching.js.map +1 -1
  71. package/dist/packageVersion.d.ts +1 -1
  72. package/dist/packageVersion.js +1 -1
  73. package/dist/packageVersion.js.map +1 -1
  74. package/dist/prefetchLatestSnapshot.js +7 -7
  75. package/dist/prefetchLatestSnapshot.js.map +1 -1
  76. package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
  77. package/dist/retryErrorsStorageAdapter.js +1 -1
  78. package/dist/retryErrorsStorageAdapter.js.map +1 -1
  79. package/dist/retryUtils.js +4 -4
  80. package/dist/retryUtils.js.map +1 -1
  81. package/dist/vroom.js +3 -3
  82. package/dist/vroom.js.map +1 -1
  83. package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
  84. package/dist/zipItDataRepresentationUtils.js +21 -12
  85. package/dist/zipItDataRepresentationUtils.js.map +1 -1
  86. package/lib/WriteBufferUtils.js +1 -1
  87. package/lib/WriteBufferUtils.js.map +1 -1
  88. package/lib/compactSnapshotParser.js.map +1 -1
  89. package/lib/compactSnapshotWriter.js.map +1 -1
  90. package/lib/contracts.d.ts +0 -1
  91. package/lib/contracts.d.ts.map +1 -1
  92. package/lib/contracts.js.map +1 -1
  93. package/lib/createFile.js.map +1 -1
  94. package/lib/epochTracker.d.ts.map +1 -1
  95. package/lib/epochTracker.js +1 -1
  96. package/lib/epochTracker.js.map +1 -1
  97. package/lib/fetchSnapshot.d.ts.map +1 -1
  98. package/lib/fetchSnapshot.js.map +1 -1
  99. package/lib/getFileLink.js +6 -6
  100. package/lib/getFileLink.js.map +1 -1
  101. package/lib/getQueryString.d.ts.map +1 -1
  102. package/lib/getQueryString.js.map +1 -1
  103. package/lib/getUrlAndHeadersWithAuth.d.ts.map +1 -1
  104. package/lib/getUrlAndHeadersWithAuth.js.map +1 -1
  105. package/lib/odspCache.d.ts.map +1 -1
  106. package/lib/odspCache.js.map +1 -1
  107. package/lib/odspDeltaStorageService.d.ts.map +1 -1
  108. package/lib/odspDeltaStorageService.js.map +1 -1
  109. package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
  110. package/lib/odspDocumentDeltaConnection.js +1 -1
  111. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  112. package/lib/odspDocumentService.js +2 -1
  113. package/lib/odspDocumentService.js.map +1 -1
  114. package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  115. package/lib/odspDocumentServiceFactoryCore.js +10 -2
  116. package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
  117. package/lib/odspDocumentStorageManager.d.ts +1 -0
  118. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  119. package/lib/odspDocumentStorageManager.js +17 -15
  120. package/lib/odspDocumentStorageManager.js.map +1 -1
  121. package/lib/odspDriverUrlResolver.js +5 -5
  122. package/lib/odspDriverUrlResolver.js.map +1 -1
  123. package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
  124. package/lib/odspError.d.ts +1 -1
  125. package/lib/odspError.d.ts.map +1 -1
  126. package/lib/odspFluidFileLink.js.map +1 -1
  127. package/lib/odspSnapshotParser.js +1 -1
  128. package/lib/odspSnapshotParser.js.map +1 -1
  129. package/lib/odspUtils.js.map +1 -1
  130. package/lib/opsCaching.js.map +1 -1
  131. package/lib/packageVersion.d.ts +1 -1
  132. package/lib/packageVersion.js +1 -1
  133. package/lib/packageVersion.js.map +1 -1
  134. package/lib/retryErrorsStorageAdapter.d.ts.map +1 -1
  135. package/lib/retryErrorsStorageAdapter.js.map +1 -1
  136. package/lib/retryUtils.js +1 -1
  137. package/lib/retryUtils.js.map +1 -1
  138. package/lib/vroom.js.map +1 -1
  139. package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
  140. package/lib/zipItDataRepresentationUtils.js +12 -3
  141. package/lib/zipItDataRepresentationUtils.js.map +1 -1
  142. package/package.json +14 -13
  143. package/src/compactSnapshotParser.ts +2 -2
  144. package/src/contracts.ts +4 -5
  145. package/src/createFile.ts +2 -2
  146. package/src/epochTracker.ts +9 -10
  147. package/src/fetchSnapshot.ts +10 -10
  148. package/src/getFileLink.ts +10 -10
  149. package/src/getQueryString.ts +1 -1
  150. package/src/getUrlAndHeadersWithAuth.ts +1 -1
  151. package/src/odspCache.ts +2 -2
  152. package/src/odspDeltaStorageService.ts +4 -5
  153. package/src/odspDocumentDeltaConnection.ts +2 -2
  154. package/src/odspDocumentService.ts +5 -5
  155. package/src/odspDocumentServiceFactoryCore.ts +13 -1
  156. package/src/odspDocumentStorageManager.ts +25 -18
  157. package/src/odspDriverUrlResolver.ts +2 -2
  158. package/src/odspDriverUrlResolverForShareLink.ts +1 -1
  159. package/src/odspSnapshotParser.ts +2 -2
  160. package/src/odspUtils.ts +6 -6
  161. package/src/opsCaching.ts +2 -2
  162. package/src/packageVersion.ts +1 -1
  163. package/src/retryErrorsStorageAdapter.ts +1 -1
  164. package/src/vroom.ts +1 -1
  165. package/src/zipItDataRepresentationUtils.ts +15 -13
@@ -1 +1 @@
1
- {"version":3,"file":"fetchSnapshot.js","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, fromUtf8ToBase64, performance } from \"@fluidframework/common-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport {\n IOdspResolvedUrl,\n ISnapshotOptions,\n OdspErrorType,\n InstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { isSystemMessage } from \"@fluidframework/protocol-base\";\nimport { IOdspSnapshot, ISnapshotCachedEntry, IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { getQueryString } from \"./getQueryString\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n fetchAndParseAsJSONHelper,\n fetchHelper,\n getWithRetryForTokenRefresh,\n getWithRetryForTokenRefreshRepeat,\n IOdspResponse,\n ISnapshotContents,\n} from \"./odspUtils\";\nimport { convertOdspSnapshotToSnapsohtTreeAndBlobs } from \"./odspSnapshotParser\";\nimport { currentReadVersion, parseCompactSnapshotResponse } from \"./compactSnapshotParser\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { EpochTracker } from \"./epochTracker\";\n\n/**\n * Enum to support different types of snapshot formats.\n */\nexport enum SnapshotFormatSupportType {\n Json = 0,\n Binary = 1,\n JsonAndBinary = 2,\n}\n\n/**\n * Fetches a snapshot from the server with a given version id.\n * @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched\n * @param token - token used for authorization in the request\n * @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot\n * @param versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n snapshotUrl: string,\n token: string | null,\n versionId: string,\n fetchFullSnapshot: boolean,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (url: string, fetchOptions: {[index: string]: any}) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshotContents> {\n const path = `/trees/${versionId}`;\n let queryParams: ISnapshotOptions = {};\n\n if (fetchFullSnapshot) {\n if (versionId !== \"latest\") {\n queryParams = { channels: 1, blobs: 2 };\n } else {\n queryParams = { deltas: 1, channels: 1, blobs: 2 };\n }\n }\n\n const queryString = getQueryString(queryParams);\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${snapshotUrl}${path}${queryString}`, token, forceAccessTokenViaAuthorizationHeader);\n const response = await PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"fetchSnapshot\",\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n },\n async () => snapshotDownloader(url, { headers }),\n ) as IOdspResponse<IOdspSnapshot>;\n return convertOdspSnapshotToSnapsohtTreeAndBlobs(response.content);\n}\n\nexport async function fetchSnapshotWithRedeem(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n removeEntries: () => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if(sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n return fetchLatestSnapshotCore(\n odspResolvedUrl,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n enableRedeemFallback,\n ).catch(async (error) => {\n if (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n // Execute the redeem fallback\n logger.sendErrorEvent({\n eventName: \"RedeemFallback\",\n errorType: error.errorType,\n }, error);\n await redeemSharingLink(\n odspResolvedUrl, storageTokenFetcher, logger, forceAccessTokenViaAuthorizationHeader);\n const odspResolvedUrlWithoutShareLink: IOdspResolvedUrl =\n { ...odspResolvedUrl,\n shareLinkInfo: {\n ...odspResolvedUrl.shareLinkInfo,\n sharingLinkToRedeem: undefined,\n },\n };\n\n return fetchLatestSnapshotCore(\n odspResolvedUrlWithoutShareLink,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n );\n } else {\n throw error;\n }\n }).catch(async (error) => {\n // Clear the cache on 401/403/404 on snapshot fetch from network because this means either the user doesn't\n // have permissions for the file or it was deleted. So, if we do not clear cache, we will continue fetching\n // snapshot from cache in the future.\n if (typeof error === \"object\" && error !== null && error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError) {\n await removeEntries();\n }\n throw error;\n });\n}\n\nasync function redeemSharingLink(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n) {\n return PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"RedeemShareLink\",\n },\n async () => getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n assert(!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n 0x1ed /* \"Share link should be present\" */);\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"RedeemShareLink\");\n const encodedShareUrl = getEncodedShareUrl(odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem);\n const redeemUrl = `${odspResolvedUrl.siteUrl}/_api/v2.0/shares/${encodedShareUrl}`;\n const { url, headers } = getUrlAndHeadersWithAuth(\n redeemUrl, storageToken, forceAccessTokenViaAuthorizationHeader);\n headers.prefer = \"redeemSharingLink\";\n return fetchAndParseAsJSONHelper(url, { headers });\n }),\n );\n}\n\nasync function fetchLatestSnapshotCore(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n return getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"TreesLatest\", true);\n assert(storageToken !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\n let controller: AbortController | undefined;\n if (snapshotOptions?.timeout !== undefined) {\n controller = new AbortController();\n setTimeout(\n () => controller!.abort(),\n snapshotOptions.timeout,\n );\n }\n const perfEvent = {\n eventName: \"TreesLatest\",\n attempts: tokenFetchOptions.refresh ? 2 : 1,\n shareLinkPresent: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined,\n isSummarizer: odspResolvedUrl.summarizer,\n redeemFallbackEnabled: enableRedeemFallback,\n };\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n perfEvent[`snapshotOption_${key}`] = value;\n }\n });\n }\n // This event measures only successful cases of getLatest call (no tokens, no retries).\n return PerformanceEvent.timedExecAsync(\n logger,\n perfEvent,\n async (event) => {\n const response = await snapshotDownloader(\n odspResolvedUrl,\n storageToken,\n snapshotOptions,\n controller,\n );\n const snapshot = response.odspSnapshotResponse.content;\n // From: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming\n // fetchStart: immediately before the browser starts to fetch the resource.\n // requestStart: immediately before the browser starts requesting the resource from the server\n // responseStart: immediately after the browser receives the first byte of the response from the server.\n // responseEnd: immediately after the browser receives the last byte of the resource\n // or immediately before the transport connection is closed, whichever comes first.\n // secureConnectionStart: immediately before the browser starts the handshake process to secure the\n // current connection. If a secure connection is not used, this property returns zero.\n // startTime: Time when the resource fetch started. This value is equivalent to fetchStart.\n // domainLookupStart: immediately before the browser starts the domain name lookup for the resource.\n // domainLookupEnd: immediately after the browser finishes the domain name lookup for the resource.\n // redirectStart: start time of the fetch which that initiates the redirect.\n // redirectEnd: immediately after receiving the last byte of the response of the last redirect.\n let dnsLookupTime: number | undefined; // domainLookupEnd - domainLookupStart\n let redirectTime: number | undefined; // redirectEnd - redirectStart\n let tcpHandshakeTime: number | undefined; // connectEnd - connectStart\n let secureConnectionTime: number | undefined; // connectEnd - secureConnectionStart\n let responseNetworkTime: number | undefined; // responsEnd - responseStart\n let fetchStartToResponseEndTime: number | undefined; // responseEnd - fetchStart\n let reqStartToResponseEndTime: number | undefined; // responseEnd - requestStart\n let networkTime: number | undefined; // responseEnd - startTime\n const spReqDuration = response.odspSnapshotResponse.headers.get(\"sprequestduration\");\n\n // getEntriesByType is only available in browser performance object\n const resources1 = performance.getEntriesByType?.(\"resource\") ?? [];\n // Usually the latest fetch call is to the end of resources, so we start from the end.\n for (let i = resources1.length - 1; i > 0; i--) {\n const indResTime = resources1[i] as PerformanceResourceTiming;\n const resource_name = indResTime.name;\n const resource_initiatortype = indResTime.initiatorType;\n if ((resource_initiatortype.localeCompare(\"fetch\") === 0)\n && (resource_name.localeCompare(response.requestUrl) === 0)) {\n redirectTime = indResTime.redirectEnd - indResTime.redirectStart;\n dnsLookupTime = indResTime.domainLookupEnd - indResTime.domainLookupStart;\n tcpHandshakeTime = indResTime.connectEnd - indResTime.connectStart;\n secureConnectionTime = (indResTime.secureConnectionStart > 0) ?\n (indResTime.connectEnd - indResTime.secureConnectionStart) : undefined;\n responseNetworkTime = (indResTime.responseStart > 0) ?\n (indResTime.responseEnd - indResTime.responseStart) : undefined;\n fetchStartToResponseEndTime = (indResTime.fetchStart > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n reqStartToResponseEndTime = (indResTime.requestStart > 0) ?\n (indResTime.responseEnd - indResTime.requestStart) : undefined;\n networkTime = (indResTime.startTime > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n if (spReqDuration !== undefined && networkTime !== undefined) {\n networkTime = networkTime - parseInt(spReqDuration, 10);\n }\n break;\n }\n }\n\n const { numTrees, numBlobs, encodedBlobsSize } =\n validateAndEvalBlobsAndTrees(response.odspSnapshotResponse.content);\n\n // There are some scenarios in ODSP where we cannot cache, trees/latest will explicitly tell us when we\n // cannot cache using an HTTP response header.\n const canCache =\n response.odspSnapshotResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\";\n const sequenceNumber: number = snapshot.sequenceNumber ?? 0;\n const seqNumberFromOps = snapshot.ops && snapshot.ops.length > 0 ?\n snapshot.ops[0].sequenceNumber - 1 :\n undefined;\n\n if (!Number.isInteger(sequenceNumber)\n || seqNumberFromOps !== undefined && seqNumberFromOps !== sequenceNumber) {\n logger.sendErrorEvent({ eventName: \"fetchSnapshotError\", sequenceNumber, seqNumberFromOps });\n snapshot.sequenceNumber = undefined;\n } else if (canCache) {\n const fluidEpoch = response.odspSnapshotResponse.headers.get(\"x-fluid-epoch\");\n assert(fluidEpoch !== undefined, 0x1e6 /* \"Epoch should be present in response\" */);\n const value: ISnapshotCachedEntry = {\n ...snapshot,\n cacheEntryTime: Date.now(),\n };\n const valueWithEpoch: IVersionedValueWithEpoch = {\n value,\n fluidEpoch,\n version: persistedCacheValueVersion,\n };\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n putInCache(valueWithEpoch);\n }\n event.end({\n trees: numTrees,\n blobs: snapshot.blobs?.size ?? 0,\n leafNodes: numBlobs,\n encodedBlobsSize,\n sequenceNumber,\n ops: snapshot.ops?.length ?? 0,\n nonSysOps: snapshot.ops?.filter((op) => !isSystemMessage(op)).length ?? 0,\n headers: Object.keys(response.requestHeaders).length !== 0 ? true : undefined,\n // Interval between the first fetch until the last byte of the last redirect.\n redirectTime,\n // Interval between start and finish of the domain name lookup for the resource.\n dnsLookupTime,\n // Interval to receive all (first to last) bytes form the server.\n responseNetworkTime,\n // Time to establish the connection to the server to retrieve the resource.\n tcpHandshakeTime,\n // Time from the end of the connection until the inital handshake process to secure the connection.\n secureConnectionTime,\n // Interval between the initial fetch until the last byte is received.\n fetchStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte.\n reqStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte but\n // excluding the Snaphot request duration indicated on the snapshot response header.\n networkTime,\n // Sharing link telemetry regarding sharing link redeem status and performance. Ex: FRL; dur=100,\n // Azure Fluid Relay service; desc=S, FRP; desc=False. Here, FRL is the duration taken for redeem,\n // Azure Fluid Relay service is the redeem status (S means success), and FRP is a flag to indicate\n // if the permission has changed.\n sltelemetry: response.odspSnapshotResponse.headers.get(\"x-fluid-sltelemetry\"),\n ...response.odspSnapshotResponse.propsToLog,\n });\n return snapshot;\n },\n ).catch((error) => {\n // We hit these errors in stress tests, under load\n // It's useful to try one more time in such case.\n // We might want to add DriverErrorType.offlineError in the future if we see evidence it happens\n // (not in \"real\" offline) and it actually helps.\n if (typeof error === \"object\" && error !== null && (error.errorType === DriverErrorType.fetchFailure ||\n error.errorType === OdspErrorType.fetchTimeout)) {\n error[getWithRetryForTokenRefreshRepeat] = true;\n }\n throw error;\n });\n });\n}\n\ninterface ISnapshotRequestAndResponseOptions {\n odspSnapshotResponse: IOdspResponse<ISnapshotContents>,\n requestUrl: string,\n requestHeaders: {[index: string]: any},\n}\n\nfunction getFormBodyAndHeaders(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n headers?: {[index: string]: string},\n) {\n const formBoundary = uuid();\n const formParams: string[] = [];\n formParams.push(`--${formBoundary}`);\n formParams.push(`Authorization: Bearer ${storageToken}`);\n formParams.push(`X-HTTP-Method-Override: GET`);\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (headers !== undefined) {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem) {\n formParams.push(`sl: ${odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem}`);\n }\n formParams.push(`_post: 1`);\n formParams.push(`\\r\\n--${formBoundary}--`);\n const postBody = formParams.join(\"\\r\\n\");\n const header: {[index: string]: any} = {\n \"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n };\n return { body: postBody, headers: header };\n}\n\nfunction validateAndEvalBlobsAndTrees(snapshot: ISnapshotContents) {\n assert(snapshot.snapshotTree !== undefined,\n 0x200 /* \"Returned odsp snapshot is malformed. No trees!\" */);\n assert(snapshot.blobs !== undefined,\n 0x201 /* \"Returned odsp snapshot is malformed. No blobs!\" */);\n const numTrees = countTreesInSnapshotTree(snapshot.snapshotTree);\n const numBlobs = snapshot.blobs.size;\n let encodedBlobsSize = 0;\n for (const [_, blobContent] of snapshot.blobs) {\n encodedBlobsSize += blobContent.byteLength;\n }\n return { numTrees, numBlobs, encodedBlobsSize };\n}\n\nfunction countTreesInSnapshotTree(snapshotTree: ISnapshotTree): number {\n let numTrees = 0;\n for (const [_, tree] of Object.entries(snapshotTree.trees)) {\n numTrees += 1;\n numTrees += countTreesInSnapshotTree(tree);\n }\n return numTrees;\n}\n\n/**\n * This function fetches the snapshot and parse it according to what is mentioned in response headers.\n * @param odspResolvedUrl - resolved odsp url.\n * @param storageToken - token to do the auth for network request.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param controller - abort controller if caller needs to abort the network call.\n * @param epochTracker - epoch tracker used to add/validate epoch in the network call.\n * @returns fetched snapshot.\n */\nexport async function downloadSnapshot(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n logger: ITelemetryLogger,\n snapshotOptions: ISnapshotOptions | undefined,\n snapshotFormatFetchType?: SnapshotFormatSupportType,\n controller?: AbortController,\n epochTracker?: EpochTracker,\n): Promise<ISnapshotRequestAndResponseOptions> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if(sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n const snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n const url = `${snapshotUrl}/trees/latest?ump=1`;\n // The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n // Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n // This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n // for futher reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n const header = {prefer: \"manualredirect\"};\n const { body, headers } = getFormBodyAndHeaders(\n odspResolvedUrl, storageToken, snapshotOptions, header);\n const fetchOptions = {\n body,\n headers,\n signal: controller?.signal,\n method: \"POST\",\n };\n // Decide what snapshot format to fetch as per the feature gate.\n switch (snapshotFormatFetchType) {\n case SnapshotFormatSupportType.JsonAndBinary:\n headers.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n break;\n case SnapshotFormatSupportType.Binary:\n headers.accept = `application/ms-fluid; v=${currentReadVersion}`;\n break;\n default:\n headers.accept = \"application/json\";\n }\n\n const response = await (epochTracker?.fetch(url, fetchOptions, \"treesLatest\", true) ??\n fetchHelper(url, fetchOptions));\n\n let finalSnapshotContents: IOdspResponse<ISnapshotContents>;\n const contentType = response.headers.get(\"content-type\");\n if (contentType === \"application/json\") {\n const text = await response.content.text();\n const content: IOdspSnapshot = JSON.parse(text);\n response.propsToLog.bodySize = text.length;\n const snapshotContents: ISnapshotContents = convertOdspSnapshotToSnapsohtTreeAndBlobs(content);\n finalSnapshotContents = { ...response, content: snapshotContents };\n } else {\n assert(contentType === \"application/ms-fluid\", 0x2c3 /* \"Content type should be application/ms-fluid\" */);\n const content = await response.content.arrayBuffer();\n response.propsToLog.bodySize = content.byteLength;\n const snapshotContents: ISnapshotContents = parseCompactSnapshotResponse(\n new ReadBuffer(new Uint8Array(content)));\n finalSnapshotContents = { ...response, content: snapshotContents };\n }\n response.propsToLog.contentType = contentType;\n return {\n odspSnapshotResponse: finalSnapshotContents,\n requestHeaders: headers,\n requestUrl: url,\n };\n}\n\nfunction isRedeemSharingLinkError(odspResolvedUrl: IOdspResolvedUrl, error: any) {\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined\n && (typeof error === \"object\" && error !== null)\n && (error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError)) {\n return true;\n }\n return false;\n}\n\nfunction getEncodedShareUrl(url: string): string {\n /**\n * Encode the url to accepted format by Sharepoint\n * https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get\n */\n let encodedUrl = fromUtf8ToBase64(encodeURI(url));\n encodedUrl = encodedUrl\n .replace(/=+$/g, \"\")\n .replace(/\\//g, \"_\")\n .replace(/\\+/g, \"-\");\n encodedUrl = \"u!\".concat(encodedUrl);\n return 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 { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, fromUtf8ToBase64, performance } from \"@fluidframework/common-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport {\n IOdspResolvedUrl,\n ISnapshotOptions,\n OdspErrorType,\n InstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { isSystemMessage } from \"@fluidframework/protocol-base\";\nimport { IOdspSnapshot, ISnapshotCachedEntry, IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { getQueryString } from \"./getQueryString\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n fetchAndParseAsJSONHelper,\n fetchHelper,\n getWithRetryForTokenRefresh,\n getWithRetryForTokenRefreshRepeat,\n IOdspResponse,\n ISnapshotContents,\n} from \"./odspUtils\";\nimport { convertOdspSnapshotToSnapsohtTreeAndBlobs } from \"./odspSnapshotParser\";\nimport { currentReadVersion, parseCompactSnapshotResponse } from \"./compactSnapshotParser\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { EpochTracker } from \"./epochTracker\";\n\n/**\n * Enum to support different types of snapshot formats.\n */\nexport enum SnapshotFormatSupportType {\n Json = 0,\n Binary = 1,\n JsonAndBinary = 2,\n}\n\n/**\n * Fetches a snapshot from the server with a given version id.\n * @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched\n * @param token - token used for authorization in the request\n * @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot\n * @param versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n snapshotUrl: string,\n token: string | null,\n versionId: string,\n fetchFullSnapshot: boolean,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (url: string, fetchOptions: { [index: string]: any; }) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshotContents> {\n const path = `/trees/${versionId}`;\n let queryParams: ISnapshotOptions = {};\n\n if (fetchFullSnapshot) {\n if (versionId !== \"latest\") {\n queryParams = { channels: 1, blobs: 2 };\n } else {\n queryParams = { deltas: 1, channels: 1, blobs: 2 };\n }\n }\n\n const queryString = getQueryString(queryParams);\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${snapshotUrl}${path}${queryString}`, token, forceAccessTokenViaAuthorizationHeader);\n const response = await PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"fetchSnapshot\",\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n },\n async () => snapshotDownloader(url, { headers }),\n ) as IOdspResponse<IOdspSnapshot>;\n return convertOdspSnapshotToSnapsohtTreeAndBlobs(response.content);\n}\n\nexport async function fetchSnapshotWithRedeem(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n removeEntries: () => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if (sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n return fetchLatestSnapshotCore(\n odspResolvedUrl,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n enableRedeemFallback,\n ).catch(async (error) => {\n if (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n // Execute the redeem fallback\n logger.sendErrorEvent({\n eventName: \"RedeemFallback\",\n errorType: error.errorType,\n }, error);\n await redeemSharingLink(\n odspResolvedUrl, storageTokenFetcher, logger, forceAccessTokenViaAuthorizationHeader);\n const odspResolvedUrlWithoutShareLink: IOdspResolvedUrl =\n { ...odspResolvedUrl,\n shareLinkInfo: {\n ...odspResolvedUrl.shareLinkInfo,\n sharingLinkToRedeem: undefined,\n },\n };\n\n return fetchLatestSnapshotCore(\n odspResolvedUrlWithoutShareLink,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n );\n } else {\n throw error;\n }\n }).catch(async (error) => {\n // Clear the cache on 401/403/404 on snapshot fetch from network because this means either the user doesn't\n // have permissions for the file or it was deleted. So, if we do not clear cache, we will continue fetching\n // snapshot from cache in the future.\n if (typeof error === \"object\" && error !== null && error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError) {\n await removeEntries();\n }\n throw error;\n });\n}\n\nasync function redeemSharingLink(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n) {\n return PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"RedeemShareLink\",\n },\n async () => getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n assert(!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n 0x1ed /* \"Share link should be present\" */);\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"RedeemShareLink\");\n const encodedShareUrl = getEncodedShareUrl(odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem);\n const redeemUrl = `${odspResolvedUrl.siteUrl}/_api/v2.0/shares/${encodedShareUrl}`;\n const { url, headers } = getUrlAndHeadersWithAuth(\n redeemUrl, storageToken, forceAccessTokenViaAuthorizationHeader);\n headers.prefer = \"redeemSharingLink\";\n return fetchAndParseAsJSONHelper(url, { headers });\n }),\n );\n}\n\nasync function fetchLatestSnapshotCore(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n return getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"TreesLatest\", true);\n assert(storageToken !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\n let controller: AbortController | undefined;\n if (snapshotOptions?.timeout !== undefined) {\n controller = new AbortController();\n setTimeout(\n () => controller!.abort(),\n snapshotOptions.timeout,\n );\n }\n const perfEvent = {\n eventName: \"TreesLatest\",\n attempts: tokenFetchOptions.refresh ? 2 : 1,\n shareLinkPresent: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined,\n isSummarizer: odspResolvedUrl.summarizer,\n redeemFallbackEnabled: enableRedeemFallback,\n };\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n perfEvent[`snapshotOption_${key}`] = value;\n }\n });\n }\n // This event measures only successful cases of getLatest call (no tokens, no retries).\n return PerformanceEvent.timedExecAsync(\n logger,\n perfEvent,\n async (event) => {\n const response = await snapshotDownloader(\n odspResolvedUrl,\n storageToken,\n snapshotOptions,\n controller,\n );\n const snapshot = response.odspSnapshotResponse.content;\n // From: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming\n // fetchStart: immediately before the browser starts to fetch the resource.\n // requestStart: immediately before the browser starts requesting the resource from the server\n // responseStart: immediately after the browser receives the first byte of the response from the server.\n // responseEnd: immediately after the browser receives the last byte of the resource\n // or immediately before the transport connection is closed, whichever comes first.\n // secureConnectionStart: immediately before the browser starts the handshake process to secure the\n // current connection. If a secure connection is not used, this property returns zero.\n // startTime: Time when the resource fetch started. This value is equivalent to fetchStart.\n // domainLookupStart: immediately before the browser starts the domain name lookup for the resource.\n // domainLookupEnd: immediately after the browser finishes the domain name lookup for the resource.\n // redirectStart: start time of the fetch which that initiates the redirect.\n // redirectEnd: immediately after receiving the last byte of the response of the last redirect.\n let dnsLookupTime: number | undefined; // domainLookupEnd - domainLookupStart\n let redirectTime: number | undefined; // redirectEnd - redirectStart\n let tcpHandshakeTime: number | undefined; // connectEnd - connectStart\n let secureConnectionTime: number | undefined; // connectEnd - secureConnectionStart\n let responseNetworkTime: number | undefined; // responsEnd - responseStart\n let fetchStartToResponseEndTime: number | undefined; // responseEnd - fetchStart\n let reqStartToResponseEndTime: number | undefined; // responseEnd - requestStart\n let networkTime: number | undefined; // responseEnd - startTime\n const spReqDuration = response.odspSnapshotResponse.headers.get(\"sprequestduration\");\n\n // getEntriesByType is only available in browser performance object\n const resources1 = performance.getEntriesByType?.(\"resource\") ?? [];\n // Usually the latest fetch call is to the end of resources, so we start from the end.\n for (let i = resources1.length - 1; i > 0; i--) {\n const indResTime = resources1[i] as PerformanceResourceTiming;\n const resource_name = indResTime.name;\n const resource_initiatortype = indResTime.initiatorType;\n if ((resource_initiatortype.localeCompare(\"fetch\") === 0)\n && (resource_name.localeCompare(response.requestUrl) === 0)) {\n redirectTime = indResTime.redirectEnd - indResTime.redirectStart;\n dnsLookupTime = indResTime.domainLookupEnd - indResTime.domainLookupStart;\n tcpHandshakeTime = indResTime.connectEnd - indResTime.connectStart;\n secureConnectionTime = (indResTime.secureConnectionStart > 0) ?\n (indResTime.connectEnd - indResTime.secureConnectionStart) : undefined;\n responseNetworkTime = (indResTime.responseStart > 0) ?\n (indResTime.responseEnd - indResTime.responseStart) : undefined;\n fetchStartToResponseEndTime = (indResTime.fetchStart > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n reqStartToResponseEndTime = (indResTime.requestStart > 0) ?\n (indResTime.responseEnd - indResTime.requestStart) : undefined;\n networkTime = (indResTime.startTime > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n if (spReqDuration !== undefined && networkTime !== undefined) {\n networkTime = networkTime - parseInt(spReqDuration, 10);\n }\n break;\n }\n }\n\n const { numTrees, numBlobs, encodedBlobsSize } =\n validateAndEvalBlobsAndTrees(response.odspSnapshotResponse.content);\n\n // There are some scenarios in ODSP where we cannot cache, trees/latest will explicitly tell us when we\n // cannot cache using an HTTP response header.\n const canCache =\n response.odspSnapshotResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\";\n const sequenceNumber: number = snapshot.sequenceNumber ?? 0;\n const seqNumberFromOps = snapshot.ops && snapshot.ops.length > 0 ?\n snapshot.ops[0].sequenceNumber - 1 :\n undefined;\n\n if (!Number.isInteger(sequenceNumber)\n || seqNumberFromOps !== undefined && seqNumberFromOps !== sequenceNumber) {\n logger.sendErrorEvent({ eventName: \"fetchSnapshotError\", sequenceNumber, seqNumberFromOps });\n snapshot.sequenceNumber = undefined;\n } else if (canCache) {\n const fluidEpoch = response.odspSnapshotResponse.headers.get(\"x-fluid-epoch\");\n assert(fluidEpoch !== undefined, 0x1e6 /* \"Epoch should be present in response\" */);\n const value: ISnapshotCachedEntry = {\n ...snapshot,\n cacheEntryTime: Date.now(),\n };\n const valueWithEpoch: IVersionedValueWithEpoch = {\n value,\n fluidEpoch,\n version: persistedCacheValueVersion,\n };\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n putInCache(valueWithEpoch);\n }\n event.end({\n trees: numTrees,\n blobs: snapshot.blobs?.size ?? 0,\n leafNodes: numBlobs,\n encodedBlobsSize,\n sequenceNumber,\n ops: snapshot.ops?.length ?? 0,\n nonSysOps: snapshot.ops?.filter((op) => !isSystemMessage(op)).length ?? 0,\n headers: Object.keys(response.requestHeaders).length !== 0 ? true : undefined,\n // Interval between the first fetch until the last byte of the last redirect.\n redirectTime,\n // Interval between start and finish of the domain name lookup for the resource.\n dnsLookupTime,\n // Interval to receive all (first to last) bytes form the server.\n responseNetworkTime,\n // Time to establish the connection to the server to retrieve the resource.\n tcpHandshakeTime,\n // Time from the end of the connection until the inital handshake process to secure the connection.\n secureConnectionTime,\n // Interval between the initial fetch until the last byte is received.\n fetchStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte.\n reqStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte but\n // excluding the Snaphot request duration indicated on the snapshot response header.\n networkTime,\n // Sharing link telemetry regarding sharing link redeem status and performance. Ex: FRL; dur=100,\n // Azure Fluid Relay service; desc=S, FRP; desc=False. Here, FRL is the duration taken for redeem,\n // Azure Fluid Relay service is the redeem status (S means success), and FRP is a flag to indicate\n // if the permission has changed.\n sltelemetry: response.odspSnapshotResponse.headers.get(\"x-fluid-sltelemetry\"),\n ...response.odspSnapshotResponse.propsToLog,\n });\n return snapshot;\n },\n ).catch((error) => {\n // We hit these errors in stress tests, under load\n // It's useful to try one more time in such case.\n // We might want to add DriverErrorType.offlineError in the future if we see evidence it happens\n // (not in \"real\" offline) and it actually helps.\n if (typeof error === \"object\" && error !== null && (error.errorType === DriverErrorType.fetchFailure ||\n error.errorType === OdspErrorType.fetchTimeout)) {\n error[getWithRetryForTokenRefreshRepeat] = true;\n }\n throw error;\n });\n });\n}\n\ninterface ISnapshotRequestAndResponseOptions {\n odspSnapshotResponse: IOdspResponse<ISnapshotContents>;\n requestUrl: string;\n requestHeaders: { [index: string]: any; };\n}\n\nfunction getFormBodyAndHeaders(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n headers?: { [index: string]: string; },\n) {\n const formBoundary = uuid();\n const formParams: string[] = [];\n formParams.push(`--${formBoundary}`);\n formParams.push(`Authorization: Bearer ${storageToken}`);\n formParams.push(`X-HTTP-Method-Override: GET`);\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (headers !== undefined) {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem) {\n formParams.push(`sl: ${odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem}`);\n }\n formParams.push(`_post: 1`);\n formParams.push(`\\r\\n--${formBoundary}--`);\n const postBody = formParams.join(\"\\r\\n\");\n const header: { [index: string]: any; } = {\n \"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n };\n return { body: postBody, headers: header };\n}\n\nfunction validateAndEvalBlobsAndTrees(snapshot: ISnapshotContents) {\n assert(snapshot.snapshotTree !== undefined,\n 0x200 /* \"Returned odsp snapshot is malformed. No trees!\" */);\n assert(snapshot.blobs !== undefined,\n 0x201 /* \"Returned odsp snapshot is malformed. No blobs!\" */);\n const numTrees = countTreesInSnapshotTree(snapshot.snapshotTree);\n const numBlobs = snapshot.blobs.size;\n let encodedBlobsSize = 0;\n for (const [_, blobContent] of snapshot.blobs) {\n encodedBlobsSize += blobContent.byteLength;\n }\n return { numTrees, numBlobs, encodedBlobsSize };\n}\n\nfunction countTreesInSnapshotTree(snapshotTree: ISnapshotTree): number {\n let numTrees = 0;\n for (const [_, tree] of Object.entries(snapshotTree.trees)) {\n numTrees += 1;\n numTrees += countTreesInSnapshotTree(tree);\n }\n return numTrees;\n}\n\n/**\n * This function fetches the snapshot and parse it according to what is mentioned in response headers.\n * @param odspResolvedUrl - resolved odsp url.\n * @param storageToken - token to do the auth for network request.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param controller - abort controller if caller needs to abort the network call.\n * @param epochTracker - epoch tracker used to add/validate epoch in the network call.\n * @returns fetched snapshot.\n */\nexport async function downloadSnapshot(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n logger: ITelemetryLogger,\n snapshotOptions: ISnapshotOptions | undefined,\n snapshotFormatFetchType?: SnapshotFormatSupportType,\n controller?: AbortController,\n epochTracker?: EpochTracker,\n): Promise<ISnapshotRequestAndResponseOptions> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if (sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n const snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n const url = `${snapshotUrl}/trees/latest?ump=1`;\n // The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n // Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n // This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n // for futher reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n const header = { prefer: \"manualredirect\" };\n const { body, headers } = getFormBodyAndHeaders(\n odspResolvedUrl, storageToken, snapshotOptions, header);\n const fetchOptions = {\n body,\n headers,\n signal: controller?.signal,\n method: \"POST\",\n };\n // Decide what snapshot format to fetch as per the feature gate.\n switch (snapshotFormatFetchType) {\n case SnapshotFormatSupportType.JsonAndBinary:\n headers.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n break;\n case SnapshotFormatSupportType.Binary:\n headers.accept = `application/ms-fluid; v=${currentReadVersion}`;\n break;\n default:\n headers.accept = \"application/json\";\n }\n\n const response = await (epochTracker?.fetch(url, fetchOptions, \"treesLatest\", true) ??\n fetchHelper(url, fetchOptions));\n\n let finalSnapshotContents: IOdspResponse<ISnapshotContents>;\n const contentType = response.headers.get(\"content-type\");\n if (contentType === \"application/json\") {\n const text = await response.content.text();\n const content: IOdspSnapshot = JSON.parse(text);\n response.propsToLog.bodySize = text.length;\n const snapshotContents: ISnapshotContents = convertOdspSnapshotToSnapsohtTreeAndBlobs(content);\n finalSnapshotContents = { ...response, content: snapshotContents };\n } else {\n assert(contentType === \"application/ms-fluid\", 0x2c3 /* \"Content type should be application/ms-fluid\" */);\n const content = await response.content.arrayBuffer();\n response.propsToLog.bodySize = content.byteLength;\n const snapshotContents: ISnapshotContents = parseCompactSnapshotResponse(\n new ReadBuffer(new Uint8Array(content)));\n finalSnapshotContents = { ...response, content: snapshotContents };\n }\n response.propsToLog.contentType = contentType;\n return {\n odspSnapshotResponse: finalSnapshotContents,\n requestHeaders: headers,\n requestUrl: url,\n };\n}\n\nfunction isRedeemSharingLinkError(odspResolvedUrl: IOdspResolvedUrl, error: any) {\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined\n && (typeof error === \"object\" && error !== null)\n && (error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError)) {\n return true;\n }\n return false;\n}\n\nfunction getEncodedShareUrl(url: string): string {\n /**\n * Encode the url to accepted format by Sharepoint\n * https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get\n */\n let encodedUrl = fromUtf8ToBase64(encodeURI(url));\n encodedUrl = encodedUrl\n .replace(/=+$/g, \"\")\n .replace(/\\//g, \"_\")\n .replace(/\\+/g, \"-\");\n encodedUrl = \"u!\".concat(encodedUrl);\n return encodedUrl;\n}\n"]}
@@ -69,7 +69,7 @@ async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
69
69
  return fileItem.webUrl;
70
70
  }
71
71
  // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder
72
- return PerformanceEvent.timedExecAsync(logger, { eventName: "odspFileLink", requestName: "getSharingInformation" }, async (event) => {
72
+ return PerformanceEvent.timedExecAsync(logger, { eventName: "odspFileLink", requestName: "getSharingLink" }, async (event) => {
73
73
  let attempts = 0;
74
74
  let additionalProps;
75
75
  const fileLink = await getWithRetryForTokenRefresh(async (options) => {
@@ -78,7 +78,7 @@ async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
78
78
  const storageTokenFetcher = toInstrumentedOdspTokenFetcher(logger, odspUrlParts, getToken, true /* throwOnNullToken */);
79
79
  const storageToken = await storageTokenFetcher(options, "GetFileLinkCore");
80
80
  assert(storageToken !== null, 0x2bb /* "Instrumented token fetcher with throwOnNullToken = true should never return null" */);
81
- const { url, headers } = getUrlAndHeadersWithAuth(`${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${encodeURIComponent(`'${fileItem.webDavUrl}'`)}`, storageToken, false);
81
+ const { url, headers } = getUrlAndHeadersWithAuth(`${odspUrlParts.siteUrl}/_api/web/GetFileByServerRelativeUrl(@a1)/Linkingurl?@a1=${encodeURIComponent(`'${new URL(fileItem.webDavUrl).pathname}'`)}`, storageToken, false);
82
82
  const requestInit = {
83
83
  method: "POST",
84
84
  headers: Object.assign({ "Content-Type": "application/json;odata=verbose", "Accept": "application/json;odata=verbose" }, headers),
@@ -86,12 +86,12 @@ async function getFileLinkCore(getToken, odspUrlParts, identityType, logger) {
86
86
  const response = await fetchHelper(url, requestInit);
87
87
  additionalProps = response.propsToLog;
88
88
  const sharingInfo = await response.content.json();
89
- const directUrl = (_a = sharingInfo === null || sharingInfo === void 0 ? void 0 : sharingInfo.d) === null || _a === void 0 ? void 0 : _a.directUrl;
90
- if (typeof directUrl !== "string") {
89
+ const linkingUrl = (_a = sharingInfo === null || sharingInfo === void 0 ? void 0 : sharingInfo.d) === null || _a === void 0 ? void 0 : _a.LinkingUrl;
90
+ if (typeof linkingUrl !== "string") {
91
91
  // This will retry once in getWithRetryForTokenRefresh
92
- throw new NonRetryableError("Malformed GetSharingInformation response", DriverErrorType.incorrectServerResponse, { driverVersion });
92
+ throw new NonRetryableError("Malformed GetSharingLink response", DriverErrorType.incorrectServerResponse, { driverVersion });
93
93
  }
94
- return directUrl;
94
+ return linkingUrl;
95
95
  });
96
96
  event.end(Object.assign(Object.assign({}, additionalProps), { attempts }));
97
97
  return fileLink;
@@ -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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay } from \"@fluidframework/common-utils\";\nimport { canRetryOnError, getRetryDelayFromError, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspUrlParts,\n OdspResourceTokenFetchOptions,\n IdentityType,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport { fetchHelper, getWithRetryForTokenRefresh, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\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 siteUrl - url of the site that contains the file\n * @param driveId - drive where file is stored\n * @param itemId - file id\n * @param identityType - type of client account\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 async function getFileLink(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const cacheKey = `${odspUrlParts.siteUrl}_${odspUrlParts.driveId}_${odspUrlParts.itemId}`;\n const maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n if (maybeFileLinkCacheEntry !== undefined) {\n return maybeFileLinkCacheEntry;\n }\n\n const valueGenerator = async function() {\n let result: string | undefined;\n let success = false;\n let retryAfterMs = 1000;\n do {\n try {\n result = await getFileLinkCore(getToken, odspUrlParts, identityType, logger);\n success = true;\n } catch (err) {\n // If it is not retriable, then just throw\n if (!canRetryOnError(err)) {\n // Delete from the cache to permit retrying later.\n fileLinkCache.delete(cacheKey);\n throw err;\n }\n // If the error is throttling error, then wait for the specified time before retrying.\n // If the waitTime is not specified, then we start with retrying immediately to max of 8s.\n retryAfterMs = getRetryDelayFromError(err) ?? Math.min(retryAfterMs * 2, 8000);\n await delay(retryAfterMs);\n }\n } while (!success);\n\n // We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n assert(result !== undefined, 0x292 /* \"Unexpected undefined result from getFileLinkCore\" */);\n return result;\n };\n const fileLink = valueGenerator();\n fileLinkCache.set(cacheKey, fileLink);\n return fileLink;\n}\n\nasync function getFileLinkCore(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === \"Consumer\");\n\n // ODC canonical link does not require any additional processing\n if (identityType === \"Consumer\") {\n return fileItem.webUrl;\n }\n\n // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getSharingInformation\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileLink = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options,\"GetFileLinkCore\");\n assert(storageToken !== null,\n 0x2bb /* \"Instrumented token fetcher with throwOnNullToken = true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${odspUrlParts.siteUrl}/_api/web/GetFileByUrl(@a1)/ListItemAllFields/GetSharingInformation?@a1=${\n encodeURIComponent(`'${fileItem.webDavUrl}'`)\n }`,\n storageToken,\n false,\n );\n const requestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json;odata=verbose\",\n \"Accept\": \"application/json;odata=verbose\",\n ...headers,\n },\n };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const sharingInfo = await response.content.json();\n const directUrl = sharingInfo?.d?.directUrl;\n if (typeof directUrl !== \"string\") {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed GetSharingInformation response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return directUrl;\n });\n event.end({ ...additionalProps, attempts });\n return fileLink;\n },\n );\n}\n\n/**\n * This represents a lite version of file item containing only the webUrl and webDavUrl properties\n */\ninterface FileItemLite {\n webUrl: string;\n webDavUrl: string;\n}\n\nconst isFileItemLite = (maybeFileItemLite: any): maybeFileItemLite is FileItemLite => {\n if (typeof maybeFileItemLite.webUrl !== \"string\" || typeof maybeFileItemLite.webDavUrl !== \"string\") {\n return false;\n }\n return true;\n};\n\nasync function getFileItemLite(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<FileItemLite> {\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileItem = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const {siteUrl, driveId, itemId} = odspUrlParts;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options,\"GetFileItemLite\");\n assert(storageToken !== null,\n 0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl`,\n storageToken,\n forceAccessTokenViaAuthorizationHeader,\n );\n const requestInit = { method: \"GET\", headers };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const responseJson = await response.content.json();\n if (!isFileItemLite(responseJson)) {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed getFileItemLite response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return responseJson;\n });\n event.end({ ...additionalProps, attempts });\n return fileItem;\n },\n );\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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay } from \"@fluidframework/common-utils\";\nimport { canRetryOnError, getRetryDelayFromError, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IOdspUrlParts,\n OdspResourceTokenFetchOptions,\n IdentityType,\n TokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport { fetchHelper, getWithRetryForTokenRefresh, toInstrumentedOdspTokenFetcher } from \"./odspUtils\";\nimport { pkgVersion as driverVersion } from \"./packageVersion\";\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 siteUrl - url of the site that contains the file\n * @param driveId - drive where file is stored\n * @param itemId - file id\n * @param identityType - type of client account\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 async function getFileLink(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const cacheKey = `${odspUrlParts.siteUrl}_${odspUrlParts.driveId}_${odspUrlParts.itemId}`;\n const maybeFileLinkCacheEntry = fileLinkCache.get(cacheKey);\n if (maybeFileLinkCacheEntry !== undefined) {\n return maybeFileLinkCacheEntry;\n }\n\n const valueGenerator = async function() {\n let result: string | undefined;\n let success = false;\n let retryAfterMs = 1000;\n do {\n try {\n result = await getFileLinkCore(getToken, odspUrlParts, identityType, logger);\n success = true;\n } catch (err) {\n // If it is not retriable, then just throw\n if (!canRetryOnError(err)) {\n // Delete from the cache to permit retrying later.\n fileLinkCache.delete(cacheKey);\n throw err;\n }\n // If the error is throttling error, then wait for the specified time before retrying.\n // If the waitTime is not specified, then we start with retrying immediately to max of 8s.\n retryAfterMs = getRetryDelayFromError(err) ?? Math.min(retryAfterMs * 2, 8000);\n await delay(retryAfterMs);\n }\n } while (!success);\n\n // We are guaranteed to run the getFileLinkCore at least once with successful result (which must be a string)\n assert(result !== undefined, 0x292 /* \"Unexpected undefined result from getFileLinkCore\" */);\n return result;\n };\n const fileLink = valueGenerator();\n fileLinkCache.set(cacheKey, fileLink);\n return fileLink;\n}\n\nasync function getFileLinkCore(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n identityType: IdentityType,\n logger: ITelemetryLogger,\n): Promise<string> {\n const fileItem = await getFileItemLite(getToken, odspUrlParts, logger, identityType === \"Consumer\");\n\n // ODC canonical link does not require any additional processing\n if (identityType === \"Consumer\") {\n return fileItem.webUrl;\n }\n\n // ODSP link requires extra call to return link that is resistant to file being renamed or moved to different folder\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getSharingLink\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileLink = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileLinkCore\");\n assert(storageToken !== null,\n 0x2bb /* \"Instrumented token fetcher with throwOnNullToken = true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${odspUrlParts.siteUrl}/_api/web/GetFileByServerRelativeUrl(@a1)/Linkingurl?@a1=${\n encodeURIComponent(`'${new URL(fileItem.webDavUrl).pathname}'`)\n }`,\n storageToken,\n false,\n );\n const requestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json;odata=verbose\",\n \"Accept\": \"application/json;odata=verbose\",\n ...headers,\n },\n };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const sharingInfo = await response.content.json();\n const linkingUrl = sharingInfo?.d?.LinkingUrl;\n if (typeof linkingUrl !== \"string\") {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed GetSharingLink response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return linkingUrl;\n });\n event.end({ ...additionalProps, attempts });\n return fileLink;\n },\n );\n}\n\n/**\n * This represents a lite version of file item containing only the webUrl and webDavUrl properties\n */\ninterface FileItemLite {\n webUrl: string;\n webDavUrl: string;\n}\n\nconst isFileItemLite = (maybeFileItemLite: any): maybeFileItemLite is FileItemLite => {\n if (typeof maybeFileItemLite.webUrl !== \"string\" || typeof maybeFileItemLite.webDavUrl !== \"string\") {\n return false;\n }\n return true;\n};\n\nasync function getFileItemLite(\n getToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n odspUrlParts: IOdspUrlParts,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): Promise<FileItemLite> {\n return PerformanceEvent.timedExecAsync(\n logger,\n { eventName: \"odspFileLink\", requestName: \"getFileItemLite\" },\n async (event) => {\n let attempts = 0;\n let additionalProps;\n const fileItem = await getWithRetryForTokenRefresh(async (options) => {\n attempts++;\n const { siteUrl, driveId, itemId } = odspUrlParts;\n const storageTokenFetcher = toInstrumentedOdspTokenFetcher(\n logger,\n odspUrlParts,\n getToken,\n true /* throwOnNullToken */,\n );\n const storageToken = await storageTokenFetcher(options, \"GetFileItemLite\");\n assert(storageToken !== null,\n 0x2bc /* \"Instrumented token fetcher with throwOnNullToken =true should never return null\" */);\n\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${siteUrl}/_api/v2.0/drives/${driveId}/items/${itemId}?select=webUrl,webDavUrl`,\n storageToken,\n forceAccessTokenViaAuthorizationHeader,\n );\n const requestInit = { method: \"GET\", headers };\n const response = await fetchHelper(url, requestInit);\n additionalProps = response.propsToLog;\n\n const responseJson = await response.content.json();\n if (!isFileItemLite(responseJson)) {\n // This will retry once in getWithRetryForTokenRefresh\n throw new NonRetryableError(\n \"Malformed getFileItemLite response\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion });\n }\n return responseJson;\n });\n event.end({ ...additionalProps, attempts });\n return fileItem;\n },\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getQueryString.d.ts","sourceRoot":"","sources":["../src/getQueryString.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAE3E;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,gBAAgB,GAAG,MAAM,CAUzG"}
1
+ {"version":3,"file":"getQueryString.d.ts","sourceRoot":"","sources":["../src/getQueryString.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAE3E;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAAE,GAAG,gBAAgB,GAAG,MAAM,CAU1G"}
@@ -1 +1 @@
1
- {"version":3,"file":"getQueryString.js","sourceRoot":"","sources":["../src/getQueryString.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,WAAkE;IAC7F,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;QACxC,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YAChC,MAAM,SAAS,GAAG,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACjD,WAAW,IAAI,GAAG,SAAS,GAAG,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;SAC/E;KACJ;IAED,OAAO,WAAW,CAAC;AACvB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { ISnapshotOptions } from \"@fluidframework/odsp-driver-definitions\";\n\n/**\n * Generates query string from the given query parameters.\n * @param queryParams - Query parameters from which to create a query.\n */\nexport function getQueryString(queryParams: { [key: string]: string | number } | ISnapshotOptions): string {\n let queryString = \"\";\n for (const key of Object.keys(queryParams)) {\n if (queryParams[key] !== undefined) {\n const startChar = queryString === \"\" ? \"?\" : \"&\";\n queryString += `${startChar}${key}=${encodeURIComponent(queryParams[key])}`;\n }\n }\n\n return queryString;\n}\n"]}
1
+ {"version":3,"file":"getQueryString.js","sourceRoot":"","sources":["../src/getQueryString.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmE;IAC9F,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;QACxC,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YAChC,MAAM,SAAS,GAAG,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACjD,WAAW,IAAI,GAAG,SAAS,GAAG,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;SAC/E;KACJ;IAED,OAAO,WAAW,CAAC;AACvB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { ISnapshotOptions } from \"@fluidframework/odsp-driver-definitions\";\n\n/**\n * Generates query string from the given query parameters.\n * @param queryParams - Query parameters from which to create a query.\n */\nexport function getQueryString(queryParams: { [key: string]: string | number; } | ISnapshotOptions): string {\n let queryString = \"\";\n for (const key of Object.keys(queryParams)) {\n if (queryParams[key] !== undefined) {\n const startChar = queryString === \"\" ? \"?\" : \"&\";\n queryString += `${startChar}${key}=${encodeURIComponent(queryParams[key])}`;\n }\n }\n\n return queryString;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getUrlAndHeadersWithAuth.d.ts","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,wBAAwB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,sCAAsC,EAAE,OAAO,GAChD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CAAE,CAgCvD"}
1
+ {"version":3,"file":"getUrlAndHeadersWithAuth.d.ts","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,wBAAwB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,sCAAsC,EAAE,OAAO,GAChD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;KAAE,CAAC;CAAE,CAgCzD"}
@@ -1 +1 @@
1
- {"version":3,"file":"getUrlAndHeadersWithAuth.js","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,wBAAwB,CACpC,GAAW,EACX,KAAoB,EACpB,sCAA+C;IAE/C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;QAC9B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;KAC/B;IAED,IAAI,CAAC,sCAAsC,EAAE;QACzC,4FAA4F;QAC5F,6DAA6D;QAC7D,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACrD,4FAA4F;QAC5F,qCAAqC;QACrC,+BAA+B,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACxE,mFAAmF;QACnF,wGAAwG;QACxG,4EAA4E;QAC5E,2GAA2G;QAC3G,0GAA0G;QAC1G,gBAAgB;QAChB,IAAI,+BAA+B,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE;YACvD,OAAO;gBACH,OAAO,EAAE,EAAE;gBACX,GAAG,EAAE,+BAA+B,CAAC,IAAI;aAC5C,CAAC;SACL;KACJ;IAED,OAAO;QACH,OAAO,EAAE;YACL,aAAa,EAAE,UAAU,KAAK,EAAE;SACnC;QACD,GAAG;KACN,CAAC;AACN,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport function getUrlAndHeadersWithAuth(\n url: string,\n token: string | null,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): { url: string, headers: { [index: string]: string } } {\n if (!token || token.length === 0) {\n return { url, headers: {} };\n }\n\n if (!forceAccessTokenViaAuthorizationHeader) {\n // Pass access token via query string: this will make request be treated as 'simple' request\n // which does not require OPTIONS call as part of CORS check.\n const urlWithAccessTokenInQueryString = new URL(url);\n // IMPORTANT: Do not apply encodeURIComponent to token, param value is automatically encoded\n // when set via URLSearchParams class\n urlWithAccessTokenInQueryString.searchParams.set(\"access_token\", token);\n // ODSP APIs have a limitation that the query string cannot exceed 2048 characters.\n // If the query string exceeds 2048, we have to fall back to sending the access token as a header, which\n // has a negative performance implication as it adds a performance overhead.\n // NOTE: URL.search.length value includes '?' symbol and it is unclear whether backend logic which enforces\n // query length limit accounts for it. This logic errs on side of caution and includes that key in overall\n // query length.\n if (urlWithAccessTokenInQueryString.search.length <= 2048) {\n return {\n headers: {},\n url: urlWithAccessTokenInQueryString.href,\n };\n }\n }\n\n return {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n url,\n };\n}\n"]}
1
+ {"version":3,"file":"getUrlAndHeadersWithAuth.js","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,wBAAwB,CACpC,GAAW,EACX,KAAoB,EACpB,sCAA+C;IAE/C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;QAC9B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;KAC/B;IAED,IAAI,CAAC,sCAAsC,EAAE;QACzC,4FAA4F;QAC5F,6DAA6D;QAC7D,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACrD,4FAA4F;QAC5F,qCAAqC;QACrC,+BAA+B,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACxE,mFAAmF;QACnF,wGAAwG;QACxG,4EAA4E;QAC5E,2GAA2G;QAC3G,0GAA0G;QAC1G,gBAAgB;QAChB,IAAI,+BAA+B,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE;YACvD,OAAO;gBACH,OAAO,EAAE,EAAE;gBACX,GAAG,EAAE,+BAA+B,CAAC,IAAI;aAC5C,CAAC;SACL;KACJ;IAED,OAAO;QACH,OAAO,EAAE;YACL,aAAa,EAAE,UAAU,KAAK,EAAE;SACnC;QACD,GAAG;KACN,CAAC;AACN,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport function getUrlAndHeadersWithAuth(\n url: string,\n token: string | null,\n forceAccessTokenViaAuthorizationHeader: boolean,\n): { url: string; headers: { [index: string]: string; }; } {\n if (!token || token.length === 0) {\n return { url, headers: {} };\n }\n\n if (!forceAccessTokenViaAuthorizationHeader) {\n // Pass access token via query string: this will make request be treated as 'simple' request\n // which does not require OPTIONS call as part of CORS check.\n const urlWithAccessTokenInQueryString = new URL(url);\n // IMPORTANT: Do not apply encodeURIComponent to token, param value is automatically encoded\n // when set via URLSearchParams class\n urlWithAccessTokenInQueryString.searchParams.set(\"access_token\", token);\n // ODSP APIs have a limitation that the query string cannot exceed 2048 characters.\n // If the query string exceeds 2048, we have to fall back to sending the access token as a header, which\n // has a negative performance implication as it adds a performance overhead.\n // NOTE: URL.search.length value includes '?' symbol and it is unclear whether backend logic which enforces\n // query length limit accounts for it. This logic errs on side of caution and includes that key in overall\n // query length.\n if (urlWithAccessTokenInQueryString.search.length <= 2048) {\n return {\n headers: {},\n url: urlWithAccessTokenInQueryString.href,\n };\n }\n }\n\n return {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n url,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"odspCache.d.ts","sourceRoot":"","sources":["../src/odspCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACH,gBAAgB,EAChB,UAAU,EACV,MAAM,EACN,eAAe,EACf,WAAW,EACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAKrC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAJxD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAEhD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoD;gBAEnD,oBAAoB,SAAc;IAEhE,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAMrC,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG;IAMlC,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,OAAO,CAAC,2BAA2B;IAcnC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,YAAY;CAGvB;AACD,qBAAa,oCAAoC,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpE,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,OAAO;CAGlD;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;OAEG;IACH,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAC,MAAM,EAC1C;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,uBAAuB,CAAA;KAAE,CAAC,CAAC;IAEzE;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACjE;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,mBAAmB;IACnD;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;CAChD;AAED,qBAAa,kBAAmB,YAAW,mBAAmB;IAC1D,SAAgB,gBAAgB;mBACU,MAAM;6BAAuB,uBAAuB;OAAM;IAEpG,SAAgB,YAAY,yCAAgD;CAC/E"}
1
+ {"version":3,"file":"odspCache.d.ts","sourceRoot":"","sources":["../src/odspCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACH,gBAAgB,EAChB,UAAU,EACV,MAAM,EACN,eAAe,EACf,WAAW,EACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAKrC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAJxD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAEhD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoD;gBAEnD,oBAAoB,SAAc;IAEhE,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAMrC,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG;IAMlC,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,OAAO,CAAC,2BAA2B;IAcnC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,YAAY;CAGvB;AACD,qBAAa,oCAAoC,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpE,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,OAAO;CAGlD;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;OAEG;IACH,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAC,MAAM,EAC1C;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,uBAAuB,CAAC;KAAE,CAAC,CAAC;IAE1E;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACjE;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,mBAAmB;IACnD;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;CAChD;AAED,qBAAa,kBAAmB,YAAW,mBAAmB;IAC1D,SAAgB,gBAAgB;mBACU,MAAM;6BAAuB,uBAAuB;OAAO;IAErG,SAAgB,YAAY,yCAAgD;CAC/E"}
@@ -1 +1 @@
1
- {"version":3,"file":"odspCache.js","sourceRoot":"","sources":["../src/odspCache.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 */\nimport { PromiseCache } from \"@fluidframework/common-utils\";\nimport {\n IOdspResolvedUrl,\n IFileEntry,\n IEntry,\n IPersistedCache,\n ICacheEntry,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISocketStorageDiscovery } from \"./contracts\";\n/**\n * Similar to IPersistedCache, but exposes cache interface for single file\n */\nexport interface IPersistedFileCache {\n get(entry: IEntry): Promise<any>;\n put(entry: IEntry, value: any): Promise<void>;\n removeEntries(): Promise<void>;\n}\n\n/**\n * Default local-only implementation of IPersistedCache,\n * used if no persisted cache is provided by the host\n */\nexport class LocalPersistentCache implements IPersistedCache {\n private readonly cache = new Map<string, any>();\n // For every document id there will be a single expiration entry inspite of the number of cache entries.\n private readonly docIdExpirationMap = new Map<string, ReturnType<typeof setTimeout>>();\n\n public constructor(private readonly snapshotExpiryPolicy = 3600 * 1000) { }\n\n async get(entry: ICacheEntry): Promise<any> {\n const key = this.keyFromEntry(entry);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return this.cache.get(key);\n }\n\n async put(entry: ICacheEntry, value: any) {\n const key = this.keyFromEntry(entry);\n this.cache.set(key, value);\n this.updateExpirationEntry(entry.file.docId);\n }\n\n async removeEntries(file: IFileEntry): Promise<void> {\n this.removeDocIdEntriesFromCache(file.docId);\n }\n\n private removeDocIdEntriesFromCache(docId: string) {\n this.removeExpirationEntry(docId);\n return Array.from(this.cache)\n .filter(([cachekey]) => {\n const docIdFromKey = cachekey.split(\"_\");\n if (docIdFromKey[0] === docId) {\n return true;\n }\n })\n .map(([cachekey]) => {\n this.cache.delete(cachekey);\n });\n }\n\n private removeExpirationEntry(docId: string) {\n const timeout = this.docIdExpirationMap.get(docId);\n if (timeout !== undefined) {\n clearTimeout(timeout);\n this.docIdExpirationMap.delete(docId);\n }\n }\n\n private updateExpirationEntry(docId: string) {\n this.removeExpirationEntry(docId);\n this.docIdExpirationMap.set(\n docId,\n setTimeout(\n () => {\n this.removeDocIdEntriesFromCache(docId);\n },\n this.snapshotExpiryPolicy,\n ),\n );\n }\n\n private keyFromEntry(entry: ICacheEntry): string {\n return `${entry.file.docId}_${entry.type}_${entry.key}`;\n }\n}\nexport class PromiseCacheWithOneHourSlidingExpiry<T> extends PromiseCache<string, T> {\n constructor(removeOnError?: (e: any) => boolean) {\n super({ expiry: { policy: \"sliding\", durationMs: 3600000 }, removeOnError });\n }\n}\n\n/**\n * Internal cache interface used within driver only\n */\nexport interface INonPersistentCache {\n /**\n * Cache of joined/joining session info\n */\n readonly sessionJoinCache: PromiseCache<string,\n { entryTime: number, joinSessionResponse: ISocketStorageDiscovery }>;\n\n /**\n * Cache of resolved/resolving file URLs\n */\n readonly fileUrlCache: PromiseCache<string, IOdspResolvedUrl>;\n}\n\n/**\n * Internal cache interface used within driver only\n */\nexport interface IOdspCache extends INonPersistentCache {\n /**\n * Persisted cache - only serializable content is allowed\n */\n readonly persistedCache: IPersistedFileCache;\n}\n\nexport class NonPersistentCache implements INonPersistentCache {\n public readonly sessionJoinCache =\n new PromiseCache<string, { entryTime: number, joinSessionResponse: ISocketStorageDiscovery }>();\n\n public readonly fileUrlCache = new PromiseCache<string, IOdspResolvedUrl>();\n}\n"]}
1
+ {"version":3,"file":"odspCache.js","sourceRoot":"","sources":["../src/odspCache.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 */\nimport { PromiseCache } from \"@fluidframework/common-utils\";\nimport {\n IOdspResolvedUrl,\n IFileEntry,\n IEntry,\n IPersistedCache,\n ICacheEntry,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISocketStorageDiscovery } from \"./contracts\";\n/**\n * Similar to IPersistedCache, but exposes cache interface for single file\n */\nexport interface IPersistedFileCache {\n get(entry: IEntry): Promise<any>;\n put(entry: IEntry, value: any): Promise<void>;\n removeEntries(): Promise<void>;\n}\n\n/**\n * Default local-only implementation of IPersistedCache,\n * used if no persisted cache is provided by the host\n */\nexport class LocalPersistentCache implements IPersistedCache {\n private readonly cache = new Map<string, any>();\n // For every document id there will be a single expiration entry inspite of the number of cache entries.\n private readonly docIdExpirationMap = new Map<string, ReturnType<typeof setTimeout>>();\n\n public constructor(private readonly snapshotExpiryPolicy = 3600 * 1000) { }\n\n async get(entry: ICacheEntry): Promise<any> {\n const key = this.keyFromEntry(entry);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return this.cache.get(key);\n }\n\n async put(entry: ICacheEntry, value: any) {\n const key = this.keyFromEntry(entry);\n this.cache.set(key, value);\n this.updateExpirationEntry(entry.file.docId);\n }\n\n async removeEntries(file: IFileEntry): Promise<void> {\n this.removeDocIdEntriesFromCache(file.docId);\n }\n\n private removeDocIdEntriesFromCache(docId: string) {\n this.removeExpirationEntry(docId);\n return Array.from(this.cache)\n .filter(([cachekey]) => {\n const docIdFromKey = cachekey.split(\"_\");\n if (docIdFromKey[0] === docId) {\n return true;\n }\n })\n .map(([cachekey]) => {\n this.cache.delete(cachekey);\n });\n }\n\n private removeExpirationEntry(docId: string) {\n const timeout = this.docIdExpirationMap.get(docId);\n if (timeout !== undefined) {\n clearTimeout(timeout);\n this.docIdExpirationMap.delete(docId);\n }\n }\n\n private updateExpirationEntry(docId: string) {\n this.removeExpirationEntry(docId);\n this.docIdExpirationMap.set(\n docId,\n setTimeout(\n () => {\n this.removeDocIdEntriesFromCache(docId);\n },\n this.snapshotExpiryPolicy,\n ),\n );\n }\n\n private keyFromEntry(entry: ICacheEntry): string {\n return `${entry.file.docId}_${entry.type}_${entry.key}`;\n }\n}\nexport class PromiseCacheWithOneHourSlidingExpiry<T> extends PromiseCache<string, T> {\n constructor(removeOnError?: (e: any) => boolean) {\n super({ expiry: { policy: \"sliding\", durationMs: 3600000 }, removeOnError });\n }\n}\n\n/**\n * Internal cache interface used within driver only\n */\nexport interface INonPersistentCache {\n /**\n * Cache of joined/joining session info\n */\n readonly sessionJoinCache: PromiseCache<string,\n { entryTime: number; joinSessionResponse: ISocketStorageDiscovery; }>;\n\n /**\n * Cache of resolved/resolving file URLs\n */\n readonly fileUrlCache: PromiseCache<string, IOdspResolvedUrl>;\n}\n\n/**\n * Internal cache interface used within driver only\n */\nexport interface IOdspCache extends INonPersistentCache {\n /**\n * Persisted cache - only serializable content is allowed\n */\n readonly persistedCache: IPersistedFileCache;\n}\n\nexport class NonPersistentCache implements INonPersistentCache {\n public readonly sessionJoinCache =\n new PromiseCache<string, { entryTime: number; joinSessionResponse: ISocketStorageDiscovery; }>();\n\n public readonly fileUrlCache = new PromiseCache<string, IOdspResolvedUrl>();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"odspDeltaStorageService.d.ts","sourceRoot":"","sources":["../src/odspDeltaStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAMtG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,qBAAa,uBAAuB;IAE5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAHN,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,+BAA+B,EAChD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,gBAAgB;IAI7C;;;;;;OAMG;IACW,GAAG,CACb,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,kBAAkB,CAAC;IAiEvB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAK3C;AAED,qBAAa,yBAA0B,YAAW,4BAA4B;IAItE,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAK/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAdhC,OAAO,CAAC,cAAc,CAA2B;gBAGrC,WAAW,EAAE,yBAAyB,EAAE,GAAG,SAAS,EAC3C,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,CAC7B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,EACvC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,yBAAyB,EAAE,CAAC,EAC7E,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,EACrD,WAAW,EAAE,CAAC,GAAG,EAAE,yBAAyB,EAAE,KAAK,IAAI;IAI5E,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,yBAAyB,EAAE,EAAE,IAAI,EAAE,MAAM;IAiBvF,aAAa,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,CAAC,EAAE,OAAO,EACpB,WAAW,CAAC,EAAE,MAAM;CAmF3B"}
1
+ {"version":3,"file":"odspDeltaStorageService.d.ts","sourceRoot":"","sources":["../src/odspDeltaStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAMtG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,qBAAa,uBAAuB;IAE5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAHN,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,+BAA+B,EAChD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,gBAAgB;IAI7C;;;;;;OAMG;IACW,GAAG,CACb,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,kBAAkB,CAAC;IAiEvB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAK3C;AAED,qBAAa,yBAA0B,YAAW,4BAA4B;IAItE,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAK/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAdhC,OAAO,CAAC,cAAc,CAA2B;gBAGrC,WAAW,EAAE,yBAAyB,EAAE,GAAG,SAAS,EAC3C,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,CAC7B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,oBAAoB,EACpC,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,EACvC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,yBAAyB,EAAE,CAAC,EAC7E,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,EACrD,WAAW,EAAE,CAAC,GAAG,EAAE,yBAAyB,EAAE,KAAK,IAAI;IAI5E,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,yBAAyB,EAAE,EAAE,IAAI,EAAE,MAAM;IAiBvF,aAAa,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,CAAC,EAAE,OAAO,EACpB,WAAW,CAAC,EAAE,MAAM;CAkF3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"odspDeltaStorageService.js","sourceRoot":"","sources":["../src/odspDeltaStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryLogger, ITelemetryProperties } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { InstrumentedStorageTokenFetcher } from \"@fluidframework/odsp-driver-definitions\";\nimport { IDeltasFetchResult, IDocumentDeltaStorageService } from \"@fluidframework/driver-definitions\";\nimport {\n requestOps,\n streamObserver,\n} from \"@fluidframework/driver-utils\";\nimport { IDeltaStorageGetResponse, ISequencedDeltaOpMessage } from \"./contracts\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { getWithRetryForTokenRefresh } from \"./odspUtils\";\n\n/**\n * Provides access to the underlying delta storage on the server for sharepoint driver.\n */\nexport class OdspDeltaStorageService {\n constructor(\n private readonly deltaFeedUrl: string,\n private readonly getStorageToken: InstrumentedStorageTokenFetcher,\n private readonly epochTracker: EpochTracker,\n private readonly logger: ITelemetryLogger,\n ) {\n }\n\n /**\n * Retrieves ops from cache\n * @param from - inclusive\n * @param to - exclusive\n * @param telemetryProps - properties to add when issuing telemetry events\n * @returns ops retrieved & info if result was partial (i.e. more is available)\n */\n public async get(\n from: number,\n to: number,\n telemetryProps: ITelemetryProperties,\n fetchReason?: string,\n ): Promise<IDeltasFetchResult> {\n return getWithRetryForTokenRefresh(async (options) => {\n // Note - this call ends up in getSocketStorageDiscovery() and can refresh token\n // Thus it needs to be done before we call getStorageToken() to reduce extra calls\n const baseUrl = this.buildUrl(from, to);\n const storageToken = await this.getStorageToken(options, \"DeltaStorage\");\n\n const formBoundary = uuid();\n let postBody = `--${formBoundary}\\r\\n`;\n postBody += `Authorization: Bearer ${storageToken}\\r\\n`;\n postBody += `X-HTTP-Method-Override: GET\\r\\n`;\n\n postBody += `_post: 1\\r\\n`;\n postBody += `\\r\\n--${formBoundary}--`;\n const headers: {[index: string]: any} = {\n \"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n };\n\n // Some request take a long time (1-2 minutes) to complete, where telemetry shows very small amount\n // of time spent on server, and usually small payload sizes. I.e. all the time is spent somewhere in\n // networking. Even bigger problem - a lot of requests timeout (based on cursory look - after 1-2 minutes)\n // So adding some timeout to ensure we retry again in hope of faster success.\n // Please see https://github.com/microsoft/FluidFramework/issues/6997 for details.\n const abort = new AbortController();\n const timer = setTimeout(() => abort.abort(), 30000);\n\n const response = await this.epochTracker.fetchAndParseAsJSON<IDeltaStorageGetResponse>(\n baseUrl,\n {\n headers,\n body: postBody,\n method: \"POST\",\n signal: abort.signal,\n },\n \"ops\",\n true,\n fetchReason,\n );\n clearTimeout(timer);\n const deltaStorageResponse = response.content;\n let messages: ISequencedDocumentMessage[];\n if (deltaStorageResponse.value.length > 0 && \"op\" in deltaStorageResponse.value[0]) {\n messages = (deltaStorageResponse.value as ISequencedDeltaOpMessage[]).map((operation) => operation.op);\n } else {\n messages = deltaStorageResponse.value as ISequencedDocumentMessage[];\n }\n\n this.logger.sendPerformanceEvent({\n eventName: \"OpsFetch\",\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n length: messages.length,\n duration: response.duration, // this duration for single attempt!\n ...response.propsToLog,\n attempts: options.refresh ? 2 : 1,\n from,\n to,\n ...telemetryProps,\n });\n\n // It is assumed that server always returns all the ops that it has in the range that was requested.\n // This may change in the future, if so, we need to adjust and receive \"end\" value from server in such case.\n return { messages, partialResult: false };\n });\n }\n\n public buildUrl(from: number, to: number) {\n const filter = encodeURIComponent(`sequenceNumber ge ${from} and sequenceNumber le ${to - 1}`);\n const queryString = `?ump=1&filter=${filter}`;\n return `${this.deltaFeedUrl}${queryString}`;\n }\n}\n\nexport class OdspDeltaStorageWithCache implements IDocumentDeltaStorageService {\n private firstCacheMiss = Number.MAX_SAFE_INTEGER;\n\n public constructor(\n private snapshotOps: ISequencedDocumentMessage[] | undefined,\n private readonly logger: ITelemetryLogger,\n private readonly batchSize: number,\n private readonly concurrency: number,\n private readonly getFromStorage: (\n from: number,\n to: number,\n telemetryProps: ITelemetryProperties,\n fetchReason?: string) => Promise<IDeltasFetchResult>,\n private readonly getCached: (from: number, to: number) => Promise<ISequencedDocumentMessage[]>,\n private readonly requestFromSocket: (from: number, to: number) => void,\n private readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,\n ) {\n }\n\n protected validateMessages(reason: string, messages: ISequencedDocumentMessage[], from: number) {\n if (messages.length !== 0) {\n const start = messages[0].sequenceNumber;\n const length = messages.length;\n const last = messages[length - 1].sequenceNumber;\n if (start !== from) {\n this.logger.sendErrorEvent({ eventName: \"OpsFetchViolation\", reason, from, start, last, length});\n messages.length = 0;\n }\n if (last + 1 !== from + length) {\n this.logger.sendErrorEvent({ eventName: \"OpsFetchViolation\", reason, from, start, last, length});\n // we can do better here by finding consecutive sub-block and return it\n messages.length = 0;\n }\n }\n }\n\n public fetchMessages(\n fromTotal: number,\n toTotal: number | undefined,\n abortSignal?: AbortSignal,\n cachedOnly?: boolean,\n fetchReason?: string)\n {\n // We do not control what's in the cache. Current API assumes that fetchMessages() keeps banging on\n // storage / cache until it gets ops it needs. This would result in deadlock if fixed range is asked from\n // cache and it's not there.\n // Better implementation would be to return only what we have in cache, but that also breaks API\n assert(!cachedOnly || toTotal === undefined, 0x1e3);\n\n let opsFromSnapshot = 0;\n let opsFromCache = 0;\n let opsFromStorage = 0;\n\n const requestCallback = async (from: number, to: number, telemetryProps: ITelemetryProperties) => {\n if (this.snapshotOps !== undefined && this.snapshotOps.length !== 0) {\n const messages = this.snapshotOps.filter((op) =>\n op.sequenceNumber >= from && op.sequenceNumber < to);\n this.validateMessages(\"cached\", messages, from);\n if (messages.length > 0 && messages[0].sequenceNumber === from) {\n this.snapshotOps = this.snapshotOps.filter((op) => op.sequenceNumber >= to);\n opsFromSnapshot = messages.length;\n return { messages, partialResult: true };\n }\n this.snapshotOps = undefined;\n }\n\n // Kick out request to PUSH for ops if it has them\n this.requestFromSocket(from, to);\n\n // Cache in normal flow is continuous. Once there is a miss, stop consulting cache.\n // This saves a bit of processing time\n if (from < this.firstCacheMiss) {\n const messagesFromCache = await this.getCached(from, to);\n this.validateMessages(\"cached\", messagesFromCache, from);\n if (messagesFromCache.length !== 0) {\n opsFromCache += messagesFromCache.length;\n return {\n messages: messagesFromCache,\n partialResult: true,\n };\n }\n this.firstCacheMiss = Math.min(this.firstCacheMiss, from);\n }\n\n if (cachedOnly) {\n return { messages: [], partialResult: false };\n }\n\n const ops = await this.getFromStorage(from, to, telemetryProps, fetchReason);\n this.validateMessages(\"storage\", ops.messages, from);\n opsFromStorage += ops.messages.length;\n this.opsReceived(ops.messages);\n return ops;\n };\n\n const stream = requestOps(\n async (from: number, to: number, telemetryProps: ITelemetryProperties) => {\n const result = await requestCallback(from, to, telemetryProps);\n // Catch all case, just in case\n this.validateMessages(\"catch all\", result.messages, from);\n return result;\n },\n // Staging: starting with no concurrency, listening for feedback first.\n // In future releases we will switch to actual concurrency\n this.concurrency,\n fromTotal, // inclusive\n toTotal, // exclusive\n this.batchSize,\n this.logger,\n abortSignal,\n fetchReason,\n );\n\n return streamObserver(stream, (result) => {\n if (result.done && opsFromSnapshot + opsFromCache + opsFromStorage !== 0) {\n this.logger.sendPerformanceEvent({\n eventName: \"CacheOpsRetrieved\",\n opsFromSnapshot,\n opsFromCache,\n opsFromStorage,\n });\n }\n });\n}\n}\n"]}
1
+ {"version":3,"file":"odspDeltaStorageService.js","sourceRoot":"","sources":["../src/odspDeltaStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryLogger, ITelemetryProperties } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { InstrumentedStorageTokenFetcher } from \"@fluidframework/odsp-driver-definitions\";\nimport { IDeltasFetchResult, IDocumentDeltaStorageService } from \"@fluidframework/driver-definitions\";\nimport {\n requestOps,\n streamObserver,\n} from \"@fluidframework/driver-utils\";\nimport { IDeltaStorageGetResponse, ISequencedDeltaOpMessage } from \"./contracts\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { getWithRetryForTokenRefresh } from \"./odspUtils\";\n\n/**\n * Provides access to the underlying delta storage on the server for sharepoint driver.\n */\nexport class OdspDeltaStorageService {\n constructor(\n private readonly deltaFeedUrl: string,\n private readonly getStorageToken: InstrumentedStorageTokenFetcher,\n private readonly epochTracker: EpochTracker,\n private readonly logger: ITelemetryLogger,\n ) {\n }\n\n /**\n * Retrieves ops from cache\n * @param from - inclusive\n * @param to - exclusive\n * @param telemetryProps - properties to add when issuing telemetry events\n * @returns ops retrieved & info if result was partial (i.e. more is available)\n */\n public async get(\n from: number,\n to: number,\n telemetryProps: ITelemetryProperties,\n fetchReason?: string,\n ): Promise<IDeltasFetchResult> {\n return getWithRetryForTokenRefresh(async (options) => {\n // Note - this call ends up in getSocketStorageDiscovery() and can refresh token\n // Thus it needs to be done before we call getStorageToken() to reduce extra calls\n const baseUrl = this.buildUrl(from, to);\n const storageToken = await this.getStorageToken(options, \"DeltaStorage\");\n\n const formBoundary = uuid();\n let postBody = `--${formBoundary}\\r\\n`;\n postBody += `Authorization: Bearer ${storageToken}\\r\\n`;\n postBody += `X-HTTP-Method-Override: GET\\r\\n`;\n\n postBody += `_post: 1\\r\\n`;\n postBody += `\\r\\n--${formBoundary}--`;\n const headers: { [index: string]: any; } = {\n \"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n };\n\n // Some request take a long time (1-2 minutes) to complete, where telemetry shows very small amount\n // of time spent on server, and usually small payload sizes. I.e. all the time is spent somewhere in\n // networking. Even bigger problem - a lot of requests timeout (based on cursory look - after 1-2 minutes)\n // So adding some timeout to ensure we retry again in hope of faster success.\n // Please see https://github.com/microsoft/FluidFramework/issues/6997 for details.\n const abort = new AbortController();\n const timer = setTimeout(() => abort.abort(), 30000);\n\n const response = await this.epochTracker.fetchAndParseAsJSON<IDeltaStorageGetResponse>(\n baseUrl,\n {\n headers,\n body: postBody,\n method: \"POST\",\n signal: abort.signal,\n },\n \"ops\",\n true,\n fetchReason,\n );\n clearTimeout(timer);\n const deltaStorageResponse = response.content;\n let messages: ISequencedDocumentMessage[];\n if (deltaStorageResponse.value.length > 0 && \"op\" in deltaStorageResponse.value[0]) {\n messages = (deltaStorageResponse.value as ISequencedDeltaOpMessage[]).map((operation) => operation.op);\n } else {\n messages = deltaStorageResponse.value as ISequencedDocumentMessage[];\n }\n\n this.logger.sendPerformanceEvent({\n eventName: \"OpsFetch\",\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n length: messages.length,\n duration: response.duration, // this duration for single attempt!\n ...response.propsToLog,\n attempts: options.refresh ? 2 : 1,\n from,\n to,\n ...telemetryProps,\n });\n\n // It is assumed that server always returns all the ops that it has in the range that was requested.\n // This may change in the future, if so, we need to adjust and receive \"end\" value from server in such case.\n return { messages, partialResult: false };\n });\n }\n\n public buildUrl(from: number, to: number) {\n const filter = encodeURIComponent(`sequenceNumber ge ${from} and sequenceNumber le ${to - 1}`);\n const queryString = `?ump=1&filter=${filter}`;\n return `${this.deltaFeedUrl}${queryString}`;\n }\n}\n\nexport class OdspDeltaStorageWithCache implements IDocumentDeltaStorageService {\n private firstCacheMiss = Number.MAX_SAFE_INTEGER;\n\n public constructor(\n private snapshotOps: ISequencedDocumentMessage[] | undefined,\n private readonly logger: ITelemetryLogger,\n private readonly batchSize: number,\n private readonly concurrency: number,\n private readonly getFromStorage: (\n from: number,\n to: number,\n telemetryProps: ITelemetryProperties,\n fetchReason?: string) => Promise<IDeltasFetchResult>,\n private readonly getCached: (from: number, to: number) => Promise<ISequencedDocumentMessage[]>,\n private readonly requestFromSocket: (from: number, to: number) => void,\n private readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,\n ) {\n }\n\n protected validateMessages(reason: string, messages: ISequencedDocumentMessage[], from: number) {\n if (messages.length !== 0) {\n const start = messages[0].sequenceNumber;\n const length = messages.length;\n const last = messages[length - 1].sequenceNumber;\n if (start !== from) {\n this.logger.sendErrorEvent({ eventName: \"OpsFetchViolation\", reason, from, start, last, length });\n messages.length = 0;\n }\n if (last + 1 !== from + length) {\n this.logger.sendErrorEvent({ eventName: \"OpsFetchViolation\", reason, from, start, last, length });\n // we can do better here by finding consecutive sub-block and return it\n messages.length = 0;\n }\n }\n }\n\n public fetchMessages(\n fromTotal: number,\n toTotal: number | undefined,\n abortSignal?: AbortSignal,\n cachedOnly?: boolean,\n fetchReason?: string) {\n // We do not control what's in the cache. Current API assumes that fetchMessages() keeps banging on\n // storage / cache until it gets ops it needs. This would result in deadlock if fixed range is asked from\n // cache and it's not there.\n // Better implementation would be to return only what we have in cache, but that also breaks API\n assert(!cachedOnly || toTotal === undefined, 0x1e3);\n\n let opsFromSnapshot = 0;\n let opsFromCache = 0;\n let opsFromStorage = 0;\n\n const requestCallback = async (from: number, to: number, telemetryProps: ITelemetryProperties) => {\n if (this.snapshotOps !== undefined && this.snapshotOps.length !== 0) {\n const messages = this.snapshotOps.filter((op) =>\n op.sequenceNumber >= from && op.sequenceNumber < to);\n this.validateMessages(\"cached\", messages, from);\n if (messages.length > 0 && messages[0].sequenceNumber === from) {\n this.snapshotOps = this.snapshotOps.filter((op) => op.sequenceNumber >= to);\n opsFromSnapshot = messages.length;\n return { messages, partialResult: true };\n }\n this.snapshotOps = undefined;\n }\n\n // Kick out request to PUSH for ops if it has them\n this.requestFromSocket(from, to);\n\n // Cache in normal flow is continuous. Once there is a miss, stop consulting cache.\n // This saves a bit of processing time\n if (from < this.firstCacheMiss) {\n const messagesFromCache = await this.getCached(from, to);\n this.validateMessages(\"cached\", messagesFromCache, from);\n if (messagesFromCache.length !== 0) {\n opsFromCache += messagesFromCache.length;\n return {\n messages: messagesFromCache,\n partialResult: true,\n };\n }\n this.firstCacheMiss = Math.min(this.firstCacheMiss, from);\n }\n\n if (cachedOnly) {\n return { messages: [], partialResult: false };\n }\n\n const ops = await this.getFromStorage(from, to, telemetryProps, fetchReason);\n this.validateMessages(\"storage\", ops.messages, from);\n opsFromStorage += ops.messages.length;\n this.opsReceived(ops.messages);\n return ops;\n };\n\n const stream = requestOps(\n async (from: number, to: number, telemetryProps: ITelemetryProperties) => {\n const result = await requestCallback(from, to, telemetryProps);\n // Catch all case, just in case\n this.validateMessages(\"catch all\", result.messages, from);\n return result;\n },\n // Staging: starting with no concurrency, listening for feedback first.\n // In future releases we will switch to actual concurrency\n this.concurrency,\n fromTotal, // inclusive\n toTotal, // exclusive\n this.batchSize,\n this.logger,\n abortSignal,\n fetchReason,\n );\n\n return streamObserver(stream, (result) => {\n if (result.done && opsFromSnapshot + opsFromCache + opsFromStorage !== 0) {\n this.logger.sendPerformanceEvent({\n eventName: \"CacheOpsRetrieved\",\n opsFromSnapshot,\n opsFromCache,\n opsFromStorage,\n });\n }\n });\n}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"odspDocumentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/odspDocumentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAA6B,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACH,OAAO,EACP,QAAQ,EAIX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAU,EAAE,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ9C,MAAM,WAAW,WAAW;IACxB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,WAAW,aAAc,SAAQ,MAAM;IACzC,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,IAAI,OAAE;CACxF;AAyID;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,uBAAuB;IAoKhE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAnKxC;;;;;;;;;;;;;;;OAeG;WACiB,MAAM,CACtB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,EAAE,EAAE,OAAO,oBAAoB,EAC/B,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,gBAAgB,EACjC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,wBAAwB,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAsEvF,OAAO,CAAC,eAAe,CAA8B;IAErD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuE;IACjG,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,aAAa,CAAoC;IAEzD;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,QAAQ,UAAO,GAAG,eAAe;IAW3F;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA8B3C;;;;;;OAMG;IACH,OAAO;IAYP;;;;;OAKG;IACK,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAwD9B,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IA4B1C,SAAS,CAAC,uBAAuB,UAAW,eAAe,GAAG,SAAS,UAErE;cAEc,UAAU,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IAqFpE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;IAsC9E;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe;CAe7E"}
1
+ {"version":3,"file":"odspDocumentDeltaConnection.d.ts","sourceRoot":"","sources":["../src/odspDocumentDeltaConnection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAA6B,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACH,OAAO,EACP,QAAQ,EAIX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAU,EAAE,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ9C,MAAM,WAAW,WAAW;IACxB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,WAAW,aAAc,SAAQ,MAAM;IACzC,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,IAAI,OAAE;CACxF;AAyID;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,uBAAuB;IAoKhE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAnKxC;;;;;;;;;;;;;;;OAeG;WACiB,MAAM,CACtB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,EAAE,EAAE,OAAO,oBAAoB,EAC/B,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,gBAAgB,EACjC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,wBAAwB,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAsEvF,OAAO,CAAC,eAAe,CAA8B;IAErD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAC/C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwE;IAClG,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,aAAa,CAAoC;IAEzD;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,QAAQ,UAAO,GAAG,eAAe;IAW3F;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IA8B3C;;;;;;OAMG;IACH,OAAO;IAYP;;;;;OAKG;IACK,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAwD9B,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IA4B1C,SAAS,CAAC,uBAAuB,UAAW,eAAe,GAAG,SAAS,UAErE;cAEc,UAAU,CAAC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM;IAqFpE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;IAsC9E;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe;CAe7E"}
@@ -46,7 +46,7 @@ class SocketReference extends TypedEventEmitter {
46
46
  static find(key, logger) {
47
47
  const socketReference = SocketReference.socketIoSockets.get(key);
48
48
  // Verify the socket is healthy before reusing it
49
- if (socketReference && socketReference.disconnected) {
49
+ if (socketReference === null || socketReference === void 0 ? void 0 : socketReference.disconnected) {
50
50
  // The socket is in a bad state. fully remove the reference
51
51
  socketReference.closeSocket();
52
52
  return undefined;