@fluidframework/odsp-driver 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.225277

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 (666) hide show
  1. package/.eslintrc.js +12 -12
  2. package/.mocharc.js +12 -0
  3. package/CHANGELOG.md +162 -0
  4. package/README.md +56 -0
  5. package/api-extractor-esm.json +4 -0
  6. package/api-extractor-lint.json +4 -0
  7. package/api-extractor.json +2 -2
  8. package/api-report/odsp-driver.api.md +309 -0
  9. package/dist/{ReadBufferUtils.js → ReadBufferUtils.cjs} +16 -9
  10. package/dist/ReadBufferUtils.cjs.map +1 -0
  11. package/dist/ReadBufferUtils.d.ts.map +1 -1
  12. package/dist/{WriteBufferUtils.js → WriteBufferUtils.cjs} +73 -69
  13. package/dist/WriteBufferUtils.cjs.map +1 -0
  14. package/dist/WriteBufferUtils.d.ts +3 -5
  15. package/dist/WriteBufferUtils.d.ts.map +1 -1
  16. package/dist/{checkUrl.js → checkUrl.cjs} +7 -6
  17. package/dist/checkUrl.cjs.map +1 -0
  18. package/dist/checkUrl.d.ts +1 -0
  19. package/dist/checkUrl.d.ts.map +1 -1
  20. package/dist/compactSnapshotParser.cjs +207 -0
  21. package/dist/compactSnapshotParser.cjs.map +1 -0
  22. package/dist/compactSnapshotParser.d.ts +12 -3
  23. package/dist/compactSnapshotParser.d.ts.map +1 -1
  24. package/dist/{compactSnapshotWriter.js → compactSnapshotWriter.cjs} +43 -33
  25. package/dist/compactSnapshotWriter.cjs.map +1 -0
  26. package/dist/compactSnapshotWriter.d.ts +2 -3
  27. package/dist/compactSnapshotWriter.d.ts.map +1 -1
  28. package/dist/{constants.js → constants.cjs} +7 -1
  29. package/dist/constants.cjs.map +1 -0
  30. package/dist/constants.d.ts +6 -0
  31. package/dist/constants.d.ts.map +1 -1
  32. package/dist/{contracts.js → contracts.cjs} +1 -1
  33. package/dist/contracts.cjs.map +1 -0
  34. package/dist/contracts.d.ts +16 -53
  35. package/dist/contracts.d.ts.map +1 -1
  36. package/dist/{contractsPublic.js → contractsPublic.cjs} +9 -3
  37. package/dist/contractsPublic.cjs.map +1 -0
  38. package/dist/contractsPublic.d.ts +15 -0
  39. package/dist/contractsPublic.d.ts.map +1 -1
  40. package/dist/createFile.cjs +177 -0
  41. package/dist/createFile.cjs.map +1 -0
  42. package/dist/createFile.d.ts +6 -10
  43. package/dist/createFile.d.ts.map +1 -1
  44. package/dist/createNewContainerOnExistingFile.cjs +60 -0
  45. package/dist/createNewContainerOnExistingFile.cjs.map +1 -0
  46. package/dist/createNewContainerOnExistingFile.d.ts +22 -0
  47. package/dist/createNewContainerOnExistingFile.d.ts.map +1 -0
  48. package/dist/createNewModule.cjs +12 -0
  49. package/dist/createNewModule.cjs.map +1 -0
  50. package/dist/createNewModule.d.ts +7 -0
  51. package/dist/createNewModule.d.ts.map +1 -0
  52. package/dist/createNewUtils.cjs +203 -0
  53. package/dist/createNewUtils.cjs.map +1 -0
  54. package/dist/createNewUtils.d.ts +16 -0
  55. package/dist/createNewUtils.d.ts.map +1 -1
  56. package/dist/{createOdspCreateContainerRequest.js → createOdspCreateContainerRequest.cjs} +8 -4
  57. package/dist/createOdspCreateContainerRequest.cjs.map +1 -0
  58. package/dist/createOdspCreateContainerRequest.d.ts +5 -3
  59. package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
  60. package/dist/{createOdspUrl.js → createOdspUrl.cjs} +2 -1
  61. package/dist/createOdspUrl.cjs.map +1 -0
  62. package/dist/createOdspUrl.d.ts +1 -0
  63. package/dist/createOdspUrl.d.ts.map +1 -1
  64. package/dist/{epochTracker.js → epochTracker.cjs} +102 -48
  65. package/dist/epochTracker.cjs.map +1 -0
  66. package/dist/epochTracker.d.ts +32 -8
  67. package/dist/epochTracker.d.ts.map +1 -1
  68. package/dist/{fetch.js → fetch.cjs} +1 -1
  69. package/dist/fetch.cjs.map +1 -0
  70. package/dist/fetch.d.ts +1 -1
  71. package/dist/fetch.d.ts.map +1 -1
  72. package/dist/{fetchSnapshot.js → fetchSnapshot.cjs} +192 -176
  73. package/dist/fetchSnapshot.cjs.map +1 -0
  74. package/dist/fetchSnapshot.d.ts +10 -5
  75. package/dist/fetchSnapshot.d.ts.map +1 -1
  76. package/dist/{getFileLink.js → getFileLink.cjs} +52 -41
  77. package/dist/getFileLink.cjs.map +1 -0
  78. package/dist/getFileLink.d.ts +4 -7
  79. package/dist/getFileLink.d.ts.map +1 -1
  80. package/dist/{getQueryString.js → getQueryString.cjs} +1 -1
  81. package/dist/getQueryString.cjs.map +1 -0
  82. package/dist/getQueryString.d.ts.map +1 -1
  83. package/dist/{getUrlAndHeadersWithAuth.js → getUrlAndHeadersWithAuth.cjs} +4 -2
  84. package/dist/getUrlAndHeadersWithAuth.cjs.map +1 -0
  85. package/dist/getUrlAndHeadersWithAuth.d.ts.map +1 -1
  86. package/dist/index.cjs +59 -0
  87. package/dist/index.cjs.map +1 -0
  88. package/dist/index.d.ts +19 -16
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/localOdspDriver/localOdspDeltaStorageService.cjs +35 -0
  91. package/dist/localOdspDriver/localOdspDeltaStorageService.cjs.map +1 -0
  92. package/dist/localOdspDriver/localOdspDeltaStorageService.d.ts +17 -0
  93. package/dist/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -0
  94. package/dist/localOdspDriver/{localOdspDocumentService.js → localOdspDocumentService.cjs} +7 -5
  95. package/dist/localOdspDriver/localOdspDocumentService.cjs.map +1 -0
  96. package/dist/localOdspDriver/localOdspDocumentService.d.ts +3 -2
  97. package/dist/localOdspDriver/localOdspDocumentService.d.ts.map +1 -1
  98. package/dist/localOdspDriver/{localOdspDocumentServiceFactory.js → localOdspDocumentServiceFactory.cjs} +9 -10
  99. package/dist/localOdspDriver/localOdspDocumentServiceFactory.cjs.map +1 -0
  100. package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts +2 -3
  101. package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -1
  102. package/dist/localOdspDriver/{localOdspDocumentStorageManager.js → localOdspDocumentStorageManager.cjs} +13 -11
  103. package/dist/localOdspDriver/localOdspDocumentStorageManager.cjs.map +1 -0
  104. package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts +2 -2
  105. package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
  106. package/dist/odsp-driver-alpha.d.ts +496 -0
  107. package/dist/odsp-driver-beta.d.ts +160 -0
  108. package/dist/odsp-driver-public.d.ts +160 -0
  109. package/dist/odsp-driver-untrimmed.d.ts +565 -0
  110. package/dist/{odspCache.js → odspCache.cjs} +9 -10
  111. package/dist/odspCache.cjs.map +1 -0
  112. package/dist/odspCache.d.ts +19 -4
  113. package/dist/odspCache.d.ts.map +1 -1
  114. package/dist/odspDelayLoadedDeltaStream.cjs +291 -0
  115. package/dist/odspDelayLoadedDeltaStream.cjs.map +1 -0
  116. package/dist/odspDelayLoadedDeltaStream.d.ts +75 -0
  117. package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -0
  118. package/dist/{odspDeltaStorageService.js → odspDeltaStorageService.cjs} +70 -71
  119. package/dist/odspDeltaStorageService.cjs.map +1 -0
  120. package/dist/odspDeltaStorageService.d.ts +8 -6
  121. package/dist/odspDeltaStorageService.d.ts.map +1 -1
  122. package/dist/{odspDocumentDeltaConnection.js → odspDocumentDeltaConnection.cjs} +224 -113
  123. package/dist/odspDocumentDeltaConnection.cjs.map +1 -0
  124. package/dist/odspDocumentDeltaConnection.d.ts +32 -12
  125. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  126. package/dist/odspDocumentService.cjs +225 -0
  127. package/dist/odspDocumentService.cjs.map +1 -0
  128. package/dist/odspDocumentService.d.ts +11 -25
  129. package/dist/odspDocumentService.d.ts.map +1 -1
  130. package/dist/{odspDocumentServiceFactory.js → odspDocumentServiceFactory.cjs} +8 -5
  131. package/dist/odspDocumentServiceFactory.cjs.map +1 -0
  132. package/dist/odspDocumentServiceFactory.d.ts +4 -0
  133. package/dist/odspDocumentServiceFactory.d.ts.map +1 -1
  134. package/dist/odspDocumentServiceFactoryCore.cjs +196 -0
  135. package/dist/odspDocumentServiceFactoryCore.cjs.map +1 -0
  136. package/dist/odspDocumentServiceFactoryCore.d.ts +18 -11
  137. package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  138. package/dist/odspDocumentServiceFactoryWithCodeSplit.cjs +20 -0
  139. package/dist/odspDocumentServiceFactoryWithCodeSplit.cjs.map +1 -0
  140. package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts +5 -0
  141. package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +1 -1
  142. package/dist/odspDocumentStorageManager.cjs +490 -0
  143. package/dist/odspDocumentStorageManager.cjs.map +1 -0
  144. package/dist/odspDocumentStorageManager.d.ts +11 -5
  145. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  146. package/dist/{odspDocumentStorageServiceBase.js → odspDocumentStorageServiceBase.cjs} +32 -34
  147. package/dist/odspDocumentStorageServiceBase.cjs.map +1 -0
  148. package/dist/odspDocumentStorageServiceBase.d.ts +7 -9
  149. package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
  150. package/dist/{odspDriverUrlResolver.js → odspDriverUrlResolver.cjs} +50 -36
  151. package/dist/odspDriverUrlResolver.cjs.map +1 -0
  152. package/dist/odspDriverUrlResolver.d.ts +12 -0
  153. package/dist/odspDriverUrlResolver.d.ts.map +1 -1
  154. package/dist/{odspDriverUrlResolverForShareLink.js → odspDriverUrlResolverForShareLink.cjs} +37 -26
  155. package/dist/odspDriverUrlResolverForShareLink.cjs.map +1 -0
  156. package/dist/odspDriverUrlResolverForShareLink.d.ts +5 -3
  157. package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  158. package/dist/{odspError.js → odspError.cjs} +7 -3
  159. package/dist/odspError.cjs.map +1 -0
  160. package/dist/odspError.d.ts.map +1 -1
  161. package/dist/{odspFluidFileLink.js → odspFluidFileLink.cjs} +25 -18
  162. package/dist/odspFluidFileLink.cjs.map +1 -0
  163. package/dist/odspFluidFileLink.d.ts +10 -1
  164. package/dist/odspFluidFileLink.d.ts.map +1 -1
  165. package/dist/odspLocationRedirection.cjs +24 -0
  166. package/dist/odspLocationRedirection.cjs.map +1 -0
  167. package/dist/odspLocationRedirection.d.ts +14 -0
  168. package/dist/odspLocationRedirection.d.ts.map +1 -0
  169. package/dist/{odspPublicUtils.js → odspPublicUtils.cjs} +7 -4
  170. package/dist/odspPublicUtils.cjs.map +1 -0
  171. package/dist/odspPublicUtils.d.ts +6 -0
  172. package/dist/odspPublicUtils.d.ts.map +1 -1
  173. package/dist/{odspSnapshotParser.js → odspSnapshotParser.cjs} +11 -12
  174. package/dist/odspSnapshotParser.cjs.map +1 -0
  175. package/dist/odspSnapshotParser.d.ts.map +1 -1
  176. package/dist/{odspSummaryUploadManager.js → odspSummaryUploadManager.cjs} +47 -34
  177. package/dist/odspSummaryUploadManager.cjs.map +1 -0
  178. package/dist/odspSummaryUploadManager.d.ts +7 -4
  179. package/dist/odspSummaryUploadManager.d.ts.map +1 -1
  180. package/dist/{odspUrlHelper.js → odspUrlHelper.cjs} +9 -3
  181. package/dist/odspUrlHelper.cjs.map +1 -0
  182. package/dist/odspUrlHelper.d.ts +5 -0
  183. package/dist/odspUrlHelper.d.ts.map +1 -1
  184. package/dist/{odspUtils.js → odspUtils.cjs} +118 -30
  185. package/dist/odspUtils.cjs.map +1 -0
  186. package/dist/odspUtils.d.ts +35 -6
  187. package/dist/odspUtils.d.ts.map +1 -1
  188. package/dist/{opsCaching.js → opsCaching.cjs} +25 -9
  189. package/dist/opsCaching.cjs.map +1 -0
  190. package/dist/opsCaching.d.ts +3 -3
  191. package/dist/opsCaching.d.ts.map +1 -1
  192. package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
  193. package/dist/packageVersion.cjs.map +1 -0
  194. package/dist/packageVersion.d.ts +1 -1
  195. package/dist/packageVersion.d.ts.map +1 -1
  196. package/dist/prefetchLatestSnapshot.cjs +100 -0
  197. package/dist/prefetchLatestSnapshot.cjs.map +1 -0
  198. package/dist/prefetchLatestSnapshot.d.ts +12 -7
  199. package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
  200. package/dist/{retryErrorsStorageAdapter.js → retryErrorsStorageAdapter.cjs} +13 -6
  201. package/dist/retryErrorsStorageAdapter.cjs.map +1 -0
  202. package/dist/retryErrorsStorageAdapter.d.ts +5 -4
  203. package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
  204. package/dist/{retryUtils.js → retryUtils.cjs} +30 -14
  205. package/dist/retryUtils.cjs.map +1 -0
  206. package/dist/retryUtils.d.ts +2 -2
  207. package/dist/retryUtils.d.ts.map +1 -1
  208. package/dist/socketModule.cjs +10 -0
  209. package/dist/socketModule.cjs.map +1 -0
  210. package/dist/socketModule.d.ts +7 -0
  211. package/dist/socketModule.d.ts.map +1 -0
  212. package/dist/tsdoc-metadata.json +11 -0
  213. package/dist/{vroom.js → vroom.cjs} +24 -9
  214. package/dist/vroom.cjs.map +1 -0
  215. package/dist/vroom.d.ts +4 -4
  216. package/dist/vroom.d.ts.map +1 -1
  217. package/dist/{zipItDataRepresentationUtils.js → zipItDataRepresentationUtils.cjs} +227 -118
  218. package/dist/zipItDataRepresentationUtils.cjs.map +1 -0
  219. package/dist/zipItDataRepresentationUtils.d.ts +47 -20
  220. package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
  221. package/lib/{ReadBufferUtils.d.ts → ReadBufferUtils.d.mts} +1 -1
  222. package/lib/ReadBufferUtils.d.mts.map +1 -0
  223. package/lib/{ReadBufferUtils.js → ReadBufferUtils.mjs} +14 -7
  224. package/lib/ReadBufferUtils.mjs.map +1 -0
  225. package/lib/{WriteBufferUtils.d.ts → WriteBufferUtils.d.mts} +4 -6
  226. package/lib/WriteBufferUtils.d.mts.map +1 -0
  227. package/lib/{WriteBufferUtils.js → WriteBufferUtils.mjs} +68 -64
  228. package/lib/WriteBufferUtils.mjs.map +1 -0
  229. package/lib/{checkUrl.d.ts → checkUrl.d.mts} +2 -1
  230. package/lib/checkUrl.d.mts.map +1 -0
  231. package/lib/{checkUrl.js → checkUrl.mjs} +7 -6
  232. package/lib/checkUrl.mjs.map +1 -0
  233. package/lib/compactSnapshotParser.d.mts +24 -0
  234. package/lib/compactSnapshotParser.d.mts.map +1 -0
  235. package/lib/compactSnapshotParser.mjs +203 -0
  236. package/lib/compactSnapshotParser.mjs.map +1 -0
  237. package/lib/{compactSnapshotWriter.d.ts → compactSnapshotWriter.d.mts} +4 -5
  238. package/lib/compactSnapshotWriter.d.mts.map +1 -0
  239. package/lib/{compactSnapshotWriter.js → compactSnapshotWriter.mjs} +41 -31
  240. package/lib/compactSnapshotWriter.mjs.map +1 -0
  241. package/lib/{constants.d.ts → constants.d.mts} +7 -1
  242. package/lib/constants.d.mts.map +1 -0
  243. package/lib/{constants.js → constants.mjs} +7 -1
  244. package/lib/constants.mjs.map +1 -0
  245. package/lib/{contracts.d.ts → contracts.d.mts} +18 -55
  246. package/lib/contracts.d.mts.map +1 -0
  247. package/lib/{contracts.js → contracts.mjs} +1 -1
  248. package/lib/contracts.mjs.map +1 -0
  249. package/lib/{contractsPublic.d.ts → contractsPublic.d.mts} +16 -1
  250. package/lib/contractsPublic.d.mts.map +1 -0
  251. package/lib/{contractsPublic.js → contractsPublic.mjs} +7 -1
  252. package/lib/contractsPublic.mjs.map +1 -0
  253. package/lib/createFile.d.mts +18 -0
  254. package/lib/createFile.d.mts.map +1 -0
  255. package/lib/createFile.mjs +171 -0
  256. package/lib/createFile.mjs.map +1 -0
  257. package/lib/createNewContainerOnExistingFile.d.mts +22 -0
  258. package/lib/createNewContainerOnExistingFile.d.mts.map +1 -0
  259. package/lib/createNewContainerOnExistingFile.mjs +56 -0
  260. package/lib/createNewContainerOnExistingFile.mjs.map +1 -0
  261. package/lib/createNewModule.d.mts +7 -0
  262. package/lib/createNewModule.d.mts.map +1 -0
  263. package/lib/createNewModule.mjs +7 -0
  264. package/lib/createNewModule.mjs.map +1 -0
  265. package/lib/createNewUtils.d.mts +27 -0
  266. package/lib/createNewUtils.d.mts.map +1 -0
  267. package/lib/createNewUtils.mjs +197 -0
  268. package/lib/createNewUtils.mjs.map +1 -0
  269. package/lib/{createOdspCreateContainerRequest.d.ts → createOdspCreateContainerRequest.d.mts} +6 -8
  270. package/lib/createOdspCreateContainerRequest.d.mts.map +1 -0
  271. package/lib/{createOdspCreateContainerRequest.js → createOdspCreateContainerRequest.mjs} +8 -4
  272. package/lib/createOdspCreateContainerRequest.mjs.map +1 -0
  273. package/lib/{createOdspUrl.d.ts → createOdspUrl.d.mts} +3 -2
  274. package/lib/createOdspUrl.d.mts.map +1 -0
  275. package/lib/{createOdspUrl.js → createOdspUrl.mjs} +2 -1
  276. package/lib/createOdspUrl.mjs.map +1 -0
  277. package/lib/{epochTracker.d.ts → epochTracker.d.mts} +35 -11
  278. package/lib/epochTracker.d.mts.map +1 -0
  279. package/lib/{epochTracker.js → epochTracker.mjs} +97 -43
  280. package/lib/epochTracker.mjs.map +1 -0
  281. package/lib/{fetch.d.ts → fetch.d.mts} +2 -2
  282. package/lib/fetch.d.mts.map +1 -0
  283. package/lib/{fetch.js → fetch.mjs} +1 -1
  284. package/lib/fetch.mjs.map +1 -0
  285. package/lib/{fetchSnapshot.d.ts → fetchSnapshot.d.mts} +15 -10
  286. package/lib/fetchSnapshot.d.mts.map +1 -0
  287. package/lib/{fetchSnapshot.js → fetchSnapshot.mjs} +185 -167
  288. package/lib/fetchSnapshot.mjs.map +1 -0
  289. package/lib/{getFileLink.d.ts → getFileLink.d.mts} +5 -8
  290. package/lib/getFileLink.d.mts.map +1 -0
  291. package/lib/{getFileLink.js → getFileLink.mjs} +49 -38
  292. package/lib/getFileLink.mjs.map +1 -0
  293. package/lib/{getQueryString.d.ts → getQueryString.d.mts} +1 -5
  294. package/lib/getQueryString.d.mts.map +1 -0
  295. package/lib/{getQueryString.js → getQueryString.mjs} +1 -1
  296. package/lib/getQueryString.mjs.map +1 -0
  297. package/lib/{getUrlAndHeadersWithAuth.d.ts → getUrlAndHeadersWithAuth.d.mts} +1 -1
  298. package/lib/getUrlAndHeadersWithAuth.d.mts.map +1 -0
  299. package/lib/{getUrlAndHeadersWithAuth.js → getUrlAndHeadersWithAuth.mjs} +4 -2
  300. package/lib/getUrlAndHeadersWithAuth.mjs.map +1 -0
  301. package/lib/index.d.mts +24 -0
  302. package/lib/index.d.mts.map +1 -0
  303. package/lib/index.mjs +22 -0
  304. package/lib/index.mjs.map +1 -0
  305. package/lib/localOdspDriver/localOdspDeltaStorageService.d.mts +17 -0
  306. package/lib/localOdspDriver/localOdspDeltaStorageService.d.mts.map +1 -0
  307. package/lib/localOdspDriver/localOdspDeltaStorageService.mjs +31 -0
  308. package/lib/localOdspDriver/localOdspDeltaStorageService.mjs.map +1 -0
  309. package/lib/localOdspDriver/{localOdspDocumentService.d.ts → localOdspDocumentService.d.mts} +4 -3
  310. package/lib/localOdspDriver/localOdspDocumentService.d.mts.map +1 -0
  311. package/lib/localOdspDriver/{localOdspDocumentService.js → localOdspDocumentService.mjs} +8 -6
  312. package/lib/localOdspDriver/localOdspDocumentService.mjs.map +1 -0
  313. package/lib/localOdspDriver/{localOdspDocumentServiceFactory.d.ts → localOdspDocumentServiceFactory.d.mts} +5 -6
  314. package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.mts.map +1 -0
  315. package/lib/localOdspDriver/{localOdspDocumentServiceFactory.js → localOdspDocumentServiceFactory.mjs} +9 -10
  316. package/lib/localOdspDriver/localOdspDocumentServiceFactory.mjs.map +1 -0
  317. package/lib/localOdspDriver/{localOdspDocumentStorageManager.d.ts → localOdspDocumentStorageManager.d.mts} +4 -4
  318. package/lib/localOdspDriver/localOdspDocumentStorageManager.d.mts.map +1 -0
  319. package/lib/localOdspDriver/{localOdspDocumentStorageManager.js → localOdspDocumentStorageManager.mjs} +11 -9
  320. package/lib/localOdspDriver/localOdspDocumentStorageManager.mjs.map +1 -0
  321. package/lib/odsp-driver-alpha.d.mts +496 -0
  322. package/lib/odsp-driver-beta.d.mts +160 -0
  323. package/lib/odsp-driver-public.d.mts +160 -0
  324. package/lib/odsp-driver-untrimmed.d.mts +565 -0
  325. package/lib/{odspCache.d.ts → odspCache.d.mts} +20 -9
  326. package/lib/odspCache.d.mts.map +1 -0
  327. package/lib/{odspCache.js → odspCache.mjs} +6 -11
  328. package/lib/odspCache.mjs.map +1 -0
  329. package/lib/odspDelayLoadedDeltaStream.d.mts +75 -0
  330. package/lib/odspDelayLoadedDeltaStream.d.mts.map +1 -0
  331. package/lib/odspDelayLoadedDeltaStream.mjs +287 -0
  332. package/lib/odspDelayLoadedDeltaStream.mjs.map +1 -0
  333. package/lib/{odspDeltaStorageService.d.ts → odspDeltaStorageService.d.mts} +10 -8
  334. package/lib/odspDeltaStorageService.d.mts.map +1 -0
  335. package/lib/{odspDeltaStorageService.js → odspDeltaStorageService.mjs} +70 -68
  336. package/lib/odspDeltaStorageService.mjs.map +1 -0
  337. package/lib/{odspDocumentDeltaConnection.d.ts → odspDocumentDeltaConnection.d.mts} +34 -14
  338. package/lib/odspDocumentDeltaConnection.d.mts.map +1 -0
  339. package/lib/{odspDocumentDeltaConnection.js → odspDocumentDeltaConnection.mjs} +214 -103
  340. package/lib/odspDocumentDeltaConnection.mjs.map +1 -0
  341. package/lib/{odspDocumentService.d.ts → odspDocumentService.d.mts} +15 -29
  342. package/lib/odspDocumentService.d.mts.map +1 -0
  343. package/lib/odspDocumentService.mjs +221 -0
  344. package/lib/odspDocumentService.mjs.map +1 -0
  345. package/lib/{odspDocumentServiceFactory.d.ts → odspDocumentServiceFactory.d.mts} +6 -2
  346. package/lib/odspDocumentServiceFactory.d.mts.map +1 -0
  347. package/lib/{odspDocumentServiceFactory.js → odspDocumentServiceFactory.mjs} +8 -6
  348. package/lib/odspDocumentServiceFactory.mjs.map +1 -0
  349. package/lib/{odspDocumentServiceFactoryCore.d.ts → odspDocumentServiceFactoryCore.d.mts} +20 -13
  350. package/lib/odspDocumentServiceFactoryCore.d.mts.map +1 -0
  351. package/lib/odspDocumentServiceFactoryCore.mjs +192 -0
  352. package/lib/odspDocumentServiceFactoryCore.mjs.map +1 -0
  353. package/lib/{odspDocumentServiceFactoryWithCodeSplit.d.ts → odspDocumentServiceFactoryWithCodeSplit.d.mts} +7 -2
  354. package/lib/odspDocumentServiceFactoryWithCodeSplit.d.mts.map +1 -0
  355. package/lib/{odspDocumentServiceFactoryWithCodeSplit.js → odspDocumentServiceFactoryWithCodeSplit.mjs} +8 -3
  356. package/lib/odspDocumentServiceFactoryWithCodeSplit.mjs.map +1 -0
  357. package/lib/{odspDocumentStorageManager.d.ts → odspDocumentStorageManager.d.mts} +18 -12
  358. package/lib/odspDocumentStorageManager.d.mts.map +1 -0
  359. package/lib/odspDocumentStorageManager.mjs +486 -0
  360. package/lib/odspDocumentStorageManager.mjs.map +1 -0
  361. package/lib/{odspDocumentStorageServiceBase.d.ts → odspDocumentStorageServiceBase.d.mts} +9 -11
  362. package/lib/odspDocumentStorageServiceBase.d.mts.map +1 -0
  363. package/lib/{odspDocumentStorageServiceBase.js → odspDocumentStorageServiceBase.mjs} +31 -33
  364. package/lib/odspDocumentStorageServiceBase.mjs.map +1 -0
  365. package/lib/{odspDriverUrlResolver.d.ts → odspDriverUrlResolver.d.mts} +13 -1
  366. package/lib/odspDriverUrlResolver.d.mts.map +1 -0
  367. package/lib/{odspDriverUrlResolver.js → odspDriverUrlResolver.mjs} +50 -40
  368. package/lib/odspDriverUrlResolver.mjs.map +1 -0
  369. package/lib/{odspDriverUrlResolverForShareLink.d.ts → odspDriverUrlResolverForShareLink.d.mts} +7 -5
  370. package/lib/odspDriverUrlResolverForShareLink.d.mts.map +1 -0
  371. package/lib/{odspDriverUrlResolverForShareLink.js → odspDriverUrlResolverForShareLink.mjs} +36 -29
  372. package/lib/odspDriverUrlResolverForShareLink.mjs.map +1 -0
  373. package/lib/{odspError.d.ts → odspError.d.mts} +2 -2
  374. package/lib/odspError.d.mts.map +1 -0
  375. package/lib/{odspError.js → odspError.mjs} +7 -3
  376. package/lib/odspError.mjs.map +1 -0
  377. package/lib/{odspFluidFileLink.d.ts → odspFluidFileLink.d.mts} +12 -3
  378. package/lib/odspFluidFileLink.d.mts.map +1 -0
  379. package/lib/{odspFluidFileLink.js → odspFluidFileLink.mjs} +23 -16
  380. package/lib/odspFluidFileLink.mjs.map +1 -0
  381. package/lib/odspLocationRedirection.d.mts +14 -0
  382. package/lib/odspLocationRedirection.d.mts.map +1 -0
  383. package/lib/odspLocationRedirection.mjs +20 -0
  384. package/lib/odspLocationRedirection.mjs.map +1 -0
  385. package/lib/{odspPublicUtils.d.ts → odspPublicUtils.d.mts} +7 -1
  386. package/lib/odspPublicUtils.d.mts.map +1 -0
  387. package/lib/{odspPublicUtils.js → odspPublicUtils.mjs} +5 -2
  388. package/lib/odspPublicUtils.mjs.map +1 -0
  389. package/lib/{odspSnapshotParser.d.ts → odspSnapshotParser.d.mts} +3 -3
  390. package/lib/odspSnapshotParser.d.mts.map +1 -0
  391. package/lib/{odspSnapshotParser.js → odspSnapshotParser.mjs} +10 -11
  392. package/lib/odspSnapshotParser.mjs.map +1 -0
  393. package/lib/{odspSummaryUploadManager.d.ts → odspSummaryUploadManager.d.mts} +9 -6
  394. package/lib/odspSummaryUploadManager.d.mts.map +1 -0
  395. package/lib/{odspSummaryUploadManager.js → odspSummaryUploadManager.mjs} +41 -32
  396. package/lib/odspSummaryUploadManager.mjs.map +1 -0
  397. package/lib/{odspUrlHelper.d.ts → odspUrlHelper.d.mts} +6 -1
  398. package/lib/odspUrlHelper.d.mts.map +1 -0
  399. package/lib/{odspUrlHelper.js → odspUrlHelper.mjs} +9 -3
  400. package/lib/odspUrlHelper.mjs.map +1 -0
  401. package/lib/{odspUtils.d.ts → odspUtils.d.mts} +37 -8
  402. package/lib/odspUtils.d.mts.map +1 -0
  403. package/lib/{odspUtils.js → odspUtils.mjs} +109 -27
  404. package/lib/odspUtils.mjs.map +1 -0
  405. package/lib/{opsCaching.d.ts → opsCaching.d.mts} +4 -4
  406. package/lib/opsCaching.d.mts.map +1 -0
  407. package/lib/{opsCaching.js → opsCaching.mjs} +23 -7
  408. package/lib/opsCaching.mjs.map +1 -0
  409. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +2 -2
  410. package/lib/packageVersion.d.mts.map +1 -0
  411. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  412. package/lib/packageVersion.mjs.map +1 -0
  413. package/lib/{prefetchLatestSnapshot.d.ts → prefetchLatestSnapshot.d.mts} +14 -9
  414. package/lib/prefetchLatestSnapshot.d.mts.map +1 -0
  415. package/lib/prefetchLatestSnapshot.mjs +96 -0
  416. package/lib/prefetchLatestSnapshot.mjs.map +1 -0
  417. package/lib/{retryErrorsStorageAdapter.d.ts → retryErrorsStorageAdapter.d.mts} +6 -5
  418. package/lib/retryErrorsStorageAdapter.d.mts.map +1 -0
  419. package/lib/{retryErrorsStorageAdapter.js → retryErrorsStorageAdapter.mjs} +13 -6
  420. package/lib/retryErrorsStorageAdapter.mjs.map +1 -0
  421. package/lib/{retryUtils.d.ts → retryUtils.d.mts} +3 -3
  422. package/lib/retryUtils.d.mts.map +1 -0
  423. package/lib/{retryUtils.js → retryUtils.mjs} +27 -11
  424. package/lib/retryUtils.mjs.map +1 -0
  425. package/lib/socketModule.d.mts +7 -0
  426. package/lib/socketModule.d.mts.map +1 -0
  427. package/lib/socketModule.mjs +7 -0
  428. package/lib/socketModule.mjs.map +1 -0
  429. package/lib/{vroom.d.ts → vroom.d.mts} +7 -7
  430. package/lib/vroom.d.mts.map +1 -0
  431. package/lib/{vroom.js → vroom.mjs} +24 -9
  432. package/lib/vroom.mjs.map +1 -0
  433. package/lib/{zipItDataRepresentationUtils.d.ts → zipItDataRepresentationUtils.d.mts} +49 -22
  434. package/lib/zipItDataRepresentationUtils.d.mts.map +1 -0
  435. package/lib/{zipItDataRepresentationUtils.js → zipItDataRepresentationUtils.mjs} +213 -111
  436. package/lib/zipItDataRepresentationUtils.mjs.map +1 -0
  437. package/package.json +87 -69
  438. package/prettier.config.cjs +8 -0
  439. package/src/ReadBufferUtils.ts +51 -44
  440. package/src/WriteBufferUtils.ts +203 -181
  441. package/src/checkUrl.ts +16 -15
  442. package/src/compactSnapshotParser.ts +219 -103
  443. package/src/compactSnapshotWriter.ts +118 -97
  444. package/src/constants.ts +7 -0
  445. package/src/contracts.ts +96 -136
  446. package/src/contractsPublic.ts +31 -16
  447. package/src/createFile.ts +243 -305
  448. package/src/createNewContainerOnExistingFile.ts +93 -0
  449. package/src/createNewModule.ts +7 -0
  450. package/src/createNewUtils.ts +266 -56
  451. package/src/createOdspCreateContainerRequest.ts +22 -18
  452. package/src/createOdspUrl.ts +12 -13
  453. package/src/epochTracker.ts +596 -457
  454. package/src/fetch.ts +4 -4
  455. package/src/fetchSnapshot.ts +583 -508
  456. package/src/getFileLink.ts +194 -155
  457. package/src/getQueryString.ts +11 -9
  458. package/src/getUrlAndHeadersWithAuth.ts +34 -33
  459. package/src/index.ts +42 -18
  460. package/src/localOdspDriver/localOdspDeltaStorageService.ts +49 -0
  461. package/src/localOdspDriver/localOdspDocumentService.ts +40 -38
  462. package/src/localOdspDriver/localOdspDocumentServiceFactory.ts +46 -43
  463. package/src/localOdspDriver/localOdspDocumentStorageManager.ts +55 -50
  464. package/src/odspCache.ts +112 -90
  465. package/src/odspDelayLoadedDeltaStream.ts +459 -0
  466. package/src/odspDeltaStorageService.ts +232 -221
  467. package/src/odspDocumentDeltaConnection.ts +751 -563
  468. package/src/odspDocumentService.ts +324 -523
  469. package/src/odspDocumentServiceFactory.ts +20 -21
  470. package/src/odspDocumentServiceFactoryCore.ts +329 -200
  471. package/src/odspDocumentServiceFactoryWithCodeSplit.ts +20 -20
  472. package/src/odspDocumentStorageManager.ts +730 -534
  473. package/src/odspDocumentStorageServiceBase.ts +279 -254
  474. package/src/odspDriverUrlResolver.ts +230 -188
  475. package/src/odspDriverUrlResolverForShareLink.ts +223 -203
  476. package/src/odspError.ts +27 -19
  477. package/src/odspFluidFileLink.ts +106 -87
  478. package/src/odspLocationRedirection.ts +26 -0
  479. package/src/odspPublicUtils.ts +20 -14
  480. package/src/odspSnapshotParser.ts +53 -46
  481. package/src/odspSummaryUploadManager.ts +243 -218
  482. package/src/odspUrlHelper.ts +81 -71
  483. package/src/odspUtils.ts +401 -259
  484. package/src/opsCaching.ts +214 -193
  485. package/src/packageVersion.ts +1 -1
  486. package/src/prefetchLatestSnapshot.ts +142 -80
  487. package/src/retryErrorsStorageAdapter.ts +92 -77
  488. package/src/retryUtils.ts +80 -57
  489. package/src/socketModule.ts +8 -0
  490. package/src/vroom.ts +92 -83
  491. package/src/zipItDataRepresentationUtils.ts +534 -394
  492. package/tsc-multi.test.json +4 -0
  493. package/tsconfig.json +11 -13
  494. package/.editorconfig +0 -7
  495. package/dist/ReadBufferUtils.js.map +0 -1
  496. package/dist/WriteBufferUtils.js.map +0 -1
  497. package/dist/checkUrl.js.map +0 -1
  498. package/dist/compactSnapshotParser.js +0 -115
  499. package/dist/compactSnapshotParser.js.map +0 -1
  500. package/dist/compactSnapshotWriter.js.map +0 -1
  501. package/dist/constants.js.map +0 -1
  502. package/dist/contracts.js.map +0 -1
  503. package/dist/contractsPublic.js.map +0 -1
  504. package/dist/createFile.js +0 -242
  505. package/dist/createFile.js.map +0 -1
  506. package/dist/createNewUtils.js +0 -67
  507. package/dist/createNewUtils.js.map +0 -1
  508. package/dist/createOdspCreateContainerRequest.js.map +0 -1
  509. package/dist/createOdspUrl.js.map +0 -1
  510. package/dist/epochTracker.js.map +0 -1
  511. package/dist/fetch.js.map +0 -1
  512. package/dist/fetchSnapshot.js.map +0 -1
  513. package/dist/getFileLink.js.map +0 -1
  514. package/dist/getQueryString.js.map +0 -1
  515. package/dist/getSocketIo.d.ts +0 -11
  516. package/dist/getSocketIo.d.ts.map +0 -1
  517. package/dist/getSocketIo.js +0 -20
  518. package/dist/getSocketIo.js.map +0 -1
  519. package/dist/getUrlAndHeadersWithAuth.js.map +0 -1
  520. package/dist/index.js +0 -41
  521. package/dist/index.js.map +0 -1
  522. package/dist/localOdspDriver/localOdspDocumentService.js.map +0 -1
  523. package/dist/localOdspDriver/localOdspDocumentServiceFactory.js.map +0 -1
  524. package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +0 -1
  525. package/dist/odspCache.js.map +0 -1
  526. package/dist/odspDeltaStorageService.js.map +0 -1
  527. package/dist/odspDocumentDeltaConnection.js.map +0 -1
  528. package/dist/odspDocumentService.js +0 -364
  529. package/dist/odspDocumentService.js.map +0 -1
  530. package/dist/odspDocumentServiceFactory.js.map +0 -1
  531. package/dist/odspDocumentServiceFactoryCore.js +0 -118
  532. package/dist/odspDocumentServiceFactoryCore.js.map +0 -1
  533. package/dist/odspDocumentServiceFactoryWithCodeSplit.js +0 -34
  534. package/dist/odspDocumentServiceFactoryWithCodeSplit.js.map +0 -1
  535. package/dist/odspDocumentStorageManager.js +0 -356
  536. package/dist/odspDocumentStorageManager.js.map +0 -1
  537. package/dist/odspDocumentStorageServiceBase.js.map +0 -1
  538. package/dist/odspDriverUrlResolver.js.map +0 -1
  539. package/dist/odspDriverUrlResolverForShareLink.js.map +0 -1
  540. package/dist/odspError.js.map +0 -1
  541. package/dist/odspFluidFileLink.js.map +0 -1
  542. package/dist/odspPublicUtils.js.map +0 -1
  543. package/dist/odspSnapshotParser.js.map +0 -1
  544. package/dist/odspSummaryUploadManager.js.map +0 -1
  545. package/dist/odspUrlHelper.js.map +0 -1
  546. package/dist/odspUtils.js.map +0 -1
  547. package/dist/opsCaching.js.map +0 -1
  548. package/dist/packageVersion.js.map +0 -1
  549. package/dist/prefetchLatestSnapshot.js +0 -57
  550. package/dist/prefetchLatestSnapshot.js.map +0 -1
  551. package/dist/retryErrorsStorageAdapter.js.map +0 -1
  552. package/dist/retryUtils.js.map +0 -1
  553. package/dist/vroom.js.map +0 -1
  554. package/dist/zipItDataRepresentationUtils.js.map +0 -1
  555. package/lib/ReadBufferUtils.d.ts.map +0 -1
  556. package/lib/ReadBufferUtils.js.map +0 -1
  557. package/lib/WriteBufferUtils.d.ts.map +0 -1
  558. package/lib/WriteBufferUtils.js.map +0 -1
  559. package/lib/checkUrl.d.ts.map +0 -1
  560. package/lib/checkUrl.js.map +0 -1
  561. package/lib/compactSnapshotParser.d.ts +0 -15
  562. package/lib/compactSnapshotParser.d.ts.map +0 -1
  563. package/lib/compactSnapshotParser.js +0 -111
  564. package/lib/compactSnapshotParser.js.map +0 -1
  565. package/lib/compactSnapshotWriter.d.ts.map +0 -1
  566. package/lib/compactSnapshotWriter.js.map +0 -1
  567. package/lib/constants.d.ts.map +0 -1
  568. package/lib/constants.js.map +0 -1
  569. package/lib/contracts.d.ts.map +0 -1
  570. package/lib/contracts.js.map +0 -1
  571. package/lib/contractsPublic.d.ts.map +0 -1
  572. package/lib/contractsPublic.js.map +0 -1
  573. package/lib/createFile.d.ts +0 -22
  574. package/lib/createFile.d.ts.map +0 -1
  575. package/lib/createFile.js +0 -235
  576. package/lib/createFile.js.map +0 -1
  577. package/lib/createNewUtils.d.ts +0 -11
  578. package/lib/createNewUtils.d.ts.map +0 -1
  579. package/lib/createNewUtils.js +0 -63
  580. package/lib/createNewUtils.js.map +0 -1
  581. package/lib/createOdspCreateContainerRequest.d.ts.map +0 -1
  582. package/lib/createOdspCreateContainerRequest.js.map +0 -1
  583. package/lib/createOdspUrl.d.ts.map +0 -1
  584. package/lib/createOdspUrl.js.map +0 -1
  585. package/lib/epochTracker.d.ts.map +0 -1
  586. package/lib/epochTracker.js.map +0 -1
  587. package/lib/fetch.d.ts.map +0 -1
  588. package/lib/fetch.js.map +0 -1
  589. package/lib/fetchSnapshot.d.ts.map +0 -1
  590. package/lib/fetchSnapshot.js.map +0 -1
  591. package/lib/getFileLink.d.ts.map +0 -1
  592. package/lib/getFileLink.js.map +0 -1
  593. package/lib/getQueryString.d.ts.map +0 -1
  594. package/lib/getQueryString.js.map +0 -1
  595. package/lib/getSocketIo.d.ts +0 -11
  596. package/lib/getSocketIo.d.ts.map +0 -1
  597. package/lib/getSocketIo.js +0 -13
  598. package/lib/getSocketIo.js.map +0 -1
  599. package/lib/getUrlAndHeadersWithAuth.d.ts.map +0 -1
  600. package/lib/getUrlAndHeadersWithAuth.js.map +0 -1
  601. package/lib/index.d.ts +0 -21
  602. package/lib/index.d.ts.map +0 -1
  603. package/lib/index.js +0 -29
  604. package/lib/index.js.map +0 -1
  605. package/lib/localOdspDriver/localOdspDocumentService.d.ts.map +0 -1
  606. package/lib/localOdspDriver/localOdspDocumentService.js.map +0 -1
  607. package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +0 -1
  608. package/lib/localOdspDriver/localOdspDocumentServiceFactory.js.map +0 -1
  609. package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +0 -1
  610. package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +0 -1
  611. package/lib/odspCache.d.ts.map +0 -1
  612. package/lib/odspCache.js.map +0 -1
  613. package/lib/odspDeltaStorageService.d.ts.map +0 -1
  614. package/lib/odspDeltaStorageService.js.map +0 -1
  615. package/lib/odspDocumentDeltaConnection.d.ts.map +0 -1
  616. package/lib/odspDocumentDeltaConnection.js.map +0 -1
  617. package/lib/odspDocumentService.d.ts.map +0 -1
  618. package/lib/odspDocumentService.js +0 -360
  619. package/lib/odspDocumentService.js.map +0 -1
  620. package/lib/odspDocumentServiceFactory.d.ts.map +0 -1
  621. package/lib/odspDocumentServiceFactory.js.map +0 -1
  622. package/lib/odspDocumentServiceFactoryCore.d.ts.map +0 -1
  623. package/lib/odspDocumentServiceFactoryCore.js +0 -114
  624. package/lib/odspDocumentServiceFactoryCore.js.map +0 -1
  625. package/lib/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +0 -1
  626. package/lib/odspDocumentServiceFactoryWithCodeSplit.js.map +0 -1
  627. package/lib/odspDocumentStorageManager.d.ts.map +0 -1
  628. package/lib/odspDocumentStorageManager.js +0 -352
  629. package/lib/odspDocumentStorageManager.js.map +0 -1
  630. package/lib/odspDocumentStorageServiceBase.d.ts.map +0 -1
  631. package/lib/odspDocumentStorageServiceBase.js.map +0 -1
  632. package/lib/odspDriverUrlResolver.d.ts.map +0 -1
  633. package/lib/odspDriverUrlResolver.js.map +0 -1
  634. package/lib/odspDriverUrlResolverForShareLink.d.ts.map +0 -1
  635. package/lib/odspDriverUrlResolverForShareLink.js.map +0 -1
  636. package/lib/odspError.d.ts.map +0 -1
  637. package/lib/odspError.js.map +0 -1
  638. package/lib/odspFluidFileLink.d.ts.map +0 -1
  639. package/lib/odspFluidFileLink.js.map +0 -1
  640. package/lib/odspPublicUtils.d.ts.map +0 -1
  641. package/lib/odspPublicUtils.js.map +0 -1
  642. package/lib/odspSnapshotParser.d.ts.map +0 -1
  643. package/lib/odspSnapshotParser.js.map +0 -1
  644. package/lib/odspSummaryUploadManager.d.ts.map +0 -1
  645. package/lib/odspSummaryUploadManager.js.map +0 -1
  646. package/lib/odspUrlHelper.d.ts.map +0 -1
  647. package/lib/odspUrlHelper.js.map +0 -1
  648. package/lib/odspUtils.d.ts.map +0 -1
  649. package/lib/odspUtils.js.map +0 -1
  650. package/lib/opsCaching.d.ts.map +0 -1
  651. package/lib/opsCaching.js.map +0 -1
  652. package/lib/packageVersion.d.ts.map +0 -1
  653. package/lib/packageVersion.js.map +0 -1
  654. package/lib/prefetchLatestSnapshot.d.ts.map +0 -1
  655. package/lib/prefetchLatestSnapshot.js +0 -53
  656. package/lib/prefetchLatestSnapshot.js.map +0 -1
  657. package/lib/retryErrorsStorageAdapter.d.ts.map +0 -1
  658. package/lib/retryErrorsStorageAdapter.js.map +0 -1
  659. package/lib/retryUtils.d.ts.map +0 -1
  660. package/lib/retryUtils.js.map +0 -1
  661. package/lib/vroom.d.ts.map +0 -1
  662. package/lib/vroom.js.map +0 -1
  663. package/lib/zipItDataRepresentationUtils.d.ts.map +0 -1
  664. package/lib/zipItDataRepresentationUtils.js.map +0 -1
  665. package/src/getSocketIo.ts +0 -14
  666. package/tsconfig.esnext.json +0 -7
@@ -4,491 +4,630 @@
4
4
  */
5
5
 
6
6
  import { v4 as uuid } from "uuid";
7
- import { assert, Deferred } from "@fluidframework/common-utils";
8
- import { ITelemetryLogger } from "@fluidframework/common-definitions";
9
- import { ThrottlingError, RateLimiter, NonRetryableError } from "@fluidframework/driver-utils";
10
- import { IConnected } from "@fluidframework/protocol-definitions";
7
+ import { assert, Deferred } from "@fluidframework/core-utils";
11
8
  import {
12
- snapshotKey,
13
- ICacheEntry,
14
- IEntry,
15
- IFileEntry,
16
- IPersistedCache,
17
- IOdspError,
9
+ ITelemetryLoggerExt,
10
+ PerformanceEvent,
11
+ isFluidError,
12
+ normalizeError,
13
+ loggerToMonitoringContext,
14
+ wrapError,
15
+ } from "@fluidframework/telemetry-utils";
16
+ import {
17
+ ThrottlingError,
18
+ RateLimiter,
19
+ NonRetryableError,
20
+ LocationRedirectionError,
21
+ } from "@fluidframework/driver-utils";
22
+ import {
23
+ snapshotKey,
24
+ ICacheEntry,
25
+ IEntry,
26
+ IFileEntry,
27
+ IPersistedCache,
28
+ IOdspError,
29
+ IOdspErrorAugmentations,
30
+ IOdspResolvedUrl,
18
31
  } from "@fluidframework/odsp-driver-definitions";
19
32
  import { DriverErrorType } from "@fluidframework/driver-definitions";
20
- import { PerformanceEvent, isFluidError, normalizeError } from "@fluidframework/telemetry-utils";
21
- import { fetchAndParseAsJSONHelper, fetchArray, fetchHelper, getOdspResolvedUrl, IOdspResponse } from "./odspUtils";
22
33
  import {
23
- IOdspCache,
24
- INonPersistentCache,
25
- IPersistedFileCache,
26
- } from "./odspCache";
34
+ fetchAndParseAsJSONHelper,
35
+ fetchArray,
36
+ fetchHelper,
37
+ getOdspResolvedUrl,
38
+ IOdspResponse,
39
+ } from "./odspUtils";
40
+ import { IOdspCache, INonPersistentCache, IPersistedFileCache } from "./odspCache";
27
41
  import { IVersionedValueWithEpoch, persistedCacheValueVersion } from "./contracts";
28
42
  import { ClpCompliantAppHeader } from "./contractsPublic";
29
43
  import { pkgVersion as driverVersion } from "./packageVersion";
44
+ import { patchOdspResolvedUrl } from "./odspLocationRedirection";
30
45
 
31
- export type FetchType = "blob" | "createBlob" | "createFile" | "joinSession" | "ops" | "test" | "snapshotTree" |
32
- "treesLatest" | "uploadSummary" | "push" | "versions";
46
+ /**
47
+ * @alpha
48
+ */
49
+ export type FetchType =
50
+ | "blob"
51
+ | "createBlob"
52
+ | "createFile"
53
+ | "joinSession"
54
+ | "ops"
55
+ | "test"
56
+ | "snapshotTree"
57
+ | "treesLatest"
58
+ | "uploadSummary"
59
+ | "push"
60
+ | "versions";
33
61
 
62
+ /**
63
+ * @alpha
64
+ */
34
65
  export type FetchTypeInternal = FetchType | "cache";
35
66
 
36
67
  export const Odsp409Error = "Odsp409Error";
37
68
 
38
- // Please update the README file in odsp-driver-definitions if you change the defaultCacheExpiryTimeoutMs.
39
- export const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000;
69
+ // Must be less than policy of 5 days
70
+ export const defaultCacheExpiryTimeoutMs: number = 2 * 24 * 60 * 60 * 1000; // 2 days in ms
40
71
 
41
72
  /**
73
+ * In ODSP, the concept of "epoch" refers to binary updates to files. For example, this might include using
74
+ * version restore, or if the user downloads a Fluid file and then uploads it again. These result in the epoch
75
+ * value being incremented.
76
+ *
77
+ * The implications of these binary updates is that the Fluid state is disrupted: the sequence number might
78
+ * go backwards, the data might be inconsistent with the latest state of collaboration, etc. As a result, it's
79
+ * not safe to continue collaboration across an epoch change. We need to detect these epoch changes and
80
+ * error out from the collaboration.
81
+ *
42
82
  * This class is a wrapper around fetch calls. It adds epoch to the request made so that the
43
83
  * server can match it with its epoch value in order to match the version.
44
84
  * It also validates the epoch value received in response of fetch calls. If the epoch does not match,
45
85
  * then it also clears all the cached entries for the given container.
86
+ * @alpha
46
87
  */
47
88
  export class EpochTracker implements IPersistedFileCache {
48
- private _fluidEpoch: string | undefined;
49
-
50
- public readonly rateLimiter: RateLimiter;
51
- private readonly driverId = uuid();
52
- // This tracks the request number made by the driver instance.
53
- private networkCallNumber = 1;
54
- constructor(
55
- protected readonly cache: IPersistedCache,
56
- protected readonly fileEntry: IFileEntry,
57
- protected readonly logger: ITelemetryLogger,
58
- protected readonly clientIsSummarizer?: boolean,
59
- ) {
60
- // Limits the max number of concurrent requests to 24.
61
- this.rateLimiter = new RateLimiter(24);
62
- }
63
-
64
- // public for UT purposes only!
65
- public setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {
66
- assert(this._fluidEpoch === undefined, 0x1db /* "epoch exists" */);
67
- this._fluidEpoch = epoch;
68
-
69
- this.logger.sendTelemetryEvent(
70
- {
71
- eventName: "EpochLearnedFirstTime",
72
- epoch,
73
- fetchType,
74
- fromCache,
75
- },
76
- );
77
- }
78
-
79
- public async get(
80
- entry: IEntry,
81
- ): Promise<any> {
82
- try {
83
- // Return undefined so that the ops/snapshots are grabbed from the server instead of the cache
84
- const value: IVersionedValueWithEpoch = await this.cache.get(this.fileEntryFromEntry(entry));
85
- // Version mismatch between what the runtime expects and what it recieved.
86
- // The cached value should not be used
87
- if (value === undefined || value.version !== persistedCacheValueVersion) {
88
- return undefined;
89
- }
90
- assert(value.fluidEpoch !== undefined, 0x1dc /* "all entries have to have epoch" */);
91
- if (this._fluidEpoch === undefined) {
92
- this.setEpoch(value.fluidEpoch, true, "cache");
93
- // Epoch mismatch, the cached value is considerably different from what the current state of
94
- // the runtime and should not be used
95
- } else if (this._fluidEpoch !== value.fluidEpoch) {
96
- return undefined;
97
- }
98
- // Expire the cached snapshot if it's older than the defaultCacheExpiryTimeoutMs and immediately
99
- // expire all old caches that do not have cacheEntryTime
100
- if (entry.type === snapshotKey) {
101
- const cacheTime = value.value?.cacheEntryTime;
102
- const currentTime = Date.now();
103
- if (cacheTime === undefined || currentTime - cacheTime >= defaultCacheExpiryTimeoutMs) {
104
- this.logger.sendTelemetryEvent(
105
- {
106
- eventName: "odspVersionsCacheExpired",
107
- duration: currentTime - cacheTime,
108
- maxCacheAgeMs: defaultCacheExpiryTimeoutMs,
109
- });
110
- await this.removeEntries();
111
- return undefined;
112
- }
113
- }
114
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
115
- return value.value;
116
- } catch (error) {
117
- this.logger.sendErrorEvent({ eventName: "cacheFetchError", type: entry.type }, error);
118
- return undefined;
119
- }
120
- }
121
-
122
- public async put(entry: IEntry, value: any) {
123
- assert(this._fluidEpoch !== undefined, 0x1dd /* "no epoch" */);
124
- // For snapshots, the value should have the cacheEntryTime. This will be used to expire snapshots older
125
- // than the defaultCacheExpiryTimeoutMs.
126
- if (entry.type === snapshotKey) {
127
- value.cacheEntryTime = value.cacheEntryTime ?? Date.now();
128
- }
129
- const data: IVersionedValueWithEpoch = {
130
- value,
131
- version: persistedCacheValueVersion,
132
- fluidEpoch: this._fluidEpoch,
133
- };
134
- return this.cache.put(this.fileEntryFromEntry(entry), data)
135
- .catch((error) => {
136
- this.logger.sendErrorEvent({ eventName: "cachePutError", type: entry.type }, error);
137
- throw error;
138
- });
139
- }
140
-
141
- public async removeEntries(): Promise<void> {
142
- try {
143
- return await this.cache.removeEntries(this.fileEntry);
144
- } catch (error) {
145
- this.logger.sendErrorEvent({ eventName: "removeCacheEntries" }, error);
146
- }
147
- }
148
-
149
- public get fluidEpoch() {
150
- return this._fluidEpoch;
151
- }
152
-
153
- public async validateEpochFromPush(details: IConnected) {
154
- const epoch = details.epoch;
155
- assert(epoch !== undefined, 0x09d /* "Connection details should contain epoch" */);
156
- try {
157
- this.validateEpochFromResponse(epoch, "push");
158
- } catch (error) {
159
- await this.checkForEpochError(error, epoch, "push");
160
- throw error;
161
- }
162
- }
163
-
164
- /**
165
- * Api to fetch the response for given request and parse it as json.
166
- * @param url - url of the request
167
- * @param fetchOptions - fetch options for request containing body, headers etc.
168
- * @param fetchType - method for which fetch is called.
169
- * @param addInBody - Pass True if caller wants to add epoch in post body.
170
- * @param fetchReason - fetch reason to add to the request.
171
- */
172
- public async fetchAndParseAsJSON<T>(
173
- url: string,
174
- fetchOptions: RequestInit,
175
- fetchType: FetchType,
176
- addInBody: boolean = false,
177
- fetchReason?: string,
178
- ): Promise<IOdspResponse<T>> {
179
- return this.fetchCore<T>(url, fetchOptions, fetchAndParseAsJSONHelper, fetchType, addInBody, fetchReason);
180
- }
181
-
182
- /**
183
- * Api to fetch the response for given request and parse it as json.
184
- * @param url - url of the request
185
- * @param fetchOptions - fetch options for request containing body, headers etc.
186
- * @param fetchType - method for which fetch is called.
187
- * @param addInBody - Pass True if caller wants to add epoch in post body.
188
- * @param fetchReason - fetch reason to add to the request.
189
- */
190
- public async fetch(
191
- url: string,
192
- fetchOptions: RequestInit,
193
- fetchType: FetchType,
194
- addInBody: boolean = false,
195
- fetchReason?: string,
196
- ) {
197
- return this.fetchCore<Response>(url, fetchOptions, fetchHelper, fetchType, addInBody, fetchReason);
198
- }
199
-
200
- private async fetchCore<T>(
201
- url: string,
202
- fetchOptions: { [index: string]: any; },
203
- fetcher: (url: string, fetchOptions: { [index: string]: any; }) => Promise<IOdspResponse<T>>,
204
- fetchType: FetchType,
205
- addInBody: boolean = false,
206
- fetchReason?: string,
207
- ) {
208
- const clientCorrelationId = this.formatClientCorrelationId(fetchReason);
209
- // Add epoch in fetch request.
210
- this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
211
- let epochFromResponse: string | undefined;
212
- return this.rateLimiter.schedule(
213
- async () => fetcher(url, fetchOptions),
214
- ).then((response) => {
215
- epochFromResponse = response.headers.get("x-fluid-epoch");
216
- this.validateEpochFromResponse(epochFromResponse, fetchType);
217
- response.propsToLog.XRequestStatsHeader = clientCorrelationId;
218
- return response;
219
- }).catch(async (error) => {
220
- // Get the server epoch from error in case we don't have it as if undefined we won't be able
221
- // to mark it as epoch error.
222
- if (epochFromResponse === undefined) {
223
- epochFromResponse = (error as IOdspError).serverEpoch;
224
- }
225
- await this.checkForEpochError(error, epochFromResponse, fetchType);
226
- throw error;
227
- }).catch((error) => {
228
- const fluidError = normalizeError(error, { props: { XRequestStatsHeader: clientCorrelationId } });
229
- throw fluidError;
230
- });
231
- }
232
-
233
- /**
234
- * Api to fetch the response as it is for given request.
235
- * @param url - url of the request
236
- * @param fetchOptions - fetch options for request containing body, headers etc.
237
- * @param fetchType - method for which fetch is called.
238
- * @param addInBody - Pass True if caller wants to add epoch in post body.
239
- * @param fetchReason - fetch reason to add to the request.
240
- */
241
- public async fetchArray(
242
- url: string,
243
- fetchOptions: { [index: string]: any; },
244
- fetchType: FetchType,
245
- addInBody: boolean = false,
246
- fetchReason?: string,
247
- ) {
248
- return this.fetchCore<ArrayBuffer>(url, fetchOptions, fetchArray, fetchType, addInBody, fetchReason);
249
- }
250
-
251
- private addEpochInRequest(
252
- fetchOptions: RequestInit,
253
- addInBody: boolean,
254
- clientCorrelationId: string,
255
- ) {
256
- const isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;
257
- if (addInBody) {
258
- const headers: { [key: string]: string; } = {};
259
- headers["X-RequestStats"] = clientCorrelationId;
260
- if (this.fluidEpoch !== undefined) {
261
- headers["x-fluid-epoch"] = this.fluidEpoch;
262
- }
263
- if (isClpCompliantApp) {
264
- headers[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();
265
- }
266
- this.addParamInBody(fetchOptions, headers);
267
- } else {
268
- const addHeader = (key: string, val: string) => {
269
- fetchOptions.headers = {
270
- ...fetchOptions.headers,
271
- };
272
- assert(fetchOptions.headers !== undefined, 0x282 /* "Headers should be present now" */);
273
- fetchOptions.headers[key] = val;
274
- };
275
- addHeader("X-RequestStats", clientCorrelationId);
276
- if (this.fluidEpoch !== undefined) {
277
- addHeader("x-fluid-epoch", this.fluidEpoch);
278
- }
279
- if (isClpCompliantApp) {
280
- addHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());
281
- }
282
- }
283
- }
284
-
285
- private addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string; }) {
286
- // We use multi part form request for post body where we want to use this.
287
- // So extract the form boundary to mark the end of form.
288
- const body = fetchOptions.body;
289
- assert(typeof body === "string", 0x21d /* "body is not string" */);
290
- const splitBody = body.split("\r\n");
291
- const firstLine = splitBody.shift();
292
- assert(firstLine?.startsWith("--") === true, 0x21e /* "improper boundary format" */);
293
- const formParams = [firstLine];
294
- Object.entries(headers).forEach(([key, value]) => {
295
- formParams.push(`${key}: ${value}`);
296
- });
297
- splitBody.forEach((value: string) => {
298
- formParams.push(value);
299
- });
300
- fetchOptions.body = formParams.join("\r\n");
301
- }
302
-
303
- private formatClientCorrelationId(fetchReason?: string) {
304
- const items: string[] = [
305
- `driverId=${this.driverId}`,
306
- `RequestNumber=${this.networkCallNumber++}`,
307
- `driverVersion=${driverVersion}`,
308
- `isSummarizer=${this.clientIsSummarizer}`,
309
- ];
310
- if (fetchReason !== undefined) {
311
- items.push(`fetchReason=${fetchReason}`);
312
- }
313
- return items.join(", ");
314
- }
315
-
316
- protected validateEpochFromResponse(
317
- epochFromResponse: string | undefined,
318
- fetchType: FetchTypeInternal,
319
- fromCache: boolean = false,
320
- ) {
321
- const error = this.checkForEpochErrorCore(epochFromResponse);
322
- if (error !== undefined) {
323
- throw error;
324
- }
325
- if (epochFromResponse !== undefined) {
326
- if (this._fluidEpoch === undefined) {
327
- this.setEpoch(epochFromResponse, fromCache, fetchType);
328
- }
329
- }
330
- }
331
-
332
- private async checkForEpochError(
333
- error: unknown,
334
- epochFromResponse: string | null | undefined,
335
- fetchType: FetchTypeInternal,
336
- fromCache: boolean = false,
337
- ) {
338
- if (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {
339
- const epochError = this.checkForEpochErrorCore(epochFromResponse);
340
- if (epochError !== undefined) {
341
- epochError.addTelemetryProperties({
342
- fromCache,
343
- clientEpoch: this.fluidEpoch,
344
- fetchType,
345
- });
346
- this.logger.sendErrorEvent({ eventName: "fileOverwrittenInStorage" }, epochError);
347
- // If the epoch mismatches, then clear all entries for such file entry from cache.
348
- await this.removeEntries();
349
- throw epochError;
350
- }
351
- // If it was categorized as epoch error but the epoch returned in response matches with the client epoch
352
- // then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling
353
- // time is 1s.
354
- throw new ThrottlingError(
355
- `Coherency 409: ${error.message}`,
356
- 1 /* retryAfterSeconds */,
357
- { [Odsp409Error]: true, driverVersion });
358
- }
359
- }
360
-
361
- private checkForEpochErrorCore(epochFromResponse: string | null | undefined) {
362
- // If epoch is undefined, then don't compare it because initially for createNew or TreesLatest
363
- // initializes this value. Sometimes response does not contain epoch as it is still in
364
- // implementation phase at server side. In that case also, don't compare it with our epoch value.
365
- if (this.fluidEpoch && epochFromResponse && (this.fluidEpoch !== epochFromResponse)) {
366
- // This is similar in nature to how fluidEpochMismatchError (409) is handled.
367
- // Difference - client detected mismatch, instead of server detecting it.
368
- return new NonRetryableError(
369
- "Epoch mismatch", DriverErrorType.fileOverwrittenInStorage, { driverVersion });
370
- }
371
- }
372
-
373
- private fileEntryFromEntry(entry: IEntry): ICacheEntry {
374
- return { ...entry, file: this.fileEntry };
375
- }
89
+ private _fluidEpoch: string | undefined;
90
+
91
+ private readonly snapshotCacheExpiryTimeoutMs: number;
92
+ public readonly rateLimiter: RateLimiter;
93
+ private readonly driverId = uuid();
94
+ // This tracks the request number made by the driver instance.
95
+ private networkCallNumber = 1;
96
+ constructor(
97
+ protected readonly cache: IPersistedCache,
98
+ protected readonly fileEntry: IFileEntry,
99
+ protected readonly logger: ITelemetryLoggerExt,
100
+ protected readonly clientIsSummarizer?: boolean,
101
+ ) {
102
+ // Limits the max number of concurrent requests to 24.
103
+ this.rateLimiter = new RateLimiter(24);
104
+
105
+ // Matches the TestOverride logic for the policy defined in odspDocumentStorageServiceBase.ts
106
+ this.snapshotCacheExpiryTimeoutMs = loggerToMonitoringContext(logger).config.getBoolean(
107
+ "Fluid.Driver.Odsp.TestOverride.DisableSnapshotCache",
108
+ )
109
+ ? 0
110
+ : defaultCacheExpiryTimeoutMs;
111
+ }
112
+
113
+ // public for UT purposes only!
114
+ public setEpoch(epoch: string, fromCache: boolean, fetchType: FetchTypeInternal) {
115
+ assert(this._fluidEpoch === undefined, 0x1db /* "epoch exists" */);
116
+ this._fluidEpoch = epoch;
117
+
118
+ this.logger.sendTelemetryEvent({
119
+ eventName: "EpochLearnedFirstTime",
120
+ epoch,
121
+ fetchType,
122
+ fromCache,
123
+ });
124
+ }
125
+
126
+ public async get(entry: IEntry): Promise<any> {
127
+ try {
128
+ // Return undefined so that the ops/snapshots are grabbed from the server instead of the cache
129
+ const value: IVersionedValueWithEpoch = await this.cache.get(
130
+ this.fileEntryFromEntry(entry),
131
+ );
132
+ // Version mismatch between what the runtime expects and what it recieved.
133
+ // The cached value should not be used
134
+ if (value === undefined || value.version !== persistedCacheValueVersion) {
135
+ return undefined;
136
+ }
137
+ assert(value.fluidEpoch !== undefined, 0x1dc /* "all entries have to have epoch" */);
138
+ if (this._fluidEpoch === undefined) {
139
+ this.setEpoch(value.fluidEpoch, true, "cache");
140
+ // Epoch mismatch, the cached value is considerably different from what the current state of
141
+ // the runtime and should not be used
142
+ } else if (this._fluidEpoch !== value.fluidEpoch) {
143
+ return undefined;
144
+ }
145
+ // Expire the cached snapshot if it's older than snapshotCacheExpiryTimeoutMs and immediately
146
+ // expire all old caches that do not have cacheEntryTime
147
+ if (entry.type === snapshotKey) {
148
+ const cacheTime = value.value?.cacheEntryTime;
149
+ const currentTime = Date.now();
150
+ if (
151
+ cacheTime === undefined ||
152
+ currentTime - cacheTime >= this.snapshotCacheExpiryTimeoutMs
153
+ ) {
154
+ this.logger.sendTelemetryEvent({
155
+ eventName: "odspVersionsCacheExpired",
156
+ duration: currentTime - cacheTime,
157
+ maxCacheAgeMs: this.snapshotCacheExpiryTimeoutMs,
158
+ });
159
+ await this.removeEntries();
160
+ return undefined;
161
+ }
162
+ }
163
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
164
+ return value.value;
165
+ } catch (error) {
166
+ this.logger.sendErrorEvent({ eventName: "cacheFetchError", type: entry.type }, error);
167
+ return undefined;
168
+ }
169
+ }
170
+
171
+ public async put(entry: IEntry, value: any) {
172
+ assert(this._fluidEpoch !== undefined, 0x1dd /* "no epoch" */);
173
+ // For snapshots, the value should have the cacheEntryTime.
174
+ // This will be used to expire snapshots older than snapshotCacheExpiryTimeoutMs.
175
+ if (entry.type === snapshotKey) {
176
+ value.cacheEntryTime = value.cacheEntryTime ?? Date.now();
177
+ }
178
+ const data: IVersionedValueWithEpoch = {
179
+ value,
180
+ version: persistedCacheValueVersion,
181
+ fluidEpoch: this._fluidEpoch,
182
+ };
183
+ return this.cache.put(this.fileEntryFromEntry(entry), data).catch((error) => {
184
+ this.logger.sendErrorEvent({ eventName: "cachePutError", type: entry.type }, error);
185
+ throw error;
186
+ });
187
+ }
188
+
189
+ public async removeEntries(): Promise<void> {
190
+ try {
191
+ return await this.cache.removeEntries(this.fileEntry);
192
+ } catch (error) {
193
+ this.logger.sendErrorEvent({ eventName: "removeCacheEntries" }, error);
194
+ }
195
+ }
196
+
197
+ public get fluidEpoch() {
198
+ return this._fluidEpoch;
199
+ }
200
+
201
+ public async validateEpoch(epoch: string | undefined, fetchType: FetchType) {
202
+ assert(epoch !== undefined, 0x584 /* response should contain epoch */);
203
+ try {
204
+ this.validateEpochFromResponse(epoch, fetchType);
205
+ } catch (error) {
206
+ await this.checkForEpochError(error, epoch, fetchType);
207
+ throw error;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Api to fetch the response for given request and parse it as json.
213
+ * @param url - url of the request
214
+ * @param fetchOptions - fetch options for request containing body, headers etc.
215
+ * @param fetchType - method for which fetch is called.
216
+ * @param addInBody - Pass True if caller wants to add epoch in post body.
217
+ * @param fetchReason - fetch reason to add to the request.
218
+ */
219
+ public async fetchAndParseAsJSON<T>(
220
+ url: string,
221
+ fetchOptions: RequestInit,
222
+ fetchType: FetchType,
223
+ addInBody: boolean = false,
224
+ fetchReason?: string,
225
+ ): Promise<IOdspResponse<T>> {
226
+ return this.fetchCore<T>(
227
+ url,
228
+ fetchOptions,
229
+ fetchAndParseAsJSONHelper,
230
+ fetchType,
231
+ addInBody,
232
+ fetchReason,
233
+ );
234
+ }
235
+
236
+ /**
237
+ * Api to fetch the response for given request and parse it as json.
238
+ * @param url - url of the request
239
+ * @param fetchOptions - fetch options for request containing body, headers etc.
240
+ * @param fetchType - method for which fetch is called.
241
+ * @param addInBody - Pass True if caller wants to add epoch in post body.
242
+ * @param fetchReason - fetch reason to add to the request.
243
+ */
244
+ public async fetch(
245
+ url: string,
246
+ fetchOptions: RequestInit,
247
+ fetchType: FetchType,
248
+ addInBody: boolean = false,
249
+ fetchReason?: string,
250
+ ) {
251
+ return this.fetchCore<Response>(
252
+ url,
253
+ fetchOptions,
254
+ fetchHelper,
255
+ fetchType,
256
+ addInBody,
257
+ fetchReason,
258
+ );
259
+ }
260
+
261
+ private async fetchCore<T>(
262
+ url: string,
263
+ fetchOptions: { [index: string]: any },
264
+ fetcher: (url: string, fetchOptions: { [index: string]: any }) => Promise<IOdspResponse<T>>,
265
+ fetchType: FetchType,
266
+ addInBody: boolean = false,
267
+ fetchReason?: string,
268
+ ) {
269
+ const clientCorrelationId = this.formatClientCorrelationId(fetchReason);
270
+ // Add epoch in fetch request.
271
+ this.addEpochInRequest(fetchOptions, addInBody, clientCorrelationId);
272
+ let epochFromResponse: string | undefined;
273
+ return this.rateLimiter
274
+ .schedule(async () => fetcher(url, fetchOptions))
275
+ .then((response) => {
276
+ epochFromResponse = response.headers.get("x-fluid-epoch");
277
+ this.validateEpochFromResponse(epochFromResponse, fetchType);
278
+ response.propsToLog.XRequestStatsHeader = clientCorrelationId;
279
+ return response;
280
+ })
281
+ .catch(async (error) => {
282
+ // Get the server epoch from error in case we don't have it as if undefined we won't be able
283
+ // to mark it as epoch error.
284
+ if (epochFromResponse === undefined) {
285
+ epochFromResponse = (error as IOdspError).serverEpoch;
286
+ }
287
+ await this.checkForEpochError(error, epochFromResponse, fetchType);
288
+ throw error;
289
+ })
290
+ .catch((error) => {
291
+ // If the error is about location redirection, then we need to generate new resolved url with correct
292
+ // location info.
293
+ if (
294
+ isFluidError(error) &&
295
+ error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError
296
+ ) {
297
+ const redirectLocation = (error as IOdspErrorAugmentations).redirectLocation;
298
+ if (redirectLocation !== undefined) {
299
+ const redirectUrl: IOdspResolvedUrl = patchOdspResolvedUrl(
300
+ this.fileEntry.resolvedUrl,
301
+ redirectLocation,
302
+ );
303
+ const locationRedirectionError = new LocationRedirectionError(
304
+ error.message,
305
+ redirectUrl,
306
+ { driverVersion, redirectLocation },
307
+ );
308
+ locationRedirectionError.addTelemetryProperties(
309
+ error.getTelemetryProperties(),
310
+ );
311
+ throw locationRedirectionError;
312
+ }
313
+ }
314
+ throw error;
315
+ })
316
+ .catch((error) => {
317
+ const fluidError = normalizeError(error, {
318
+ props: { XRequestStatsHeader: clientCorrelationId },
319
+ });
320
+ throw fluidError;
321
+ });
322
+ }
323
+
324
+ /**
325
+ * Api to fetch the response as it is for given request.
326
+ * @param url - url of the request
327
+ * @param fetchOptions - fetch options for request containing body, headers etc.
328
+ * @param fetchType - method for which fetch is called.
329
+ * @param addInBody - Pass True if caller wants to add epoch in post body.
330
+ * @param fetchReason - fetch reason to add to the request.
331
+ */
332
+ public async fetchArray(
333
+ url: string,
334
+ fetchOptions: { [index: string]: any },
335
+ fetchType: FetchType,
336
+ addInBody: boolean = false,
337
+ fetchReason?: string,
338
+ ) {
339
+ return this.fetchCore<ArrayBuffer>(
340
+ url,
341
+ fetchOptions,
342
+ fetchArray,
343
+ fetchType,
344
+ addInBody,
345
+ fetchReason,
346
+ );
347
+ }
348
+
349
+ private addEpochInRequest(
350
+ fetchOptions: RequestInit,
351
+ addInBody: boolean,
352
+ clientCorrelationId: string,
353
+ ) {
354
+ const isClpCompliantApp = getOdspResolvedUrl(this.fileEntry.resolvedUrl).isClpCompliantApp;
355
+ if (addInBody) {
356
+ const headers: { [key: string]: string } = {};
357
+ headers["X-RequestStats"] = clientCorrelationId;
358
+ if (this.fluidEpoch !== undefined) {
359
+ headers["x-fluid-epoch"] = this.fluidEpoch;
360
+ }
361
+ if (isClpCompliantApp) {
362
+ headers[ClpCompliantAppHeader.isClpCompliantApp] = isClpCompliantApp.toString();
363
+ }
364
+ this.addParamInBody(fetchOptions, headers);
365
+ } else {
366
+ const addHeader = (key: string, val: string) => {
367
+ fetchOptions.headers = {
368
+ ...fetchOptions.headers,
369
+ };
370
+ assert(
371
+ fetchOptions.headers !== undefined,
372
+ 0x282 /* "Headers should be present now" */,
373
+ );
374
+ fetchOptions.headers[key] = val;
375
+ };
376
+ addHeader("X-RequestStats", clientCorrelationId);
377
+ if (this.fluidEpoch !== undefined) {
378
+ addHeader("x-fluid-epoch", this.fluidEpoch);
379
+ }
380
+ if (isClpCompliantApp) {
381
+ addHeader(ClpCompliantAppHeader.isClpCompliantApp, isClpCompliantApp.toString());
382
+ }
383
+ }
384
+ }
385
+
386
+ private addParamInBody(fetchOptions: RequestInit, headers: { [key: string]: string }) {
387
+ // We use multi part form request for post body where we want to use this.
388
+ // So extract the form boundary to mark the end of form.
389
+ const body = fetchOptions.body;
390
+ assert(typeof body === "string", 0x21d /* "body is not string" */);
391
+ const splitBody = body.split("\r\n");
392
+ const firstLine = splitBody.shift();
393
+ assert(firstLine?.startsWith("--") === true, 0x21e /* "improper boundary format" */);
394
+ const formParams = [firstLine];
395
+ Object.entries(headers).forEach(([key, value]) => {
396
+ formParams.push(`${key}: ${value}`);
397
+ });
398
+ splitBody.forEach((value: string) => {
399
+ formParams.push(value);
400
+ });
401
+ fetchOptions.body = formParams.join("\r\n");
402
+ }
403
+
404
+ private formatClientCorrelationId(fetchReason?: string) {
405
+ const items: string[] = [
406
+ `driverId=${this.driverId}`,
407
+ `RequestNumber=${this.networkCallNumber++}`,
408
+ `driverVersion=${driverVersion}`,
409
+ `isSummarizer=${this.clientIsSummarizer}`,
410
+ ];
411
+ if (fetchReason !== undefined) {
412
+ items.push(`fetchReason=${fetchReason}`);
413
+ }
414
+ return items.join(", ");
415
+ }
416
+
417
+ protected validateEpochFromResponse(
418
+ epochFromResponse: string | undefined,
419
+ fetchType: FetchTypeInternal,
420
+ fromCache: boolean = false,
421
+ ) {
422
+ const error = this.checkForEpochErrorCore(epochFromResponse);
423
+ if (error !== undefined) {
424
+ throw error;
425
+ }
426
+ if (epochFromResponse !== undefined) {
427
+ if (this._fluidEpoch === undefined) {
428
+ this.setEpoch(epochFromResponse, fromCache, fetchType);
429
+ }
430
+ }
431
+ }
432
+
433
+ private async checkForEpochError(
434
+ error: unknown,
435
+ epochFromResponse: string | null | undefined,
436
+ fetchType: FetchTypeInternal,
437
+ fromCache: boolean = false,
438
+ ) {
439
+ if (isFluidError(error) && error.errorType === DriverErrorType.fileOverwrittenInStorage) {
440
+ const epochError = this.checkForEpochErrorCore(epochFromResponse);
441
+ if (epochError !== undefined) {
442
+ epochError.addTelemetryProperties({
443
+ fromCache,
444
+ fetchType,
445
+ });
446
+ this.logger.sendErrorEvent({ eventName: "fileOverwrittenInStorage" }, epochError);
447
+ // If the epoch mismatches, then clear all entries for such file entry from cache.
448
+ await this.removeEntries();
449
+ throw epochError;
450
+ }
451
+ // If it was categorized as epoch error but the epoch returned in response matches with the client epoch
452
+ // then it was coherency 409, so rethrow it as throttling error so that it can retried. Default throttling
453
+ // time is 1s.
454
+ const newError = wrapError(error, (message: string) => {
455
+ return new ThrottlingError(`Coherency 409: ${message}`, 1 /* retryAfterSeconds */, {
456
+ [Odsp409Error]: true,
457
+ driverVersion,
458
+ });
459
+ });
460
+ throw newError;
461
+ }
462
+ }
463
+
464
+ private checkForEpochErrorCore(epochFromResponse: string | null | undefined) {
465
+ // If epoch is undefined, then don't compare it because initially for createNew or TreesLatest
466
+ // initializes this value. Sometimes response does not contain epoch as it is still in
467
+ // implementation phase at server side. In that case also, don't compare it with our epoch value.
468
+ if (this.fluidEpoch && epochFromResponse && this.fluidEpoch !== epochFromResponse) {
469
+ // This is similar in nature to how fluidEpochMismatchError (409) is handled.
470
+ // Difference - client detected mismatch, instead of server detecting it.
471
+ return new NonRetryableError(
472
+ "Epoch mismatch",
473
+ DriverErrorType.fileOverwrittenInStorage,
474
+ { driverVersion, serverEpoch: epochFromResponse, clientEpoch: this.fluidEpoch },
475
+ );
476
+ }
477
+ }
478
+
479
+ private fileEntryFromEntry(entry: IEntry): ICacheEntry {
480
+ return { ...entry, file: this.fileEntry };
481
+ }
376
482
  }
377
483
 
378
484
  export class EpochTrackerWithRedemption extends EpochTracker {
379
- private readonly treesLatestDeferral = new Deferred<void>();
380
-
381
- protected validateEpochFromResponse(
382
- epochFromResponse: string | undefined,
383
- fetchType: FetchType,
384
- fromCache: boolean = false,
385
- ) {
386
- super.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);
387
-
388
- // Any successful call means we have access to a file, i.e. any redemption that was required already happened.
389
- // That covers cases of "treesLatest" as well as "getVersions" or "createFile" - all the ways we can start
390
- // exploring a file.
391
- this.treesLatestDeferral.resolve();
392
- }
393
-
394
- public async get(
395
- entry: IEntry,
396
- ): Promise<any> {
397
- let result = super.get(entry);
398
-
399
- // equivalence of what happens in fetchAndParseAsJSON()
400
- if (entry.type === snapshotKey) {
401
- result = result
402
- .then((value) => {
403
- // If there is nothing in cache, we need to wait for network call to complete (and do redemption)
404
- // Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry
405
- if (value !== undefined) {
406
- this.treesLatestDeferral.resolve();
407
- }
408
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
409
- return value;
410
- })
411
- .catch((error) => {
412
- this.treesLatestDeferral.reject(error);
413
- throw error;
414
- });
415
- }
416
- return result;
417
- }
418
-
419
- public async fetchAndParseAsJSON<T>(
420
- url: string,
421
- fetchOptions: { [index: string]: any; },
422
- fetchType: FetchType,
423
- addInBody: boolean = false,
424
- fetchReason?: string,
425
- ): Promise<IOdspResponse<T>> {
426
- // Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started
427
- // joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.
428
- const completed = this.treesLatestDeferral.isCompleted;
429
-
430
- try {
431
- return await super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody, fetchReason);
432
- } catch (error: any) {
433
- // Only handling here treesLatest. If createFile failed, we should never try to do joinSession.
434
- // Similar, if getVersions failed, we should not do any further storage calls.
435
- // So treesLatest is the only call that can have parallel joinSession request.
436
- if (fetchType === "treesLatest") {
437
- this.treesLatestDeferral.reject(error);
438
- }
439
- if (fetchType !== "joinSession" || error.statusCode < 401 || error.statusCode > 404 || completed) {
440
- throw error;
441
- }
442
- }
443
-
444
- // It is joinSession failing with 401..404 error
445
- // Repeat after waiting for treeLatest succeeding (or fail if it failed).
446
- // No special handling after first call - if file has been deleted, then it's game over.
447
-
448
- // Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.
449
- // If we waited too long, we will log error event and proceed with call.
450
- // It may result in failure for user, but refreshing document would address it.
451
- // Thus we use rather long timeout (not to get these failures as much as possible), but not large enough
452
- // to unblock the process.
453
- await PerformanceEvent.timedExecAsync(
454
- this.logger,
455
- { eventName: "JoinSessionSyncWait" },
456
- async (event) => {
457
- const timeoutRes = 51; // anything will work here
458
- let timer: ReturnType<typeof setTimeout>;
459
- const timeoutP = new Promise<number>((resolve) => {
460
- timer = setTimeout(() => { resolve(timeoutRes); }, 15000);
461
- });
462
- const res = await Promise.race([
463
- timeoutP,
464
- // cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)
465
- this.treesLatestDeferral.promise.finally(() => clearTimeout(timer))]);
466
- if (res === timeoutRes) {
467
- event.cancel();
468
- }
469
- },
470
- { start: true, end: true, cancel: "generic" });
471
- return super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);
472
- }
485
+ private readonly treesLatestDeferral = new Deferred<void>();
486
+
487
+ constructor(
488
+ protected readonly cache: IPersistedCache,
489
+ protected readonly fileEntry: IFileEntry,
490
+ protected readonly logger: ITelemetryLoggerExt,
491
+ protected readonly clientIsSummarizer?: boolean,
492
+ ) {
493
+ super(cache, fileEntry, logger, clientIsSummarizer);
494
+ // Handles the rejected promise within treesLatestDeferral.
495
+ this.treesLatestDeferral.promise.catch(() => {});
496
+ }
497
+
498
+ protected validateEpochFromResponse(
499
+ epochFromResponse: string | undefined,
500
+ fetchType: FetchType,
501
+ fromCache: boolean = false,
502
+ ) {
503
+ super.validateEpochFromResponse(epochFromResponse, fetchType, fromCache);
504
+
505
+ // Any successful call means we have access to a file, i.e. any redemption that was required already happened.
506
+ // That covers cases of "treesLatest" as well as "getVersions" or "createFile" - all the ways we can start
507
+ // exploring a file.
508
+ this.treesLatestDeferral.resolve();
509
+ }
510
+
511
+ public async get(entry: IEntry): Promise<any> {
512
+ let result = super.get(entry);
513
+
514
+ // equivalence of what happens in fetchAndParseAsJSON()
515
+ if (entry.type === snapshotKey) {
516
+ result = result
517
+ .then((value) => {
518
+ // If there is nothing in cache, we need to wait for network call to complete (and do redemption)
519
+ // Otherwise file was redeemed in prior session, so if joinSession failed, we should not retry
520
+ if (value !== undefined) {
521
+ this.treesLatestDeferral.resolve();
522
+ }
523
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
524
+ return value;
525
+ })
526
+ .catch((error) => {
527
+ this.treesLatestDeferral.reject(error);
528
+ throw error;
529
+ });
530
+ }
531
+ return result;
532
+ }
533
+
534
+ public async fetchAndParseAsJSON<T>(
535
+ url: string,
536
+ fetchOptions: { [index: string]: any },
537
+ fetchType: FetchType,
538
+ addInBody: boolean = false,
539
+ fetchReason?: string,
540
+ ): Promise<IOdspResponse<T>> {
541
+ // Optimize the flow if we know that treesLatestDeferral was already completed by the timer we started
542
+ // joinSession call. If we did - there is no reason to repeat the call as it will fail with same error.
543
+ const completed = this.treesLatestDeferral.isCompleted;
544
+
545
+ try {
546
+ return await super.fetchAndParseAsJSON<T>(
547
+ url,
548
+ fetchOptions,
549
+ fetchType,
550
+ addInBody,
551
+ fetchReason,
552
+ );
553
+ } catch (error: any) {
554
+ // Only handling here treesLatest. If createFile failed, we should never try to do joinSession.
555
+ // Similar, if getVersions failed, we should not do any further storage calls.
556
+ // So treesLatest is the only call that can have parallel joinSession request.
557
+ if (fetchType === "treesLatest") {
558
+ this.treesLatestDeferral.reject(error);
559
+ }
560
+ if (
561
+ fetchType !== "joinSession" ||
562
+ error.statusCode < 401 ||
563
+ error.statusCode > 404 ||
564
+ completed
565
+ ) {
566
+ throw error;
567
+ }
568
+ }
569
+
570
+ // It is joinSession failing with 401..404 error
571
+ // Repeat after waiting for treeLatest succeeding (or fail if it failed).
572
+ // No special handling after first call - if file has been deleted, then it's game over.
573
+
574
+ // Ensure we have some safety here - we do not want to deadlock if we got logic somewhere wrong.
575
+ // If we waited too long, we will log error event and proceed with call.
576
+ // It may result in failure for user, but refreshing document would address it.
577
+ // Thus we use rather long timeout (not to get these failures as much as possible), but not large enough
578
+ // to unblock the process.
579
+ await PerformanceEvent.timedExecAsync(
580
+ this.logger,
581
+ { eventName: "JoinSessionSyncWait" },
582
+ async (event) => {
583
+ const timeoutRes = 51; // anything will work here
584
+ let timer: ReturnType<typeof setTimeout>;
585
+ const timeoutP = new Promise<number>((resolve) => {
586
+ timer = setTimeout(() => {
587
+ resolve(timeoutRes);
588
+ }, 15000);
589
+ });
590
+ const res = await Promise.race([
591
+ timeoutP,
592
+ // cancel timeout to unblock UTs (otherwise Node process does not exit for 15 sec)
593
+ this.treesLatestDeferral.promise.finally(() => clearTimeout(timer)),
594
+ ]);
595
+ if (res === timeoutRes) {
596
+ event.cancel();
597
+ }
598
+ },
599
+ { start: true, end: true, cancel: "generic" },
600
+ );
601
+ return super.fetchAndParseAsJSON<T>(url, fetchOptions, fetchType, addInBody);
602
+ }
473
603
  }
474
604
 
605
+ /**
606
+ * @alpha
607
+ */
475
608
  export interface ICacheAndTracker {
476
- cache: IOdspCache;
477
- epochTracker: EpochTracker;
609
+ cache: IOdspCache;
610
+ epochTracker: EpochTracker;
478
611
  }
479
612
 
480
613
  export function createOdspCacheAndTracker(
481
- persistedCacheArg: IPersistedCache,
482
- nonpersistentCache: INonPersistentCache,
483
- fileEntry: IFileEntry,
484
- logger: ITelemetryLogger,
485
- clientIsSummarizer?: boolean): ICacheAndTracker {
486
- const epochTracker = new EpochTrackerWithRedemption(persistedCacheArg, fileEntry, logger, clientIsSummarizer);
487
- return {
488
- cache: {
489
- ...nonpersistentCache,
490
- persistedCache: epochTracker,
491
- },
492
- epochTracker,
493
- };
614
+ persistedCacheArg: IPersistedCache,
615
+ nonpersistentCache: INonPersistentCache,
616
+ fileEntry: IFileEntry,
617
+ logger: ITelemetryLoggerExt,
618
+ clientIsSummarizer?: boolean,
619
+ ): ICacheAndTracker {
620
+ const epochTracker = new EpochTrackerWithRedemption(
621
+ persistedCacheArg,
622
+ fileEntry,
623
+ logger,
624
+ clientIsSummarizer,
625
+ );
626
+ return {
627
+ cache: {
628
+ ...nonpersistentCache,
629
+ persistedCache: epochTracker,
630
+ },
631
+ epochTracker,
632
+ };
494
633
  }