@fluidframework/container-runtime 2.0.0-dev.5.3.2.178189 → 2.0.0-dev.6.4.0.191457

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 (526) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/README.md +4 -3
  3. package/dist/batchTracker.d.ts +3 -2
  4. package/dist/batchTracker.d.ts.map +1 -1
  5. package/dist/batchTracker.js +6 -5
  6. package/dist/batchTracker.js.map +1 -1
  7. package/dist/blobManager.d.ts +10 -16
  8. package/dist/blobManager.d.ts.map +1 -1
  9. package/dist/blobManager.js +184 -172
  10. package/dist/blobManager.js.map +1 -1
  11. package/dist/connectionTelemetry.d.ts.map +1 -1
  12. package/dist/connectionTelemetry.js +25 -16
  13. package/dist/connectionTelemetry.js.map +1 -1
  14. package/dist/containerRuntime.d.ts +161 -35
  15. package/dist/containerRuntime.d.ts.map +1 -1
  16. package/dist/containerRuntime.js +697 -449
  17. package/dist/containerRuntime.js.map +1 -1
  18. package/dist/dataStore.d.ts.map +1 -1
  19. package/dist/dataStore.js +15 -7
  20. package/dist/dataStore.js.map +1 -1
  21. package/dist/dataStoreContext.d.ts +3 -2
  22. package/dist/dataStoreContext.d.ts.map +1 -1
  23. package/dist/dataStoreContext.js +83 -87
  24. package/dist/dataStoreContext.js.map +1 -1
  25. package/dist/dataStoreContexts.d.ts +1 -2
  26. package/dist/dataStoreContexts.d.ts.map +1 -1
  27. package/dist/dataStoreContexts.js +8 -9
  28. package/dist/dataStoreContexts.js.map +1 -1
  29. package/dist/dataStoreRegistry.js +2 -2
  30. package/dist/dataStoreRegistry.js.map +1 -1
  31. package/dist/dataStores.d.ts +22 -6
  32. package/dist/dataStores.d.ts.map +1 -1
  33. package/dist/dataStores.js +123 -81
  34. package/dist/dataStores.js.map +1 -1
  35. package/dist/deltaManagerProxyBase.d.ts +35 -0
  36. package/dist/deltaManagerProxyBase.d.ts.map +1 -0
  37. package/dist/deltaManagerProxyBase.js +77 -0
  38. package/dist/deltaManagerProxyBase.js.map +1 -0
  39. package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
  40. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
  41. package/dist/deltaManagerSummarizerProxy.js +4 -2
  42. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  43. package/dist/deltaScheduler.d.ts.map +1 -1
  44. package/dist/deltaScheduler.js +10 -10
  45. package/dist/deltaScheduler.js.map +1 -1
  46. package/dist/error.d.ts +14 -0
  47. package/dist/error.d.ts.map +1 -0
  48. package/dist/error.js +21 -0
  49. package/dist/error.js.map +1 -0
  50. package/dist/gc/garbageCollection.d.ts +10 -9
  51. package/dist/gc/garbageCollection.d.ts.map +1 -1
  52. package/dist/gc/garbageCollection.js +61 -53
  53. package/dist/gc/garbageCollection.js.map +1 -1
  54. package/dist/gc/gcConfigs.d.ts.map +1 -1
  55. package/dist/gc/gcConfigs.js +18 -14
  56. package/dist/gc/gcConfigs.js.map +1 -1
  57. package/dist/gc/gcDefinitions.d.ts +17 -4
  58. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  59. package/dist/gc/gcDefinitions.js +14 -15
  60. package/dist/gc/gcDefinitions.js.map +1 -1
  61. package/dist/gc/gcHelpers.d.ts +0 -8
  62. package/dist/gc/gcHelpers.d.ts.map +1 -1
  63. package/dist/gc/gcHelpers.js +11 -24
  64. package/dist/gc/gcHelpers.js.map +1 -1
  65. package/dist/gc/gcSummaryStateTracker.d.ts +4 -7
  66. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  67. package/dist/gc/gcSummaryStateTracker.js +19 -58
  68. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  69. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  70. package/dist/gc/gcTelemetry.js +45 -35
  71. package/dist/gc/gcTelemetry.js.map +1 -1
  72. package/dist/gc/gcUnreferencedStateTracker.js +4 -4
  73. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  74. package/dist/gc/index.d.ts +2 -2
  75. package/dist/gc/index.d.ts.map +1 -1
  76. package/dist/gc/index.js +3 -5
  77. package/dist/gc/index.js.map +1 -1
  78. package/dist/id-compressor/appendOnlySortedMap.d.ts +8 -30
  79. package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
  80. package/dist/id-compressor/appendOnlySortedMap.js +26 -68
  81. package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
  82. package/dist/id-compressor/finalSpace.d.ts +29 -0
  83. package/dist/id-compressor/finalSpace.d.ts.map +1 -0
  84. package/dist/id-compressor/finalSpace.js +62 -0
  85. package/dist/id-compressor/finalSpace.js.map +1 -0
  86. package/dist/id-compressor/idCompressor.d.ts +25 -250
  87. package/dist/id-compressor/idCompressor.d.ts.map +1 -1
  88. package/dist/id-compressor/idCompressor.js +390 -1153
  89. package/dist/id-compressor/idCompressor.js.map +1 -1
  90. package/dist/id-compressor/identifiers.d.ts +32 -0
  91. package/dist/id-compressor/identifiers.d.ts.map +1 -0
  92. package/dist/id-compressor/identifiers.js +15 -0
  93. package/dist/id-compressor/identifiers.js.map +1 -0
  94. package/dist/id-compressor/index.d.ts +5 -6
  95. package/dist/id-compressor/index.d.ts.map +1 -1
  96. package/dist/id-compressor/index.js +20 -26
  97. package/dist/id-compressor/index.js.map +1 -1
  98. package/dist/id-compressor/persistanceUtilities.d.ts +22 -0
  99. package/dist/id-compressor/persistanceUtilities.d.ts.map +1 -0
  100. package/dist/id-compressor/persistanceUtilities.js +43 -0
  101. package/dist/id-compressor/persistanceUtilities.js.map +1 -0
  102. package/dist/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
  103. package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
  104. package/dist/id-compressor/sessionSpaceNormalizer.js +80 -0
  105. package/dist/id-compressor/sessionSpaceNormalizer.js.map +1 -0
  106. package/dist/id-compressor/sessions.d.ts +115 -0
  107. package/dist/id-compressor/sessions.d.ts.map +1 -0
  108. package/dist/id-compressor/sessions.js +305 -0
  109. package/dist/id-compressor/sessions.js.map +1 -0
  110. package/dist/id-compressor/utilities.d.ts +49 -0
  111. package/dist/id-compressor/utilities.d.ts.map +1 -0
  112. package/dist/id-compressor/utilities.js +166 -0
  113. package/dist/id-compressor/utilities.js.map +1 -0
  114. package/dist/index.d.ts +3 -3
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +6 -4
  117. package/dist/index.js.map +1 -1
  118. package/dist/opLifecycle/batchManager.js +10 -6
  119. package/dist/opLifecycle/batchManager.js.map +1 -1
  120. package/dist/opLifecycle/opCompressor.d.ts +2 -2
  121. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  122. package/dist/opLifecycle/opCompressor.js +12 -7
  123. package/dist/opLifecycle/opCompressor.js.map +1 -1
  124. package/dist/opLifecycle/opDecompressor.d.ts +2 -2
  125. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  126. package/dist/opLifecycle/opDecompressor.js +23 -20
  127. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  128. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  129. package/dist/opLifecycle/opGroupingManager.js +19 -9
  130. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  131. package/dist/opLifecycle/opSplitter.d.ts +2 -2
  132. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  133. package/dist/opLifecycle/opSplitter.js +22 -19
  134. package/dist/opLifecycle/opSplitter.js.map +1 -1
  135. package/dist/opLifecycle/outbox.d.ts +7 -5
  136. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  137. package/dist/opLifecycle/outbox.js +22 -31
  138. package/dist/opLifecycle/outbox.js.map +1 -1
  139. package/dist/opLifecycle/remoteMessageProcessor.d.ts +6 -1
  140. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  141. package/dist/opLifecycle/remoteMessageProcessor.js +19 -7
  142. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  143. package/dist/opProperties.js +1 -2
  144. package/dist/opProperties.js.map +1 -1
  145. package/dist/packageVersion.d.ts +1 -1
  146. package/dist/packageVersion.js +1 -1
  147. package/dist/packageVersion.js.map +1 -1
  148. package/dist/pendingStateManager.d.ts +18 -8
  149. package/dist/pendingStateManager.d.ts.map +1 -1
  150. package/dist/pendingStateManager.js +73 -51
  151. package/dist/pendingStateManager.js.map +1 -1
  152. package/dist/scheduleManager.d.ts.map +1 -1
  153. package/dist/scheduleManager.js +36 -32
  154. package/dist/scheduleManager.js.map +1 -1
  155. package/dist/summary/index.d.ts +3 -3
  156. package/dist/summary/index.d.ts.map +1 -1
  157. package/dist/summary/index.js +2 -1
  158. package/dist/summary/index.js.map +1 -1
  159. package/dist/summary/orderedClientElection.d.ts +3 -3
  160. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  161. package/dist/summary/orderedClientElection.js +26 -27
  162. package/dist/summary/orderedClientElection.js.map +1 -1
  163. package/dist/summary/runWhileConnectedCoordinator.js +3 -3
  164. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  165. package/dist/summary/runningSummarizer.d.ts +31 -10
  166. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  167. package/dist/summary/runningSummarizer.js +271 -139
  168. package/dist/summary/runningSummarizer.js.map +1 -1
  169. package/dist/summary/summarizer.d.ts +8 -7
  170. package/dist/summary/summarizer.d.ts.map +1 -1
  171. package/dist/summary/summarizer.js +79 -78
  172. package/dist/summary/summarizer.js.map +1 -1
  173. package/dist/summary/summarizerClientElection.d.ts +2 -2
  174. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  175. package/dist/summary/summarizerClientElection.js +7 -11
  176. package/dist/summary/summarizerClientElection.js.map +1 -1
  177. package/dist/summary/summarizerHeuristics.js +10 -14
  178. package/dist/summary/summarizerHeuristics.js.map +1 -1
  179. package/dist/summary/summarizerNode/index.d.ts +1 -1
  180. package/dist/summary/summarizerNode/index.d.ts.map +1 -1
  181. package/dist/summary/summarizerNode/index.js.map +1 -1
  182. package/dist/summary/summarizerNode/summarizerNode.d.ts +10 -19
  183. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  184. package/dist/summary/summarizerNode/summarizerNode.js +57 -130
  185. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  186. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +6 -30
  187. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  188. package/dist/summary/summarizerNode/summarizerNodeUtils.js +2 -4
  189. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  190. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +4 -14
  191. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  192. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +15 -101
  193. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  194. package/dist/summary/summarizerTypes.d.ts +38 -25
  195. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  196. package/dist/summary/summarizerTypes.js.map +1 -1
  197. package/dist/summary/summaryCollection.d.ts +2 -3
  198. package/dist/summary/summaryCollection.d.ts.map +1 -1
  199. package/dist/summary/summaryCollection.js +12 -13
  200. package/dist/summary/summaryCollection.js.map +1 -1
  201. package/dist/summary/summaryFormat.d.ts +3 -0
  202. package/dist/summary/summaryFormat.d.ts.map +1 -1
  203. package/dist/summary/summaryFormat.js +6 -4
  204. package/dist/summary/summaryFormat.js.map +1 -1
  205. package/dist/summary/summaryGenerator.d.ts +10 -4
  206. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  207. package/dist/summary/summaryGenerator.js +106 -57
  208. package/dist/summary/summaryGenerator.js.map +1 -1
  209. package/dist/summary/summaryManager.d.ts +8 -8
  210. package/dist/summary/summaryManager.d.ts.map +1 -1
  211. package/dist/summary/summaryManager.js +38 -28
  212. package/dist/summary/summaryManager.js.map +1 -1
  213. package/lib/batchTracker.d.ts +3 -2
  214. package/lib/batchTracker.d.ts.map +1 -1
  215. package/lib/batchTracker.js +5 -4
  216. package/lib/batchTracker.js.map +1 -1
  217. package/lib/blobManager.d.ts +10 -16
  218. package/lib/blobManager.d.ts.map +1 -1
  219. package/lib/blobManager.js +159 -147
  220. package/lib/blobManager.js.map +1 -1
  221. package/lib/connectionTelemetry.d.ts.map +1 -1
  222. package/lib/connectionTelemetry.js +15 -6
  223. package/lib/connectionTelemetry.js.map +1 -1
  224. package/lib/containerRuntime.d.ts +161 -35
  225. package/lib/containerRuntime.d.ts.map +1 -1
  226. package/lib/containerRuntime.js +651 -402
  227. package/lib/containerRuntime.js.map +1 -1
  228. package/lib/dataStore.d.ts.map +1 -1
  229. package/lib/dataStore.js +13 -5
  230. package/lib/dataStore.js.map +1 -1
  231. package/lib/dataStoreContext.d.ts +3 -2
  232. package/lib/dataStoreContext.d.ts.map +1 -1
  233. package/lib/dataStoreContext.js +47 -51
  234. package/lib/dataStoreContext.js.map +1 -1
  235. package/lib/dataStoreContexts.d.ts +1 -2
  236. package/lib/dataStoreContexts.d.ts.map +1 -1
  237. package/lib/dataStoreContexts.js +3 -4
  238. package/lib/dataStoreContexts.js.map +1 -1
  239. package/lib/dataStoreRegistry.js +1 -1
  240. package/lib/dataStoreRegistry.js.map +1 -1
  241. package/lib/dataStores.d.ts +22 -6
  242. package/lib/dataStores.d.ts.map +1 -1
  243. package/lib/dataStores.js +107 -65
  244. package/lib/dataStores.js.map +1 -1
  245. package/lib/deltaManagerProxyBase.d.ts +35 -0
  246. package/lib/deltaManagerProxyBase.d.ts.map +1 -0
  247. package/lib/deltaManagerProxyBase.js +73 -0
  248. package/lib/deltaManagerProxyBase.js.map +1 -0
  249. package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
  250. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
  251. package/lib/deltaManagerSummarizerProxy.js +3 -1
  252. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  253. package/lib/deltaScheduler.d.ts.map +1 -1
  254. package/lib/deltaScheduler.js +7 -7
  255. package/lib/deltaScheduler.js.map +1 -1
  256. package/lib/error.d.ts +14 -0
  257. package/lib/error.d.ts.map +1 -0
  258. package/lib/error.js +17 -0
  259. package/lib/error.js.map +1 -0
  260. package/lib/gc/garbageCollection.d.ts +10 -9
  261. package/lib/gc/garbageCollection.d.ts.map +1 -1
  262. package/lib/gc/garbageCollection.js +61 -53
  263. package/lib/gc/garbageCollection.js.map +1 -1
  264. package/lib/gc/gcConfigs.d.ts.map +1 -1
  265. package/lib/gc/gcConfigs.js +16 -12
  266. package/lib/gc/gcConfigs.js.map +1 -1
  267. package/lib/gc/gcDefinitions.d.ts +17 -4
  268. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  269. package/lib/gc/gcDefinitions.js +13 -14
  270. package/lib/gc/gcDefinitions.js.map +1 -1
  271. package/lib/gc/gcHelpers.d.ts +0 -8
  272. package/lib/gc/gcHelpers.d.ts.map +1 -1
  273. package/lib/gc/gcHelpers.js +5 -17
  274. package/lib/gc/gcHelpers.js.map +1 -1
  275. package/lib/gc/gcSummaryStateTracker.d.ts +4 -7
  276. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  277. package/lib/gc/gcSummaryStateTracker.js +20 -59
  278. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  279. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  280. package/lib/gc/gcTelemetry.js +46 -36
  281. package/lib/gc/gcTelemetry.js.map +1 -1
  282. package/lib/gc/gcUnreferencedStateTracker.js +1 -1
  283. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  284. package/lib/gc/index.d.ts +2 -2
  285. package/lib/gc/index.d.ts.map +1 -1
  286. package/lib/gc/index.js +2 -2
  287. package/lib/gc/index.js.map +1 -1
  288. package/lib/id-compressor/appendOnlySortedMap.d.ts +8 -30
  289. package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
  290. package/lib/id-compressor/appendOnlySortedMap.js +25 -66
  291. package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
  292. package/lib/id-compressor/finalSpace.d.ts +29 -0
  293. package/lib/id-compressor/finalSpace.d.ts.map +1 -0
  294. package/lib/id-compressor/finalSpace.js +58 -0
  295. package/lib/id-compressor/finalSpace.js.map +1 -0
  296. package/lib/id-compressor/idCompressor.d.ts +25 -250
  297. package/lib/id-compressor/idCompressor.d.ts.map +1 -1
  298. package/lib/id-compressor/idCompressor.js +385 -1142
  299. package/lib/id-compressor/idCompressor.js.map +1 -1
  300. package/lib/id-compressor/identifiers.d.ts +32 -0
  301. package/lib/id-compressor/identifiers.d.ts.map +1 -0
  302. package/lib/id-compressor/identifiers.js +11 -0
  303. package/lib/id-compressor/identifiers.js.map +1 -0
  304. package/lib/id-compressor/index.d.ts +5 -6
  305. package/lib/id-compressor/index.d.ts.map +1 -1
  306. package/lib/id-compressor/index.js +5 -6
  307. package/lib/id-compressor/index.js.map +1 -1
  308. package/lib/id-compressor/persistanceUtilities.d.ts +22 -0
  309. package/lib/id-compressor/persistanceUtilities.d.ts.map +1 -0
  310. package/lib/id-compressor/persistanceUtilities.js +34 -0
  311. package/lib/id-compressor/persistanceUtilities.js.map +1 -0
  312. package/lib/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
  313. package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
  314. package/lib/id-compressor/sessionSpaceNormalizer.js +76 -0
  315. package/lib/id-compressor/sessionSpaceNormalizer.js.map +1 -0
  316. package/lib/id-compressor/sessions.d.ts +115 -0
  317. package/lib/id-compressor/sessions.d.ts.map +1 -0
  318. package/lib/id-compressor/sessions.js +290 -0
  319. package/lib/id-compressor/sessions.js.map +1 -0
  320. package/lib/id-compressor/utilities.d.ts +49 -0
  321. package/lib/id-compressor/utilities.d.ts.map +1 -0
  322. package/lib/id-compressor/utilities.js +148 -0
  323. package/lib/id-compressor/utilities.js.map +1 -0
  324. package/lib/index.d.ts +3 -3
  325. package/lib/index.d.ts.map +1 -1
  326. package/lib/index.js +2 -2
  327. package/lib/index.js.map +1 -1
  328. package/lib/opLifecycle/batchManager.js +10 -6
  329. package/lib/opLifecycle/batchManager.js.map +1 -1
  330. package/lib/opLifecycle/opCompressor.d.ts +2 -2
  331. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  332. package/lib/opLifecycle/opCompressor.js +10 -5
  333. package/lib/opLifecycle/opCompressor.js.map +1 -1
  334. package/lib/opLifecycle/opDecompressor.d.ts +2 -2
  335. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  336. package/lib/opLifecycle/opDecompressor.js +15 -12
  337. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  338. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  339. package/lib/opLifecycle/opGroupingManager.js +17 -7
  340. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  341. package/lib/opLifecycle/opSplitter.d.ts +2 -2
  342. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  343. package/lib/opLifecycle/opSplitter.js +13 -10
  344. package/lib/opLifecycle/opSplitter.js.map +1 -1
  345. package/lib/opLifecycle/outbox.d.ts +7 -5
  346. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  347. package/lib/opLifecycle/outbox.js +13 -22
  348. package/lib/opLifecycle/outbox.js.map +1 -1
  349. package/lib/opLifecycle/remoteMessageProcessor.d.ts +6 -1
  350. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  351. package/lib/opLifecycle/remoteMessageProcessor.js +20 -8
  352. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  353. package/lib/opProperties.js +1 -2
  354. package/lib/opProperties.js.map +1 -1
  355. package/lib/packageVersion.d.ts +1 -1
  356. package/lib/packageVersion.js +1 -1
  357. package/lib/packageVersion.js.map +1 -1
  358. package/lib/pendingStateManager.d.ts +18 -8
  359. package/lib/pendingStateManager.d.ts.map +1 -1
  360. package/lib/pendingStateManager.js +62 -40
  361. package/lib/pendingStateManager.js.map +1 -1
  362. package/lib/scheduleManager.d.ts.map +1 -1
  363. package/lib/scheduleManager.js +18 -14
  364. package/lib/scheduleManager.js.map +1 -1
  365. package/lib/summary/index.d.ts +3 -3
  366. package/lib/summary/index.d.ts.map +1 -1
  367. package/lib/summary/index.js +1 -1
  368. package/lib/summary/index.js.map +1 -1
  369. package/lib/summary/orderedClientElection.d.ts +3 -3
  370. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  371. package/lib/summary/orderedClientElection.js +21 -22
  372. package/lib/summary/orderedClientElection.js.map +1 -1
  373. package/lib/summary/runWhileConnectedCoordinator.js +1 -1
  374. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  375. package/lib/summary/runningSummarizer.d.ts +31 -10
  376. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  377. package/lib/summary/runningSummarizer.js +265 -133
  378. package/lib/summary/runningSummarizer.js.map +1 -1
  379. package/lib/summary/summarizer.d.ts +8 -7
  380. package/lib/summary/summarizer.d.ts.map +1 -1
  381. package/lib/summary/summarizer.js +75 -74
  382. package/lib/summary/summarizer.js.map +1 -1
  383. package/lib/summary/summarizerClientElection.d.ts +2 -2
  384. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  385. package/lib/summary/summarizerClientElection.js +6 -10
  386. package/lib/summary/summarizerClientElection.js.map +1 -1
  387. package/lib/summary/summarizerHeuristics.js +9 -13
  388. package/lib/summary/summarizerHeuristics.js.map +1 -1
  389. package/lib/summary/summarizerNode/index.d.ts +1 -1
  390. package/lib/summary/summarizerNode/index.d.ts.map +1 -1
  391. package/lib/summary/summarizerNode/index.js.map +1 -1
  392. package/lib/summary/summarizerNode/summarizerNode.d.ts +10 -19
  393. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  394. package/lib/summary/summarizerNode/summarizerNode.js +42 -115
  395. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  396. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +6 -30
  397. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  398. package/lib/summary/summarizerNode/summarizerNodeUtils.js +2 -4
  399. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  400. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +4 -14
  401. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  402. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +14 -100
  403. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  404. package/lib/summary/summarizerTypes.d.ts +38 -25
  405. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  406. package/lib/summary/summarizerTypes.js.map +1 -1
  407. package/lib/summary/summaryCollection.d.ts +2 -3
  408. package/lib/summary/summaryCollection.d.ts.map +1 -1
  409. package/lib/summary/summaryCollection.js +5 -6
  410. package/lib/summary/summaryCollection.js.map +1 -1
  411. package/lib/summary/summaryFormat.d.ts +3 -0
  412. package/lib/summary/summaryFormat.d.ts.map +1 -1
  413. package/lib/summary/summaryFormat.js +5 -3
  414. package/lib/summary/summaryFormat.js.map +1 -1
  415. package/lib/summary/summaryGenerator.d.ts +10 -4
  416. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  417. package/lib/summary/summaryGenerator.js +100 -51
  418. package/lib/summary/summaryGenerator.js.map +1 -1
  419. package/lib/summary/summaryManager.d.ts +8 -8
  420. package/lib/summary/summaryManager.d.ts.map +1 -1
  421. package/lib/summary/summaryManager.js +35 -25
  422. package/lib/summary/summaryManager.js.map +1 -1
  423. package/package.json +28 -31
  424. package/src/batchTracker.ts +7 -5
  425. package/src/blobManager.ts +188 -166
  426. package/src/connectionTelemetry.ts +9 -4
  427. package/src/containerRuntime.ts +806 -441
  428. package/src/dataStore.ts +12 -4
  429. package/src/dataStoreContext.ts +39 -43
  430. package/src/dataStoreContexts.ts +4 -6
  431. package/src/dataStoreRegistry.ts +1 -1
  432. package/src/dataStores.ts +114 -80
  433. package/src/deltaManagerProxyBase.ts +111 -0
  434. package/src/deltaManagerSummarizerProxy.ts +4 -1
  435. package/src/deltaScheduler.ts +7 -11
  436. package/src/error.ts +18 -0
  437. package/src/gc/garbageCollection.md +53 -5
  438. package/src/gc/garbageCollection.ts +58 -52
  439. package/src/gc/gcConfigs.ts +4 -2
  440. package/src/gc/gcDefinitions.ts +17 -20
  441. package/src/gc/gcEarlyAdoption.md +145 -0
  442. package/src/gc/gcHelpers.ts +1 -12
  443. package/src/gc/gcSummaryStateTracker.ts +19 -65
  444. package/src/gc/gcTelemetry.ts +14 -12
  445. package/src/gc/gcUnreferencedStateTracker.ts +1 -1
  446. package/src/gc/index.ts +2 -4
  447. package/src/id-compressor/appendOnlySortedMap.ts +26 -87
  448. package/src/id-compressor/finalSpace.ts +67 -0
  449. package/src/id-compressor/idCompressor.ts +458 -1682
  450. package/src/id-compressor/identifiers.ts +42 -0
  451. package/src/id-compressor/index.ts +11 -20
  452. package/src/id-compressor/persistanceUtilities.ts +58 -0
  453. package/src/id-compressor/sessionSpaceNormalizer.ts +83 -0
  454. package/src/id-compressor/sessions.ts +405 -0
  455. package/src/id-compressor/utilities.ts +187 -0
  456. package/src/index.ts +7 -2
  457. package/src/opLifecycle/opCompressor.ts +6 -5
  458. package/src/opLifecycle/opDecompressor.ts +6 -4
  459. package/src/opLifecycle/opGroupingManager.ts +9 -6
  460. package/src/opLifecycle/opSplitter.ts +7 -6
  461. package/src/opLifecycle/outbox.ts +23 -32
  462. package/src/opLifecycle/remoteMessageProcessor.ts +27 -8
  463. package/src/packageVersion.ts +1 -1
  464. package/src/pendingStateManager.ts +72 -42
  465. package/src/scheduleManager.ts +7 -5
  466. package/src/summary/index.ts +4 -3
  467. package/src/summary/orderedClientElection.ts +10 -6
  468. package/src/summary/runWhileConnectedCoordinator.ts +1 -1
  469. package/src/summary/runningSummarizer.ts +291 -163
  470. package/src/summary/summarizer.ts +27 -16
  471. package/src/summary/summarizerClientElection.ts +2 -2
  472. package/src/summary/summarizerHeuristics.ts +1 -1
  473. package/src/summary/summarizerNode/index.ts +1 -2
  474. package/src/summary/summarizerNode/summarizerNode.ts +36 -160
  475. package/src/summary/summarizerNode/summarizerNodeUtils.ts +7 -38
  476. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +11 -130
  477. package/src/summary/summarizerTypes.ts +40 -25
  478. package/src/summary/summaryCollection.ts +3 -3
  479. package/src/summary/summaryFormat.ts +4 -1
  480. package/src/summary/summaryGenerator.ts +52 -52
  481. package/src/summary/summaryManager.ts +44 -17
  482. package/dist/id-compressor/idRange.d.ts +0 -11
  483. package/dist/id-compressor/idRange.d.ts.map +0 -1
  484. package/dist/id-compressor/idRange.js +0 -29
  485. package/dist/id-compressor/idRange.js.map +0 -1
  486. package/dist/id-compressor/numericUuid.d.ts +0 -59
  487. package/dist/id-compressor/numericUuid.d.ts.map +0 -1
  488. package/dist/id-compressor/numericUuid.js +0 -325
  489. package/dist/id-compressor/numericUuid.js.map +0 -1
  490. package/dist/id-compressor/sessionIdNormalizer.d.ts +0 -138
  491. package/dist/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
  492. package/dist/id-compressor/sessionIdNormalizer.js +0 -488
  493. package/dist/id-compressor/sessionIdNormalizer.js.map +0 -1
  494. package/dist/id-compressor/utils.d.ts +0 -57
  495. package/dist/id-compressor/utils.d.ts.map +0 -1
  496. package/dist/id-compressor/utils.js +0 -90
  497. package/dist/id-compressor/utils.js.map +0 -1
  498. package/dist/id-compressor/uuidUtilities.d.ts +0 -28
  499. package/dist/id-compressor/uuidUtilities.d.ts.map +0 -1
  500. package/dist/id-compressor/uuidUtilities.js +0 -104
  501. package/dist/id-compressor/uuidUtilities.js.map +0 -1
  502. package/lib/id-compressor/idRange.d.ts +0 -11
  503. package/lib/id-compressor/idRange.d.ts.map +0 -1
  504. package/lib/id-compressor/idRange.js +0 -25
  505. package/lib/id-compressor/idRange.js.map +0 -1
  506. package/lib/id-compressor/numericUuid.d.ts +0 -59
  507. package/lib/id-compressor/numericUuid.d.ts.map +0 -1
  508. package/lib/id-compressor/numericUuid.js +0 -315
  509. package/lib/id-compressor/numericUuid.js.map +0 -1
  510. package/lib/id-compressor/sessionIdNormalizer.d.ts +0 -138
  511. package/lib/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
  512. package/lib/id-compressor/sessionIdNormalizer.js +0 -484
  513. package/lib/id-compressor/sessionIdNormalizer.js.map +0 -1
  514. package/lib/id-compressor/utils.d.ts +0 -57
  515. package/lib/id-compressor/utils.d.ts.map +0 -1
  516. package/lib/id-compressor/utils.js +0 -79
  517. package/lib/id-compressor/utils.js.map +0 -1
  518. package/lib/id-compressor/uuidUtilities.d.ts +0 -28
  519. package/lib/id-compressor/uuidUtilities.d.ts.map +0 -1
  520. package/lib/id-compressor/uuidUtilities.js +0 -96
  521. package/lib/id-compressor/uuidUtilities.js.map +0 -1
  522. package/src/id-compressor/idRange.ts +0 -35
  523. package/src/id-compressor/numericUuid.ts +0 -383
  524. package/src/id-compressor/sessionIdNormalizer.ts +0 -609
  525. package/src/id-compressor/utils.ts +0 -114
  526. package/src/id-compressor/uuidUtilities.ts +0 -120
@@ -4,12 +4,12 @@
4
4
  */
5
5
  import { v4 as uuid } from "uuid";
6
6
  import { createResponseError, generateHandleContextPath, responseToException, SummaryTreeBuilder, } from "@fluidframework/runtime-utils";
7
- import { assert, bufferToString, Deferred, stringToBuffer, TypedEventEmitter, } from "@fluidframework/common-utils";
7
+ import { assert, Deferred } from "@fluidframework/core-utils";
8
+ import { bufferToString, stringToBuffer, TypedEventEmitter } from "@fluid-internal/client-utils";
8
9
  import { AttachState } from "@fluidframework/container-definitions";
9
- import { ChildLogger, loggerToMonitoringContext, PerformanceEvent, } from "@fluidframework/telemetry-utils";
10
- import { GenericError } from "@fluidframework/container-utils";
10
+ import { createChildMonitoringContext, GenericError, LoggingError, PerformanceEvent, } from "@fluidframework/telemetry-utils";
11
11
  import { TombstoneResponseHeaderKey } from "./containerRuntime";
12
- import { sendGCUnexpectedUsageEvent, sweepAttachmentBlobsKey, throwOnTombstoneLoadKey } from "./gc";
12
+ import { sendGCUnexpectedUsageEvent, disableAttachmentBlobSweepKey, throwOnTombstoneLoadKey, } from "./gc";
13
13
  import { Throttler, formExponentialFn } from "./throttler";
14
14
  import { summarizerClientType } from "./summary";
15
15
  /**
@@ -35,10 +35,9 @@ export class BlobHandle {
35
35
  return this.routeContext.isAttached && this.attached;
36
36
  }
37
37
  attachGraph() {
38
- var _a;
39
38
  if (!this.attached) {
40
39
  this.attached = true;
41
- (_a = this.onAttachGraph) === null || _a === void 0 ? void 0 : _a.call(this);
40
+ this.onAttachGraph?.();
42
41
  }
43
42
  }
44
43
  bind(handle) {
@@ -61,15 +60,6 @@ class CancellableThrottler {
61
60
  this.cancelP = new Deferred();
62
61
  }
63
62
  }
64
- // Note that while offline we "submit" an op before uploading the blob, but we always
65
- // expect blobs to be uploaded before we actually see the op round-trip
66
- var PendingBlobStatus;
67
- (function (PendingBlobStatus) {
68
- PendingBlobStatus[PendingBlobStatus["OnlinePendingUpload"] = 0] = "OnlinePendingUpload";
69
- PendingBlobStatus[PendingBlobStatus["OnlinePendingOp"] = 1] = "OnlinePendingOp";
70
- PendingBlobStatus[PendingBlobStatus["OfflinePendingUpload"] = 2] = "OfflinePendingUpload";
71
- PendingBlobStatus[PendingBlobStatus["OfflinePendingOp"] = 3] = "OfflinePendingOp";
72
- })(PendingBlobStatus || (PendingBlobStatus = {}));
73
63
  export class BlobManager extends TypedEventEmitter {
74
64
  constructor(routeContext, snapshot, getStorage,
75
65
  /**
@@ -97,9 +87,7 @@ export class BlobManager extends TypedEventEmitter {
97
87
  this.runtime = runtime;
98
88
  this.closeContainer = closeContainer;
99
89
  /**
100
- * Blobs which have not been uploaded or for which we have not yet seen a BlobAttach op round-trip.
101
- * Until we see the op round-trip, there is a possibility we may need to re-upload the blob, so
102
- * we must save it. This is true for both the online and offline flow.
90
+ * Blobs which we have not yet seen a BlobAttach op round-trip and not yet attached to a DDS.
103
91
  */
104
92
  this.pendingBlobs = new Map();
105
93
  /**
@@ -117,27 +105,32 @@ export class BlobManager extends TypedEventEmitter {
117
105
  * Tombstone is a temporary feature that imitates a blob getting swept by garbage collection.
118
106
  */
119
107
  this.tombstonedBlobs = new Set();
120
- this.mc = loggerToMonitoringContext(ChildLogger.create(this.runtime.logger, "BlobManager"));
108
+ this.mc = createChildMonitoringContext({
109
+ logger: this.runtime.logger,
110
+ namespace: "BlobManager",
111
+ });
121
112
  // Read the feature flag that tells whether to throw when a tombstone blob is requested.
122
113
  this.throwOnTombstoneLoad =
123
114
  this.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&
124
115
  this.runtime.gcTombstoneEnforcementAllowed &&
125
116
  this.runtime.clientDetails.type !== summarizerClientType;
126
- this.runtime.on("disconnected", () => this.onDisconnected());
127
117
  this.redirectTable = this.load(snapshot);
128
118
  // Begin uploading stashed blobs from previous container instance
129
119
  Object.entries(stashedBlobs).forEach(([localId, entry]) => {
130
120
  const blob = stringToBuffer(entry.blob, "base64");
131
121
  const attached = entry.attached;
132
122
  const acked = entry.acked;
123
+ const storageId = entry.storageId; // entry.storageId = response.id
133
124
  if (entry.minTTLInSeconds && entry.uploadTime) {
134
125
  const timeLapseSinceLocalUpload = (Date.now() - entry.uploadTime) / 1000;
135
126
  // stashed entries with more than half-life in storage will not be reuploaded
136
127
  if (entry.minTTLInSeconds - timeLapseSinceLocalUpload > entry.minTTLInSeconds / 2) {
137
128
  this.pendingBlobs.set(localId, {
138
129
  blob,
139
- status: PendingBlobStatus.OfflinePendingOp,
130
+ uploading: false,
131
+ opsent: true,
140
132
  handleP: new Deferred(),
133
+ storageId,
141
134
  uploadP: undefined,
142
135
  uploadTime: entry.uploadTime,
143
136
  minTTLInSeconds: entry.minTTLInSeconds,
@@ -149,21 +142,22 @@ export class BlobManager extends TypedEventEmitter {
149
142
  }
150
143
  this.pendingBlobs.set(localId, {
151
144
  blob,
152
- status: PendingBlobStatus.OfflinePendingUpload,
145
+ uploading: true,
153
146
  handleP: new Deferred(),
154
147
  uploadP: this.uploadBlob(localId, blob),
155
148
  attached,
156
149
  acked,
150
+ opsent: true,
157
151
  });
158
152
  });
159
153
  this.sendBlobAttachOp = (localId, blobId) => {
160
154
  const pendingEntry = this.pendingBlobs.get(localId);
161
- if ((pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.uploadTime) && (pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.minTTLInSeconds)) {
155
+ assert(pendingEntry !== undefined, 0x725 /* Must have pending blob entry for upcoming op */);
156
+ if (pendingEntry?.uploadTime && pendingEntry?.minTTLInSeconds) {
162
157
  const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
163
158
  const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
164
159
  this.mc.logger.sendTelemetryEvent({
165
160
  eventName: "sendBlobAttach",
166
- entryStatus: pendingEntry.status,
167
161
  secondsSinceUpload,
168
162
  minTTLInSeconds: pendingEntry.minTTLInSeconds,
169
163
  expired,
@@ -173,48 +167,45 @@ export class BlobManager extends TypedEventEmitter {
173
167
  this.closeContainer(new GenericError("Trying to submit a BlobAttach for expired blob", undefined, {
174
168
  localId,
175
169
  blobId,
176
- entryStatus: pendingEntry.status,
177
170
  secondsSinceUpload,
178
171
  }));
179
172
  }
180
173
  }
174
+ pendingEntry.opsent = true;
181
175
  return sendBlobAttachOp(localId, blobId);
182
176
  };
183
177
  }
184
- get pendingOfflineUploads() {
185
- return Array.from(this.pendingBlobs.values()).filter((e) => e.status === PendingBlobStatus.OfflinePendingUpload);
186
- }
187
- get hasPendingOfflineUploads() {
188
- return this.pendingOfflineUploads.length > 0;
178
+ get allBlobsAttached() {
179
+ for (const [, entry] of this.pendingBlobs) {
180
+ if (entry.attached === false) {
181
+ return false;
182
+ }
183
+ }
184
+ return true;
189
185
  }
190
186
  get hasPendingBlobs() {
191
187
  return ((this.runtime.attachState !== AttachState.Attached && this.redirectTable.size > 0) ||
192
188
  this.pendingBlobs.size > 0);
193
189
  }
190
+ createAbortError(pending) {
191
+ return new LoggingError("uploadBlob aborted", {
192
+ acked: pending?.acked,
193
+ uploadTime: pending?.uploadTime,
194
+ });
195
+ }
194
196
  /**
195
197
  * Upload blobs added while offline. This must be completed before connecting and resubmitting ops.
196
198
  */
197
- async onConnected() {
199
+ async processStashedChanges() {
198
200
  this.retryThrottler.cancel();
199
- const pendingUploads = this.pendingOfflineUploads.map(async (e) => e.uploadP);
201
+ const pendingUploads = Array.from(this.pendingBlobs.values())
202
+ .filter((e) => e.uploading === true)
203
+ .map(async (e) => e.uploadP);
200
204
  await PerformanceEvent.timedExecAsync(this.mc.logger, {
201
- eventName: "BlobUploadOnConnected",
205
+ eventName: "BlobUploadProcessStashedChanges",
202
206
  count: pendingUploads.length,
203
207
  }, async () => Promise.all(pendingUploads), { start: true, end: true });
204
208
  }
205
- /**
206
- * Transition online blobs waiting for BlobAttach op round-trip since we will not see the op until we are connected
207
- * again
208
- */
209
- onDisconnected() {
210
- for (const [localId, entry] of this.pendingBlobs) {
211
- if (entry.status === PendingBlobStatus.OnlinePendingOp) {
212
- // This will submit another BlobAttach op for this blob. This is necessary because the one we sent
213
- // already didn't have the local ID.
214
- this.transitionToOffline(localId);
215
- }
216
- }
217
- }
218
209
  /**
219
210
  * Set of actual storage IDs (i.e., IDs that can be requested from storage). This will be empty if the container is
220
211
  * detached or there are no (non-pending) attachment blobs in the document
@@ -261,6 +252,7 @@ export class BlobManager extends TypedEventEmitter {
261
252
  const callback = pending
262
253
  ? () => {
263
254
  pending.attached = true;
255
+ this.emit("blobAttached", pending);
264
256
  this.deletePendingBlobMaybe(id);
265
257
  }
266
258
  : undefined;
@@ -273,7 +265,7 @@ export class BlobManager extends TypedEventEmitter {
273
265
  this.setRedirection(response.id, undefined);
274
266
  return this.getBlobHandle(response.id);
275
267
  }
276
- async createBlob(blob) {
268
+ async createBlob(blob, signal) {
277
269
  if (this.runtime.attachState === AttachState.Detached) {
278
270
  return this.createBlobDetached(blob);
279
271
  }
@@ -283,19 +275,32 @@ export class BlobManager extends TypedEventEmitter {
283
275
  await new Promise((resolve) => this.runtime.once("attached", resolve));
284
276
  }
285
277
  assert(this.runtime.attachState === AttachState.Attached, 0x385 /* For clarity and paranoid defense against adding future attachment states */);
278
+ if (signal?.aborted) {
279
+ throw this.createAbortError();
280
+ }
286
281
  // Create a local ID for the blob. After uploading it to storage and before returning it, a local ID to
287
282
  // storage ID mapping is created.
288
283
  const localId = uuid();
289
284
  const pendingEntry = {
290
285
  blob,
291
- status: PendingBlobStatus.OnlinePendingUpload,
286
+ uploading: true,
292
287
  handleP: new Deferred(),
293
288
  uploadP: this.uploadBlob(localId, blob),
294
289
  attached: false,
295
290
  acked: false,
291
+ abortSignal: signal,
292
+ opsent: false,
296
293
  };
297
294
  this.pendingBlobs.set(localId, pendingEntry);
298
- return pendingEntry.handleP.promise;
295
+ const abortListener = () => {
296
+ if (!pendingEntry.acked) {
297
+ pendingEntry.handleP.reject(this.createAbortError(pendingEntry));
298
+ }
299
+ };
300
+ signal?.addEventListener("abort", abortListener, { once: true });
301
+ return pendingEntry.handleP.promise.finally(() => {
302
+ signal?.removeEventListener("abort", abortListener);
303
+ });
299
304
  }
300
305
  async uploadBlob(localId, blob) {
301
306
  return PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "createBlob" }, async () => this.getStorage().createBlob(blob), { end: true, cancel: this.runtime.connected ? "error" : "generic" }).then((response) => this.onUploadResolve(localId, response), async (err) => this.onUploadReject(localId, err));
@@ -310,69 +315,59 @@ export class BlobManager extends TypedEventEmitter {
310
315
  deletePendingBlobMaybe(id) {
311
316
  if (this.pendingBlobs.has(id)) {
312
317
  const entry = this.pendingBlobs.get(id);
313
- if ((entry === null || entry === void 0 ? void 0 : entry.attached) && (entry === null || entry === void 0 ? void 0 : entry.acked)) {
314
- this.pendingBlobs.delete(id);
315
- if (!this.hasPendingBlobs) {
316
- this.emit("noPendingBlobs");
317
- }
318
+ if (entry?.attached && entry?.acked) {
319
+ this.deletePendingBlob(id);
318
320
  }
319
321
  }
320
322
  }
323
+ deletePendingBlob(id) {
324
+ if (this.pendingBlobs.delete(id) && !this.hasPendingBlobs) {
325
+ this.emit("noPendingBlobs");
326
+ }
327
+ }
321
328
  onUploadResolve(localId, response) {
322
- var _a;
323
329
  const entry = this.pendingBlobs.get(localId);
324
330
  assert(entry !== undefined, 0x6c8 /* pending blob entry not found for uploaded blob */);
325
- assert(entry.status === PendingBlobStatus.OnlinePendingUpload ||
326
- entry.status === PendingBlobStatus.OfflinePendingUpload, 0x386 /* Must have pending blob entry for uploaded blob */);
331
+ if (entry.abortSignal?.aborted === true && !entry.opsent) {
332
+ this.deletePendingBlob(localId);
333
+ return;
334
+ }
335
+ assert(entry.uploading === true, 0x386 /* Must have pending blob entry for uploaded blob */);
327
336
  entry.storageId = response.id;
328
337
  entry.uploadTime = Date.now();
329
338
  entry.minTTLInSeconds = response.minTTLInSeconds;
330
- if (this.runtime.connected) {
331
- if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
332
- // Send a blob attach op. This serves two purposes:
333
- // 1. If its a new blob, i.e., it isn't de-duped, the server will keep the blob alive if it sees this op
334
- // until its storage ID is added to the next summary.
335
- // 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
336
- // blob from the server via the storage ID.
337
- this.sendBlobAttachOp(localId, response.id);
338
- if (this.storageIds.has(response.id)) {
339
- // The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
340
- // an existing blob, we don't have to wait for the op to be ack'd since this step has already
341
- // happened before and so, the server won't delete it.
342
- this.setRedirection(localId, response.id);
343
- entry.handleP.resolve(this.getBlobHandle(localId));
344
- this.deletePendingBlobMaybe(localId);
345
- }
346
- else {
347
- // If there is already an op for this storage ID, append the local ID to the list. Once any op for
348
- // this storage ID is ack'd, all pending blobs for it can be resolved since the op will keep the
349
- // blob alive in storage.
350
- this.opsInFlight.set(response.id, ((_a = this.opsInFlight.get(response.id)) !== null && _a !== void 0 ? _a : []).concat(localId));
351
- entry.status = PendingBlobStatus.OnlinePendingOp;
352
- }
353
- }
354
- else if (entry.status === PendingBlobStatus.OfflinePendingUpload) {
355
- // We already submitted a BlobAttach op for this blob when it was transitioned to offline flow
356
- entry.status = PendingBlobStatus.OfflinePendingOp;
357
- }
339
+ // Send a blob attach op. This serves two purposes:
340
+ // 1. If its a new blob, i.e., it isn't de-duped, the server will keep the blob alive if it sees this op
341
+ // until its storage ID is added to the next summary.
342
+ // 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
343
+ // blob from the server via the storage ID.
344
+ if (!entry.opsent) {
345
+ this.sendBlobAttachOp(localId, response.id);
346
+ }
347
+ if (this.storageIds.has(response.id)) {
348
+ // The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
349
+ // an existing blob, we don't have to wait for the op to be ack'd since this step has already
350
+ // happened before and so, the server won't delete it.
351
+ this.setRedirection(localId, response.id);
352
+ entry.handleP.resolve(this.getBlobHandle(localId));
353
+ this.deletePendingBlobMaybe(localId);
358
354
  }
359
355
  else {
360
- // connected to storage but not ordering service?
361
- this.mc.logger.sendTelemetryEvent({ eventName: "BlobUploadSuccessWhileDisconnected" });
362
- if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
363
- this.transitionToOffline(localId);
364
- }
365
- entry.status = PendingBlobStatus.OfflinePendingOp;
356
+ // If there is already an op for this storage ID, append the local ID to the list. Once any op for
357
+ // this storage ID is ack'd, all pending blobs for it can be resolved since the op will keep the
358
+ // blob alive in storage.
359
+ this.opsInFlight.set(response.id, (this.opsInFlight.get(response.id) ?? []).concat(localId));
366
360
  }
367
361
  return response;
368
362
  }
369
363
  async onUploadReject(localId, error) {
370
364
  const entry = this.pendingBlobs.get(localId);
371
365
  assert(!!entry, 0x387 /* Must have pending blob entry for blob which failed to upload */);
366
+ if (entry.abortSignal?.aborted === true && !entry.opsent) {
367
+ this.deletePendingBlob(localId);
368
+ return;
369
+ }
372
370
  if (!this.runtime.connected) {
373
- if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
374
- this.transitionToOffline(localId);
375
- }
376
371
  // we are probably not connected to storage but start another upload request in case we are
377
372
  entry.uploadP = this.retryThrottler
378
373
  .getDelay()
@@ -384,27 +379,6 @@ export class BlobManager extends TypedEventEmitter {
384
379
  throw error;
385
380
  }
386
381
  }
387
- transitionToOffline(localId) {
388
- assert(!this.runtime.connected, 0x388 /* Must only transition to offline flow while runtime is disconnected */);
389
- const entry = this.pendingBlobs.get(localId);
390
- assert(!!entry, 0x389 /* No pending blob entry */);
391
- assert([PendingBlobStatus.OnlinePendingUpload, PendingBlobStatus.OnlinePendingOp].includes(entry.status), 0x38a /* Blob must be in online flow to transition to offline flow */);
392
- /**
393
- * If we haven't already submitted a BlobAttach op for this entry, send it before returning the blob handle.
394
- * This will make sure that the BlobAttach op is sequenced prior to any ops referencing the handle. Otherwise,
395
- * an invalid handle could be added to the document.
396
- * storageId may be undefined but since we are not connected we will have a chance to add it when reSubmit()
397
- * is called on reconnection.
398
- */
399
- if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
400
- this.sendBlobAttachOp(localId, entry.storageId);
401
- }
402
- entry.status =
403
- entry.status === PendingBlobStatus.OnlinePendingUpload
404
- ? PendingBlobStatus.OfflinePendingUpload
405
- : PendingBlobStatus.OfflinePendingOp;
406
- entry.handleP.resolve(this.getBlobHandle(localId));
407
- }
408
382
  /**
409
383
  * Resubmit a BlobAttach op. Used to add storage IDs to ops that were
410
384
  * submitted to runtime while disconnected.
@@ -417,16 +391,21 @@ export class BlobManager extends TypedEventEmitter {
417
391
  const pendingEntry = this.pendingBlobs.get(localId);
418
392
  if (!blobId) {
419
393
  // We submitted this op while offline. The blob should have been uploaded by now.
420
- assert((pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.status) === PendingBlobStatus.OfflinePendingOp &&
421
- !!(pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.storageId), 0x38d /* blob must be uploaded before resubmitting BlobAttach op */);
422
- return this.sendBlobAttachOp(localId, pendingEntry.storageId);
394
+ assert(pendingEntry?.opsent === true && !!pendingEntry?.storageId, 0x38d /* blob must be uploaded before resubmitting BlobAttach op */);
395
+ return this.sendBlobAttachOp(localId, pendingEntry?.storageId);
423
396
  }
424
397
  return this.sendBlobAttachOp(localId, blobId);
425
398
  }
426
399
  processBlobAttachOp(message, local) {
427
- var _a, _b;
428
- const localId = (_a = message.metadata) === null || _a === void 0 ? void 0 : _a.localId;
429
- const blobId = (_b = message.metadata) === null || _b === void 0 ? void 0 : _b.blobId;
400
+ const localId = message.metadata?.localId;
401
+ const blobId = message.metadata?.blobId;
402
+ if (localId) {
403
+ const pendingEntry = this.pendingBlobs.get(localId);
404
+ if (pendingEntry?.abortSignal?.aborted) {
405
+ this.deletePendingBlob(localId);
406
+ return;
407
+ }
408
+ }
430
409
  assert(blobId !== undefined, 0x12a /* "Missing blob id on metadata" */);
431
410
  // Set up a mapping from local ID to storage ID. This is crucial since without this the blob cannot be
432
411
  // requested from the server.
@@ -447,21 +426,17 @@ export class BlobManager extends TypedEventEmitter {
447
426
  waitingBlobs.forEach((pendingLocalId) => {
448
427
  const entry = this.pendingBlobs.get(pendingLocalId);
449
428
  assert(entry !== undefined, 0x38f /* local online BlobAttach op with no pending blob entry */);
450
- // It's possible we transitioned to offline flow while waiting for this op.
451
- if (entry.status === PendingBlobStatus.OnlinePendingOp) {
452
- this.setRedirection(pendingLocalId, blobId);
453
- entry.acked = true;
454
- entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
455
- this.deletePendingBlobMaybe(pendingLocalId);
456
- }
429
+ this.setRedirection(pendingLocalId, blobId);
430
+ entry.acked = true;
431
+ entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
432
+ this.deletePendingBlobMaybe(pendingLocalId);
457
433
  });
458
434
  this.opsInFlight.delete(blobId);
459
435
  }
460
- // offline flow does not resolve the handle (since it was already resolved)
461
- // but we still need to delete the entry in case is acked and attached.
462
436
  const localEntry = this.pendingBlobs.get(localId);
463
437
  if (localEntry) {
464
438
  localEntry.acked = true;
439
+ localEntry.handleP.resolve(this.getBlobHandle(localId));
465
440
  this.deletePendingBlobMaybe(localId);
466
441
  }
467
442
  }
@@ -490,11 +465,10 @@ export class BlobManager extends TypedEventEmitter {
490
465
  * Load a set of previously attached blob IDs and redirect table from a previous snapshot.
491
466
  */
492
467
  load(snapshot) {
493
- var _a, _b, _c;
494
468
  this.mc.logger.sendTelemetryEvent({
495
469
  eventName: "AttachmentBlobsLoaded",
496
- count: (_b = (_a = snapshot.ids) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
497
- redirectTable: (_c = snapshot.redirectTable) === null || _c === void 0 ? void 0 : _c.length,
470
+ count: snapshot.ids?.length ?? 0,
471
+ redirectTable: snapshot.redirectTable?.length,
498
472
  });
499
473
  const table = new Map(snapshot.redirectTable);
500
474
  if (snapshot.ids) {
@@ -553,11 +527,11 @@ export class BlobManager extends TypedEventEmitter {
553
527
  * Delete attachment blobs that are sweep ready.
554
528
  * @param sweepReadyBlobRoutes - The routes of blobs that are sweep ready and should be deleted. These routes will
555
529
  * be based off of local ids.
556
- * @returns - The routes of blobs that were deleted.
530
+ * @returns The routes of blobs that were deleted.
557
531
  */
558
532
  deleteSweepReadyNodes(sweepReadyBlobRoutes) {
559
533
  // If sweep for attachment blobs is not enabled, return empty list indicating nothing is deleted.
560
- if (this.mc.config.getBoolean(sweepAttachmentBlobsKey) !== true) {
534
+ if (this.mc.config.getBoolean(disableAttachmentBlobSweepKey) === true) {
561
535
  return [];
562
536
  }
563
537
  this.deleteBlobsFromRedirectTable(sweepReadyBlobRoutes);
@@ -681,18 +655,56 @@ export class BlobManager extends TypedEventEmitter {
681
655
  this.setRedirection(storageId, storageId);
682
656
  }
683
657
  }
684
- getPendingBlobs() {
685
- const blobs = {};
686
- for (const [key, entry] of this.pendingBlobs) {
687
- blobs[key] = {
688
- blob: bufferToString(entry.blob, "base64"),
689
- attached: entry.attached,
690
- acked: entry.acked,
691
- minTTLInSeconds: entry.minTTLInSeconds,
692
- uploadTime: entry.uploadTime,
693
- };
694
- }
695
- return blobs;
658
+ async getPendingBlobs(waitBlobsToAttach) {
659
+ return PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "GetPendingBlobs" }, async () => {
660
+ if (this.pendingBlobs.size === 0) {
661
+ return;
662
+ }
663
+ const blobs = {};
664
+ const localBlobs = new Set();
665
+ while (localBlobs.size < this.pendingBlobs.size) {
666
+ const attachBlobsP = [];
667
+ for (const [id, entry] of this.pendingBlobs) {
668
+ if (!localBlobs.has(entry)) {
669
+ localBlobs.add(entry);
670
+ if (waitBlobsToAttach) {
671
+ if (!entry.opsent) {
672
+ this.sendBlobAttachOp(id, entry.storageId);
673
+ }
674
+ entry.handleP.resolve(this.getBlobHandle(id));
675
+ attachBlobsP.push(new Promise((resolve) => {
676
+ const onBlobAttached = (attachedEntry) => {
677
+ if (attachedEntry === entry) {
678
+ this.off("blobAttached", onBlobAttached);
679
+ resolve();
680
+ }
681
+ };
682
+ if (!entry.attached) {
683
+ this.on("blobAttached", onBlobAttached);
684
+ }
685
+ else {
686
+ resolve();
687
+ }
688
+ }));
689
+ }
690
+ }
691
+ }
692
+ await Promise.all(attachBlobsP);
693
+ }
694
+ // another for is needed to correctly mark attach state
695
+ // future optimization won't add unattached blobs to the list
696
+ for (const [id, entry] of this.pendingBlobs) {
697
+ blobs[id] = {
698
+ blob: bufferToString(entry.blob, "base64"),
699
+ storageId: entry.storageId,
700
+ attached: entry.attached,
701
+ acked: entry.acked,
702
+ minTTLInSeconds: entry.minTTLInSeconds,
703
+ uploadTime: entry.uploadTime,
704
+ };
705
+ }
706
+ return blobs;
707
+ });
696
708
  }
697
709
  }
698
710
  BlobManager.basePath = "_blobs";