@fluidframework/container-runtime 2.13.0 → 2.21.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 (489) hide show
  1. package/.eslintrc.cjs +71 -5
  2. package/CHANGELOG.md +84 -0
  3. package/api-report/container-runtime.legacy.alpha.api.md +38 -232
  4. package/dist/batchTracker.d.ts +1 -2
  5. package/dist/batchTracker.d.ts.map +1 -1
  6. package/dist/batchTracker.js +1 -1
  7. package/dist/batchTracker.js.map +1 -1
  8. package/dist/blobManager/blobManager.d.ts +5 -1
  9. package/dist/blobManager/blobManager.d.ts.map +1 -1
  10. package/dist/blobManager/blobManager.js +30 -13
  11. package/dist/blobManager/blobManager.js.map +1 -1
  12. package/dist/blobManager/blobManagerSnapSum.d.ts +1 -0
  13. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  14. package/dist/blobManager/blobManagerSnapSum.js +7 -5
  15. package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
  16. package/dist/channelCollection.d.ts +23 -12
  17. package/dist/channelCollection.d.ts.map +1 -1
  18. package/dist/channelCollection.js +85 -53
  19. package/dist/channelCollection.js.map +1 -1
  20. package/dist/connectionTelemetry.d.ts +2 -2
  21. package/dist/connectionTelemetry.d.ts.map +1 -1
  22. package/dist/connectionTelemetry.js +10 -6
  23. package/dist/connectionTelemetry.js.map +1 -1
  24. package/dist/containerHandleContext.d.ts +1 -1
  25. package/dist/containerHandleContext.d.ts.map +1 -1
  26. package/dist/containerHandleContext.js.map +1 -1
  27. package/dist/containerRuntime.d.ts +87 -94
  28. package/dist/containerRuntime.d.ts.map +1 -1
  29. package/dist/containerRuntime.js +312 -226
  30. package/dist/containerRuntime.js.map +1 -1
  31. package/dist/dataStore.d.ts +7 -3
  32. package/dist/dataStore.d.ts.map +1 -1
  33. package/dist/dataStore.js +8 -4
  34. package/dist/dataStore.js.map +1 -1
  35. package/dist/dataStoreContext.d.ts +41 -25
  36. package/dist/dataStoreContext.d.ts.map +1 -1
  37. package/dist/dataStoreContext.js +47 -29
  38. package/dist/dataStoreContext.js.map +1 -1
  39. package/dist/dataStoreContexts.d.ts +6 -2
  40. package/dist/dataStoreContexts.d.ts.map +1 -1
  41. package/dist/dataStoreContexts.js +7 -2
  42. package/dist/dataStoreContexts.js.map +1 -1
  43. package/dist/dataStoreRegistry.d.ts +1 -1
  44. package/dist/dataStoreRegistry.d.ts.map +1 -1
  45. package/dist/dataStoreRegistry.js.map +1 -1
  46. package/dist/deltaManagerProxies.d.ts +1 -17
  47. package/dist/deltaManagerProxies.d.ts.map +1 -1
  48. package/dist/deltaManagerProxies.js.map +1 -1
  49. package/dist/deltaScheduler.d.ts +9 -6
  50. package/dist/deltaScheduler.d.ts.map +1 -1
  51. package/dist/deltaScheduler.js +95 -89
  52. package/dist/deltaScheduler.js.map +1 -1
  53. package/dist/gc/garbageCollection.d.ts +21 -7
  54. package/dist/gc/garbageCollection.d.ts.map +1 -1
  55. package/dist/gc/garbageCollection.js +48 -19
  56. package/dist/gc/garbageCollection.js.map +1 -1
  57. package/dist/gc/gcConfigs.d.ts +11 -0
  58. package/dist/gc/gcConfigs.d.ts.map +1 -1
  59. package/dist/gc/gcConfigs.js +5 -2
  60. package/dist/gc/gcConfigs.js.map +1 -1
  61. package/dist/gc/gcDefinitions.d.ts +218 -70
  62. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  63. package/dist/gc/gcDefinitions.js +40 -13
  64. package/dist/gc/gcDefinitions.js.map +1 -1
  65. package/dist/gc/gcHelpers.d.ts +6 -2
  66. package/dist/gc/gcHelpers.d.ts.map +1 -1
  67. package/dist/gc/gcHelpers.js +14 -7
  68. package/dist/gc/gcHelpers.js.map +1 -1
  69. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  70. package/dist/gc/gcSummaryDefinitions.d.ts +18 -6
  71. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
  72. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  73. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  74. package/dist/gc/gcSummaryStateTracker.js +2 -1
  75. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  76. package/dist/gc/gcTelemetry.d.ts +33 -11
  77. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  78. package/dist/gc/gcTelemetry.js +35 -17
  79. package/dist/gc/gcTelemetry.js.map +1 -1
  80. package/dist/gc/gcUnreferencedStateTracker.d.ts +42 -13
  81. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  82. package/dist/gc/gcUnreferencedStateTracker.js +27 -9
  83. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  84. package/dist/gc/index.d.ts +1 -0
  85. package/dist/gc/index.d.ts.map +1 -1
  86. package/dist/gc/index.js +3 -1
  87. package/dist/gc/index.js.map +1 -1
  88. package/dist/inboundBatchAggregator.d.ts +34 -0
  89. package/dist/inboundBatchAggregator.d.ts.map +1 -0
  90. package/dist/inboundBatchAggregator.js +185 -0
  91. package/dist/inboundBatchAggregator.js.map +1 -0
  92. package/dist/index.d.ts +1 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/layerCompatState.d.ts +19 -0
  96. package/dist/layerCompatState.d.ts.map +1 -0
  97. package/dist/layerCompatState.js +64 -0
  98. package/dist/layerCompatState.js.map +1 -0
  99. package/dist/legacy.d.ts +0 -4
  100. package/dist/messageTypes.d.ts +14 -5
  101. package/dist/messageTypes.d.ts.map +1 -1
  102. package/dist/messageTypes.js.map +1 -1
  103. package/dist/metadata.d.ts +12 -4
  104. package/dist/metadata.d.ts.map +1 -1
  105. package/dist/metadata.js +6 -2
  106. package/dist/metadata.js.map +1 -1
  107. package/dist/opLifecycle/batchManager.d.ts +9 -3
  108. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  109. package/dist/opLifecycle/batchManager.js +3 -1
  110. package/dist/opLifecycle/batchManager.js.map +1 -1
  111. package/dist/opLifecycle/duplicateBatchDetector.d.ts +9 -3
  112. package/dist/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  113. package/dist/opLifecycle/duplicateBatchDetector.js +11 -5
  114. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  115. package/dist/opLifecycle/opCompressor.d.ts +3 -2
  116. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  117. package/dist/opLifecycle/opCompressor.js +13 -19
  118. package/dist/opLifecycle/opCompressor.js.map +1 -1
  119. package/dist/opLifecycle/opDecompressor.d.ts +6 -1
  120. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  121. package/dist/opLifecycle/opDecompressor.js +16 -8
  122. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  123. package/dist/opLifecycle/opGroupingManager.d.ts +1 -2
  124. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  125. package/dist/opLifecycle/opGroupingManager.js +9 -6
  126. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  127. package/dist/opLifecycle/opSplitter.d.ts +13 -10
  128. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  129. package/dist/opLifecycle/opSplitter.js +16 -11
  130. package/dist/opLifecycle/opSplitter.js.map +1 -1
  131. package/dist/opLifecycle/outbox.d.ts +4 -4
  132. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  133. package/dist/opLifecycle/outbox.js +17 -16
  134. package/dist/opLifecycle/outbox.js.map +1 -1
  135. package/dist/opLifecycle/remoteMessageProcessor.d.ts +9 -3
  136. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  137. package/dist/opLifecycle/remoteMessageProcessor.js +3 -1
  138. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  139. package/dist/package.json +2 -1
  140. package/dist/packageVersion.d.ts +1 -1
  141. package/dist/packageVersion.js +1 -1
  142. package/dist/packageVersion.js.map +1 -1
  143. package/dist/pendingStateManager.d.ts +22 -11
  144. package/dist/pendingStateManager.d.ts.map +1 -1
  145. package/dist/pendingStateManager.js +24 -15
  146. package/dist/pendingStateManager.js.map +1 -1
  147. package/dist/summary/documentSchema.d.ts +7 -0
  148. package/dist/summary/documentSchema.d.ts.map +1 -1
  149. package/dist/summary/documentSchema.js +8 -4
  150. package/dist/summary/documentSchema.js.map +1 -1
  151. package/dist/summary/index.d.ts +1 -1
  152. package/dist/summary/index.d.ts.map +1 -1
  153. package/dist/summary/index.js.map +1 -1
  154. package/dist/summary/orderedClientElection.d.ts +94 -31
  155. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  156. package/dist/summary/orderedClientElection.js +28 -16
  157. package/dist/summary/orderedClientElection.js.map +1 -1
  158. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -0
  159. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  160. package/dist/summary/runWhileConnectedCoordinator.js +7 -2
  161. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  162. package/dist/summary/runningSummarizer.d.ts +17 -6
  163. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  164. package/dist/summary/runningSummarizer.js +48 -19
  165. package/dist/summary/runningSummarizer.js.map +1 -1
  166. package/dist/summary/summarizer.d.ts +10 -5
  167. package/dist/summary/summarizer.d.ts.map +1 -1
  168. package/dist/summary/summarizer.js +26 -11
  169. package/dist/summary/summarizer.js.map +1 -1
  170. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  171. package/dist/summary/summarizerClientElection.js +1 -0
  172. package/dist/summary/summarizerClientElection.js.map +1 -1
  173. package/dist/summary/summarizerHeuristics.d.ts +6 -2
  174. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  175. package/dist/summary/summarizerHeuristics.js +13 -5
  176. package/dist/summary/summarizerHeuristics.js.map +1 -1
  177. package/dist/summary/summarizerNode/index.d.ts.map +1 -1
  178. package/dist/summary/summarizerNode/index.js.map +1 -1
  179. package/dist/summary/summarizerNode/summarizerNode.d.ts +24 -8
  180. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  181. package/dist/summary/summarizerNode/summarizerNode.js +45 -36
  182. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  183. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
  184. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  185. package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -1
  186. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  187. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +13 -5
  188. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  189. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +15 -7
  190. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  191. package/dist/summary/summarizerTypes.d.ts +253 -135
  192. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  193. package/dist/summary/summarizerTypes.js.map +1 -1
  194. package/dist/summary/summaryCollection.d.ts +3 -4
  195. package/dist/summary/summaryCollection.d.ts.map +1 -1
  196. package/dist/summary/summaryCollection.js +10 -8
  197. package/dist/summary/summaryCollection.js.map +1 -1
  198. package/dist/summary/summaryFormat.d.ts +28 -9
  199. package/dist/summary/summaryFormat.d.ts.map +1 -1
  200. package/dist/summary/summaryFormat.js +3 -2
  201. package/dist/summary/summaryFormat.js.map +1 -1
  202. package/dist/summary/summaryGenerator.d.ts +9 -3
  203. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  204. package/dist/summary/summaryGenerator.js +22 -9
  205. package/dist/summary/summaryGenerator.js.map +1 -1
  206. package/dist/summary/summaryManager.d.ts +8 -4
  207. package/dist/summary/summaryManager.d.ts.map +1 -1
  208. package/dist/summary/summaryManager.js +20 -9
  209. package/dist/summary/summaryManager.js.map +1 -1
  210. package/dist/throttler.d.ts +26 -10
  211. package/dist/throttler.d.ts.map +1 -1
  212. package/dist/throttler.js +12 -4
  213. package/dist/throttler.js.map +1 -1
  214. package/lib/batchTracker.d.ts +1 -2
  215. package/lib/batchTracker.d.ts.map +1 -1
  216. package/lib/batchTracker.js +2 -2
  217. package/lib/batchTracker.js.map +1 -1
  218. package/lib/blobManager/blobManager.d.ts +5 -1
  219. package/lib/blobManager/blobManager.d.ts.map +1 -1
  220. package/lib/blobManager/blobManager.js +30 -13
  221. package/lib/blobManager/blobManager.js.map +1 -1
  222. package/lib/blobManager/blobManagerSnapSum.d.ts +1 -0
  223. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  224. package/lib/blobManager/blobManagerSnapSum.js +7 -5
  225. package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
  226. package/lib/channelCollection.d.ts +23 -12
  227. package/lib/channelCollection.d.ts.map +1 -1
  228. package/lib/channelCollection.js +88 -54
  229. package/lib/channelCollection.js.map +1 -1
  230. package/lib/connectionTelemetry.d.ts +2 -2
  231. package/lib/connectionTelemetry.d.ts.map +1 -1
  232. package/lib/connectionTelemetry.js +11 -7
  233. package/lib/connectionTelemetry.js.map +1 -1
  234. package/lib/containerHandleContext.d.ts +1 -1
  235. package/lib/containerHandleContext.d.ts.map +1 -1
  236. package/lib/containerHandleContext.js.map +1 -1
  237. package/lib/containerRuntime.d.ts +87 -94
  238. package/lib/containerRuntime.d.ts.map +1 -1
  239. package/lib/containerRuntime.js +319 -228
  240. package/lib/containerRuntime.js.map +1 -1
  241. package/lib/dataStore.d.ts +7 -3
  242. package/lib/dataStore.d.ts.map +1 -1
  243. package/lib/dataStore.js +8 -4
  244. package/lib/dataStore.js.map +1 -1
  245. package/lib/dataStoreContext.d.ts +41 -25
  246. package/lib/dataStoreContext.d.ts.map +1 -1
  247. package/lib/dataStoreContext.js +47 -29
  248. package/lib/dataStoreContext.js.map +1 -1
  249. package/lib/dataStoreContexts.d.ts +6 -2
  250. package/lib/dataStoreContexts.d.ts.map +1 -1
  251. package/lib/dataStoreContexts.js +7 -2
  252. package/lib/dataStoreContexts.js.map +1 -1
  253. package/lib/dataStoreRegistry.d.ts +1 -1
  254. package/lib/dataStoreRegistry.d.ts.map +1 -1
  255. package/lib/dataStoreRegistry.js.map +1 -1
  256. package/lib/deltaManagerProxies.d.ts +1 -17
  257. package/lib/deltaManagerProxies.d.ts.map +1 -1
  258. package/lib/deltaManagerProxies.js.map +1 -1
  259. package/lib/deltaScheduler.d.ts +9 -6
  260. package/lib/deltaScheduler.d.ts.map +1 -1
  261. package/lib/deltaScheduler.js +96 -90
  262. package/lib/deltaScheduler.js.map +1 -1
  263. package/lib/gc/garbageCollection.d.ts +21 -7
  264. package/lib/gc/garbageCollection.d.ts.map +1 -1
  265. package/lib/gc/garbageCollection.js +51 -20
  266. package/lib/gc/garbageCollection.js.map +1 -1
  267. package/lib/gc/gcConfigs.d.ts +11 -0
  268. package/lib/gc/gcConfigs.d.ts.map +1 -1
  269. package/lib/gc/gcConfigs.js +4 -2
  270. package/lib/gc/gcConfigs.js.map +1 -1
  271. package/lib/gc/gcDefinitions.d.ts +218 -70
  272. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  273. package/lib/gc/gcDefinitions.js +40 -13
  274. package/lib/gc/gcDefinitions.js.map +1 -1
  275. package/lib/gc/gcHelpers.d.ts +6 -2
  276. package/lib/gc/gcHelpers.d.ts.map +1 -1
  277. package/lib/gc/gcHelpers.js +14 -7
  278. package/lib/gc/gcHelpers.js.map +1 -1
  279. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  280. package/lib/gc/gcSummaryDefinitions.d.ts +18 -6
  281. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
  282. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  283. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  284. package/lib/gc/gcSummaryStateTracker.js +2 -1
  285. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  286. package/lib/gc/gcTelemetry.d.ts +33 -11
  287. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  288. package/lib/gc/gcTelemetry.js +38 -18
  289. package/lib/gc/gcTelemetry.js.map +1 -1
  290. package/lib/gc/gcUnreferencedStateTracker.d.ts +42 -13
  291. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  292. package/lib/gc/gcUnreferencedStateTracker.js +27 -9
  293. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  294. package/lib/gc/index.d.ts +1 -0
  295. package/lib/gc/index.d.ts.map +1 -1
  296. package/lib/gc/index.js +1 -0
  297. package/lib/gc/index.js.map +1 -1
  298. package/lib/inboundBatchAggregator.d.ts +34 -0
  299. package/lib/inboundBatchAggregator.d.ts.map +1 -0
  300. package/lib/inboundBatchAggregator.js +181 -0
  301. package/lib/inboundBatchAggregator.js.map +1 -0
  302. package/lib/index.d.ts +1 -1
  303. package/lib/index.d.ts.map +1 -1
  304. package/lib/index.js.map +1 -1
  305. package/lib/layerCompatState.d.ts +19 -0
  306. package/lib/layerCompatState.d.ts.map +1 -0
  307. package/lib/layerCompatState.js +60 -0
  308. package/lib/layerCompatState.js.map +1 -0
  309. package/lib/legacy.d.ts +0 -4
  310. package/lib/messageTypes.d.ts +14 -5
  311. package/lib/messageTypes.d.ts.map +1 -1
  312. package/lib/messageTypes.js.map +1 -1
  313. package/lib/metadata.d.ts +12 -4
  314. package/lib/metadata.d.ts.map +1 -1
  315. package/lib/metadata.js +6 -2
  316. package/lib/metadata.js.map +1 -1
  317. package/lib/opLifecycle/batchManager.d.ts +9 -3
  318. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  319. package/lib/opLifecycle/batchManager.js +3 -1
  320. package/lib/opLifecycle/batchManager.js.map +1 -1
  321. package/lib/opLifecycle/duplicateBatchDetector.d.ts +9 -3
  322. package/lib/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  323. package/lib/opLifecycle/duplicateBatchDetector.js +11 -5
  324. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  325. package/lib/opLifecycle/opCompressor.d.ts +3 -2
  326. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  327. package/lib/opLifecycle/opCompressor.js +14 -20
  328. package/lib/opLifecycle/opCompressor.js.map +1 -1
  329. package/lib/opLifecycle/opDecompressor.d.ts +6 -1
  330. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  331. package/lib/opLifecycle/opDecompressor.js +17 -9
  332. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  333. package/lib/opLifecycle/opGroupingManager.d.ts +1 -2
  334. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  335. package/lib/opLifecycle/opGroupingManager.js +10 -7
  336. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  337. package/lib/opLifecycle/opSplitter.d.ts +13 -10
  338. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  339. package/lib/opLifecycle/opSplitter.js +16 -11
  340. package/lib/opLifecycle/opSplitter.js.map +1 -1
  341. package/lib/opLifecycle/outbox.d.ts +4 -4
  342. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  343. package/lib/opLifecycle/outbox.js +17 -16
  344. package/lib/opLifecycle/outbox.js.map +1 -1
  345. package/lib/opLifecycle/remoteMessageProcessor.d.ts +9 -3
  346. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  347. package/lib/opLifecycle/remoteMessageProcessor.js +3 -1
  348. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  349. package/lib/packageVersion.d.ts +1 -1
  350. package/lib/packageVersion.js +1 -1
  351. package/lib/packageVersion.js.map +1 -1
  352. package/lib/pendingStateManager.d.ts +22 -11
  353. package/lib/pendingStateManager.d.ts.map +1 -1
  354. package/lib/pendingStateManager.js +25 -16
  355. package/lib/pendingStateManager.js.map +1 -1
  356. package/lib/summary/documentSchema.d.ts +7 -0
  357. package/lib/summary/documentSchema.d.ts.map +1 -1
  358. package/lib/summary/documentSchema.js +8 -4
  359. package/lib/summary/documentSchema.js.map +1 -1
  360. package/lib/summary/index.d.ts +1 -1
  361. package/lib/summary/index.d.ts.map +1 -1
  362. package/lib/summary/index.js.map +1 -1
  363. package/lib/summary/orderedClientElection.d.ts +94 -31
  364. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  365. package/lib/summary/orderedClientElection.js +28 -16
  366. package/lib/summary/orderedClientElection.js.map +1 -1
  367. package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -0
  368. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  369. package/lib/summary/runWhileConnectedCoordinator.js +7 -2
  370. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  371. package/lib/summary/runningSummarizer.d.ts +17 -6
  372. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  373. package/lib/summary/runningSummarizer.js +48 -19
  374. package/lib/summary/runningSummarizer.js.map +1 -1
  375. package/lib/summary/summarizer.d.ts +10 -5
  376. package/lib/summary/summarizer.d.ts.map +1 -1
  377. package/lib/summary/summarizer.js +26 -11
  378. package/lib/summary/summarizer.js.map +1 -1
  379. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  380. package/lib/summary/summarizerClientElection.js +1 -0
  381. package/lib/summary/summarizerClientElection.js.map +1 -1
  382. package/lib/summary/summarizerHeuristics.d.ts +6 -2
  383. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  384. package/lib/summary/summarizerHeuristics.js +13 -5
  385. package/lib/summary/summarizerHeuristics.js.map +1 -1
  386. package/lib/summary/summarizerNode/index.d.ts.map +1 -1
  387. package/lib/summary/summarizerNode/index.js.map +1 -1
  388. package/lib/summary/summarizerNode/summarizerNode.d.ts +24 -8
  389. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  390. package/lib/summary/summarizerNode/summarizerNode.js +45 -36
  391. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  392. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
  393. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  394. package/lib/summary/summarizerNode/summarizerNodeUtils.js +3 -1
  395. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  396. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +13 -5
  397. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  398. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +15 -7
  399. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  400. package/lib/summary/summarizerTypes.d.ts +253 -135
  401. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  402. package/lib/summary/summarizerTypes.js.map +1 -1
  403. package/lib/summary/summaryCollection.d.ts +3 -4
  404. package/lib/summary/summaryCollection.d.ts.map +1 -1
  405. package/lib/summary/summaryCollection.js +10 -8
  406. package/lib/summary/summaryCollection.js.map +1 -1
  407. package/lib/summary/summaryFormat.d.ts +28 -9
  408. package/lib/summary/summaryFormat.d.ts.map +1 -1
  409. package/lib/summary/summaryFormat.js +2 -2
  410. package/lib/summary/summaryFormat.js.map +1 -1
  411. package/lib/summary/summaryGenerator.d.ts +9 -3
  412. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  413. package/lib/summary/summaryGenerator.js +22 -9
  414. package/lib/summary/summaryGenerator.js.map +1 -1
  415. package/lib/summary/summaryManager.d.ts +8 -4
  416. package/lib/summary/summaryManager.d.ts.map +1 -1
  417. package/lib/summary/summaryManager.js +20 -9
  418. package/lib/summary/summaryManager.js.map +1 -1
  419. package/lib/throttler.d.ts +26 -10
  420. package/lib/throttler.d.ts.map +1 -1
  421. package/lib/throttler.js +12 -4
  422. package/lib/throttler.js.map +1 -1
  423. package/package.json +22 -31
  424. package/src/batchTracker.ts +34 -36
  425. package/src/blobManager/blobManager.ts +54 -33
  426. package/src/blobManager/blobManagerSnapSum.ts +10 -10
  427. package/src/channelCollection.ts +108 -82
  428. package/src/connectionTelemetry.ts +43 -19
  429. package/src/containerHandleContext.ts +2 -2
  430. package/src/containerRuntime.ts +492 -364
  431. package/src/dataStore.ts +17 -9
  432. package/src/dataStoreContext.ts +94 -73
  433. package/src/dataStoreContexts.ts +17 -12
  434. package/src/dataStoreRegistry.ts +1 -1
  435. package/src/deltaManagerProxies.ts +5 -5
  436. package/src/deltaScheduler.ts +24 -18
  437. package/src/gc/garbageCollection.ts +89 -40
  438. package/src/gc/gcConfigs.ts +13 -5
  439. package/src/gc/gcDefinitions.ts +224 -70
  440. package/src/gc/gcHelpers.ts +22 -11
  441. package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
  442. package/src/gc/gcSummaryDefinitions.ts +18 -6
  443. package/src/gc/gcSummaryStateTracker.ts +7 -3
  444. package/src/gc/gcTelemetry.ts +73 -30
  445. package/src/gc/gcUnreferencedStateTracker.ts +40 -16
  446. package/src/gc/index.ts +1 -0
  447. package/src/{scheduleManager.ts → inboundBatchAggregator.ts} +55 -122
  448. package/src/index.ts +0 -3
  449. package/src/layerCompatState.ts +75 -0
  450. package/src/messageTypes.ts +16 -5
  451. package/src/metadata.ts +12 -4
  452. package/src/opLifecycle/README.md +43 -34
  453. package/src/opLifecycle/batchManager.ts +12 -6
  454. package/src/opLifecycle/duplicateBatchDetector.ts +12 -6
  455. package/src/opLifecycle/opCompressor.ts +22 -25
  456. package/src/opLifecycle/opDecompressor.ts +23 -11
  457. package/src/opLifecycle/opGroupingManager.ts +16 -11
  458. package/src/opLifecycle/opSplitter.ts +24 -18
  459. package/src/opLifecycle/outbox.ts +35 -33
  460. package/src/opLifecycle/remoteMessageProcessor.ts +13 -5
  461. package/src/packageVersion.ts +1 -1
  462. package/src/pendingStateManager.ts +49 -26
  463. package/src/summary/documentSchema.ts +41 -22
  464. package/src/summary/index.ts +0 -3
  465. package/src/summary/orderedClientElection.ts +114 -49
  466. package/src/summary/runWhileConnectedCoordinator.ts +12 -3
  467. package/src/summary/runningSummarizer.ts +79 -36
  468. package/src/summary/summarizer.ts +51 -25
  469. package/src/summary/summarizerClientElection.ts +4 -2
  470. package/src/summary/summarizerHeuristics.ts +23 -12
  471. package/src/summary/summarizerNode/index.ts +1 -0
  472. package/src/summary/summarizerNode/summarizerNode.ts +54 -43
  473. package/src/summary/summarizerNode/summarizerNodeUtils.ts +48 -16
  474. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +25 -15
  475. package/src/summary/summarizerTypes.ts +253 -139
  476. package/src/summary/summaryCollection.ts +41 -31
  477. package/src/summary/summaryFormat.ts +34 -13
  478. package/src/summary/summaryGenerator.ts +39 -18
  479. package/src/summary/summaryManager.ts +36 -24
  480. package/src/throttler.ts +23 -11
  481. package/container-runtime.test-files.tar +0 -0
  482. package/dist/scheduleManager.d.ts +0 -28
  483. package/dist/scheduleManager.d.ts.map +0 -1
  484. package/dist/scheduleManager.js +0 -233
  485. package/dist/scheduleManager.js.map +0 -1
  486. package/lib/scheduleManager.d.ts +0 -28
  487. package/lib/scheduleManager.d.ts.map +0 -1
  488. package/lib/scheduleManager.js +0 -229
  489. package/lib/scheduleManager.js.map +0 -1
@@ -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" });
@@ -30,13 +34,14 @@ export class OpCompressor {
30
34
  * Combines the contents of the batch into a single JSON string and compresses it, putting
31
35
  * the resulting string as the first message of the batch. The rest of the messages are
32
36
  * empty placeholders to reserve sequence numbers.
37
+ * This should only take a single message batch and compress it.
33
38
  * @param batch - The batch to compress
34
39
  * @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
35
40
  */
36
- public compressBatch(batch: IBatch): IBatch {
41
+ public compressBatch(batch: IBatch): IBatch<[BatchMessage]> {
37
42
  assert(
38
- batch.contentSizeInBytes > 0 && batch.messages.length > 0,
39
- 0x5a4 /* Batch should not be empty */,
43
+ batch.contentSizeInBytes > 0 && batch.messages.length === 1,
44
+ 0x5a4 /* Batch should not be empty and should contain a single message */,
40
45
  );
41
46
 
42
47
  const compressionStart = Date.now();
@@ -45,24 +50,16 @@ export class OpCompressor {
45
50
  const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
46
51
  const duration = Date.now() - compressionStart;
47
52
 
48
- const messages: BatchMessage[] = [];
49
- messages.push({
50
- ...batch.messages[0],
51
- contents: JSON.stringify({ packedContents: compressedContent }),
52
- metadata: batch.messages[0].metadata,
53
- compression: CompressionAlgorithms.lz4,
54
- });
53
+ const messages: [BatchMessage] = [
54
+ {
55
+ ...batch.messages[0],
56
+ contents: JSON.stringify({ packedContents: compressedContent }),
57
+ metadata: batch.messages[0].metadata,
58
+ compression: CompressionAlgorithms.lz4,
59
+ },
60
+ ];
55
61
 
56
- // Add empty placeholder messages to reserve the sequence numbers
57
- for (const message of batch.messages.slice(1)) {
58
- messages.push({
59
- localOpMetadata: message.localOpMetadata,
60
- metadata: message.metadata,
61
- referenceSequenceNumber: message.referenceSequenceNumber,
62
- });
63
- }
64
-
65
- const compressedBatch: IBatch = {
62
+ const compressedBatch = {
66
63
  contentSizeInBytes: compressedContent.length,
67
64
  messages,
68
65
  referenceSequenceNumber: batch.referenceSequenceNumber,
@@ -89,8 +86,8 @@ export class OpCompressor {
89
86
  try {
90
87
  // Yields a valid JSON array, since each message.contents is already serialized to JSON
91
88
  return `[${batch.messages.map(({ contents }) => contents).join(",")}]`;
92
- } catch (e: any) {
93
- if (e.message === "Invalid string length") {
89
+ } catch (newError: unknown) {
90
+ if ((newError as Partial<Error>).message === "Invalid string length") {
94
91
  // This is how JSON.stringify signals that
95
92
  // the content size exceeds its capacity
96
93
  const error = new UsageError("Payload too large");
@@ -105,7 +102,7 @@ export class OpCompressor {
105
102
  throw error;
106
103
  }
107
104
 
108
- throw e;
105
+ throw newError;
109
106
  }
110
107
  }
111
108
  }
@@ -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";
@@ -27,12 +30,17 @@ interface IPackedContentsContents {
27
30
  * 2. Messages in the middle of a compressed batch will have neither batch metadata nor the compression property set
28
31
  * 3. The final message of a batch will have batch metadata set to false
29
32
  * 4. An individually compressed op will have undefined batch metadata and compression set to true
33
+ *
34
+ * Compressed batches from current code are always a single message but this class needs to handle a legacy compressed batch with multiple messages
35
+ * because we need that functionality for back compat.
30
36
  */
31
37
  export class OpDecompressor {
32
38
  private activeBatch = false;
39
+ // TODO: better typing
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
41
  private rootMessageContents: any | undefined;
34
42
  private processedCount = 0;
35
- private readonly logger;
43
+ private readonly logger: ITelemetryLoggerExt;
36
44
 
37
45
  constructor(logger: ITelemetryBaseLogger) {
38
46
  this.logger = createChildLogger({ logger, namespace: "OpDecompressor" });
@@ -74,18 +82,20 @@ export class OpDecompressor {
74
82
  });
75
83
  return true;
76
84
  }
77
- } catch (err) {
85
+ } catch {
78
86
  return false;
79
87
  }
80
88
 
81
89
  return false;
82
90
  }
83
91
 
84
- public get currentlyUnrolling() {
92
+ public get currentlyUnrolling(): boolean {
85
93
  return this.activeBatch;
86
94
  }
87
95
 
88
- /** Is the decompressed and stored batch only comprised of a single message */
96
+ /**
97
+ * Is the decompressed and stored batch only comprised of a single message
98
+ */
89
99
  private isSingleMessageBatch = false;
90
100
 
91
101
  /**
@@ -118,8 +128,8 @@ export class OpDecompressor {
118
128
  );
119
129
  const decompressedMessage = decompress(contents);
120
130
  const intoString = Uint8ArrayToString(decompressedMessage);
121
- const asObj = JSON.parse(intoString);
122
- this.rootMessageContents = asObj;
131
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
132
+ this.rootMessageContents = JSON.parse(intoString);
123
133
  }
124
134
 
125
135
  /**
@@ -130,6 +140,7 @@ export class OpDecompressor {
130
140
  assert(this.currentlyUnrolling, 0x942 /* not currently unrolling */);
131
141
  assert(this.rootMessageContents !== undefined, 0x943 /* missing rootMessageContents */);
132
142
  assert(
143
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
133
144
  this.rootMessageContents.length > this.processedCount,
134
145
  0x944 /* no more content to unroll */,
135
146
  );
@@ -138,6 +149,7 @@ export class OpDecompressor {
138
149
 
139
150
  if (batchMetadata === false || this.isSingleMessageBatch) {
140
151
  // End of compressed batch
152
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
141
153
  const returnMessage = newMessage(message, this.rootMessageContents[this.processedCount]);
142
154
 
143
155
  this.activeBatch = false;
@@ -148,6 +160,7 @@ export class OpDecompressor {
148
160
  return returnMessage;
149
161
  } else if (batchMetadata === true) {
150
162
  // Start of compressed batch
163
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
151
164
  return newMessage(message, this.rootMessageContents[this.processedCount++]);
152
165
  }
153
166
 
@@ -155,6 +168,7 @@ export class OpDecompressor {
155
168
  assert(message.contents === undefined, 0x512 /* Expecting empty message */);
156
169
 
157
170
  // Continuation of compressed batch
171
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
158
172
  return newMessage(message, this.rootMessageContents[this.processedCount++]);
159
173
  }
160
174
  }
@@ -162,7 +176,7 @@ export class OpDecompressor {
162
176
  // We should not be mutating the input message nor its metadata
163
177
  const newMessage = (
164
178
  originalMessage: ISequencedDocumentMessage,
165
- contents: any,
179
+ contents: unknown,
166
180
  ): ISequencedDocumentMessage => ({
167
181
  ...originalMessage,
168
182
  contents,
@@ -170,7 +184,5 @@ const newMessage = (
170
184
  // 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
185
 
172
186
  metadata:
173
- originalMessage.metadata === undefined
174
- ? undefined
175
- : { ...(originalMessage.metadata as any) },
187
+ originalMessage.metadata === undefined ? undefined : { ...originalMessage.metadata },
176
188
  });
@@ -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 {
@@ -34,13 +40,11 @@ export function isGroupedBatch(op: ISequencedDocumentMessage): boolean {
34
40
 
35
41
  export interface OpGroupingManagerConfig {
36
42
  readonly groupedBatchingEnabled: boolean;
37
- readonly opCountThreshold: number;
38
- readonly reentrantBatchGroupingEnabled: boolean;
39
43
  }
40
44
 
41
45
  export class OpGroupingManager {
42
46
  static readonly groupedBatchOp = "groupedBatch";
43
- private readonly logger;
47
+ private readonly logger: ITelemetryLoggerExt;
44
48
 
45
49
  constructor(
46
50
  private readonly config: OpGroupingManagerConfig,
@@ -97,7 +101,6 @@ export class OpGroupingManager {
97
101
  this.logger.sendTelemetryEvent({
98
102
  eventName: "GroupLargeBatch",
99
103
  length: batch.messages.length,
100
- threshold: this.config.opCountThreshold,
101
104
  reentrant: batch.hasReentrantOps,
102
105
  referenceSequenceNumber: batch.messages[0].referenceSequenceNumber,
103
106
  });
@@ -154,11 +157,13 @@ export class OpGroupingManager {
154
157
  return (
155
158
  // Grouped batching must be enabled
156
159
  this.config.groupedBatchingEnabled &&
157
- // The number of ops in the batch must surpass the configured threshold
160
+ // The number of ops in the batch must be 2 or more
158
161
  // 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)
162
+ batch.messages.length !== 1
163
+ // Support for reentrant batches will be on by default
162
164
  );
163
165
  }
166
+ public groupedBatchingEnabled(): boolean {
167
+ return this.config.groupedBatchingEnabled;
168
+ }
164
169
  }
@@ -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 = [];
@@ -98,25 +99,28 @@ export class OpSplitter {
98
99
  * Splits the first op of a compressed batch in chunks, sends the chunks separately and
99
100
  * returns a new batch composed of the last chunk and the rest of the ops in the original batch.
100
101
  *
101
- * A compressed batch is formed by one large op at the first position, followed by a series of placeholder ops
102
- * which are used in order to reserve the sequence numbers for when the first op gets unrolled into the original
103
- * uncompressed ops at ingestion in the runtime.
102
+ * A compressed batch is formed by one large op at the first position.
104
103
  *
105
- * If the first op is too large, it can be chunked (split into smaller op) which can be sent individually over the wire
104
+ * If the op is too large, it can be chunked (split into smaller op) which can be sent individually over the wire
106
105
  * and accumulate at ingestion, until the last op in the chunk is processed, when the original op is unrolled.
107
106
  *
108
- * This method will send the first N - 1 chunks separately and use the last chunk as the first message in the result batch
109
- * and then appends the original placeholder ops. This will ensure that the batch semantics of the original (non-compressed) batch
110
- * are preserved, as the original chunked op will be unrolled by the runtime when the first message in the batch is processed
111
- * (as it is the last chunk).
107
+ * This method will send the first N - 1 chunks separately and use the last chunk as the first message in the result batch.
108
+ * This will ensure that the batch semantics of the original (non-compressed) batch are preserved, as the original chunked op
109
+ * will be unrolled by the runtime when the first message in the batch is processed (as it is the last chunk).
110
+ *
111
+ * To handle legacy compressed batches with empty placeholders this method can attach the empty placeholder ops at the end
112
+ * of the result batch, ensuring that the batch semantics are preserved.
113
+ *
114
+ * To illustrate the current functionality, if the input is `[largeOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
115
+ * `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4]` will be returned.
112
116
  *
113
- * To illustrate, if the input is `[largeOp, emptyOp, emptyOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
117
+ * With the legacy code, if the input is `[largeOp, emptyOp, emptyOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
114
118
  * `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4, emptyOp, emptyOp]` will be returned.
115
119
  *
116
120
  * @remarks - A side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
117
121
  *
118
122
  * @param batch - the compressed batch which needs to be processed
119
- * @returns A new adjusted batch (last chunk + empty placeholders) which can be sent over the wire
123
+ * @returns A batch with the last chunk of the original message
120
124
  */
121
125
  public splitFirstBatchMessage(batch: IBatch): IBatch {
122
126
  assert(this.isBatchChunkingEnabled, 0x513 /* Chunking needs to be enabled */);
@@ -215,6 +219,7 @@ export class OpSplitter {
215
219
  // back-compat with 1.x builds
216
220
  // This is only required / present for non-compressed, chunked ops
217
221
  // For compressed ops, we have op grouping enabled, and type of each op is preserved within compressed content.
222
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
218
223
  completeMessage.type = (chunkedContent as any).originalType;
219
224
  completeMessage.metadata = chunkedContent.originalMetadata;
220
225
  completeMessage.compression = chunkedContent.originalCompression;
@@ -280,7 +285,7 @@ export const splitOp = (
280
285
  for (let chunkId = 1; chunkId <= chunkCount; chunkId++) {
281
286
  const chunk: IChunkedOp = {
282
287
  chunkId,
283
- contents: op.contents.substr(offset, chunkSizeInBytes),
288
+ contents: op.contents.slice(offset, offset + chunkSizeInBytes),
284
289
  totalChunks: chunkCount,
285
290
  };
286
291
 
@@ -298,6 +303,7 @@ export const splitOp = (
298
303
  // This is really bad, as we will crash on later ops and it's very hard to debug these cases.
299
304
  // 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
305
  // find info on the op like address of the channel to deliver the op)
306
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
301
307
  (chunk as any).originalType = "component";
302
308
  }
303
309
 
@@ -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
  }
@@ -130,7 +135,9 @@ export class Outbox {
130
135
  this.params.config.compressionOptions.minimumBatchSizeInBytes !==
131
136
  Number.POSITIVE_INFINITY;
132
137
  // We need to allow infinite size batches if we enable compression
133
- const hardLimit = isCompressionEnabled ? Infinity : this.params.config.maxBatchSizeInBytes;
138
+ const hardLimit = isCompressionEnabled
139
+ ? Number.POSITIVE_INFINITY
140
+ : this.params.config.maxBatchSizeInBytes;
134
141
 
135
142
  this.mainBatch = new BatchManager({ hardLimit, canRebase: true });
136
143
  this.blobAttachBatch = new BatchManager({ hardLimit, canRebase: true });
@@ -171,7 +178,7 @@ export class Outbox {
171
178
  * last message processed by the ContainerRuntime. In the absence of op reentrancy, this
172
179
  * pair will remain stable during a single JS turn during which the batch is being built up.
173
180
  */
174
- private maybeFlushPartialBatch() {
181
+ private maybeFlushPartialBatch(): void {
175
182
  const mainBatchSeqNums = this.mainBatch.sequenceNumbers;
176
183
  const blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;
177
184
  const idAllocSeqNums = this.idAllocationBatch.sequenceNumbers;
@@ -214,37 +221,25 @@ export class Outbox {
214
221
  }
215
222
  }
216
223
 
217
- public submit(message: BatchMessage) {
224
+ public submit(message: BatchMessage): void {
218
225
  this.maybeFlushPartialBatch();
219
226
 
220
227
  this.addMessageToBatchManager(this.mainBatch, message);
221
228
  }
222
229
 
223
- public submitBlobAttach(message: BatchMessage) {
230
+ public submitBlobAttach(message: BatchMessage): void {
224
231
  this.maybeFlushPartialBatch();
225
232
 
226
233
  this.addMessageToBatchManager(this.blobAttachBatch, message);
227
-
228
- // If compression is enabled, we will always successfully receive
229
- // blobAttach ops and compress then send them at the next JS turn, regardless
230
- // of the overall size of the accumulated ops in the batch.
231
- // However, it is more efficient to flush these ops faster, preferably
232
- // after they reach a size which would benefit from compression.
233
- if (
234
- this.blobAttachBatch.contentSizeInBytes >=
235
- this.params.config.compressionOptions.minimumBatchSizeInBytes
236
- ) {
237
- this.flushInternal(this.blobAttachBatch);
238
- }
239
234
  }
240
235
 
241
- public submitIdAllocation(message: BatchMessage) {
236
+ public submitIdAllocation(message: BatchMessage): void {
242
237
  this.maybeFlushPartialBatch();
243
238
 
244
239
  this.addMessageToBatchManager(this.idAllocationBatch, message);
245
240
  }
246
241
 
247
- private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
242
+ private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage): void {
248
243
  if (
249
244
  !batchManager.push(
250
245
  message,
@@ -267,7 +262,7 @@ export class Outbox {
267
262
  * @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
268
263
  * with the given Batch ID, which must be preserved
269
264
  */
270
- public flush(resubmittingBatchId?: BatchId) {
265
+ public flush(resubmittingBatchId?: BatchId): void {
271
266
  if (this.isContextReentrant()) {
272
267
  const error = new UsageError("Flushing is not supported inside DDS event handlers");
273
268
  this.params.closeContainer(error);
@@ -277,7 +272,7 @@ export class Outbox {
277
272
  this.flushAll(resubmittingBatchId);
278
273
  }
279
274
 
280
- private flushAll(resubmittingBatchId?: BatchId) {
275
+ private flushAll(resubmittingBatchId?: BatchId): void {
281
276
  // If we're resubmitting and all batches are empty, we need to flush an empty batch.
282
277
  // Note that we currently resubmit one batch at a time, so on resubmit, 2 of the 3 batches will *always* be empty.
283
278
  // 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 +299,7 @@ export class Outbox {
304
299
  );
305
300
  }
306
301
 
307
- private flushEmptyBatch(resubmittingBatchId: BatchId) {
302
+ private flushEmptyBatch(resubmittingBatchId: BatchId): void {
308
303
  const referenceSequenceNumber =
309
304
  this.params.getCurrentSequenceNumbers().referenceSequenceNumber;
310
305
  assert(
@@ -330,7 +325,7 @@ export class Outbox {
330
325
  batchManager: BatchManager,
331
326
  disableGroupedBatching: boolean = false,
332
327
  resubmittingBatchId?: BatchId,
333
- ) {
328
+ ): void {
334
329
  if (batchManager.empty) {
335
330
  return;
336
331
  }
@@ -352,9 +347,11 @@ export class Outbox {
352
347
  // If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
353
348
  // Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.
354
349
  if (this.params.shouldSend()) {
355
- const processedBatch = this.compressBatch(
356
- shouldGroup ? this.params.groupingManager.groupBatch(rawBatch) : rawBatch,
357
- );
350
+ const processedBatch = disableGroupedBatching
351
+ ? rawBatch
352
+ : this.compressAndChunkBatch(
353
+ shouldGroup ? this.params.groupingManager.groupBatch(rawBatch) : rawBatch,
354
+ );
358
355
  clientSequenceNumber = this.sendBatch(processedBatch);
359
356
  assert(
360
357
  clientSequenceNumber === undefined || clientSequenceNumber >= 0,
@@ -375,7 +372,7 @@ export class Outbox {
375
372
  *
376
373
  * @param rawBatch - the batch to be rebased
377
374
  */
378
- private rebase(rawBatch: IBatch, batchManager: BatchManager) {
375
+ private rebase(rawBatch: IBatch, batchManager: BatchManager): void {
379
376
  assert(!this.rebasing, 0x6fb /* Reentrancy */);
380
377
  assert(batchManager.options.canRebase, 0x9a7 /* BatchManager does not support rebase */);
381
378
 
@@ -415,16 +412,17 @@ export class Outbox {
415
412
  * @remarks - If chunking happens, a side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
416
413
  *
417
414
  * @param batch - Raw or Grouped batch to consider for compression/chunking
418
- * @returns Either (A) the original batch, (B) a compressed batch (same length as original),
419
- * or (C) a batch containing the last chunk (plus empty placeholders from compression if applicable).
415
+ * @returns Either (A) the original batch, (B) a compressed batch (same length as original)
416
+ * or (C) a batch containing the last chunk.
420
417
  */
421
- private compressBatch(batch: IBatch): IBatch {
418
+ private compressAndChunkBatch(batch: IBatch): IBatch {
422
419
  if (
423
420
  batch.messages.length === 0 ||
424
421
  this.params.config.compressionOptions === undefined ||
425
422
  this.params.config.compressionOptions.minimumBatchSizeInBytes >
426
423
  batch.contentSizeInBytes ||
427
- this.params.submitBatchFn === undefined
424
+ this.params.submitBatchFn === undefined ||
425
+ !this.params.groupingManager.groupedBatchingEnabled()
428
426
  ) {
429
427
  // Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
430
428
  return batch;
@@ -459,7 +457,7 @@ export class Outbox {
459
457
  * @param batch - batch to be sent
460
458
  * @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent
461
459
  */
462
- private sendBatch(batch: IBatch) {
460
+ private sendBatch(batch: IBatch): number | undefined {
463
461
  const length = batch.messages.length;
464
462
  if (length === 0) {
465
463
  return undefined; // Nothing submitted
@@ -505,9 +503,13 @@ export class Outbox {
505
503
  }
506
504
 
507
505
  /**
508
- * @returns A checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
506
+ * Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
509
507
  */
510
- public getBatchCheckpoints() {
508
+ public getBatchCheckpoints(): {
509
+ mainBatch: IBatchCheckpoint;
510
+ idAllocationBatch: IBatchCheckpoint;
511
+ blobAttachBatch: IBatchCheckpoint;
512
+ } {
511
513
  // This variable is declared with a specific type so that we have a standard import of the IBatchCheckpoint type.
512
514
  // When the type is inferred, the generated .d.ts uses a dynamic import which doesn't resolve.
513
515
  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
 
@@ -159,7 +165,9 @@ export class RemoteMessageProcessor {
159
165
  // We should be awaiting a new batch (batchInProgress false)
160
166
  assert(!this.batchInProgress, 0x9d3 /* Grouped batch interrupting another batch */);
161
167
  const batchId = asBatchMetadata(message.metadata)?.batchId;
162
- const groupedMessages = this.opGroupingManager.ungroupOp(message).map(unpack);
168
+ const groupedMessages = this.opGroupingManager
169
+ .ungroupOp(message)
170
+ .map((innerMessage) => unpack(innerMessage));
163
171
 
164
172
  return {
165
173
  type: "fullBatch",
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.13.0";
9
+ export const pkgVersion = "2.21.0";