@fluidframework/container-runtime 2.12.0 → 2.20.0

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 (440) hide show
  1. package/.eslintrc.cjs +36 -0
  2. package/CHANGELOG.md +50 -0
  3. package/api-report/container-runtime.legacy.alpha.api.md +9 -203
  4. package/container-runtime.test-files.tar +0 -0
  5. package/dist/batchTracker.d.ts.map +1 -1
  6. package/dist/batchTracker.js.map +1 -1
  7. package/dist/blobManager/blobManager.d.ts +5 -1
  8. package/dist/blobManager/blobManager.d.ts.map +1 -1
  9. package/dist/blobManager/blobManager.js +16 -2
  10. package/dist/blobManager/blobManager.js.map +1 -1
  11. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  12. package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
  13. package/dist/channelCollection.d.ts +23 -12
  14. package/dist/channelCollection.d.ts.map +1 -1
  15. package/dist/channelCollection.js +22 -12
  16. package/dist/channelCollection.js.map +1 -1
  17. package/dist/connectionTelemetry.d.ts.map +1 -1
  18. package/dist/connectionTelemetry.js +6 -2
  19. package/dist/connectionTelemetry.js.map +1 -1
  20. package/dist/containerHandleContext.d.ts +1 -1
  21. package/dist/containerHandleContext.d.ts.map +1 -1
  22. package/dist/containerHandleContext.js.map +1 -1
  23. package/dist/containerRuntime.d.ts +74 -65
  24. package/dist/containerRuntime.d.ts.map +1 -1
  25. package/dist/containerRuntime.js +53 -37
  26. package/dist/containerRuntime.js.map +1 -1
  27. package/dist/dataStore.d.ts +7 -3
  28. package/dist/dataStore.d.ts.map +1 -1
  29. package/dist/dataStore.js +2 -1
  30. package/dist/dataStore.js.map +1 -1
  31. package/dist/dataStoreContext.d.ts +41 -25
  32. package/dist/dataStoreContext.d.ts.map +1 -1
  33. package/dist/dataStoreContext.js +31 -18
  34. package/dist/dataStoreContext.js.map +1 -1
  35. package/dist/dataStoreContexts.d.ts +6 -2
  36. package/dist/dataStoreContexts.d.ts.map +1 -1
  37. package/dist/dataStoreContexts.js +6 -2
  38. package/dist/dataStoreContexts.js.map +1 -1
  39. package/dist/dataStoreRegistry.d.ts +1 -1
  40. package/dist/dataStoreRegistry.d.ts.map +1 -1
  41. package/dist/dataStoreRegistry.js.map +1 -1
  42. package/dist/deltaManagerProxies.d.ts +1 -17
  43. package/dist/deltaManagerProxies.d.ts.map +1 -1
  44. package/dist/deltaManagerProxies.js.map +1 -1
  45. package/dist/deltaScheduler.d.ts +9 -6
  46. package/dist/deltaScheduler.d.ts.map +1 -1
  47. package/dist/deltaScheduler.js +95 -89
  48. package/dist/deltaScheduler.js.map +1 -1
  49. package/dist/gc/garbageCollection.d.ts +21 -7
  50. package/dist/gc/garbageCollection.d.ts.map +1 -1
  51. package/dist/gc/garbageCollection.js +12 -5
  52. package/dist/gc/garbageCollection.js.map +1 -1
  53. package/dist/gc/gcConfigs.d.ts +11 -0
  54. package/dist/gc/gcConfigs.d.ts.map +1 -1
  55. package/dist/gc/gcConfigs.js +2 -1
  56. package/dist/gc/gcConfigs.js.map +1 -1
  57. package/dist/gc/gcDefinitions.d.ts +210 -70
  58. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  59. package/dist/gc/gcDefinitions.js +39 -13
  60. package/dist/gc/gcDefinitions.js.map +1 -1
  61. package/dist/gc/gcHelpers.d.ts +6 -2
  62. package/dist/gc/gcHelpers.d.ts.map +1 -1
  63. package/dist/gc/gcHelpers.js +6 -2
  64. package/dist/gc/gcHelpers.js.map +1 -1
  65. package/dist/gc/gcSummaryDefinitions.d.ts +18 -6
  66. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
  67. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  68. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  69. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  70. package/dist/gc/gcTelemetry.d.ts +33 -11
  71. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  72. package/dist/gc/gcTelemetry.js +6 -2
  73. package/dist/gc/gcTelemetry.js.map +1 -1
  74. package/dist/gc/gcUnreferencedStateTracker.d.ts +42 -13
  75. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  76. package/dist/gc/gcUnreferencedStateTracker.js +27 -9
  77. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  78. package/dist/gc/index.d.ts +1 -0
  79. package/dist/gc/index.d.ts.map +1 -1
  80. package/dist/gc/index.js +3 -1
  81. package/dist/gc/index.js.map +1 -1
  82. package/dist/inboundBatchAggregator.d.ts +34 -0
  83. package/dist/inboundBatchAggregator.d.ts.map +1 -0
  84. package/dist/inboundBatchAggregator.js +185 -0
  85. package/dist/inboundBatchAggregator.js.map +1 -0
  86. package/dist/index.d.ts +1 -1
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js.map +1 -1
  89. package/dist/legacy.d.ts +0 -4
  90. package/dist/messageTypes.d.ts +14 -5
  91. package/dist/messageTypes.d.ts.map +1 -1
  92. package/dist/messageTypes.js.map +1 -1
  93. package/dist/metadata.d.ts +12 -4
  94. package/dist/metadata.d.ts.map +1 -1
  95. package/dist/metadata.js +6 -2
  96. package/dist/metadata.js.map +1 -1
  97. package/dist/opLifecycle/batchManager.d.ts +9 -3
  98. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  99. package/dist/opLifecycle/batchManager.js +3 -1
  100. package/dist/opLifecycle/batchManager.js.map +1 -1
  101. package/dist/opLifecycle/duplicateBatchDetector.d.ts +9 -3
  102. package/dist/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  103. package/dist/opLifecycle/duplicateBatchDetector.js +9 -3
  104. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  105. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  106. package/dist/opLifecycle/opCompressor.js.map +1 -1
  107. package/dist/opLifecycle/opDecompressor.d.ts +3 -1
  108. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  109. package/dist/opLifecycle/opDecompressor.js +12 -8
  110. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  111. package/dist/opLifecycle/opGroupingManager.d.ts +0 -1
  112. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  113. package/dist/opLifecycle/opGroupingManager.js +5 -4
  114. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  115. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  116. package/dist/opLifecycle/opSplitter.js +2 -1
  117. package/dist/opLifecycle/opSplitter.js.map +1 -1
  118. package/dist/opLifecycle/outbox.d.ts +1 -1
  119. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  120. package/dist/opLifecycle/outbox.js +6 -1
  121. package/dist/opLifecycle/outbox.js.map +1 -1
  122. package/dist/opLifecycle/remoteMessageProcessor.d.ts +9 -3
  123. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  124. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  125. package/dist/package.json +2 -1
  126. package/dist/packageVersion.d.ts +1 -1
  127. package/dist/packageVersion.js +1 -1
  128. package/dist/packageVersion.js.map +1 -1
  129. package/dist/pendingStateManager.d.ts +22 -6
  130. package/dist/pendingStateManager.d.ts.map +1 -1
  131. package/dist/pendingStateManager.js +43 -5
  132. package/dist/pendingStateManager.js.map +1 -1
  133. package/dist/summary/documentSchema.d.ts.map +1 -1
  134. package/dist/summary/documentSchema.js +2 -0
  135. package/dist/summary/documentSchema.js.map +1 -1
  136. package/dist/summary/index.d.ts +1 -1
  137. package/dist/summary/index.d.ts.map +1 -1
  138. package/dist/summary/index.js.map +1 -1
  139. package/dist/summary/orderedClientElection.d.ts +93 -31
  140. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  141. package/dist/summary/orderedClientElection.js +15 -5
  142. package/dist/summary/orderedClientElection.js.map +1 -1
  143. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  144. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  145. package/dist/summary/runningSummarizer.d.ts +17 -6
  146. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  147. package/dist/summary/runningSummarizer.js +12 -4
  148. package/dist/summary/runningSummarizer.js.map +1 -1
  149. package/dist/summary/summarizer.d.ts +9 -5
  150. package/dist/summary/summarizer.d.ts.map +1 -1
  151. package/dist/summary/summarizer.js +9 -3
  152. package/dist/summary/summarizer.js.map +1 -1
  153. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  154. package/dist/summary/summarizerClientElection.js.map +1 -1
  155. package/dist/summary/summarizerHeuristics.d.ts +6 -2
  156. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  157. package/dist/summary/summarizerHeuristics.js +12 -4
  158. package/dist/summary/summarizerHeuristics.js.map +1 -1
  159. package/dist/summary/summarizerNode/summarizerNode.d.ts +24 -8
  160. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  161. package/dist/summary/summarizerNode/summarizerNode.js +15 -5
  162. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  163. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
  164. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  165. package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -1
  166. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  167. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +12 -4
  168. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  169. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +12 -4
  170. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  171. package/dist/summary/summarizerTypes.d.ts +246 -135
  172. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  173. package/dist/summary/summarizerTypes.js.map +1 -1
  174. package/dist/summary/summaryCollection.d.ts.map +1 -1
  175. package/dist/summary/summaryCollection.js +1 -4
  176. package/dist/summary/summaryCollection.js.map +1 -1
  177. package/dist/summary/summaryFormat.d.ts +24 -8
  178. package/dist/summary/summaryFormat.d.ts.map +1 -1
  179. package/dist/summary/summaryFormat.js.map +1 -1
  180. package/dist/summary/summaryGenerator.d.ts +9 -3
  181. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  182. package/dist/summary/summaryGenerator.js +3 -1
  183. package/dist/summary/summaryGenerator.js.map +1 -1
  184. package/dist/summary/summaryManager.d.ts +8 -4
  185. package/dist/summary/summaryManager.d.ts.map +1 -1
  186. package/dist/summary/summaryManager.js +12 -4
  187. package/dist/summary/summaryManager.js.map +1 -1
  188. package/dist/throttler.d.ts +26 -10
  189. package/dist/throttler.d.ts.map +1 -1
  190. package/dist/throttler.js +12 -4
  191. package/dist/throttler.js.map +1 -1
  192. package/lib/batchTracker.d.ts.map +1 -1
  193. package/lib/batchTracker.js.map +1 -1
  194. package/lib/blobManager/blobManager.d.ts +5 -1
  195. package/lib/blobManager/blobManager.d.ts.map +1 -1
  196. package/lib/blobManager/blobManager.js +16 -2
  197. package/lib/blobManager/blobManager.js.map +1 -1
  198. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  199. package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
  200. package/lib/channelCollection.d.ts +23 -12
  201. package/lib/channelCollection.d.ts.map +1 -1
  202. package/lib/channelCollection.js +22 -12
  203. package/lib/channelCollection.js.map +1 -1
  204. package/lib/connectionTelemetry.d.ts.map +1 -1
  205. package/lib/connectionTelemetry.js +6 -2
  206. package/lib/connectionTelemetry.js.map +1 -1
  207. package/lib/containerHandleContext.d.ts +1 -1
  208. package/lib/containerHandleContext.d.ts.map +1 -1
  209. package/lib/containerHandleContext.js.map +1 -1
  210. package/lib/containerRuntime.d.ts +74 -65
  211. package/lib/containerRuntime.d.ts.map +1 -1
  212. package/lib/containerRuntime.js +53 -37
  213. package/lib/containerRuntime.js.map +1 -1
  214. package/lib/dataStore.d.ts +7 -3
  215. package/lib/dataStore.d.ts.map +1 -1
  216. package/lib/dataStore.js +2 -1
  217. package/lib/dataStore.js.map +1 -1
  218. package/lib/dataStoreContext.d.ts +41 -25
  219. package/lib/dataStoreContext.d.ts.map +1 -1
  220. package/lib/dataStoreContext.js +31 -18
  221. package/lib/dataStoreContext.js.map +1 -1
  222. package/lib/dataStoreContexts.d.ts +6 -2
  223. package/lib/dataStoreContexts.d.ts.map +1 -1
  224. package/lib/dataStoreContexts.js +6 -2
  225. package/lib/dataStoreContexts.js.map +1 -1
  226. package/lib/dataStoreRegistry.d.ts +1 -1
  227. package/lib/dataStoreRegistry.d.ts.map +1 -1
  228. package/lib/dataStoreRegistry.js.map +1 -1
  229. package/lib/deltaManagerProxies.d.ts +1 -17
  230. package/lib/deltaManagerProxies.d.ts.map +1 -1
  231. package/lib/deltaManagerProxies.js.map +1 -1
  232. package/lib/deltaScheduler.d.ts +9 -6
  233. package/lib/deltaScheduler.d.ts.map +1 -1
  234. package/lib/deltaScheduler.js +95 -89
  235. package/lib/deltaScheduler.js.map +1 -1
  236. package/lib/gc/garbageCollection.d.ts +21 -7
  237. package/lib/gc/garbageCollection.d.ts.map +1 -1
  238. package/lib/gc/garbageCollection.js +12 -5
  239. package/lib/gc/garbageCollection.js.map +1 -1
  240. package/lib/gc/gcConfigs.d.ts +11 -0
  241. package/lib/gc/gcConfigs.d.ts.map +1 -1
  242. package/lib/gc/gcConfigs.js +1 -1
  243. package/lib/gc/gcConfigs.js.map +1 -1
  244. package/lib/gc/gcDefinitions.d.ts +210 -70
  245. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  246. package/lib/gc/gcDefinitions.js +39 -13
  247. package/lib/gc/gcDefinitions.js.map +1 -1
  248. package/lib/gc/gcHelpers.d.ts +6 -2
  249. package/lib/gc/gcHelpers.d.ts.map +1 -1
  250. package/lib/gc/gcHelpers.js +6 -2
  251. package/lib/gc/gcHelpers.js.map +1 -1
  252. package/lib/gc/gcSummaryDefinitions.d.ts +18 -6
  253. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
  254. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  255. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  256. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  257. package/lib/gc/gcTelemetry.d.ts +33 -11
  258. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  259. package/lib/gc/gcTelemetry.js +6 -2
  260. package/lib/gc/gcTelemetry.js.map +1 -1
  261. package/lib/gc/gcUnreferencedStateTracker.d.ts +42 -13
  262. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  263. package/lib/gc/gcUnreferencedStateTracker.js +27 -9
  264. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  265. package/lib/gc/index.d.ts +1 -0
  266. package/lib/gc/index.d.ts.map +1 -1
  267. package/lib/gc/index.js +1 -0
  268. package/lib/gc/index.js.map +1 -1
  269. package/lib/inboundBatchAggregator.d.ts +34 -0
  270. package/lib/inboundBatchAggregator.d.ts.map +1 -0
  271. package/lib/inboundBatchAggregator.js +181 -0
  272. package/lib/inboundBatchAggregator.js.map +1 -0
  273. package/lib/index.d.ts +1 -1
  274. package/lib/index.d.ts.map +1 -1
  275. package/lib/index.js.map +1 -1
  276. package/lib/legacy.d.ts +0 -4
  277. package/lib/messageTypes.d.ts +14 -5
  278. package/lib/messageTypes.d.ts.map +1 -1
  279. package/lib/messageTypes.js.map +1 -1
  280. package/lib/metadata.d.ts +12 -4
  281. package/lib/metadata.d.ts.map +1 -1
  282. package/lib/metadata.js +6 -2
  283. package/lib/metadata.js.map +1 -1
  284. package/lib/opLifecycle/batchManager.d.ts +9 -3
  285. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  286. package/lib/opLifecycle/batchManager.js +3 -1
  287. package/lib/opLifecycle/batchManager.js.map +1 -1
  288. package/lib/opLifecycle/duplicateBatchDetector.d.ts +9 -3
  289. package/lib/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  290. package/lib/opLifecycle/duplicateBatchDetector.js +9 -3
  291. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  292. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  293. package/lib/opLifecycle/opCompressor.js +1 -1
  294. package/lib/opLifecycle/opCompressor.js.map +1 -1
  295. package/lib/opLifecycle/opDecompressor.d.ts +3 -1
  296. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  297. package/lib/opLifecycle/opDecompressor.js +13 -9
  298. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  299. package/lib/opLifecycle/opGroupingManager.d.ts +0 -1
  300. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  301. package/lib/opLifecycle/opGroupingManager.js +6 -5
  302. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  303. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  304. package/lib/opLifecycle/opSplitter.js +2 -1
  305. package/lib/opLifecycle/opSplitter.js.map +1 -1
  306. package/lib/opLifecycle/outbox.d.ts +1 -1
  307. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  308. package/lib/opLifecycle/outbox.js +6 -1
  309. package/lib/opLifecycle/outbox.js.map +1 -1
  310. package/lib/opLifecycle/remoteMessageProcessor.d.ts +9 -3
  311. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  312. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  313. package/lib/packageVersion.d.ts +1 -1
  314. package/lib/packageVersion.js +1 -1
  315. package/lib/packageVersion.js.map +1 -1
  316. package/lib/pendingStateManager.d.ts +22 -6
  317. package/lib/pendingStateManager.d.ts.map +1 -1
  318. package/lib/pendingStateManager.js +41 -4
  319. package/lib/pendingStateManager.js.map +1 -1
  320. package/lib/summary/documentSchema.d.ts.map +1 -1
  321. package/lib/summary/documentSchema.js +2 -0
  322. package/lib/summary/documentSchema.js.map +1 -1
  323. package/lib/summary/index.d.ts +1 -1
  324. package/lib/summary/index.d.ts.map +1 -1
  325. package/lib/summary/index.js.map +1 -1
  326. package/lib/summary/orderedClientElection.d.ts +93 -31
  327. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  328. package/lib/summary/orderedClientElection.js +15 -5
  329. package/lib/summary/orderedClientElection.js.map +1 -1
  330. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  331. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  332. package/lib/summary/runningSummarizer.d.ts +17 -6
  333. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  334. package/lib/summary/runningSummarizer.js +12 -4
  335. package/lib/summary/runningSummarizer.js.map +1 -1
  336. package/lib/summary/summarizer.d.ts +9 -5
  337. package/lib/summary/summarizer.d.ts.map +1 -1
  338. package/lib/summary/summarizer.js +9 -3
  339. package/lib/summary/summarizer.js.map +1 -1
  340. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  341. package/lib/summary/summarizerClientElection.js.map +1 -1
  342. package/lib/summary/summarizerHeuristics.d.ts +6 -2
  343. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  344. package/lib/summary/summarizerHeuristics.js +12 -4
  345. package/lib/summary/summarizerHeuristics.js.map +1 -1
  346. package/lib/summary/summarizerNode/summarizerNode.d.ts +24 -8
  347. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  348. package/lib/summary/summarizerNode/summarizerNode.js +15 -5
  349. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  350. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
  351. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  352. package/lib/summary/summarizerNode/summarizerNodeUtils.js +3 -1
  353. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  354. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +12 -4
  355. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  356. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +12 -4
  357. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  358. package/lib/summary/summarizerTypes.d.ts +246 -135
  359. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  360. package/lib/summary/summarizerTypes.js.map +1 -1
  361. package/lib/summary/summaryCollection.d.ts.map +1 -1
  362. package/lib/summary/summaryCollection.js +1 -4
  363. package/lib/summary/summaryCollection.js.map +1 -1
  364. package/lib/summary/summaryFormat.d.ts +24 -8
  365. package/lib/summary/summaryFormat.d.ts.map +1 -1
  366. package/lib/summary/summaryFormat.js.map +1 -1
  367. package/lib/summary/summaryGenerator.d.ts +9 -3
  368. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  369. package/lib/summary/summaryGenerator.js +3 -1
  370. package/lib/summary/summaryGenerator.js.map +1 -1
  371. package/lib/summary/summaryManager.d.ts +8 -4
  372. package/lib/summary/summaryManager.d.ts.map +1 -1
  373. package/lib/summary/summaryManager.js +12 -4
  374. package/lib/summary/summaryManager.js.map +1 -1
  375. package/lib/throttler.d.ts +26 -10
  376. package/lib/throttler.d.ts.map +1 -1
  377. package/lib/throttler.js +12 -4
  378. package/lib/throttler.js.map +1 -1
  379. package/package.json +44 -31
  380. package/src/batchTracker.ts +31 -33
  381. package/src/blobManager/blobManager.ts +38 -19
  382. package/src/blobManager/blobManagerSnapSum.ts +1 -1
  383. package/src/channelCollection.ts +44 -37
  384. package/src/connectionTelemetry.ts +31 -13
  385. package/src/containerHandleContext.ts +2 -2
  386. package/src/containerRuntime.ts +198 -140
  387. package/src/dataStore.ts +11 -6
  388. package/src/dataStoreContext.ts +80 -59
  389. package/src/dataStoreContexts.ts +16 -12
  390. package/src/dataStoreRegistry.ts +1 -1
  391. package/src/deltaManagerProxies.ts +5 -5
  392. package/src/deltaScheduler.ts +19 -13
  393. package/src/gc/garbageCollection.ts +41 -18
  394. package/src/gc/gcConfigs.ts +4 -4
  395. package/src/gc/gcDefinitions.ts +212 -70
  396. package/src/gc/gcHelpers.ts +11 -5
  397. package/src/gc/gcSummaryDefinitions.ts +18 -6
  398. package/src/gc/gcSummaryStateTracker.ts +4 -2
  399. package/src/gc/gcTelemetry.ts +47 -19
  400. package/src/gc/gcUnreferencedStateTracker.ts +40 -16
  401. package/src/gc/index.ts +1 -0
  402. package/src/{scheduleManager.ts → inboundBatchAggregator.ts} +54 -121
  403. package/src/index.ts +0 -3
  404. package/src/messageTypes.ts +14 -5
  405. package/src/metadata.ts +12 -4
  406. package/src/opLifecycle/batchManager.ts +12 -6
  407. package/src/opLifecycle/duplicateBatchDetector.ts +10 -4
  408. package/src/opLifecycle/opCompressor.ts +8 -4
  409. package/src/opLifecycle/opDecompressor.ts +20 -11
  410. package/src/opLifecycle/opGroupingManager.ts +12 -8
  411. package/src/opLifecycle/opSplitter.ts +11 -8
  412. package/src/opLifecycle/outbox.ts +22 -13
  413. package/src/opLifecycle/remoteMessageProcessor.ts +10 -4
  414. package/src/packageVersion.ts +1 -1
  415. package/src/pendingStateManager.ts +71 -15
  416. package/src/summary/documentSchema.ts +30 -18
  417. package/src/summary/index.ts +0 -3
  418. package/src/summary/orderedClientElection.ts +100 -38
  419. package/src/summary/runWhileConnectedCoordinator.ts +6 -3
  420. package/src/summary/runningSummarizer.ts +38 -19
  421. package/src/summary/summarizer.ts +29 -16
  422. package/src/summary/summarizerClientElection.ts +2 -2
  423. package/src/summary/summarizerHeuristics.ts +22 -11
  424. package/src/summary/summarizerNode/summarizerNode.ts +22 -12
  425. package/src/summary/summarizerNode/summarizerNodeUtils.ts +48 -16
  426. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +21 -11
  427. package/src/summary/summarizerTypes.ts +246 -139
  428. package/src/summary/summaryCollection.ts +24 -25
  429. package/src/summary/summaryFormat.ts +24 -8
  430. package/src/summary/summaryGenerator.ts +14 -8
  431. package/src/summary/summaryManager.ts +28 -18
  432. package/src/throttler.ts +23 -11
  433. package/dist/scheduleManager.d.ts +0 -28
  434. package/dist/scheduleManager.d.ts.map +0 -1
  435. package/dist/scheduleManager.js +0 -235
  436. package/dist/scheduleManager.js.map +0 -1
  437. package/lib/scheduleManager.d.ts +0 -28
  438. package/lib/scheduleManager.d.ts.map +0 -1
  439. package/lib/scheduleManager.js +0 -231
  440. package/lib/scheduleManager.js.map +0 -1
@@ -13,13 +13,19 @@ import { type BatchStartInfo } from "./remoteMessageProcessor.js";
13
13
  * This class tracks recent batchIds we've seen, and checks incoming batches for duplicates.
14
14
  */
15
15
  export class DuplicateBatchDetector {
16
- /** All batchIds we've seen recently enough (based on MSN) that we need to watch for duplicates */
16
+ /**
17
+ * All batchIds we've seen recently enough (based on MSN) that we need to watch for duplicates
18
+ */
17
19
  private readonly batchIdsAll = new Set<string>();
18
20
 
19
- /** We map from sequenceNumber to batchId to find which ones we can stop tracking as MSN advances */
21
+ /**
22
+ * We map from sequenceNumber to batchId to find which ones we can stop tracking as MSN advances
23
+ */
20
24
  private readonly batchIdsBySeqNum = new Map<number, string>();
21
25
 
22
- /** Initialize from snapshot data if provided - otherwise initialize empty */
26
+ /**
27
+ * Initialize from snapshot data if provided - otherwise initialize empty
28
+ */
23
29
  constructor(batchIdsFromSnapshot: [number, string][] | undefined) {
24
30
  if (batchIdsFromSnapshot) {
25
31
  this.batchIdsBySeqNum = new Map(batchIdsFromSnapshot);
@@ -78,7 +84,7 @@ export class DuplicateBatchDetector {
78
84
  * Batches that started before the MSN are not at risk for a sequenced duplicate to arrive,
79
85
  * since the batch start has been processed by all clients, and local batches are deduped and the forked client would close.
80
86
  */
81
- private clearOldBatchIds(msn: number) {
87
+ private clearOldBatchIds(msn: number): void {
82
88
  this.batchIdsBySeqNum.forEach((batchId, sequenceNumber) => {
83
89
  if (sequenceNumber < msn) {
84
90
  this.batchIdsBySeqNum.delete(sequenceNumber);
@@ -6,7 +6,11 @@
6
6
  import { IsoBuffer } from "@fluid-internal/client-utils";
7
7
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
- import { UsageError, createChildLogger } from "@fluidframework/telemetry-utils/internal";
9
+ import {
10
+ UsageError,
11
+ createChildLogger,
12
+ type ITelemetryLoggerExt,
13
+ } from "@fluidframework/telemetry-utils/internal";
10
14
  import { compress } from "lz4js";
11
15
 
12
16
  import { CompressionAlgorithms } from "../containerRuntime.js";
@@ -20,7 +24,7 @@ import { BatchMessage, IBatch } from "./definitions.js";
20
24
  * op to reserve sequence numbers.
21
25
  */
22
26
  export class OpCompressor {
23
- private readonly logger;
27
+ private readonly logger: ITelemetryLoggerExt;
24
28
 
25
29
  constructor(logger: ITelemetryBaseLogger) {
26
30
  this.logger = createChildLogger({ logger, namespace: "OpCompressor" });
@@ -89,8 +93,8 @@ export class OpCompressor {
89
93
  try {
90
94
  // Yields a valid JSON array, since each message.contents is already serialized to JSON
91
95
  return `[${batch.messages.map(({ contents }) => contents).join(",")}]`;
92
- } catch (e: any) {
93
- if (e.message === "Invalid string length") {
96
+ } catch (e: unknown) {
97
+ if ((e as Partial<Error>).message === "Invalid string length") {
94
98
  // This is how JSON.stringify signals that
95
99
  // the content size exceeds its capacity
96
100
  const error = new UsageError("Payload too large");
@@ -7,7 +7,10 @@ import { IsoBuffer, Uint8ArrayToString } from "@fluid-internal/client-utils";
7
7
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
9
  import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
10
- import { createChildLogger } from "@fluidframework/telemetry-utils/internal";
10
+ import {
11
+ createChildLogger,
12
+ type ITelemetryLoggerExt,
13
+ } from "@fluidframework/telemetry-utils/internal";
11
14
  import { decompress } from "lz4js";
12
15
 
13
16
  import { CompressionAlgorithms } from "../containerRuntime.js";
@@ -30,9 +33,11 @@ interface IPackedContentsContents {
30
33
  */
31
34
  export class OpDecompressor {
32
35
  private activeBatch = false;
36
+ // TODO: better typing
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
38
  private rootMessageContents: any | undefined;
34
39
  private processedCount = 0;
35
- private readonly logger;
40
+ private readonly logger: ITelemetryLoggerExt;
36
41
 
37
42
  constructor(logger: ITelemetryBaseLogger) {
38
43
  this.logger = createChildLogger({ logger, namespace: "OpDecompressor" });
@@ -81,11 +86,13 @@ export class OpDecompressor {
81
86
  return false;
82
87
  }
83
88
 
84
- public get currentlyUnrolling() {
89
+ public get currentlyUnrolling(): boolean {
85
90
  return this.activeBatch;
86
91
  }
87
92
 
88
- /** Is the decompressed and stored batch only comprised of a single message */
93
+ /**
94
+ * Is the decompressed and stored batch only comprised of a single message
95
+ */
89
96
  private isSingleMessageBatch = false;
90
97
 
91
98
  /**
@@ -118,8 +125,8 @@ export class OpDecompressor {
118
125
  );
119
126
  const decompressedMessage = decompress(contents);
120
127
  const intoString = Uint8ArrayToString(decompressedMessage);
121
- const asObj = JSON.parse(intoString);
122
- this.rootMessageContents = asObj;
128
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
129
+ this.rootMessageContents = JSON.parse(intoString);
123
130
  }
124
131
 
125
132
  /**
@@ -130,6 +137,7 @@ export class OpDecompressor {
130
137
  assert(this.currentlyUnrolling, 0x942 /* not currently unrolling */);
131
138
  assert(this.rootMessageContents !== undefined, 0x943 /* missing rootMessageContents */);
132
139
  assert(
140
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
133
141
  this.rootMessageContents.length > this.processedCount,
134
142
  0x944 /* no more content to unroll */,
135
143
  );
@@ -138,6 +146,7 @@ export class OpDecompressor {
138
146
 
139
147
  if (batchMetadata === false || this.isSingleMessageBatch) {
140
148
  // End of compressed batch
149
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
141
150
  const returnMessage = newMessage(message, this.rootMessageContents[this.processedCount]);
142
151
 
143
152
  this.activeBatch = false;
@@ -148,6 +157,7 @@ export class OpDecompressor {
148
157
  return returnMessage;
149
158
  } else if (batchMetadata === true) {
150
159
  // Start of compressed batch
160
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
151
161
  return newMessage(message, this.rootMessageContents[this.processedCount++]);
152
162
  }
153
163
 
@@ -155,6 +165,7 @@ export class OpDecompressor {
155
165
  assert(message.contents === undefined, 0x512 /* Expecting empty message */);
156
166
 
157
167
  // Continuation of compressed batch
168
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
158
169
  return newMessage(message, this.rootMessageContents[this.processedCount++]);
159
170
  }
160
171
  }
@@ -162,15 +173,13 @@ export class OpDecompressor {
162
173
  // We should not be mutating the input message nor its metadata
163
174
  const newMessage = (
164
175
  originalMessage: ISequencedDocumentMessage,
165
- contents: any,
176
+ contents: unknown,
166
177
  ): ISequencedDocumentMessage => ({
167
178
  ...originalMessage,
168
179
  contents,
169
180
  compression: undefined,
170
181
  // TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.
171
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
182
+
172
183
  metadata:
173
- originalMessage.metadata === undefined
174
- ? undefined
175
- : { ...(originalMessage.metadata as any) },
184
+ originalMessage.metadata === undefined ? undefined : { ...originalMessage.metadata },
176
185
  });
@@ -6,7 +6,10 @@
6
6
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
7
7
  import { assert } from "@fluidframework/core-utils/internal";
8
8
  import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
9
- import { createChildLogger } from "@fluidframework/telemetry-utils/internal";
9
+ import {
10
+ createChildLogger,
11
+ type ITelemetryLoggerExt,
12
+ } from "@fluidframework/telemetry-utils/internal";
10
13
 
11
14
  import { IBatch, type BatchMessage } from "./definitions.js";
12
15
 
@@ -24,8 +27,11 @@ interface IGroupedMessage {
24
27
  compression?: string;
25
28
  }
26
29
 
27
- function isGroupContents(opContents: any): opContents is IGroupedBatchMessageContents {
28
- return opContents?.type === OpGroupingManager.groupedBatchOp;
30
+ function isGroupContents(opContents: unknown): opContents is IGroupedBatchMessageContents {
31
+ return (
32
+ (opContents as Partial<IGroupedBatchMessageContents>)?.type ===
33
+ OpGroupingManager.groupedBatchOp
34
+ );
29
35
  }
30
36
 
31
37
  export function isGroupedBatch(op: ISequencedDocumentMessage): boolean {
@@ -35,12 +41,11 @@ export function isGroupedBatch(op: ISequencedDocumentMessage): boolean {
35
41
  export interface OpGroupingManagerConfig {
36
42
  readonly groupedBatchingEnabled: boolean;
37
43
  readonly opCountThreshold: number;
38
- readonly reentrantBatchGroupingEnabled: boolean;
39
44
  }
40
45
 
41
46
  export class OpGroupingManager {
42
47
  static readonly groupedBatchOp = "groupedBatch";
43
- private readonly logger;
48
+ private readonly logger: ITelemetryLoggerExt;
44
49
 
45
50
  constructor(
46
51
  private readonly config: OpGroupingManagerConfig,
@@ -156,9 +161,8 @@ export class OpGroupingManager {
156
161
  this.config.groupedBatchingEnabled &&
157
162
  // The number of ops in the batch must surpass the configured threshold
158
163
  // or be empty (to allow for empty batches to be grouped)
159
- (batch.messages.length === 0 || batch.messages.length >= this.config.opCountThreshold) &&
160
- // Support for reentrant batches must be explicitly enabled
161
- (this.config.reentrantBatchGroupingEnabled || batch.hasReentrantOps !== true)
164
+ (batch.messages.length === 0 || batch.messages.length >= this.config.opCountThreshold)
165
+ // Support for reentrant batches will be on by default
162
166
  );
163
167
  }
164
168
  }
@@ -11,6 +11,7 @@ import {
11
11
  DataCorruptionError,
12
12
  createChildLogger,
13
13
  extractSafePropertiesFromMessage,
14
+ type ITelemetryLoggerExt,
14
15
  } from "@fluidframework/telemetry-utils/internal";
15
16
 
16
17
  import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes.js";
@@ -23,12 +24,12 @@ export function isChunkedMessage(message: ISequencedDocumentMessage): boolean {
23
24
  }
24
25
 
25
26
  interface IChunkedContents {
26
- type: typeof ContainerMessageType.ChunkedOp;
27
- contents: IChunkedOp;
27
+ readonly type: typeof ContainerMessageType.ChunkedOp;
28
+ readonly contents: IChunkedOp;
28
29
  }
29
30
 
30
- function isChunkedContents(contents: any): contents is IChunkedContents {
31
- return contents?.type === ContainerMessageType.ChunkedOp;
31
+ function isChunkedContents(contents: unknown): contents is IChunkedContents {
32
+ return (contents as Partial<IChunkedContents>)?.type === ContainerMessageType.ChunkedOp;
32
33
  }
33
34
 
34
35
  /**
@@ -37,7 +38,7 @@ function isChunkedContents(contents: any): contents is IChunkedContents {
37
38
  export class OpSplitter {
38
39
  // Local copy of incomplete received chunks.
39
40
  private readonly chunkMap: Map<string, string[]>;
40
- private readonly logger;
41
+ private readonly logger: ITelemetryLoggerExt;
41
42
 
42
43
  constructor(
43
44
  chunks: [string, string[]][],
@@ -62,7 +63,7 @@ export class OpSplitter {
62
63
  return this.chunkMap;
63
64
  }
64
65
 
65
- public clearPartialChunks(clientId: string) {
66
+ public clearPartialChunks(clientId: string): void {
66
67
  if (this.chunkMap.has(clientId)) {
67
68
  this.chunkMap.delete(clientId);
68
69
  }
@@ -72,7 +73,7 @@ export class OpSplitter {
72
73
  clientId: string,
73
74
  chunkedContent: IChunkedOp,
74
75
  originalMessage: ISequencedDocumentMessage,
75
- ) {
76
+ ): void {
76
77
  let map = this.chunkMap.get(clientId);
77
78
  if (map === undefined) {
78
79
  map = [];
@@ -190,7 +191,7 @@ export class OpSplitter {
190
191
  const contents: IChunkedContents = message.contents;
191
192
 
192
193
  // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
193
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
194
+
194
195
  const clientId = message.clientId as string;
195
196
  const chunkedContent = contents.contents;
196
197
  this.addChunk(clientId, chunkedContent, message);
@@ -215,6 +216,7 @@ export class OpSplitter {
215
216
  // back-compat with 1.x builds
216
217
  // This is only required / present for non-compressed, chunked ops
217
218
  // For compressed ops, we have op grouping enabled, and type of each op is preserved within compressed content.
219
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
218
220
  completeMessage.type = (chunkedContent as any).originalType;
219
221
  completeMessage.metadata = chunkedContent.originalMetadata;
220
222
  completeMessage.compression = chunkedContent.originalCompression;
@@ -298,6 +300,7 @@ export const splitOp = (
298
300
  // This is really bad, as we will crash on later ops and it's very hard to debug these cases.
299
301
  // If we put some known type here, then we will crash on it (as 1.x does not understand compression, and thus will not
300
302
  // find info on the op like address of the channel to deliver the op)
303
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
301
304
  (chunk as any).originalType = "component";
302
305
  }
303
306
 
@@ -77,6 +77,8 @@ export function serializeOpContents(contents: OutboundContainerRuntimeMessage):
77
77
  * @returns the result of the action provided
78
78
  */
79
79
  export function getLongStack<T>(action: () => T, length: number = 50): T {
80
+ // TODO: better typing here
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
80
82
  const errorObj = Error as any;
81
83
  if (
82
84
  /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
@@ -90,11 +92,14 @@ export function getLongStack<T>(action: () => T, length: number = 50): T {
90
92
  return action();
91
93
  }
92
94
 
95
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
93
96
  const originalStackTraceLimit = errorObj.stackTraceLimit;
94
97
  try {
98
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
95
99
  errorObj.stackTraceLimit = length;
96
100
  return action();
97
101
  } finally {
102
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
98
103
  errorObj.stackTraceLimit = originalStackTraceLimit;
99
104
  }
100
105
  }
@@ -171,7 +176,7 @@ export class Outbox {
171
176
  * last message processed by the ContainerRuntime. In the absence of op reentrancy, this
172
177
  * pair will remain stable during a single JS turn during which the batch is being built up.
173
178
  */
174
- private maybeFlushPartialBatch() {
179
+ private maybeFlushPartialBatch(): void {
175
180
  const mainBatchSeqNums = this.mainBatch.sequenceNumbers;
176
181
  const blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;
177
182
  const idAllocSeqNums = this.idAllocationBatch.sequenceNumbers;
@@ -214,13 +219,13 @@ export class Outbox {
214
219
  }
215
220
  }
216
221
 
217
- public submit(message: BatchMessage) {
222
+ public submit(message: BatchMessage): void {
218
223
  this.maybeFlushPartialBatch();
219
224
 
220
225
  this.addMessageToBatchManager(this.mainBatch, message);
221
226
  }
222
227
 
223
- public submitBlobAttach(message: BatchMessage) {
228
+ public submitBlobAttach(message: BatchMessage): void {
224
229
  this.maybeFlushPartialBatch();
225
230
 
226
231
  this.addMessageToBatchManager(this.blobAttachBatch, message);
@@ -238,13 +243,13 @@ export class Outbox {
238
243
  }
239
244
  }
240
245
 
241
- public submitIdAllocation(message: BatchMessage) {
246
+ public submitIdAllocation(message: BatchMessage): void {
242
247
  this.maybeFlushPartialBatch();
243
248
 
244
249
  this.addMessageToBatchManager(this.idAllocationBatch, message);
245
250
  }
246
251
 
247
- private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
252
+ private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage): void {
248
253
  if (
249
254
  !batchManager.push(
250
255
  message,
@@ -267,7 +272,7 @@ export class Outbox {
267
272
  * @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
268
273
  * with the given Batch ID, which must be preserved
269
274
  */
270
- public flush(resubmittingBatchId?: BatchId) {
275
+ public flush(resubmittingBatchId?: BatchId): void {
271
276
  if (this.isContextReentrant()) {
272
277
  const error = new UsageError("Flushing is not supported inside DDS event handlers");
273
278
  this.params.closeContainer(error);
@@ -277,7 +282,7 @@ export class Outbox {
277
282
  this.flushAll(resubmittingBatchId);
278
283
  }
279
284
 
280
- private flushAll(resubmittingBatchId?: BatchId) {
285
+ private flushAll(resubmittingBatchId?: BatchId): void {
281
286
  // If we're resubmitting and all batches are empty, we need to flush an empty batch.
282
287
  // Note that we currently resubmit one batch at a time, so on resubmit, 2 of the 3 batches will *always* be empty.
283
288
  // It's theoretically possible that we don't *need* to resubmit this empty batch, and in those cases, it'll safely be ignored
@@ -304,7 +309,7 @@ export class Outbox {
304
309
  );
305
310
  }
306
311
 
307
- private flushEmptyBatch(resubmittingBatchId: BatchId) {
312
+ private flushEmptyBatch(resubmittingBatchId: BatchId): void {
308
313
  const referenceSequenceNumber =
309
314
  this.params.getCurrentSequenceNumbers().referenceSequenceNumber;
310
315
  assert(
@@ -330,7 +335,7 @@ export class Outbox {
330
335
  batchManager: BatchManager,
331
336
  disableGroupedBatching: boolean = false,
332
337
  resubmittingBatchId?: BatchId,
333
- ) {
338
+ ): void {
334
339
  if (batchManager.empty) {
335
340
  return;
336
341
  }
@@ -375,7 +380,7 @@ export class Outbox {
375
380
  *
376
381
  * @param rawBatch - the batch to be rebased
377
382
  */
378
- private rebase(rawBatch: IBatch, batchManager: BatchManager) {
383
+ private rebase(rawBatch: IBatch, batchManager: BatchManager): void {
379
384
  assert(!this.rebasing, 0x6fb /* Reentrancy */);
380
385
  assert(batchManager.options.canRebase, 0x9a7 /* BatchManager does not support rebase */);
381
386
 
@@ -459,7 +464,7 @@ export class Outbox {
459
464
  * @param batch - batch to be sent
460
465
  * @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent
461
466
  */
462
- private sendBatch(batch: IBatch) {
467
+ private sendBatch(batch: IBatch): number | undefined {
463
468
  const length = batch.messages.length;
464
469
  if (length === 0) {
465
470
  return undefined; // Nothing submitted
@@ -505,9 +510,13 @@ export class Outbox {
505
510
  }
506
511
 
507
512
  /**
508
- * @returns A checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
513
+ * Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
509
514
  */
510
- public getBatchCheckpoints() {
515
+ public getBatchCheckpoints(): {
516
+ mainBatch: IBatchCheckpoint;
517
+ idAllocationBatch: IBatchCheckpoint;
518
+ blobAttachBatch: IBatchCheckpoint;
519
+ } {
511
520
  // This variable is declared with a specific type so that we have a standard import of the IBatchCheckpoint type.
512
521
  // When the type is inferred, the generated .d.ts uses a dynamic import which doesn't resolve.
513
522
  const mainBatch: IBatchCheckpoint = this.mainBatch.checkpoint();
@@ -22,11 +22,17 @@ import { OpSplitter, isChunkedMessage } from "./opSplitter.js";
22
22
  // eslint-disable-next-line unused-imports/no-unused-imports -- Used by "@link" comment annotation below
23
23
  import { serializeOpContents } from "./outbox.js";
24
24
 
25
- /** Info about the batch we learn when we process the first message */
25
+ /**
26
+ * Info about the batch we learn when we process the first message
27
+ */
26
28
  export interface BatchStartInfo {
27
- /** Batch ID, if present */
29
+ /**
30
+ * Batch ID, if present
31
+ */
28
32
  readonly batchId: string | undefined;
29
- /** clientId that sent this batch. Used to compute Batch ID if needed */
33
+ /**
34
+ * clientId that sent this batch. Used to compute Batch ID if needed
35
+ */
30
36
  readonly clientId: string;
31
37
  /**
32
38
  * Client Sequence Number of the Grouped Batch message, or the first message in the ungrouped batch.
@@ -101,7 +107,7 @@ export class RemoteMessageProcessor {
101
107
  return this.opSplitter.chunks;
102
108
  }
103
109
 
104
- public clearPartialMessagesFor(clientId: string) {
110
+ public clearPartialMessagesFor(clientId: string): void {
105
111
  this.opSplitter.clearPartialChunks(clientId);
106
112
  }
107
113
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.12.0";
9
+ export const pkgVersion = "2.20.0";
@@ -56,16 +56,22 @@ export interface IPendingMessage {
56
56
  * Or, -1 if it was never submitted (and clientId will be a random uuid)
57
57
  */
58
58
  batchStartCsn: number;
59
- /** length of the batch (how many runtime messages here) */
59
+ /**
60
+ * length of the batch (how many runtime messages here)
61
+ */
60
62
  length: number;
61
- /** If true, don't compare batchID of incoming batches to this. e.g. ID Allocation Batch IDs should be ignored */
63
+ /**
64
+ * If true, don't compare batchID of incoming batches to this. e.g. ID Allocation Batch IDs should be ignored
65
+ */
62
66
  ignoreBatchId?: boolean;
63
67
  };
64
68
  }
65
69
 
66
70
  type Patch<T, U> = U & Omit<T, keyof U>;
67
71
 
68
- /** First version of the type (pre-dates batchInfo) */
72
+ /**
73
+ * First version of the type (pre-dates batchInfo)
74
+ */
69
75
  type IPendingMessageV0 = Patch<IPendingMessage, { batchInfo?: undefined }>;
70
76
 
71
77
  /**
@@ -82,7 +88,9 @@ export interface IPendingLocalState {
82
88
  pendingStates: IPendingMessage[];
83
89
  }
84
90
 
85
- /** Info needed to replay/resubmit a pending message */
91
+ /**
92
+ * Info needed to replay/resubmit a pending message
93
+ */
86
94
  export type PendingMessageResubmitData = Pick<
87
95
  IPendingMessage,
88
96
  "content" | "localOpMetadata" | "opMetadata"
@@ -98,7 +106,9 @@ export interface IRuntimeStateHandler {
98
106
  }
99
107
 
100
108
  function isEmptyBatchPendingMessage(message: IPendingMessageFromStash): boolean {
109
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
101
110
  const content = JSON.parse(message.content);
111
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
102
112
  return content.type === "groupedBatch" && content.contents?.length === 0;
103
113
  }
104
114
 
@@ -131,6 +141,28 @@ function scrubAndStringify(
131
141
  return JSON.stringify(scrubbed);
132
142
  }
133
143
 
144
+ /**
145
+ * Finds and returns the index where the strings diverge, and the character at that index in each string (or undefined if not applicable)
146
+ */
147
+ export function findFirstCharacterMismatched(
148
+ a: string,
149
+ b: string,
150
+ ): [index: number, charA?: string, charB?: string] {
151
+ const minLength = Math.min(a.length, b.length);
152
+ for (let i = 0; i < minLength; i++) {
153
+ if (a[i] !== b[i]) {
154
+ return [i, a[i], b[i]];
155
+ }
156
+ }
157
+
158
+ // Since we didn't return in the loop, the shorter string must be a prefix of the other.
159
+ // If they're the same length, return -1 to indicate they're identical.
160
+ // Otherwise, the next character of the longer one is where they differ. No need to return that next character.
161
+ return a.length === b.length
162
+ ? [-1, undefined, undefined]
163
+ : [minLength, a[minLength], b[minLength]];
164
+ }
165
+
134
166
  function withoutLocalOpMetadata(message: IPendingMessage): IPendingMessage {
135
167
  return {
136
168
  ...message,
@@ -148,9 +180,13 @@ function withoutLocalOpMetadata(message: IPendingMessage): IPendingMessage {
148
180
  * It verifies that all the ops are acked, are received in the right order and batch information is correct.
149
181
  */
150
182
  export class PendingStateManager implements IDisposable {
151
- /** Messages that will need to be resubmitted if not ack'd before the next reconnection */
183
+ /**
184
+ * Messages that will need to be resubmitted if not ack'd before the next reconnection
185
+ */
152
186
  private readonly pendingMessages = new Deque<IPendingMessage>();
153
- /** Messages stashed from a previous container, now being rehydrated. Need to be resubmitted. */
187
+ /**
188
+ * Messages stashed from a previous container, now being rehydrated. Need to be resubmitted.
189
+ */
154
190
  private readonly initialMessages = new Deque<IPendingMessageFromStash>();
155
191
 
156
192
  /**
@@ -163,7 +199,9 @@ export class PendingStateManager implements IDisposable {
163
199
  this.pendingMessages.clear();
164
200
  });
165
201
 
166
- /** Used to ensure we don't replay ops on the same connection twice */
202
+ /**
203
+ * Used to ensure we don't replay ops on the same connection twice
204
+ */
167
205
  private clientIdFromLastReplay: string | undefined;
168
206
 
169
207
  /**
@@ -232,10 +270,10 @@ export class PendingStateManager implements IDisposable {
232
270
  }
233
271
  }
234
272
 
235
- public get disposed() {
273
+ public get disposed(): boolean {
236
274
  return this.disposeOnce.evaluated;
237
275
  }
238
- public readonly dispose = () => this.disposeOnce.value;
276
+ public readonly dispose = (): void => this.disposeOnce.value;
239
277
 
240
278
  /**
241
279
  * The given batch has been flushed, and needs to be tracked locally until the corresponding
@@ -249,7 +287,7 @@ export class PendingStateManager implements IDisposable {
249
287
  batch: BatchMessage[],
250
288
  clientSequenceNumber: number | undefined,
251
289
  ignoreBatchId?: boolean,
252
- ) {
290
+ ): void {
253
291
  // clientId and batchStartCsn are used for generating the batchId so we can detect container forks
254
292
  // where this batch was submitted by two different clients rehydrating from the same local state.
255
293
  // In the typical case where the batch was actually sent, use the clientId and clientSequenceNumber.
@@ -288,7 +326,7 @@ export class PendingStateManager implements IDisposable {
288
326
  * Applies stashed ops at their reference sequence number so they are ready to be ACKed or resubmitted
289
327
  * @param seqNum - Sequence number at which to apply ops. Will apply all ops if seqNum is undefined.
290
328
  */
291
- public async applyStashedOpsAt(seqNum?: number) {
329
+ public async applyStashedOpsAt(seqNum?: number): Promise<void> {
292
330
  // apply stashed ops at sequence number
293
331
  while (!this.initialMessages.isEmpty()) {
294
332
  if (seqNum !== undefined) {
@@ -459,7 +497,17 @@ export class PendingStateManager implements IDisposable {
459
497
  const messageContent = buildPendingMessageContent(message);
460
498
 
461
499
  // Stringified content should match
500
+ // If it doesn't, collect as much info about the difference as possible (privacy-wise) and log it
462
501
  if (pendingMessage.content !== messageContent) {
502
+ const [pendingLength, incomingLength] = [
503
+ pendingMessage.content.length,
504
+ messageContent.length,
505
+ ];
506
+ const [mismatchStartIndex, pendingChar, incomingChar] = findFirstCharacterMismatched(
507
+ pendingMessage.content,
508
+ messageContent,
509
+ );
510
+
463
511
  const pendingContentObj = JSON.parse(
464
512
  pendingMessage.content,
465
513
  ) as LocalContainerRuntimeMessage;
@@ -467,6 +515,7 @@ export class PendingStateManager implements IDisposable {
467
515
  messageContent,
468
516
  ) as InboundContainerRuntimeMessage;
469
517
 
518
+ // Compare inner contents object, since that both should be { type, contents }
470
519
  const contentsMatch =
471
520
  pendingContentObj.contents === incomingContentObj.contents ||
472
521
  (pendingContentObj.contents !== undefined &&
@@ -480,6 +529,11 @@ export class PendingStateManager implements IDisposable {
480
529
  pendingContentScrubbed: scrubAndStringify(pendingContentObj),
481
530
  incomingContentScrubbed: scrubAndStringify(incomingContentObj),
482
531
  contentsMatch,
532
+ pendingLength,
533
+ incomingLength,
534
+ mismatchStartIndex,
535
+ pendingChar,
536
+ incomingChar,
483
537
  },
484
538
  });
485
539
 
@@ -497,7 +551,7 @@ export class PendingStateManager implements IDisposable {
497
551
  /**
498
552
  * Check if the incoming batch matches the batch info for the next pending message.
499
553
  */
500
- private onLocalBatchBegin(batchStart: BatchStartInfo, batchLength?: number) {
554
+ private onLocalBatchBegin(batchStart: BatchStartInfo, batchLength?: number): void {
501
555
  // Get the next message from the pending queue. Verify a message exists.
502
556
  const pendingMessage = this.pendingMessages.peekFront();
503
557
  assert(
@@ -556,7 +610,7 @@ export class PendingStateManager implements IDisposable {
556
610
  * states in its queue. This includes triggering resubmission of unacked ops.
557
611
  * ! Note: successfully resubmitting an op that has been successfully sequenced is not possible due to checks in the ConnectionStateHandler (Loader layer)
558
612
  */
559
- public replayPendingStates() {
613
+ public replayPendingStates(): void {
560
614
  assert(
561
615
  this.stateHandler.connected(),
562
616
  0x172 /* "The connection state is not consistent with the runtime" */,
@@ -600,7 +654,7 @@ export class PendingStateManager implements IDisposable {
600
654
  /**
601
655
  * We must preserve the distinct batches on resubmit.
602
656
  * Note: It is not possible for the PendingStateManager to receive a partially acked batch. It will
603
- * either receive the whole batch ack or nothing at all. @see ScheduleManager for how this works.
657
+ * either receive the whole batch ack or nothing at all. See {@link InboundBatchAggregator} for how this works.
604
658
  */
605
659
  if (batchMetadataFlag === undefined) {
606
660
  // Single-message batch
@@ -667,7 +721,9 @@ export class PendingStateManager implements IDisposable {
667
721
  }
668
722
  }
669
723
 
670
- /** For back-compat if trying to apply stashed ops that pre-date batchInfo */
724
+ /**
725
+ * For back-compat if trying to apply stashed ops that pre-date batchInfo
726
+ */
671
727
  function patchbatchInfo(
672
728
  message: IPendingMessageFromStash,
673
729
  ): asserts message is IPendingMessage {