@fluidframework/container-runtime 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.6.4.0.191258

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