@fluidframework/odsp-driver 2.1.0-274160 → 2.1.0-276985

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 (252) hide show
  1. package/README.md +3 -1
  2. package/api-report/{odsp-driver.alpha.api.md → odsp-driver.legacy.alpha.api.md} +1 -1
  3. package/dist/checkUrl.d.ts +1 -0
  4. package/dist/checkUrl.d.ts.map +1 -1
  5. package/dist/checkUrl.js +1 -0
  6. package/dist/checkUrl.js.map +1 -1
  7. package/dist/constants.d.ts +2 -0
  8. package/dist/constants.d.ts.map +1 -1
  9. package/dist/constants.js +2 -0
  10. package/dist/constants.js.map +1 -1
  11. package/dist/contractsPublic.d.ts +1 -0
  12. package/dist/contractsPublic.d.ts.map +1 -1
  13. package/dist/contractsPublic.js.map +1 -1
  14. package/dist/createFile.d.ts +3 -3
  15. package/dist/createFile.d.ts.map +1 -1
  16. package/dist/createFile.js +11 -9
  17. package/dist/createFile.js.map +1 -1
  18. package/dist/createNewContainerOnExistingFile.d.ts +1 -1
  19. package/dist/createNewContainerOnExistingFile.d.ts.map +1 -1
  20. package/dist/createNewContainerOnExistingFile.js +2 -2
  21. package/dist/createNewContainerOnExistingFile.js.map +1 -1
  22. package/dist/createNewUtils.d.ts +1 -1
  23. package/dist/createNewUtils.d.ts.map +1 -1
  24. package/dist/createNewUtils.js +24 -18
  25. package/dist/createNewUtils.js.map +1 -1
  26. package/dist/createOdspCreateContainerRequest.d.ts +1 -0
  27. package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
  28. package/dist/createOdspCreateContainerRequest.js +1 -0
  29. package/dist/createOdspCreateContainerRequest.js.map +1 -1
  30. package/dist/createOdspUrl.d.ts +1 -0
  31. package/dist/createOdspUrl.d.ts.map +1 -1
  32. package/dist/createOdspUrl.js +1 -0
  33. package/dist/createOdspUrl.js.map +1 -1
  34. package/dist/epochTracker.d.ts +4 -0
  35. package/dist/epochTracker.d.ts.map +1 -1
  36. package/dist/epochTracker.js +1 -0
  37. package/dist/epochTracker.js.map +1 -1
  38. package/dist/fetchSnapshot.d.ts +7 -9
  39. package/dist/fetchSnapshot.d.ts.map +1 -1
  40. package/dist/fetchSnapshot.js +23 -21
  41. package/dist/fetchSnapshot.js.map +1 -1
  42. package/dist/getFileLink.js +14 -8
  43. package/dist/getFileLink.js.map +1 -1
  44. package/dist/getUrlAndHeadersWithAuth.d.ts +2 -5
  45. package/dist/getUrlAndHeadersWithAuth.d.ts.map +1 -1
  46. package/dist/getUrlAndHeadersWithAuth.js +7 -28
  47. package/dist/getUrlAndHeadersWithAuth.js.map +1 -1
  48. package/dist/legacy.d.ts +1 -1
  49. package/dist/odspCache.d.ts +4 -0
  50. package/dist/odspCache.d.ts.map +1 -1
  51. package/dist/odspCache.js.map +1 -1
  52. package/dist/odspDelayLoadedDeltaStream.d.ts +3 -4
  53. package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  54. package/dist/odspDelayLoadedDeltaStream.js +4 -5
  55. package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
  56. package/dist/odspDeltaStorageService.d.ts +2 -2
  57. package/dist/odspDeltaStorageService.d.ts.map +1 -1
  58. package/dist/odspDeltaStorageService.js +9 -8
  59. package/dist/odspDeltaStorageService.js.map +1 -1
  60. package/dist/odspDocumentService.d.ts +4 -4
  61. package/dist/odspDocumentService.d.ts.map +1 -1
  62. package/dist/odspDocumentService.js +9 -9
  63. package/dist/odspDocumentService.js.map +1 -1
  64. package/dist/odspDocumentServiceFactory.d.ts +2 -0
  65. package/dist/odspDocumentServiceFactory.d.ts.map +1 -1
  66. package/dist/odspDocumentServiceFactory.js +2 -0
  67. package/dist/odspDocumentServiceFactory.js.map +1 -1
  68. package/dist/odspDocumentServiceFactoryCore.d.ts +1 -0
  69. package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  70. package/dist/odspDocumentServiceFactoryCore.js +7 -4
  71. package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
  72. package/dist/odspDocumentStorageManager.d.ts +2 -2
  73. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  74. package/dist/odspDocumentStorageManager.js +25 -19
  75. package/dist/odspDocumentStorageManager.js.map +1 -1
  76. package/dist/odspDriverUrlResolver.d.ts +9 -0
  77. package/dist/odspDriverUrlResolver.d.ts.map +1 -1
  78. package/dist/odspDriverUrlResolver.js +3 -1
  79. package/dist/odspDriverUrlResolver.js.map +1 -1
  80. package/dist/odspDriverUrlResolverForShareLink.d.ts +2 -0
  81. package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  82. package/dist/odspDriverUrlResolverForShareLink.js +1 -0
  83. package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
  84. package/dist/odspFluidFileLink.d.ts +4 -0
  85. package/dist/odspFluidFileLink.d.ts.map +1 -1
  86. package/dist/odspFluidFileLink.js +4 -0
  87. package/dist/odspFluidFileLink.js.map +1 -1
  88. package/dist/odspPublicUtils.d.ts +2 -0
  89. package/dist/odspPublicUtils.d.ts.map +1 -1
  90. package/dist/odspPublicUtils.js +1 -0
  91. package/dist/odspPublicUtils.js.map +1 -1
  92. package/dist/odspSnapshotParser.js +2 -2
  93. package/dist/odspSnapshotParser.js.map +1 -1
  94. package/dist/odspSummaryUploadManager.d.ts +2 -3
  95. package/dist/odspSummaryUploadManager.d.ts.map +1 -1
  96. package/dist/odspSummaryUploadManager.js +8 -6
  97. package/dist/odspSummaryUploadManager.js.map +1 -1
  98. package/dist/odspUtils.d.ts +12 -3
  99. package/dist/odspUtils.d.ts.map +1 -1
  100. package/dist/odspUtils.js +10 -6
  101. package/dist/odspUtils.js.map +1 -1
  102. package/dist/packageVersion.d.ts +1 -1
  103. package/dist/packageVersion.js +1 -1
  104. package/dist/packageVersion.js.map +1 -1
  105. package/dist/prefetchLatestSnapshot.d.ts +2 -1
  106. package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
  107. package/dist/prefetchLatestSnapshot.js +6 -5
  108. package/dist/prefetchLatestSnapshot.js.map +1 -1
  109. package/dist/vroom.d.ts +2 -2
  110. package/dist/vroom.d.ts.map +1 -1
  111. package/dist/vroom.js +7 -9
  112. package/dist/vroom.js.map +1 -1
  113. package/lib/checkUrl.d.ts +1 -0
  114. package/lib/checkUrl.d.ts.map +1 -1
  115. package/lib/checkUrl.js +1 -0
  116. package/lib/checkUrl.js.map +1 -1
  117. package/lib/constants.d.ts +2 -0
  118. package/lib/constants.d.ts.map +1 -1
  119. package/lib/constants.js +2 -0
  120. package/lib/constants.js.map +1 -1
  121. package/lib/contractsPublic.d.ts +1 -0
  122. package/lib/contractsPublic.d.ts.map +1 -1
  123. package/lib/contractsPublic.js.map +1 -1
  124. package/lib/createFile.d.ts +3 -3
  125. package/lib/createFile.d.ts.map +1 -1
  126. package/lib/createFile.js +12 -10
  127. package/lib/createFile.js.map +1 -1
  128. package/lib/createNewContainerOnExistingFile.d.ts +1 -1
  129. package/lib/createNewContainerOnExistingFile.d.ts.map +1 -1
  130. package/lib/createNewContainerOnExistingFile.js +2 -2
  131. package/lib/createNewContainerOnExistingFile.js.map +1 -1
  132. package/lib/createNewUtils.d.ts +1 -1
  133. package/lib/createNewUtils.d.ts.map +1 -1
  134. package/lib/createNewUtils.js +26 -20
  135. package/lib/createNewUtils.js.map +1 -1
  136. package/lib/createOdspCreateContainerRequest.d.ts +1 -0
  137. package/lib/createOdspCreateContainerRequest.d.ts.map +1 -1
  138. package/lib/createOdspCreateContainerRequest.js +1 -0
  139. package/lib/createOdspCreateContainerRequest.js.map +1 -1
  140. package/lib/createOdspUrl.d.ts +1 -0
  141. package/lib/createOdspUrl.d.ts.map +1 -1
  142. package/lib/createOdspUrl.js +1 -0
  143. package/lib/createOdspUrl.js.map +1 -1
  144. package/lib/epochTracker.d.ts +4 -0
  145. package/lib/epochTracker.d.ts.map +1 -1
  146. package/lib/epochTracker.js +1 -0
  147. package/lib/epochTracker.js.map +1 -1
  148. package/lib/fetchSnapshot.d.ts +7 -9
  149. package/lib/fetchSnapshot.d.ts.map +1 -1
  150. package/lib/fetchSnapshot.js +24 -22
  151. package/lib/fetchSnapshot.js.map +1 -1
  152. package/lib/getFileLink.js +15 -9
  153. package/lib/getFileLink.js.map +1 -1
  154. package/lib/getUrlAndHeadersWithAuth.d.ts +2 -5
  155. package/lib/getUrlAndHeadersWithAuth.d.ts.map +1 -1
  156. package/lib/getUrlAndHeadersWithAuth.js +5 -26
  157. package/lib/getUrlAndHeadersWithAuth.js.map +1 -1
  158. package/lib/legacy.d.ts +1 -1
  159. package/lib/odspCache.d.ts +4 -0
  160. package/lib/odspCache.d.ts.map +1 -1
  161. package/lib/odspCache.js.map +1 -1
  162. package/lib/odspDelayLoadedDeltaStream.d.ts +3 -4
  163. package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  164. package/lib/odspDelayLoadedDeltaStream.js +4 -5
  165. package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
  166. package/lib/odspDeltaStorageService.d.ts +2 -2
  167. package/lib/odspDeltaStorageService.d.ts.map +1 -1
  168. package/lib/odspDeltaStorageService.js +9 -8
  169. package/lib/odspDeltaStorageService.js.map +1 -1
  170. package/lib/odspDocumentService.d.ts +4 -4
  171. package/lib/odspDocumentService.d.ts.map +1 -1
  172. package/lib/odspDocumentService.js +9 -9
  173. package/lib/odspDocumentService.js.map +1 -1
  174. package/lib/odspDocumentServiceFactory.d.ts +2 -0
  175. package/lib/odspDocumentServiceFactory.d.ts.map +1 -1
  176. package/lib/odspDocumentServiceFactory.js +2 -0
  177. package/lib/odspDocumentServiceFactory.js.map +1 -1
  178. package/lib/odspDocumentServiceFactoryCore.d.ts +1 -0
  179. package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  180. package/lib/odspDocumentServiceFactoryCore.js +7 -4
  181. package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
  182. package/lib/odspDocumentStorageManager.d.ts +2 -2
  183. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  184. package/lib/odspDocumentStorageManager.js +26 -20
  185. package/lib/odspDocumentStorageManager.js.map +1 -1
  186. package/lib/odspDriverUrlResolver.d.ts +9 -0
  187. package/lib/odspDriverUrlResolver.d.ts.map +1 -1
  188. package/lib/odspDriverUrlResolver.js +2 -1
  189. package/lib/odspDriverUrlResolver.js.map +1 -1
  190. package/lib/odspDriverUrlResolverForShareLink.d.ts +2 -0
  191. package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  192. package/lib/odspDriverUrlResolverForShareLink.js +1 -0
  193. package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
  194. package/lib/odspFluidFileLink.d.ts +4 -0
  195. package/lib/odspFluidFileLink.d.ts.map +1 -1
  196. package/lib/odspFluidFileLink.js +4 -0
  197. package/lib/odspFluidFileLink.js.map +1 -1
  198. package/lib/odspPublicUtils.d.ts +2 -0
  199. package/lib/odspPublicUtils.d.ts.map +1 -1
  200. package/lib/odspPublicUtils.js +1 -0
  201. package/lib/odspPublicUtils.js.map +1 -1
  202. package/lib/odspSnapshotParser.js +2 -2
  203. package/lib/odspSnapshotParser.js.map +1 -1
  204. package/lib/odspSummaryUploadManager.d.ts +2 -3
  205. package/lib/odspSummaryUploadManager.d.ts.map +1 -1
  206. package/lib/odspSummaryUploadManager.js +9 -7
  207. package/lib/odspSummaryUploadManager.js.map +1 -1
  208. package/lib/odspUtils.d.ts +12 -3
  209. package/lib/odspUtils.d.ts.map +1 -1
  210. package/lib/odspUtils.js +11 -7
  211. package/lib/odspUtils.js.map +1 -1
  212. package/lib/packageVersion.d.ts +1 -1
  213. package/lib/packageVersion.js +1 -1
  214. package/lib/packageVersion.js.map +1 -1
  215. package/lib/prefetchLatestSnapshot.d.ts +2 -1
  216. package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
  217. package/lib/prefetchLatestSnapshot.js +6 -5
  218. package/lib/prefetchLatestSnapshot.js.map +1 -1
  219. package/lib/vroom.d.ts +2 -2
  220. package/lib/vroom.d.ts.map +1 -1
  221. package/lib/vroom.js +7 -9
  222. package/lib/vroom.js.map +1 -1
  223. package/package.json +13 -13
  224. package/src/checkUrl.ts +1 -0
  225. package/src/constants.ts +2 -0
  226. package/src/contractsPublic.ts +1 -0
  227. package/src/createFile.ts +15 -21
  228. package/src/createNewContainerOnExistingFile.ts +2 -2
  229. package/src/createNewUtils.ts +35 -26
  230. package/src/createOdspCreateContainerRequest.ts +1 -0
  231. package/src/createOdspUrl.ts +1 -0
  232. package/src/epochTracker.ts +4 -0
  233. package/src/fetchSnapshot.ts +36 -34
  234. package/src/getFileLink.ts +27 -20
  235. package/src/getUrlAndHeadersWithAuth.ts +6 -31
  236. package/src/odspCache.ts +4 -0
  237. package/src/odspDelayLoadedDeltaStream.ts +4 -5
  238. package/src/odspDeltaStorageService.ts +11 -7
  239. package/src/odspDocumentService.ts +8 -8
  240. package/src/odspDocumentServiceFactory.ts +2 -0
  241. package/src/odspDocumentServiceFactoryCore.ts +6 -3
  242. package/src/odspDocumentStorageManager.ts +36 -33
  243. package/src/odspDriverUrlResolver.ts +2 -1
  244. package/src/odspDriverUrlResolverForShareLink.ts +2 -0
  245. package/src/odspFluidFileLink.ts +4 -0
  246. package/src/odspPublicUtils.ts +2 -0
  247. package/src/odspSnapshotParser.ts +2 -2
  248. package/src/odspSummaryUploadManager.ts +11 -10
  249. package/src/odspUtils.ts +20 -6
  250. package/src/packageVersion.ts +1 -1
  251. package/src/prefetchLatestSnapshot.ts +10 -5
  252. package/src/vroom.ts +11 -11
@@ -16,7 +16,7 @@ import { createCacheSnapshotKey, createOdspLogger, getOdspResolvedUrl, toInstrum
16
16
  * @param getStorageToken - function that can provide the storage token for a given site. This is
17
17
  * is also referred to as the "VROOM" token in SPO.
18
18
  * @param persistedCache - Cache to store the fetched snapshot.
19
- * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header.
19
+ * @param forceAccessTokenViaAuthorizationHeader - @deprecated Not used, true value always used instead. Whether to force passing given token via authorization header.
20
20
  * @param logger - Logger to have telemetry events.
21
21
  * @param hostSnapshotFetchOptions - Options to fetch the snapshot if any. Otherwise default will be used.
22
22
  * @param enableRedeemFallback - True to have the sharing link redeem fallback in case the Trees Latest/Redeem
@@ -28,6 +28,7 @@ import { createCacheSnapshotKey, createOdspLogger, getOdspResolvedUrl, toInstrum
28
28
  * @param odspDocumentServiceFactory - factory to access the non persistent cache and store the prefetch promise.
29
29
  *
30
30
  * @returns `true` if the snapshot is cached, `false` otherwise.
31
+ * @legacy
31
32
  * @alpha
32
33
  */
33
34
  export async function prefetchLatestSnapshot(resolvedUrl, getStorageToken, persistedCache, forceAccessTokenViaAuthorizationHeader, logger, hostSnapshotFetchOptions, enableRedeemFallback = true, fetchBinarySnapshotFormat, snapshotFormatFetchType, odspDocumentServiceFactory) {
@@ -43,9 +44,9 @@ export async function prefetchLatestSnapshot(resolvedUrl, getStorageToken, persi
43
44
  driveId: odspResolvedUrl.driveId,
44
45
  itemId: odspResolvedUrl.itemId,
45
46
  };
46
- const storageTokenFetcher = toInstrumentedOdspStorageTokenFetcher(odspLogger, resolvedUrlData, getStorageToken);
47
- const snapshotDownloader = async (finalOdspResolvedUrl, storageToken, loadingGroupId, snapshotOptions, controller) => {
48
- return downloadSnapshot(finalOdspResolvedUrl, storageToken, loadingGroupId, snapshotOptions, undefined, controller);
47
+ const getAuthHeader = toInstrumentedOdspStorageTokenFetcher(odspLogger, resolvedUrlData, getStorageToken);
48
+ const snapshotDownloader = async (finalOdspResolvedUrl, storageTokenFetcher, tokenFetchOptions, loadingGroupId, snapshotOptions, controller) => {
49
+ return downloadSnapshot(finalOdspResolvedUrl, storageTokenFetcher, tokenFetchOptions, loadingGroupId, snapshotOptions, undefined, controller);
49
50
  };
50
51
  const snapshotKey = createCacheSnapshotKey(odspResolvedUrl);
51
52
  let cacheP;
@@ -63,7 +64,7 @@ export async function prefetchLatestSnapshot(resolvedUrl, getStorageToken, persi
63
64
  const nonPersistentCacheKey = getKeyForCacheEntry(snapshotKey);
64
65
  const snapshotNonPersistentCache = odspDocumentServiceFactory?.snapshotPrefetchResultCache;
65
66
  snapshotNonPersistentCache?.add(nonPersistentCacheKey, async () => snapshotContentsWithEpochP.promise);
66
- await fetchSnapshotWithRedeem(odspResolvedUrl, storageTokenFetcher, hostSnapshotFetchOptions, forceAccessTokenViaAuthorizationHeader, odspLogger, snapshotDownloader, putInCache, removeEntries, loadingGroupIds, enableRedeemFallback)
67
+ await fetchSnapshotWithRedeem(odspResolvedUrl, getAuthHeader, hostSnapshotFetchOptions, forceAccessTokenViaAuthorizationHeader, odspLogger, snapshotDownloader, putInCache, removeEntries, loadingGroupIds, enableRedeemFallback)
67
68
  .then(async (value) => {
68
69
  assert(!!snapshotEpoch, 0x585 /* prefetched snapshot should have a valid epoch */);
69
70
  snapshotContentsWithEpochP.resolve({
@@ -1 +1 @@
1
- {"version":3,"file":"prefetchLatestSnapshot.js","sourceRoot":"","sources":["../src/prefetchLatestSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAEvE,OAAO,EAON,mBAAmB,GACnB,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EACN,gBAAgB,EAChB,4BAA4B,GAC5B,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAGN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACN,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,qCAAqC,GACrC,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,WAAyB,EACzB,eAA4D,EAC5D,cAA+B,EAC/B,sCAA+C,EAC/C,MAA4B,EAC5B,wBAAsD,EACtD,uBAAgC,IAAI,EACpC,yBAAmC,EACnC,uBAAmD,EACnD,0BAAuD;IAEvD,MAAM,EAAE,GAAG,4BAA4B,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACnF,MAAM,UAAU,GAAG,gBAAgB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,2BAA2B,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CACvD,oDAAoD,CACpD,CAAC;IACF,4FAA4F;IAC5F,kDAAkD;IAClD,MAAM,eAAe,GAAG,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,MAAM,eAAe,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAExD,MAAM,eAAe,GAAkB;QACtC,OAAO,EAAE,eAAe,CAAC,OAAO;QAChC,OAAO,EAAE,eAAe,CAAC,OAAO;QAChC,MAAM,EAAE,eAAe,CAAC,MAAM;KAC9B,CAAC;IACF,MAAM,mBAAmB,GAAG,qCAAqC,CAChE,UAAU,EACV,eAAe,EACf,eAAe,CACf,CAAC;IAEF,MAAM,kBAAkB,GAAG,KAAK,EAC/B,oBAAsC,EACtC,YAAoB,EACpB,cAAoC,EACpC,eAA6C,EAC7C,UAA4B,EACkB,EAAE;QAChD,OAAO,gBAAgB,CACtB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,eAAe,EACf,SAAS,EACT,UAAU,CACV,CAAC;IACH,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,sBAAsB,CAAC,eAAe,CAAC,CAAC;IAC5D,IAAI,MAAiC,CAAC;IACtC,IAAI,aAAiC,CAAC;IACtC,MAAM,UAAU,GAAG,KAAK,EAAE,cAAwC,EAAiB,EAAE;QACpF,aAAa,GAAG,cAAc,CAAC,UAAU,CAAC;QAC1C,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE,CAC/C,cAAc,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,gBAAgB,CAAC,cAAc,CACrC,UAAU,EACV,EAAE,SAAS,EAAE,wBAAwB,EAAE,EACvC,KAAK,IAAI,EAAE;QACV,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC5C,kGAAkG;QAClG,MAAM,0BAA0B,GAAG,IAAI,QAAQ,EAA6B,CAAC;QAC7E,MAAM,qBAAqB,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAC/D,MAAM,0BAA0B,GAC/B,0BAA0B,EAAE,2BAA2B,CAAC;QACzD,0BAA0B,EAAE,GAAG,CAC9B,qBAAqB,EACrB,KAAK,IAAI,EAAE,CAAC,0BAA0B,CAAC,OAAO,CAC9C,CAAC;QACF,MAAM,uBAAuB,CAC5B,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,sCAAsC,EACtC,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,eAAe,EACf,oBAAoB,CACpB;aACC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACrB,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACnF,0BAA0B,CAAC,OAAO,CAAC;gBAClC,GAAG,KAAK;gBACR,UAAU,EAAE,aAAa;gBACzB,iBAAiB;aACjB,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;YACvE,MAAM,MAAM,CAAC;YACb,6CAA6C;YAC7C,kGAAkG;YAClG,6FAA6F;YAC7F,mGAAmG;YACnG,kGAAkG;YAClG,mGAAmG;YACnG,2FAA2F;YAC3F,+FAA+F;YAC/F,qCAAqC;YACrC,UAAU,CAAC,GAAG,EAAE;gBACf,0BAA0B,EAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;YAC3D,CAAC,EAAE,IAAI,CAAC,CAAC;QACV,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,+DAA+D;YAC/D,0BAA0B,EAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;YAC1D,0BAA0B,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzC,MAAM,KAAK,CAAC;QACb,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC;IACb,CAAC,CACD,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACvB,UAAU,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,6BAA6B,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/E,OAAO,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { performance } from \"@fluid-internal/client-utils\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred } from \"@fluidframework/core-utils/internal\";\nimport { IResolvedUrl } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tIOdspResolvedUrl,\n\tIOdspUrlParts,\n\tIPersistedCache,\n\tISnapshotOptions,\n\tOdspResourceTokenFetchOptions,\n\tTokenFetcher,\n\tgetKeyForCacheEntry,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tPerformanceEvent,\n\tcreateChildMonitoringContext,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { IVersionedValueWithEpoch } from \"./contracts.js\";\nimport {\n\tISnapshotRequestAndResponseOptions,\n\tSnapshotFormatSupportType,\n\tdownloadSnapshot,\n\tfetchSnapshotWithRedeem,\n} from \"./fetchSnapshot.js\";\nimport { IPrefetchSnapshotContents } from \"./odspCache.js\";\nimport { OdspDocumentServiceFactory } from \"./odspDocumentServiceFactory.js\";\nimport {\n\tcreateCacheSnapshotKey,\n\tcreateOdspLogger,\n\tgetOdspResolvedUrl,\n\ttoInstrumentedOdspStorageTokenFetcher,\n} from \"./odspUtils.js\";\n\n/**\n * Function to prefetch the snapshot and cached it in the persistant cache, so that when the container is loaded\n * the cached latest snapshot could be used and removes the network call from the critical path.\n *\n * @param resolvedUrl - Resolved url to fetch the snapshot.\n * @param getStorageToken - function that can provide the storage token for a given site. This is\n * is also referred to as the \"VROOM\" token in SPO.\n * @param persistedCache - Cache to store the fetched snapshot.\n * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header.\n * @param logger - Logger to have telemetry events.\n * @param hostSnapshotFetchOptions - Options to fetch the snapshot if any. Otherwise default will be used.\n * @param enableRedeemFallback - True to have the sharing link redeem fallback in case the Trees Latest/Redeem\n * 1RT call fails with redeem error. During fallback it will first redeem the sharing link and then make\n * the Trees latest call.\n * Note: this can be considered deprecated - it will be replaced with `snapshotFormatFetchType`.\n * @param fetchBinarySnapshotFormat - Control if we want to fetch binary format snapshot.\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param odspDocumentServiceFactory - factory to access the non persistent cache and store the prefetch promise.\n *\n * @returns `true` if the snapshot is cached, `false` otherwise.\n * @alpha\n */\nexport async function prefetchLatestSnapshot(\n\tresolvedUrl: IResolvedUrl,\n\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\tpersistedCache: IPersistedCache,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: ITelemetryBaseLogger,\n\thostSnapshotFetchOptions: ISnapshotOptions | undefined,\n\tenableRedeemFallback: boolean = true,\n\tfetchBinarySnapshotFormat?: boolean,\n\tsnapshotFormatFetchType?: SnapshotFormatSupportType,\n\todspDocumentServiceFactory?: OdspDocumentServiceFactory,\n): Promise<boolean> {\n\tconst mc = createChildMonitoringContext({ logger, namespace: \"PrefetchSnapshot\" });\n\tconst odspLogger = createOdspLogger(mc.logger);\n\tconst useGroupIdsForSnapshotFetch = mc.config.getBoolean(\n\t\t\"Fluid.Container.UseLoadingGroupIdForSnapshotFetch2\",\n\t);\n\t// For prefetch, we just want to fetch the ungrouped data and want to use the new API if the\n\t// feature gate is set, so provide an empty array.\n\tconst loadingGroupIds = useGroupIdsForSnapshotFetch ? [] : undefined;\n\tconst odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n\n\tconst resolvedUrlData: IOdspUrlParts = {\n\t\tsiteUrl: odspResolvedUrl.siteUrl,\n\t\tdriveId: odspResolvedUrl.driveId,\n\t\titemId: odspResolvedUrl.itemId,\n\t};\n\tconst storageTokenFetcher = toInstrumentedOdspStorageTokenFetcher(\n\t\todspLogger,\n\t\tresolvedUrlData,\n\t\tgetStorageToken,\n\t);\n\n\tconst snapshotDownloader = async (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tstorageToken: string,\n\t\tloadingGroupId: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t): Promise<ISnapshotRequestAndResponseOptions> => {\n\t\treturn downloadSnapshot(\n\t\t\tfinalOdspResolvedUrl,\n\t\t\tstorageToken,\n\t\t\tloadingGroupId,\n\t\t\tsnapshotOptions,\n\t\t\tundefined,\n\t\t\tcontroller,\n\t\t);\n\t};\n\tconst snapshotKey = createCacheSnapshotKey(odspResolvedUrl);\n\tlet cacheP: Promise<void> | undefined;\n\tlet snapshotEpoch: string | undefined;\n\tconst putInCache = async (valueWithEpoch: IVersionedValueWithEpoch): Promise<void> => {\n\t\tsnapshotEpoch = valueWithEpoch.fluidEpoch;\n\t\tcacheP = persistedCache.put(snapshotKey, valueWithEpoch);\n\t\treturn cacheP;\n\t};\n\n\tconst removeEntries = async (): Promise<void> =>\n\t\tpersistedCache.removeEntries(snapshotKey.file);\n\treturn PerformanceEvent.timedExecAsync(\n\t\todspLogger,\n\t\t{ eventName: \"PrefetchLatestSnapshot\" },\n\t\tasync () => {\n\t\t\tconst prefetchStartTime = performance.now();\n\t\t\t// Add the deferred promise to the cache, so that it can be leveraged while loading the container.\n\t\t\tconst snapshotContentsWithEpochP = new Deferred<IPrefetchSnapshotContents>();\n\t\t\tconst nonPersistentCacheKey = getKeyForCacheEntry(snapshotKey);\n\t\t\tconst snapshotNonPersistentCache =\n\t\t\t\todspDocumentServiceFactory?.snapshotPrefetchResultCache;\n\t\t\tsnapshotNonPersistentCache?.add(\n\t\t\t\tnonPersistentCacheKey,\n\t\t\t\tasync () => snapshotContentsWithEpochP.promise,\n\t\t\t);\n\t\t\tawait fetchSnapshotWithRedeem(\n\t\t\t\todspResolvedUrl,\n\t\t\t\tstorageTokenFetcher,\n\t\t\t\thostSnapshotFetchOptions,\n\t\t\t\tforceAccessTokenViaAuthorizationHeader,\n\t\t\t\todspLogger,\n\t\t\t\tsnapshotDownloader,\n\t\t\t\tputInCache,\n\t\t\t\tremoveEntries,\n\t\t\t\tloadingGroupIds,\n\t\t\t\tenableRedeemFallback,\n\t\t\t)\n\t\t\t\t.then(async (value) => {\n\t\t\t\t\tassert(!!snapshotEpoch, 0x585 /* prefetched snapshot should have a valid epoch */);\n\t\t\t\t\tsnapshotContentsWithEpochP.resolve({\n\t\t\t\t\t\t...value,\n\t\t\t\t\t\tfluidEpoch: snapshotEpoch,\n\t\t\t\t\t\tprefetchStartTime,\n\t\t\t\t\t});\n\t\t\t\t\tassert(cacheP !== undefined, 0x1e7 /* \"caching was not performed!\" */);\n\t\t\t\t\tawait cacheP;\n\t\t\t\t\t// Schedule it to remove from cache after 5s.\n\t\t\t\t\t// 1. While it's in snapshotNonPersistentCache: Load flow will use this value and will not attempt\n\t\t\t\t\t// to fetch snapshot from network again. That's the best from perf POV, but cache will not be\n\t\t\t\t\t// updated if we keep it in this cache, thus we want to eventually remove snapshot from this cache.\n\t\t\t\t\t// 2. After it's removed from snapshotNonPersistentCache: snapshot is present in persistent cache,\n\t\t\t\t\t// so we sill still use it (in accordance with cache policy controlled by host). But load flow will\n\t\t\t\t\t// also fetch snapshot (in parallel) from storage and update cache. This is fine long term,\n\t\t\t\t\t// but is an extra cost (unneeded network call). However since it is 5s older, new network call\n\t\t\t\t\t// will update the snapshot in cache.\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tsnapshotNonPersistentCache?.remove(nonPersistentCacheKey);\n\t\t\t\t\t}, 5000);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\t// Remove it from the non persistent cache if an error occured.\n\t\t\t\t\tsnapshotNonPersistentCache?.remove(nonPersistentCacheKey);\n\t\t\t\t\tsnapshotContentsWithEpochP.reject(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t\treturn true;\n\t\t},\n\t).catch(async (error) => {\n\t\todspLogger.sendErrorEvent({ eventName: \"PrefetchLatestSnapshotError\" }, error);\n\t\treturn false;\n\t});\n}\n"]}
1
+ {"version":3,"file":"prefetchLatestSnapshot.js","sourceRoot":"","sources":["../src/prefetchLatestSnapshot.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 { performance } from \"@fluid-internal/client-utils\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred } from \"@fluidframework/core-utils/internal\";\nimport { IResolvedUrl } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tIOdspResolvedUrl,\n\tIOdspUrlParts,\n\tIPersistedCache,\n\tISnapshotOptions,\n\tOdspResourceTokenFetchOptions,\n\tTokenFetcher,\n\tgetKeyForCacheEntry,\n\ttype InstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tPerformanceEvent,\n\tcreateChildMonitoringContext,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { IVersionedValueWithEpoch } from \"./contracts.js\";\nimport {\n\tISnapshotRequestAndResponseOptions,\n\tSnapshotFormatSupportType,\n\tdownloadSnapshot,\n\tfetchSnapshotWithRedeem,\n} from \"./fetchSnapshot.js\";\nimport { IPrefetchSnapshotContents } from \"./odspCache.js\";\nimport { OdspDocumentServiceFactory } from \"./odspDocumentServiceFactory.js\";\nimport {\n\tcreateCacheSnapshotKey,\n\tcreateOdspLogger,\n\tgetOdspResolvedUrl,\n\ttoInstrumentedOdspStorageTokenFetcher,\n\ttype TokenFetchOptionsEx,\n} from \"./odspUtils.js\";\n\n/**\n * Function to prefetch the snapshot and cached it in the persistant cache, so that when the container is loaded\n * the cached latest snapshot could be used and removes the network call from the critical path.\n *\n * @param resolvedUrl - Resolved url to fetch the snapshot.\n * @param getStorageToken - function that can provide the storage token for a given site. This is\n * is also referred to as the \"VROOM\" token in SPO.\n * @param persistedCache - Cache to store the fetched snapshot.\n * @param forceAccessTokenViaAuthorizationHeader - @deprecated Not used, true value always used instead. Whether to force passing given token via authorization header.\n * @param logger - Logger to have telemetry events.\n * @param hostSnapshotFetchOptions - Options to fetch the snapshot if any. Otherwise default will be used.\n * @param enableRedeemFallback - True to have the sharing link redeem fallback in case the Trees Latest/Redeem\n * 1RT call fails with redeem error. During fallback it will first redeem the sharing link and then make\n * the Trees latest call.\n * Note: this can be considered deprecated - it will be replaced with `snapshotFormatFetchType`.\n * @param fetchBinarySnapshotFormat - Control if we want to fetch binary format snapshot.\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param odspDocumentServiceFactory - factory to access the non persistent cache and store the prefetch promise.\n *\n * @returns `true` if the snapshot is cached, `false` otherwise.\n * @legacy\n * @alpha\n */\nexport async function prefetchLatestSnapshot(\n\tresolvedUrl: IResolvedUrl,\n\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\tpersistedCache: IPersistedCache,\n\tforceAccessTokenViaAuthorizationHeader: boolean,\n\tlogger: ITelemetryBaseLogger,\n\thostSnapshotFetchOptions: ISnapshotOptions | undefined,\n\tenableRedeemFallback: boolean = true,\n\tfetchBinarySnapshotFormat?: boolean,\n\tsnapshotFormatFetchType?: SnapshotFormatSupportType,\n\todspDocumentServiceFactory?: OdspDocumentServiceFactory,\n): Promise<boolean> {\n\tconst mc = createChildMonitoringContext({ logger, namespace: \"PrefetchSnapshot\" });\n\tconst odspLogger = createOdspLogger(mc.logger);\n\tconst useGroupIdsForSnapshotFetch = mc.config.getBoolean(\n\t\t\"Fluid.Container.UseLoadingGroupIdForSnapshotFetch2\",\n\t);\n\t// For prefetch, we just want to fetch the ungrouped data and want to use the new API if the\n\t// feature gate is set, so provide an empty array.\n\tconst loadingGroupIds = useGroupIdsForSnapshotFetch ? [] : undefined;\n\tconst odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n\n\tconst resolvedUrlData: IOdspUrlParts = {\n\t\tsiteUrl: odspResolvedUrl.siteUrl,\n\t\tdriveId: odspResolvedUrl.driveId,\n\t\titemId: odspResolvedUrl.itemId,\n\t};\n\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\todspLogger,\n\t\tresolvedUrlData,\n\t\tgetStorageToken,\n\t);\n\n\tconst snapshotDownloader = async (\n\t\tfinalOdspResolvedUrl: IOdspResolvedUrl,\n\t\tstorageTokenFetcher: InstrumentedStorageTokenFetcher,\n\t\ttokenFetchOptions: TokenFetchOptionsEx,\n\t\tloadingGroupId: string[] | undefined,\n\t\tsnapshotOptions: ISnapshotOptions | undefined,\n\t\tcontroller?: AbortController,\n\t): Promise<ISnapshotRequestAndResponseOptions> => {\n\t\treturn downloadSnapshot(\n\t\t\tfinalOdspResolvedUrl,\n\t\t\tstorageTokenFetcher,\n\t\t\ttokenFetchOptions,\n\t\t\tloadingGroupId,\n\t\t\tsnapshotOptions,\n\t\t\tundefined,\n\t\t\tcontroller,\n\t\t);\n\t};\n\tconst snapshotKey = createCacheSnapshotKey(odspResolvedUrl);\n\tlet cacheP: Promise<void> | undefined;\n\tlet snapshotEpoch: string | undefined;\n\tconst putInCache = async (valueWithEpoch: IVersionedValueWithEpoch): Promise<void> => {\n\t\tsnapshotEpoch = valueWithEpoch.fluidEpoch;\n\t\tcacheP = persistedCache.put(snapshotKey, valueWithEpoch);\n\t\treturn cacheP;\n\t};\n\n\tconst removeEntries = async (): Promise<void> =>\n\t\tpersistedCache.removeEntries(snapshotKey.file);\n\treturn PerformanceEvent.timedExecAsync(\n\t\todspLogger,\n\t\t{ eventName: \"PrefetchLatestSnapshot\" },\n\t\tasync () => {\n\t\t\tconst prefetchStartTime = performance.now();\n\t\t\t// Add the deferred promise to the cache, so that it can be leveraged while loading the container.\n\t\t\tconst snapshotContentsWithEpochP = new Deferred<IPrefetchSnapshotContents>();\n\t\t\tconst nonPersistentCacheKey = getKeyForCacheEntry(snapshotKey);\n\t\t\tconst snapshotNonPersistentCache =\n\t\t\t\todspDocumentServiceFactory?.snapshotPrefetchResultCache;\n\t\t\tsnapshotNonPersistentCache?.add(\n\t\t\t\tnonPersistentCacheKey,\n\t\t\t\tasync () => snapshotContentsWithEpochP.promise,\n\t\t\t);\n\t\t\tawait fetchSnapshotWithRedeem(\n\t\t\t\todspResolvedUrl,\n\t\t\t\tgetAuthHeader,\n\t\t\t\thostSnapshotFetchOptions,\n\t\t\t\tforceAccessTokenViaAuthorizationHeader,\n\t\t\t\todspLogger,\n\t\t\t\tsnapshotDownloader,\n\t\t\t\tputInCache,\n\t\t\t\tremoveEntries,\n\t\t\t\tloadingGroupIds,\n\t\t\t\tenableRedeemFallback,\n\t\t\t)\n\t\t\t\t.then(async (value) => {\n\t\t\t\t\tassert(!!snapshotEpoch, 0x585 /* prefetched snapshot should have a valid epoch */);\n\t\t\t\t\tsnapshotContentsWithEpochP.resolve({\n\t\t\t\t\t\t...value,\n\t\t\t\t\t\tfluidEpoch: snapshotEpoch,\n\t\t\t\t\t\tprefetchStartTime,\n\t\t\t\t\t});\n\t\t\t\t\tassert(cacheP !== undefined, 0x1e7 /* \"caching was not performed!\" */);\n\t\t\t\t\tawait cacheP;\n\t\t\t\t\t// Schedule it to remove from cache after 5s.\n\t\t\t\t\t// 1. While it's in snapshotNonPersistentCache: Load flow will use this value and will not attempt\n\t\t\t\t\t// to fetch snapshot from network again. That's the best from perf POV, but cache will not be\n\t\t\t\t\t// updated if we keep it in this cache, thus we want to eventually remove snapshot from this cache.\n\t\t\t\t\t// 2. After it's removed from snapshotNonPersistentCache: snapshot is present in persistent cache,\n\t\t\t\t\t// so we sill still use it (in accordance with cache policy controlled by host). But load flow will\n\t\t\t\t\t// also fetch snapshot (in parallel) from storage and update cache. This is fine long term,\n\t\t\t\t\t// but is an extra cost (unneeded network call). However since it is 5s older, new network call\n\t\t\t\t\t// will update the snapshot in cache.\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tsnapshotNonPersistentCache?.remove(nonPersistentCacheKey);\n\t\t\t\t\t}, 5000);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\t// Remove it from the non persistent cache if an error occured.\n\t\t\t\t\tsnapshotNonPersistentCache?.remove(nonPersistentCacheKey);\n\t\t\t\t\tsnapshotContentsWithEpochP.reject(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\t\t\treturn true;\n\t\t},\n\t).catch(async (error) => {\n\t\todspLogger.sendErrorEvent({ eventName: \"PrefetchLatestSnapshotError\" }, error);\n\t\treturn false;\n\t});\n}\n"]}
package/lib/vroom.d.ts CHANGED
@@ -12,7 +12,7 @@ import { TokenFetchOptionsEx } from "./odspUtils.js";
12
12
  * @param path - The API path that is relevant to this request
13
13
  * @param method - The type of request, such as GET or POST
14
14
  * @param logger - A logger to use for this request
15
- * @param getStorageToken - A function that is able to provide the access token for this request
15
+ * @param getAuthHeader - A function that is able to provide the access token for this request
16
16
  * @param epochTracker - fetch wrapper which incorporates epoch logic around joinSession call
17
17
  * @param requestSocketToken - flag indicating whether joinSession is expected to return access token
18
18
  * which is used when establishing websocket connection with collab session backend service.
@@ -22,5 +22,5 @@ import { TokenFetchOptionsEx } from "./odspUtils.js";
22
22
  * @param guestDisplayName - display name used to identify guest user joining a session.
23
23
  * This is optional and used only when collab session is being joined via invite.
24
24
  */
25
- export declare function fetchJoinSession(urlParts: IOdspUrlParts, path: string, method: string, logger: ITelemetryLoggerExt, getStorageToken: InstrumentedStorageTokenFetcher, epochTracker: EpochTracker, requestSocketToken: boolean, options: TokenFetchOptionsEx, disableJoinSessionRefresh: boolean | undefined, isRefreshingJoinSession: boolean, guestDisplayName?: string): Promise<ISocketStorageDiscovery>;
25
+ export declare function fetchJoinSession(urlParts: IOdspUrlParts, path: string, method: "GET" | "POST", logger: ITelemetryLoggerExt, getAuthHeader: InstrumentedStorageTokenFetcher, epochTracker: EpochTracker, requestSocketToken: boolean, options: TokenFetchOptionsEx, disableJoinSessionRefresh: boolean | undefined, isRefreshingJoinSession: boolean): Promise<ISocketStorageDiscovery>;
26
26
  //# sourceMappingURL=vroom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vroom.d.ts","sourceRoot":"","sources":["../src/vroom.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,aAAa,EACb,uBAAuB,EACvB,+BAA+B,EAC/B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EACN,mBAAmB,EAEnB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAQrD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACrC,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,mBAAmB,EAC3B,eAAe,EAAE,+BAA+B,EAChD,YAAY,EAAE,YAAY,EAC1B,kBAAkB,EAAE,OAAO,EAC3B,OAAO,EAAE,mBAAmB,EAC5B,yBAAyB,EAAE,OAAO,GAAG,SAAS,EAC9C,uBAAuB,EAAE,OAAO,EAChC,gBAAgB,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,uBAAuB,CAAC,CA+ElC"}
1
+ {"version":3,"file":"vroom.d.ts","sourceRoot":"","sources":["../src/vroom.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,aAAa,EACb,uBAAuB,EACvB,+BAA+B,EAC/B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EACN,mBAAmB,EAEnB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAQrD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACrC,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,MAAM,EAAE,mBAAmB,EAC3B,aAAa,EAAE,+BAA+B,EAC9C,YAAY,EAAE,YAAY,EAC1B,kBAAkB,EAAE,OAAO,EAC3B,OAAO,EAAE,mBAAmB,EAC5B,yBAAyB,EAAE,OAAO,GAAG,SAAS,EAC9C,uBAAuB,EAAE,OAAO,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAgFlC"}
package/lib/vroom.js CHANGED
@@ -12,7 +12,7 @@ import { runWithRetry } from "./retryUtils.js";
12
12
  * @param path - The API path that is relevant to this request
13
13
  * @param method - The type of request, such as GET or POST
14
14
  * @param logger - A logger to use for this request
15
- * @param getStorageToken - A function that is able to provide the access token for this request
15
+ * @param getAuthHeader - A function that is able to provide the access token for this request
16
16
  * @param epochTracker - fetch wrapper which incorporates epoch logic around joinSession call
17
17
  * @param requestSocketToken - flag indicating whether joinSession is expected to return access token
18
18
  * which is used when establishing websocket connection with collab session backend service.
@@ -22,8 +22,10 @@ import { runWithRetry } from "./retryUtils.js";
22
22
  * @param guestDisplayName - display name used to identify guest user joining a session.
23
23
  * This is optional and used only when collab session is being joined via invite.
24
24
  */
25
- export async function fetchJoinSession(urlParts, path, method, logger, getStorageToken, epochTracker, requestSocketToken, options, disableJoinSessionRefresh, isRefreshingJoinSession, guestDisplayName) {
26
- const token = await getStorageToken(options, "JoinSession");
25
+ export async function fetchJoinSession(urlParts, path, method, logger, getAuthHeader, epochTracker, requestSocketToken, options, disableJoinSessionRefresh, isRefreshingJoinSession) {
26
+ const apiRoot = getApiRoot(new URL(urlParts.siteUrl));
27
+ const url = `${apiRoot}/drives/${urlParts.driveId}/items/${urlParts.itemId}/${path}?ump=1`;
28
+ const authHeader = await getAuthHeader({ ...options, request: { url, method } }, "JoinSession");
27
29
  const tokenRefreshProps = options.refresh
28
30
  ? { hasClaims: !!options.claims, hasTenantId: !!options.tenantId }
29
31
  : {};
@@ -39,10 +41,9 @@ export async function fetchJoinSession(urlParts, path, method, logger, getStorag
39
41
  details: JSON.stringify(details),
40
42
  ...tokenRefreshProps,
41
43
  }, async (event) => {
42
- const apiRoot = getApiRoot(new URL(urlParts.siteUrl));
43
44
  const formBoundary = uuid();
44
45
  let postBody = `--${formBoundary}\r\n`;
45
- postBody += `Authorization: Bearer ${token}\r\n`;
46
+ postBody += `Authorization: ${authHeader}\r\n`;
46
47
  postBody += `X-HTTP-Method-Override: POST\r\n`;
47
48
  postBody += `Content-Type: application/json\r\n`;
48
49
  if (!disableJoinSessionRefresh) {
@@ -53,16 +54,13 @@ export async function fetchJoinSession(urlParts, path, method, logger, getStorag
53
54
  const body = {
54
55
  requestSocketToken: true,
55
56
  };
56
- if (guestDisplayName !== undefined) {
57
- body.guestDisplayName = guestDisplayName;
58
- }
59
57
  postBody += `\r\n${JSON.stringify(body)}\r\n`;
60
58
  }
61
59
  postBody += `\r\n--${formBoundary}--`;
62
60
  const headers = {
63
61
  "Content-Type": `multipart/form-data;boundary=${formBoundary}`,
64
62
  };
65
- const response = await runWithRetry(async () => epochTracker.fetchAndParseAsJSON(`${apiRoot}/drives/${urlParts.driveId}/items/${urlParts.itemId}/${path}?ump=1`, { method, headers, body: postBody }, "joinSession", true), "joinSession", logger);
63
+ const response = await runWithRetry(async () => epochTracker.fetchAndParseAsJSON(url, { method, headers, body: postBody }, "joinSession", true), "joinSession", logger);
66
64
  const socketUrl = response.content.deltaStreamSocketUrl;
67
65
  // expecting socketUrl to be something like https://{hostName}/...
68
66
  const webSocketHostName = socketUrl.split("/")[2];
package/lib/vroom.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vroom.js","sourceRoot":"","sources":["../src/vroom.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 { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tIOdspUrlParts,\n\tISocketStorageDiscovery,\n\tInstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { EpochTracker } from \"./epochTracker.js\";\nimport { getApiRoot } from \"./odspUrlHelper.js\";\nimport { TokenFetchOptionsEx } from \"./odspUtils.js\";\nimport { runWithRetry } from \"./retryUtils.js\";\n\ninterface IJoinSessionBody {\n\trequestSocketToken: boolean;\n\tguestDisplayName?: string;\n}\n\n/**\n * Makes join session call on SPO to get information about the web socket for a document\n * @param urlParts - The SPO drive id, itemId, siteUrl that this request should be made against\n * @param path - The API path that is relevant to this request\n * @param method - The type of request, such as GET or POST\n * @param logger - A logger to use for this request\n * @param getStorageToken - A function that is able to provide the access token for this request\n * @param epochTracker - fetch wrapper which incorporates epoch logic around joinSession call\n * @param requestSocketToken - flag indicating whether joinSession is expected to return access token\n * which is used when establishing websocket connection with collab session backend service.\n * @param options - Options to fetch the token.\n * @param disableJoinSessionRefresh - Whether the caller wants to disable refreshing join session periodically.\n * @param isRefreshingJoinSession - whether call is to refresh the session before expiry.\n * @param guestDisplayName - display name used to identify guest user joining a session.\n * This is optional and used only when collab session is being joined via invite.\n */\nexport async function fetchJoinSession(\n\turlParts: IOdspUrlParts,\n\tpath: string,\n\tmethod: string,\n\tlogger: ITelemetryLoggerExt,\n\tgetStorageToken: InstrumentedStorageTokenFetcher,\n\tepochTracker: EpochTracker,\n\trequestSocketToken: boolean,\n\toptions: TokenFetchOptionsEx,\n\tdisableJoinSessionRefresh: boolean | undefined,\n\tisRefreshingJoinSession: boolean,\n\tguestDisplayName?: string,\n): Promise<ISocketStorageDiscovery> {\n\tconst token = await getStorageToken(options, \"JoinSession\");\n\n\tconst tokenRefreshProps = options.refresh\n\t\t? { hasClaims: !!options.claims, hasTenantId: !!options.tenantId }\n\t\t: {};\n\tconst details: ITelemetryBaseProperties = {\n\t\trefreshedToken: options.refresh,\n\t\trequestSocketToken,\n\t\t...tokenRefreshProps,\n\t\trefreshingSession: isRefreshingJoinSession,\n\t};\n\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"JoinSession\",\n\t\t\tattempts: options.refresh ? 2 : 1,\n\t\t\tdetails: JSON.stringify(details),\n\t\t\t...tokenRefreshProps,\n\t\t},\n\t\tasync (event) => {\n\t\t\tconst apiRoot = getApiRoot(new URL(urlParts.siteUrl));\n\t\t\tconst formBoundary = uuid();\n\t\t\tlet postBody = `--${formBoundary}\\r\\n`;\n\t\t\tpostBody += `Authorization: Bearer ${token}\\r\\n`;\n\t\t\tpostBody += `X-HTTP-Method-Override: POST\\r\\n`;\n\t\t\tpostBody += `Content-Type: application/json\\r\\n`;\n\t\t\tif (!disableJoinSessionRefresh) {\n\t\t\t\tpostBody += `prefer: FluidRemoveCheckAccess\\r\\n`;\n\t\t\t}\n\t\t\tpostBody += `_post: 1\\r\\n`;\n\n\t\t\tif (requestSocketToken) {\n\t\t\t\tconst body: IJoinSessionBody = {\n\t\t\t\t\trequestSocketToken: true,\n\t\t\t\t};\n\t\t\t\tif (guestDisplayName !== undefined) {\n\t\t\t\t\tbody.guestDisplayName = guestDisplayName;\n\t\t\t\t}\n\t\t\t\tpostBody += `\\r\\n${JSON.stringify(body)}\\r\\n`;\n\t\t\t}\n\t\t\tpostBody += `\\r\\n--${formBoundary}--`;\n\t\t\tconst headers: { [index: string]: string } = {\n\t\t\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t\t\t};\n\n\t\t\tconst response = await runWithRetry(\n\t\t\t\tasync () =>\n\t\t\t\t\tepochTracker.fetchAndParseAsJSON<ISocketStorageDiscovery>(\n\t\t\t\t\t\t`${apiRoot}/drives/${urlParts.driveId}/items/${urlParts.itemId}/${path}?ump=1`,\n\t\t\t\t\t\t{ method, headers, body: postBody },\n\t\t\t\t\t\t\"joinSession\",\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t),\n\t\t\t\t\"joinSession\",\n\t\t\t\tlogger,\n\t\t\t);\n\n\t\t\tconst socketUrl = response.content.deltaStreamSocketUrl;\n\t\t\t// expecting socketUrl to be something like https://{hostName}/...\n\t\t\tconst webSocketHostName = socketUrl.split(\"/\")[2];\n\n\t\t\t// TODO SPO-specific telemetry\n\t\t\tevent.end({\n\t\t\t\t...response.propsToLog,\n\t\t\t\t// pushV2 websocket urls will contain pushf\n\t\t\t\tpushv2: socketUrl.includes(\"pushf\"),\n\t\t\t\twebSocketHostName,\n\t\t\t\trefreshSessionDurationSeconds: response.content.refreshSessionDurationSeconds,\n\t\t\t});\n\n\t\t\tif (response.content.runtimeTenantId && !response.content.tenantId) {\n\t\t\t\tresponse.content.tenantId = response.content.runtimeTenantId;\n\t\t\t}\n\n\t\t\treturn response.content;\n\t\t},\n\t);\n}\n"]}
1
+ {"version":3,"file":"vroom.js","sourceRoot":"","sources":["../src/vroom.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAEN,gBAAgB,GAChB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAGlC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAO/C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,QAAuB,EACvB,IAAY,EACZ,MAAsB,EACtB,MAA2B,EAC3B,aAA8C,EAC9C,YAA0B,EAC1B,kBAA2B,EAC3B,OAA4B,EAC5B,yBAA8C,EAC9C,uBAAgC;IAEhC,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,GAAG,OAAO,WAAW,QAAQ,CAAC,OAAO,UAAU,QAAQ,CAAC,MAAM,IAAI,IAAI,QAAQ,CAAC;IAC3F,MAAM,UAAU,GAAG,MAAM,aAAa,CACrC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EACxC,aAAa,CACb,CAAC;IAEF,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO;QACxC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;QAClE,CAAC,CAAC,EAAE,CAAC;IACN,MAAM,OAAO,GAA6B;QACzC,cAAc,EAAE,OAAO,CAAC,OAAO;QAC/B,kBAAkB;QAClB,GAAG,iBAAiB;QACpB,iBAAiB,EAAE,uBAAuB;KAC1C,CAAC;IAEF,OAAO,gBAAgB,CAAC,cAAc,CACrC,MAAM,EACN;QACC,SAAS,EAAE,aAAa;QACxB,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAChC,GAAG,iBAAiB;KACpB,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACf,MAAM,YAAY,GAAG,IAAI,EAAE,CAAC;QAC5B,IAAI,QAAQ,GAAG,KAAK,YAAY,MAAM,CAAC;QACvC,QAAQ,IAAI,kBAAkB,UAAU,MAAM,CAAC;QAC/C,QAAQ,IAAI,kCAAkC,CAAC;QAC/C,QAAQ,IAAI,oCAAoC,CAAC;QACjD,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAChC,QAAQ,IAAI,oCAAoC,CAAC;QAClD,CAAC;QACD,QAAQ,IAAI,cAAc,CAAC;QAE3B,IAAI,kBAAkB,EAAE,CAAC;YACxB,MAAM,IAAI,GAAqB;gBAC9B,kBAAkB,EAAE,IAAI;aACxB,CAAC;YACF,QAAQ,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/C,CAAC;QACD,QAAQ,IAAI,SAAS,YAAY,IAAI,CAAC;QACtC,MAAM,OAAO,GAAgC;YAC5C,cAAc,EAAE,gCAAgC,YAAY,EAAE;SAC9D,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,YAAY,CAClC,KAAK,IAAI,EAAE,CACV,YAAY,CAAC,mBAAmB,CAC/B,GAAG,EACH,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EACnC,aAAa,EACb,IAAI,CACJ,EACF,aAAa,EACb,MAAM,CACN,CAAC;QAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC;QACxD,kEAAkE;QAClE,MAAM,iBAAiB,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAElD,8BAA8B;QAC9B,KAAK,CAAC,GAAG,CAAC;YACT,GAAG,QAAQ,CAAC,UAAU;YACtB,2CAA2C;YAC3C,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;YACnC,iBAAiB;YACjB,6BAA6B,EAAE,QAAQ,CAAC,OAAO,CAAC,6BAA6B;SAC7E,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACpE,QAAQ,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC;QAC9D,CAAC;QAED,OAAO,QAAQ,CAAC,OAAO,CAAC;IACzB,CAAC,CACD,CAAC;AACH,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tIOdspUrlParts,\n\tISocketStorageDiscovery,\n\tInstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tPerformanceEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { EpochTracker } from \"./epochTracker.js\";\nimport { getApiRoot } from \"./odspUrlHelper.js\";\nimport { TokenFetchOptionsEx } from \"./odspUtils.js\";\nimport { runWithRetry } from \"./retryUtils.js\";\n\ninterface IJoinSessionBody {\n\trequestSocketToken: boolean;\n\tguestDisplayName?: string;\n}\n\n/**\n * Makes join session call on SPO to get information about the web socket for a document\n * @param urlParts - The SPO drive id, itemId, siteUrl that this request should be made against\n * @param path - The API path that is relevant to this request\n * @param method - The type of request, such as GET or POST\n * @param logger - A logger to use for this request\n * @param getAuthHeader - A function that is able to provide the access token for this request\n * @param epochTracker - fetch wrapper which incorporates epoch logic around joinSession call\n * @param requestSocketToken - flag indicating whether joinSession is expected to return access token\n * which is used when establishing websocket connection with collab session backend service.\n * @param options - Options to fetch the token.\n * @param disableJoinSessionRefresh - Whether the caller wants to disable refreshing join session periodically.\n * @param isRefreshingJoinSession - whether call is to refresh the session before expiry.\n * @param guestDisplayName - display name used to identify guest user joining a session.\n * This is optional and used only when collab session is being joined via invite.\n */\nexport async function fetchJoinSession(\n\turlParts: IOdspUrlParts,\n\tpath: string,\n\tmethod: \"GET\" | \"POST\",\n\tlogger: ITelemetryLoggerExt,\n\tgetAuthHeader: InstrumentedStorageTokenFetcher,\n\tepochTracker: EpochTracker,\n\trequestSocketToken: boolean,\n\toptions: TokenFetchOptionsEx,\n\tdisableJoinSessionRefresh: boolean | undefined,\n\tisRefreshingJoinSession: boolean,\n): Promise<ISocketStorageDiscovery> {\n\tconst apiRoot = getApiRoot(new URL(urlParts.siteUrl));\n\tconst url = `${apiRoot}/drives/${urlParts.driveId}/items/${urlParts.itemId}/${path}?ump=1`;\n\tconst authHeader = await getAuthHeader(\n\t\t{ ...options, request: { url, method } },\n\t\t\"JoinSession\",\n\t);\n\n\tconst tokenRefreshProps = options.refresh\n\t\t? { hasClaims: !!options.claims, hasTenantId: !!options.tenantId }\n\t\t: {};\n\tconst details: ITelemetryBaseProperties = {\n\t\trefreshedToken: options.refresh,\n\t\trequestSocketToken,\n\t\t...tokenRefreshProps,\n\t\trefreshingSession: isRefreshingJoinSession,\n\t};\n\n\treturn PerformanceEvent.timedExecAsync(\n\t\tlogger,\n\t\t{\n\t\t\teventName: \"JoinSession\",\n\t\t\tattempts: options.refresh ? 2 : 1,\n\t\t\tdetails: JSON.stringify(details),\n\t\t\t...tokenRefreshProps,\n\t\t},\n\t\tasync (event) => {\n\t\t\tconst formBoundary = uuid();\n\t\t\tlet postBody = `--${formBoundary}\\r\\n`;\n\t\t\tpostBody += `Authorization: ${authHeader}\\r\\n`;\n\t\t\tpostBody += `X-HTTP-Method-Override: POST\\r\\n`;\n\t\t\tpostBody += `Content-Type: application/json\\r\\n`;\n\t\t\tif (!disableJoinSessionRefresh) {\n\t\t\t\tpostBody += `prefer: FluidRemoveCheckAccess\\r\\n`;\n\t\t\t}\n\t\t\tpostBody += `_post: 1\\r\\n`;\n\n\t\t\tif (requestSocketToken) {\n\t\t\t\tconst body: IJoinSessionBody = {\n\t\t\t\t\trequestSocketToken: true,\n\t\t\t\t};\n\t\t\t\tpostBody += `\\r\\n${JSON.stringify(body)}\\r\\n`;\n\t\t\t}\n\t\t\tpostBody += `\\r\\n--${formBoundary}--`;\n\t\t\tconst headers: { [index: string]: string } = {\n\t\t\t\t\"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n\t\t\t};\n\n\t\t\tconst response = await runWithRetry(\n\t\t\t\tasync () =>\n\t\t\t\t\tepochTracker.fetchAndParseAsJSON<ISocketStorageDiscovery>(\n\t\t\t\t\t\turl,\n\t\t\t\t\t\t{ method, headers, body: postBody },\n\t\t\t\t\t\t\"joinSession\",\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t),\n\t\t\t\t\"joinSession\",\n\t\t\t\tlogger,\n\t\t\t);\n\n\t\t\tconst socketUrl = response.content.deltaStreamSocketUrl;\n\t\t\t// expecting socketUrl to be something like https://{hostName}/...\n\t\t\tconst webSocketHostName = socketUrl.split(\"/\")[2];\n\n\t\t\t// TODO SPO-specific telemetry\n\t\t\tevent.end({\n\t\t\t\t...response.propsToLog,\n\t\t\t\t// pushV2 websocket urls will contain pushf\n\t\t\t\tpushv2: socketUrl.includes(\"pushf\"),\n\t\t\t\twebSocketHostName,\n\t\t\t\trefreshSessionDurationSeconds: response.content.refreshSessionDurationSeconds,\n\t\t\t});\n\n\t\t\tif (response.content.runtimeTenantId && !response.content.tenantId) {\n\t\t\t\tresponse.content.tenantId = response.content.runtimeTenantId;\n\t\t\t}\n\n\t\t\treturn response.content;\n\t\t},\n\t);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/odsp-driver",
3
- "version": "2.1.0-274160",
3
+ "version": "2.1.0-276985",
4
4
  "description": "Socket storage implementation for SPO and ODC",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -77,15 +77,15 @@
77
77
  "temp-directory": "nyc/.nyc_output"
78
78
  },
79
79
  "dependencies": {
80
- "@fluid-internal/client-utils": "2.1.0-274160",
81
- "@fluidframework/core-interfaces": "2.1.0-274160",
82
- "@fluidframework/core-utils": "2.1.0-274160",
83
- "@fluidframework/driver-base": "2.1.0-274160",
84
- "@fluidframework/driver-definitions": "2.1.0-274160",
85
- "@fluidframework/driver-utils": "2.1.0-274160",
86
- "@fluidframework/odsp-doclib-utils": "2.1.0-274160",
87
- "@fluidframework/odsp-driver-definitions": "2.1.0-274160",
88
- "@fluidframework/telemetry-utils": "2.1.0-274160",
80
+ "@fluid-internal/client-utils": "2.1.0-276985",
81
+ "@fluidframework/core-interfaces": "2.1.0-276985",
82
+ "@fluidframework/core-utils": "2.1.0-276985",
83
+ "@fluidframework/driver-base": "2.1.0-276985",
84
+ "@fluidframework/driver-definitions": "2.1.0-276985",
85
+ "@fluidframework/driver-utils": "2.1.0-276985",
86
+ "@fluidframework/odsp-doclib-utils": "2.1.0-276985",
87
+ "@fluidframework/odsp-driver-definitions": "2.1.0-276985",
88
+ "@fluidframework/telemetry-utils": "2.1.0-276985",
89
89
  "node-fetch": "^2.6.9",
90
90
  "socket.io-client": "^4.7.3",
91
91
  "uuid": "^9.0.0"
@@ -93,7 +93,7 @@
93
93
  "devDependencies": {
94
94
  "@arethetypeswrong/cli": "^0.15.2",
95
95
  "@biomejs/biome": "^1.7.3",
96
- "@fluid-internal/mocha-test-setup": "2.1.0-274160",
96
+ "@fluid-internal/mocha-test-setup": "2.1.0-276985",
97
97
  "@fluid-tools/build-cli": "^0.39.0",
98
98
  "@fluidframework/build-common": "^2.0.3",
99
99
  "@fluidframework/build-tools": "^0.39.0",
@@ -124,8 +124,8 @@
124
124
  },
125
125
  "scripts": {
126
126
  "api": "fluid-build . --task api",
127
- "api-extractor:commonjs": "flub generate entrypoints --outFileAlpha legacy --outDir ./dist",
128
- "api-extractor:esnext": "flub generate entrypoints --outFileAlpha legacy --outDir ./lib --node10TypeCompat",
127
+ "api-extractor:commonjs": "flub generate entrypoints --outDir ./dist",
128
+ "api-extractor:esnext": "flub generate entrypoints --outDir ./lib --node10TypeCompat",
129
129
  "build": "fluid-build . --task build",
130
130
  "build:commonjs": "fluid-build . --task commonjs",
131
131
  "build:compile": "fluid-build . --task compile",
package/src/checkUrl.ts CHANGED
@@ -12,6 +12,7 @@ import { getLocatorFromOdspUrl } from "./odspFluidFileLink.js";
12
12
  * Note that returning information here is NOT a full guarantee that resolve will ultimately be successful.
13
13
  * Instead, this should be used as a lightweight check that can filter out easily detectable unsupported URLs
14
14
  * before the entire Fluid loading process needs to be kicked off.
15
+ * @legacy
15
16
  * @alpha
16
17
  */
17
18
  export function checkUrl(documentUrl: URL): DriverPreCheckInfo | undefined {
package/src/constants.ts CHANGED
@@ -4,11 +4,13 @@
4
4
  */
5
5
 
6
6
  /**
7
+ * @legacy
7
8
  * @alpha
8
9
  */
9
10
  export const OdcApiSiteOrigin = "https://my.microsoftpersonalcontent.com";
10
11
 
11
12
  /**
13
+ * @legacy
12
14
  * @alpha
13
15
  */
14
16
  export const OdcFileSiteOrigin = "https://1drv.ms";
@@ -6,6 +6,7 @@
6
6
  import { IOdspUrlParts } from "@fluidframework/odsp-driver-definitions/internal";
7
7
 
8
8
  /**
9
+ * @legacy
9
10
  * @alpha
10
11
  */
11
12
  export interface OdspFluidDataStoreLocator extends IOdspUrlParts {
package/src/createFile.ts CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  } from "./createNewUtils.js";
29
29
  import { createOdspUrl } from "./createOdspUrl.js";
30
30
  import { EpochTracker } from "./epochTracker.js";
31
- import { getUrlAndHeadersWithAuth } from "./getUrlAndHeadersWithAuth.js";
31
+ import { getHeadersWithAuth } from "./getUrlAndHeadersWithAuth.js";
32
32
  import { OdspDriverUrlResolver } from "./odspDriverUrlResolver.js";
33
33
  import { getApiRoot } from "./odspUrlHelper.js";
34
34
  import {
@@ -50,7 +50,7 @@ const isInvalidFileName = (fileName: string): boolean => {
50
50
  * Returns resolved url
51
51
  */
52
52
  export async function createNewFluidFile(
53
- getStorageToken: InstrumentedStorageTokenFetcher,
53
+ getAuthHeader: InstrumentedStorageTokenFetcher,
54
54
  newFileInfo: INewFileInfo,
55
55
  logger: ITelemetryLoggerExt,
56
56
  createNewSummary: ISummaryTree | undefined,
@@ -75,16 +75,10 @@ export async function createNewFluidFile(
75
75
  let summaryHandle: string = "";
76
76
  let shareLinkInfo: ShareLinkInfoType | undefined;
77
77
  if (createNewSummary === undefined) {
78
- itemId = await createNewEmptyFluidFile(
79
- getStorageToken,
80
- newFileInfo,
81
- logger,
82
- epochTracker,
83
- forceAccessTokenViaAuthorizationHeader,
84
- );
78
+ itemId = await createNewEmptyFluidFile(getAuthHeader, newFileInfo, logger, epochTracker);
85
79
  } else {
86
80
  const content = await createNewFluidFileFromSummary(
87
- getStorageToken,
81
+ getAuthHeader,
88
82
  newFileInfo,
89
83
  logger,
90
84
  createNewSummary,
@@ -163,11 +157,10 @@ function extractShareLinkData(
163
157
  }
164
158
 
165
159
  export async function createNewEmptyFluidFile(
166
- getStorageToken: InstrumentedStorageTokenFetcher,
160
+ getAuthHeader: InstrumentedStorageTokenFetcher,
167
161
  newFileInfo: INewFileInfo,
168
162
  logger: ITelemetryLoggerExt,
169
163
  epochTracker: EpochTracker,
170
- forceAccessTokenViaAuthorizationHeader: boolean,
171
164
  ): Promise<string> {
172
165
  const filePath = newFileInfo.filePath ? encodeURIComponent(`/${newFileInfo.filePath}`) : "";
173
166
  // add .tmp extension to empty file (host is expected to rename)
@@ -177,17 +170,18 @@ export async function createNewEmptyFluidFile(
177
170
  }/items/root:/${filePath}/${encodedFilename}:/content?@name.conflictBehavior=rename&select=id,name,parentReference`;
178
171
 
179
172
  return getWithRetryForTokenRefresh(async (options) => {
180
- const storageToken = await getStorageToken(options, "CreateNewFile");
173
+ const url = initialUrl;
174
+ const method = "PUT";
175
+ const authHeader = await getAuthHeader(
176
+ { ...options, request: { url, method } },
177
+ "CreateNewFile",
178
+ );
181
179
 
182
180
  return PerformanceEvent.timedExecAsync(
183
181
  logger,
184
182
  { eventName: "createNewEmptyFile" },
185
183
  async (event) => {
186
- const { url, headers } = getUrlAndHeadersWithAuth(
187
- initialUrl,
188
- storageToken,
189
- forceAccessTokenViaAuthorizationHeader,
190
- );
184
+ const headers = getHeadersWithAuth(authHeader);
191
185
  headers["Content-Type"] = "application/json";
192
186
 
193
187
  const fetchResponse = await runWithRetry(
@@ -197,7 +191,7 @@ export async function createNewEmptyFluidFile(
197
191
  {
198
192
  body: undefined,
199
193
  headers,
200
- method: "PUT",
194
+ method,
201
195
  },
202
196
  "createFile",
203
197
  ),
@@ -225,7 +219,7 @@ export async function createNewEmptyFluidFile(
225
219
  }
226
220
 
227
221
  export async function createNewFluidFileFromSummary(
228
- getStorageToken: InstrumentedStorageTokenFetcher,
222
+ getAuthHeader: InstrumentedStorageTokenFetcher,
229
223
  newFileInfo: INewFileInfo,
230
224
  logger: ITelemetryLoggerExt,
231
225
  createNewSummary: ISummaryTree,
@@ -249,7 +243,7 @@ export async function createNewFluidFileFromSummary(
249
243
 
250
244
  return createNewFluidContainerCore<ICreateFileResponse>({
251
245
  containerSnapshot,
252
- getStorageToken,
246
+ getAuthHeader,
253
247
  logger,
254
248
  initialUrl,
255
249
  forceAccessTokenViaAuthorizationHeader,
@@ -38,7 +38,7 @@ import { IExistingFileInfo, createCacheSnapshotKey } from "./odspUtils.js";
38
38
  * "alternative file partition" where the main File stub is an ASPX page.
39
39
  */
40
40
  export async function createNewContainerOnExistingFile(
41
- getStorageToken: InstrumentedStorageTokenFetcher,
41
+ getAuthHeader: InstrumentedStorageTokenFetcher,
42
42
  fileInfo: IExistingFileInfo,
43
43
  logger: ITelemetryLoggerExt,
44
44
  createNewSummary: ISummaryTree | undefined,
@@ -62,7 +62,7 @@ export async function createNewContainerOnExistingFile(
62
62
 
63
63
  const { id: summaryHandle } = await createNewFluidContainerCore<IWriteSummaryResponse>({
64
64
  containerSnapshot,
65
- getStorageToken,
65
+ getAuthHeader,
66
66
  logger,
67
67
  initialUrl,
68
68
  forceAccessTokenViaAuthorizationHeader,
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { Uint8ArrayToString, stringToBuffer } from "@fluid-internal/client-utils";
7
- import { unreachableCase } from "@fluidframework/core-utils/internal";
7
+ import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
8
8
  import {
9
9
  ISummaryBlob,
10
10
  ISummaryTree,
@@ -31,7 +31,7 @@ import {
31
31
  OdspSummaryTreeValue,
32
32
  } from "./contracts.js";
33
33
  import { EpochTracker, FetchType } from "./epochTracker.js";
34
- import { getUrlAndHeadersWithAuth } from "./getUrlAndHeadersWithAuth.js";
34
+ import { getHeadersWithAuth } from "./getUrlAndHeadersWithAuth.js";
35
35
  import { getWithRetryForTokenRefresh, maxUmpPostBodySize } from "./odspUtils.js";
36
36
  import { runWithRetry } from "./retryUtils.js";
37
37
 
@@ -149,6 +149,7 @@ function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspS
149
149
 
150
150
  const keys = Object.keys(summary.tree);
151
151
  for (const key of keys) {
152
+ assert(!key.includes("/"), "id should not include slashes");
152
153
  const summaryObject = summary.tree[key];
153
154
 
154
155
  let value: OdspSummaryTreeValue;
@@ -188,7 +189,7 @@ function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspS
188
189
  }
189
190
 
190
191
  const entry: OdspSummaryTreeEntry = {
191
- path: encodeURIComponent(key),
192
+ path: key,
192
193
  type: getGitType(summaryObject),
193
194
  value,
194
195
  unreferenced,
@@ -202,7 +203,7 @@ function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspS
202
203
 
203
204
  export async function createNewFluidContainerCore<T>(args: {
204
205
  containerSnapshot: IOdspSummaryPayload;
205
- getStorageToken: InstrumentedStorageTokenFetcher;
206
+ getAuthHeader: InstrumentedStorageTokenFetcher;
206
207
  logger: ITelemetryLoggerExt;
207
208
  initialUrl: string;
208
209
  forceAccessTokenViaAuthorizationHeader: boolean;
@@ -213,10 +214,9 @@ export async function createNewFluidContainerCore<T>(args: {
213
214
  }): Promise<T> {
214
215
  const {
215
216
  containerSnapshot,
216
- getStorageToken,
217
+ getAuthHeader,
217
218
  logger,
218
219
  initialUrl,
219
- forceAccessTokenViaAuthorizationHeader,
220
220
  epochTracker,
221
221
  telemetryName,
222
222
  fetchType,
@@ -224,8 +224,6 @@ export async function createNewFluidContainerCore<T>(args: {
224
224
  } = args;
225
225
 
226
226
  return getWithRetryForTokenRefresh(async (options) => {
227
- const storageToken = await getStorageToken(options, telemetryName);
228
-
229
227
  return PerformanceEvent.timedExecAsync(
230
228
  logger,
231
229
  { eventName: telemetryName },
@@ -235,31 +233,42 @@ export async function createNewFluidContainerCore<T>(args: {
235
233
  let headers: { [index: string]: string };
236
234
  let addInBody = false;
237
235
  const formBoundary = uuid();
238
- let postBody = `--${formBoundary}\r\n`;
239
- postBody += `Authorization: Bearer ${storageToken}\r\n`;
240
- postBody += `X-HTTP-Method-Override: POST\r\n`;
241
- postBody += `Content-Type: application/json\r\n`;
242
- postBody += `_post: 1\r\n`;
243
- postBody += `\r\n${snapshotBody}\r\n`;
244
- postBody += `\r\n--${formBoundary}--`;
236
+ const urlObj = new URL(initialUrl);
237
+ urlObj.searchParams.set("ump", "1");
238
+ const authInBodyUrl = urlObj.href;
239
+ const method = "POST";
240
+ const authHeader = await getAuthHeader(
241
+ { ...options, request: { url: authInBodyUrl, method } },
242
+ telemetryName,
243
+ );
244
+ const postBodyWithAuth =
245
+ `--${formBoundary}\r\n` +
246
+ `Authorization: ${authHeader}\r\n` +
247
+ `X-HTTP-Method-Override: POST\r\n` +
248
+ `Content-Type: application/json\r\n` +
249
+ `_post: 1\r\n` +
250
+ `\r\n${snapshotBody}\r\n` +
251
+ `\r\n--${formBoundary}--`;
245
252
 
246
- if (postBody.length <= maxUmpPostBodySize) {
247
- const urlObj = new URL(initialUrl);
248
- urlObj.searchParams.set("ump", "1");
249
- url = urlObj.href;
253
+ let postBody = snapshotBody;
254
+ if (
255
+ postBodyWithAuth.length <= maxUmpPostBodySize &&
256
+ authHeader?.startsWith("Bearer")
257
+ ) {
258
+ url = authInBodyUrl;
250
259
  headers = {
251
260
  "Content-Type": `multipart/form-data;boundary=${formBoundary}`,
252
261
  };
253
262
  addInBody = true;
263
+ postBody = postBodyWithAuth;
254
264
  } else {
255
- const parts = getUrlAndHeadersWithAuth(
256
- initialUrl,
257
- storageToken,
258
- forceAccessTokenViaAuthorizationHeader,
265
+ url = initialUrl;
266
+ const authHeaderNoUmp = await getAuthHeader(
267
+ { ...options, request: { url, method } },
268
+ telemetryName,
259
269
  );
260
- url = parts.url;
261
270
  headers = {
262
- ...parts.headers,
271
+ ...getHeadersWithAuth(authHeaderNoUmp),
263
272
  "Content-Type": "application/json",
264
273
  };
265
274
  postBody = snapshotBody;
@@ -272,7 +281,7 @@ export async function createNewFluidContainerCore<T>(args: {
272
281
  {
273
282
  body: postBody,
274
283
  headers,
275
- method: "POST",
284
+ method,
276
285
  },
277
286
  fetchType,
278
287
  addInBody,
@@ -17,6 +17,7 @@ import { buildOdspShareLinkReqParams } from "./odspUtils.js";
17
17
  * @param fileName - name of the new file to be created
18
18
  * @param createShareLinkType - type of sharing link you would like to create for this file. ShareLinkTypes
19
19
  * will be deprecated soon, so for any new implementation please provide createShareLinkType of type ShareLink
20
+ * @legacy
20
21
  * @alpha
21
22
  */
22
23
  export function createOdspCreateContainerRequest(
@@ -12,6 +12,7 @@ import { OdspFluidDataStoreLocator } from "./contractsPublic.js";
12
12
  /**
13
13
  * Encodes ODC/SPO information into a URL format that can be handled by the Loader
14
14
  * @param l -The property bag of necessary properties to locate a Fluid data store and craft a url for it
15
+ * @legacy
15
16
  * @alpha
16
17
  */
17
18
  export function createOdspUrl(l: OdspFluidDataStoreLocator): string {
@@ -46,6 +46,7 @@ import {
46
46
  import { pkgVersion as driverVersion } from "./packageVersion.js";
47
47
 
48
48
  /**
49
+ * @legacy
49
50
  * @alpha
50
51
  */
51
52
  export type FetchType =
@@ -62,6 +63,7 @@ export type FetchType =
62
63
  | "versions";
63
64
 
64
65
  /**
66
+ * @legacy
65
67
  * @alpha
66
68
  */
67
69
  export type FetchTypeInternal = FetchType | "cache";
@@ -82,6 +84,7 @@ export const Odsp409Error = "Odsp409Error";
82
84
  * server can match it with its epoch value in order to match the version.
83
85
  * It also validates the epoch value received in response of fetch calls. If the epoch does not match,
84
86
  * then it also clears all the cached entries for the given container.
87
+ * @legacy
85
88
  * @alpha
86
89
  */
87
90
  export class EpochTracker implements IPersistedFileCache {
@@ -613,6 +616,7 @@ export class EpochTrackerWithRedemption extends EpochTracker {
613
616
  }
614
617
 
615
618
  /**
619
+ * @legacy
616
620
  * @alpha
617
621
  */
618
622
  export interface ICacheAndTracker {