@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
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.ContainerRuntime = exports.loadContainerRuntime = exports.getSingleUseLegacyLogCallback = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isUnpackedRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DeletedResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
7
+ exports.ContainerRuntime = exports.loadContainerRuntime = exports.getSingleUseLegacyLogCallback = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isUnpackedRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DeletedResponseHeaderKey = exports.DefaultSummaryConfiguration = exports.isSummariesDisabled = void 0;
8
8
  const client_utils_1 = require("@fluid-internal/client-utils");
9
9
  const container_definitions_1 = require("@fluidframework/container-definitions");
10
10
  const internal_1 = require("@fluidframework/container-definitions/internal");
@@ -24,12 +24,14 @@ const containerHandleContext_js_1 = require("./containerHandleContext.js");
24
24
  const dataStore_js_1 = require("./dataStore.js");
25
25
  const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
26
26
  const deltaManagerProxies_js_1 = require("./deltaManagerProxies.js");
27
+ const deltaScheduler_js_1 = require("./deltaScheduler.js");
27
28
  const index_js_2 = require("./gc/index.js");
29
+ const inboundBatchAggregator_js_1 = require("./inboundBatchAggregator.js");
30
+ const layerCompatState_js_1 = require("./layerCompatState.js");
28
31
  const messageTypes_js_1 = require("./messageTypes.js");
29
32
  const index_js_3 = require("./opLifecycle/index.js");
30
33
  const packageVersion_js_1 = require("./packageVersion.js");
31
34
  const pendingStateManager_js_1 = require("./pendingStateManager.js");
32
- const scheduleManager_js_1 = require("./scheduleManager.js");
33
35
  const index_js_4 = require("./summary/index.js");
34
36
  const throttler_js_1 = require("./throttler.js");
35
37
  /**
@@ -51,6 +53,10 @@ function getUnknownMessageTypeError(unknownContainerRuntimeMessageType, codePath
51
53
  },
52
54
  });
53
55
  }
56
+ function isSummariesDisabled(config) {
57
+ return config.state === "disabled";
58
+ }
59
+ exports.isSummariesDisabled = isSummariesDisabled;
54
60
  /**
55
61
  * @legacy
56
62
  * @alpha
@@ -66,13 +72,14 @@ exports.DefaultSummaryConfiguration = {
66
72
  maxOpsSinceLastSummary: 7000,
67
73
  initialSummarizerDelayMs: 5 * 1000, // 5 secs.
68
74
  nonRuntimeOpWeight: 0.1,
69
- runtimeOpWeight: 1.0,
75
+ runtimeOpWeight: 1,
70
76
  nonRuntimeHeuristicThreshold: 20,
71
77
  };
72
78
  /**
73
79
  * Error responses when requesting a deleted object will have this header set to true
74
80
  * @legacy
75
81
  * @alpha
82
+ * @deprecated This type will be moved to internal in 2.30. External usage is not necessary or supported.
76
83
  */
77
84
  exports.DeletedResponseHeaderKey = "wasDeleted";
78
85
  /**
@@ -90,7 +97,9 @@ exports.TombstoneResponseHeaderKey = "isTombstoned";
90
97
  * to this was experimental and is no longer supported.
91
98
  */
92
99
  exports.InactiveResponseHeaderKey = "isInactive";
93
- /** Default values for Runtime Headers */
100
+ /**
101
+ * Default values for Runtime Headers
102
+ */
94
103
  exports.defaultRuntimeHeaderData = {
95
104
  wait: true,
96
105
  viaHandle: false,
@@ -110,7 +119,7 @@ var CompressionAlgorithms;
110
119
  * @alpha
111
120
  */
112
121
  exports.disabledCompressionConfig = {
113
- minimumBatchSizeInBytes: Infinity,
122
+ minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
114
123
  compressionAlgorithm: CompressionAlgorithms.lz4,
115
124
  };
116
125
  const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
@@ -126,9 +135,13 @@ const defaultCompressionConfig = {
126
135
  compressionAlgorithm: CompressionAlgorithms.lz4,
127
136
  };
128
137
  const defaultChunkSizeInBytes = 204800;
129
- /** The default time to wait for pending ops to be processed during summarization */
138
+ /**
139
+ * The default time to wait for pending ops to be processed during summarization
140
+ */
130
141
  exports.defaultPendingOpsWaitTimeoutMs = 1000;
131
- /** The default time to delay a summarization retry attempt when there are pending ops */
142
+ /**
143
+ * The default time to delay a summarization retry attempt when there are pending ops
144
+ */
132
145
  exports.defaultPendingOpsRetryDelayMs = 1000;
133
146
  /**
134
147
  * Instead of refreshing from latest because we do not have 100% confidence in the state
@@ -155,12 +168,15 @@ function getDeviceSpec() {
155
168
  try {
156
169
  if (typeof navigator === "object" && navigator !== null) {
157
170
  return {
171
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
158
172
  deviceMemory: navigator.deviceMemory,
159
173
  hardwareConcurrency: navigator.hardwareConcurrency,
160
174
  };
161
175
  }
162
176
  }
163
- catch { }
177
+ catch {
178
+ // Eat the error
179
+ }
164
180
  return {};
165
181
  }
166
182
  exports.getDeviceSpec = getDeviceSpec;
@@ -203,18 +219,20 @@ async function createSummarizer(loader, url) {
203
219
  let fluidObject;
204
220
  // Older containers may not have the "getEntryPoint" API
205
221
  // ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
206
- if (resolvedContainer.getEntryPoint !== undefined) {
207
- fluidObject = await resolvedContainer.getEntryPoint();
208
- }
209
- else {
210
- const response = await resolvedContainer.request({
222
+ if (resolvedContainer.getEntryPoint === undefined) {
223
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
224
+ const response = (await resolvedContainer.request({
211
225
  url: `/${summarizerRequestUrl}`,
212
- });
226
+ }));
213
227
  if (response.status !== 200 || response.mimeType !== "fluid/object") {
214
228
  throw (0, internal_6.responseToException)(response, request);
215
229
  }
230
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
216
231
  fluidObject = response.value;
217
232
  }
233
+ else {
234
+ fluidObject = await resolvedContainer.getEntryPoint();
235
+ }
218
236
  if (fluidObject?.ISummarizer === undefined) {
219
237
  throw new internal_7.UsageError("Fluid object does not implement ISummarizer");
220
238
  }
@@ -226,7 +244,9 @@ async function createSummarizer(loader, url) {
226
244
  * This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
227
245
  * Please see addMetadataToSummary() as well
228
246
  */
229
- function lastMessageFromMetadata(metadata) {
247
+ function lastMessageFromMetadata(
248
+ // eslint-disable-next-line import/no-deprecated
249
+ metadata) {
230
250
  return metadata?.documentSchema?.runtime?.explicitSchemaControl
231
251
  ? metadata?.lastMessage
232
252
  : metadata?.message;
@@ -243,6 +263,7 @@ let getSingleUseLegacyLogCallback = (logger, type) => {
243
263
  details: { codePath, type },
244
264
  });
245
265
  // Now that we've logged, prevent future logging (globally).
266
+ // eslint-disable-next-line unicorn/consistent-function-scoping
246
267
  exports.getSingleUseLegacyLogCallback = () => () => { };
247
268
  };
248
269
  };
@@ -258,15 +279,13 @@ async function loadContainerRuntime(params) {
258
279
  return ContainerRuntime.loadRuntime(params);
259
280
  }
260
281
  exports.loadContainerRuntime = loadContainerRuntime;
282
+ const defaultMaxConsecutiveReconnects = 7;
283
+ const defaultTelemetrySignalSampleCount = 100;
261
284
  /**
262
285
  * Represents the runtime of the container. Contains helper functions/state of the container.
263
286
  * It will define the store level mappings.
264
287
  *
265
- * @deprecated To be removed from the Legacy-Alpha API in version 2.20.0.
266
- * Use the loadContainerRuntime function and interfaces IContainerRuntime / IRuntime instead.
267
- *
268
- * @legacy
269
- * @alpha
288
+ * @internal
270
289
  */
271
290
  class ContainerRuntime extends client_utils_1.TypedEventEmitter {
272
291
  /**
@@ -301,7 +320,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
301
320
  },
302
321
  });
303
322
  const mc = (0, internal_7.loggerToMonitoringContext)(logger);
304
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableGroupedBatching = true, explicitSchemaControl = false, } = runtimeOptions;
323
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = runtimeOptions.enableGroupedBatching === false
324
+ ? exports.disabledCompressionConfig // Compression must be disabled if Grouping is disabled
325
+ : defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableGroupedBatching = true, explicitSchemaControl = false, } = runtimeOptions;
305
326
  const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
306
327
  const tryFetchBlob = async (blobName) => {
307
328
  const blobId = context.baseSnapshot?.blobs[blobName];
@@ -315,7 +336,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
315
336
  const [chunks, recentBatchInfo, metadata, electedSummarizerData, aliases, serializedIdCompressor,] = await Promise.all([
316
337
  tryFetchBlob(index_js_4.chunksBlobName),
317
338
  tryFetchBlob(index_js_4.recentBatchInfoBlobName),
339
+ // eslint-disable-next-line import/no-deprecated
318
340
  tryFetchBlob(index_js_4.metadataBlobName),
341
+ // eslint-disable-next-line import/no-deprecated
319
342
  tryFetchBlob(index_js_4.electedSummarizerBlobName),
320
343
  tryFetchBlob(index_js_4.aliasBlobName),
321
344
  tryFetchBlob(index_js_4.idCompressorBlobName),
@@ -329,6 +352,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
329
352
  // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
330
353
  if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
331
354
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
355
+ // eslint-disable-next-line unicorn/no-lonely-if -- Separate if statements make flow easier to parse
332
356
  if (loadSequenceNumberVerification !== "bypass" &&
333
357
  runtimeSequenceNumber !== protocolSequenceNumber) {
334
358
  // Message to OCEs:
@@ -351,15 +375,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
351
375
  }
352
376
  let desiredIdCompressorMode;
353
377
  switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
354
- case true:
378
+ case true: {
355
379
  desiredIdCompressorMode = "on";
356
380
  break;
357
- case false:
381
+ }
382
+ case false: {
358
383
  desiredIdCompressorMode = undefined;
359
384
  break;
360
- default:
385
+ }
386
+ default: {
361
387
  desiredIdCompressorMode = enableRuntimeIdCompressor;
362
388
  break;
389
+ }
363
390
  }
364
391
  // Enabling the IdCompressor is a one-way operation and we only want to
365
392
  // allow new containers to turn it on.
@@ -412,15 +439,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
412
439
  if (pendingLocalState?.pendingIdCompressorState !== undefined) {
413
440
  return deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
414
441
  }
415
- else if (serializedIdCompressor !== undefined) {
416
- return deserializeIdCompressor(serializedIdCompressor, createSessionId(), compressorLogger);
442
+ else if (serializedIdCompressor === undefined) {
443
+ return createIdCompressor(compressorLogger);
417
444
  }
418
445
  else {
419
- return createIdCompressor(compressorLogger);
446
+ return deserializeIdCompressor(serializedIdCompressor, createSessionId(), compressorLogger);
420
447
  }
421
448
  };
422
- const compressionLz4 = compressionOptions.minimumBatchSizeInBytes !== Infinity &&
449
+ const compressionLz4 = compressionOptions.minimumBatchSizeInBytes !== Number.POSITIVE_INFINITY &&
423
450
  compressionOptions.compressionAlgorithm === "lz4";
451
+ // eslint-disable-next-line import/no-deprecated
424
452
  const documentSchemaController = new index_js_4.DocumentsSchemaController(existing, protocolSequenceNumber, metadata?.documentSchema, {
425
453
  explicitSchemaControl,
426
454
  compressionLz4,
@@ -430,6 +458,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
430
458
  }, (schema) => {
431
459
  runtime.onSchemaChange(schema);
432
460
  });
461
+ if (compressionLz4 && !enableGroupedBatching) {
462
+ throw new internal_7.UsageError("If compression is enabled, op grouping must be enabled too");
463
+ }
433
464
  const featureGatesForTelemetry = {};
434
465
  // Make sure we've got all the options including internal ones
435
466
  const internalRuntimeOptions = {
@@ -490,29 +521,26 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
490
521
  * has to deal with compressed ops as other clients might send them.
491
522
  * And in reverse, session schema can have compression Off, but feature gates / runtime options want it On.
492
523
  * In such case it will be off in session schema, however this client will propose change to schema, and once / if
493
- * this op rountrips, compression will be On. Client can't send compressed ops until it's change in schema.
524
+ * this op roundtrips, compression will be On. Client can't send compressed ops until it's change in schema.
494
525
  */
495
526
  get sessionSchema() {
496
527
  return this.documentsSchemaController.sessionSchema.runtime;
497
528
  }
498
- get idCompressorMode() {
499
- return this.sessionSchema.idCompressorMode;
500
- }
501
529
  /**
502
- * See IContainerRuntimeBase.idCompressor() for details.
530
+ * {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.idCompressor}
503
531
  */
504
532
  get idCompressor() {
505
533
  // Expose ID Compressor only if it's On from the start.
506
534
  // If container uses delayed mode, then we can only expose generateDocumentUniqueId() and nothing else.
507
535
  // That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
508
536
  // to reason over such things as session ID space.
509
- if (this.idCompressorMode === "on") {
537
+ if (this.sessionSchema.idCompressorMode === "on") {
510
538
  (0, internal_2.assert)(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
511
539
  return this._idCompressor;
512
540
  }
513
541
  }
514
542
  /**
515
- * See IContainerRuntimeBase.generateDocumentUniqueId() for details.
543
+ * {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.generateDocumentUniqueId}
516
544
  */
517
545
  generateDocumentUniqueId() {
518
546
  return this._idCompressor?.generateDocumentUniqueId() ?? (0, uuid_1.v4)();
@@ -548,35 +576,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
548
576
  get connected() {
549
577
  return this._connected;
550
578
  }
551
- /** clientId of parent (non-summarizing) container that owns summarizer container */
579
+ /**
580
+ * clientId of parent (non-summarizing) container that owns summarizer container
581
+ */
552
582
  get summarizerClientId() {
553
583
  return this.summarizerClientElection?.electedClientId;
554
584
  }
555
585
  get disposed() {
556
586
  return this._disposed;
557
587
  }
558
- get summarizer() {
559
- (0, internal_2.assert)(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
560
- return this._summarizer;
561
- }
562
- isSummariesDisabled() {
563
- return this.summaryConfiguration.state === "disabled";
564
- }
565
- getMaxOpsSinceLastSummary() {
566
- return this.summaryConfiguration.state !== "disabled"
567
- ? this.summaryConfiguration.maxOpsSinceLastSummary
568
- : 0;
569
- }
570
- getInitialSummarizerDelayMs() {
571
- // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
572
- // to ISummaryConfiguration in 0.60.
573
- if (this.runtimeOptions.summaryOptions.initialSummarizerDelayMs !== undefined) {
574
- return this.runtimeOptions.summaryOptions.initialSummarizerDelayMs;
575
- }
576
- return this.summaryConfiguration.state !== "disabled"
577
- ? this.summaryConfiguration.initialSummarizerDelayMs
578
- : 0;
579
- }
580
588
  /**
581
589
  * If false, loading or using a Tombstoned object should merely log, not fail.
582
590
  * @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.
@@ -593,14 +601,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
593
601
  get gcThrowOnTombstoneUsage() {
594
602
  return false;
595
603
  }
604
+ get ILayerCompatDetails() {
605
+ return layerCompatState_js_1.RuntimeCompatDetails;
606
+ }
596
607
  /***/
597
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope,
608
+ constructor(context, registry,
609
+ // eslint-disable-next-line import/no-deprecated
610
+ metadata,
611
+ // eslint-disable-next-line import/no-deprecated
612
+ electedSummarizerData, chunks, dataStoreAliasMap, baseRuntimeOptions, containerScope,
598
613
  // Create a custom ITelemetryBaseLogger to output telemetry events.
599
- baseLogger, existing, blobManagerSnapshot, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, summaryConfiguration = {
614
+ baseLogger, existing,
615
+ // eslint-disable-next-line import/no-deprecated
616
+ blobManagerSnapshot, _storage, createIdCompressor,
617
+ // eslint-disable-next-line import/no-deprecated
618
+ documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler,
619
+ // eslint-disable-next-line unicorn/no-object-as-default-parameter
620
+ summaryConfiguration = {
600
621
  // the defaults
601
622
  ...exports.DefaultSummaryConfiguration,
602
623
  // the runtime configuration overrides
603
- ...runtimeOptions.summaryOptions?.summaryConfigOverrides,
624
+ ...baseRuntimeOptions.summaryOptions?.summaryConfigOverrides,
604
625
  }, recentBatchInfo) {
605
626
  super();
606
627
  this.registry = registry;
@@ -611,19 +632,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
611
632
  this.createIdCompressor = createIdCompressor;
612
633
  this.documentsSchemaController = documentsSchemaController;
613
634
  this.requestHandler = requestHandler;
614
- this.summaryConfiguration = summaryConfiguration;
615
635
  this.imminentClosure = false;
616
636
  // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
617
637
  // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
618
638
  this.pendingIdCompressorOps = [];
619
- this.defaultMaxConsecutiveReconnects = 7;
620
639
  this._orderSequentiallyCalls = 0;
621
640
  this.flushTaskExists = false;
622
641
  this.consecutiveReconnects = 0;
623
642
  this.ensureNoDataModelChangesCalls = 0;
624
643
  this._disposed = false;
625
644
  this.emitDirtyDocumentEvent = true;
626
- this.defaultTelemetrySignalSampleCount = 100;
627
645
  this._signalTracking = {
628
646
  totalSignalsSentInLatencyWindow: 0,
629
647
  signalsLost: 0,
@@ -642,16 +660,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
642
660
  this.snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
643
661
  expiry: { policy: "absolute", durationMs: 60000 },
644
662
  });
663
+ this.readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
645
664
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, snapshotWithContents, } = context;
665
+ // In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
666
+ this.disposeFn = disposeFn ?? closeFn;
667
+ const maybeLoaderCompatDetails = context;
668
+ (0, layerCompatState_js_1.validateLoaderCompatibility)(maybeLoaderCompatDetails.ILayerCompatDetails, this.disposeFn);
646
669
  // Backfill in defaults for the internal runtimeOptions, since they may not be present on the provided runtimeOptions object
647
- this.runtimeOptions = {
670
+ const runtimeOptions = {
648
671
  flushMode: defaultFlushMode,
649
- enableGroupedBatching: true,
650
- ...runtimeOptions,
672
+ ...baseRuntimeOptions,
651
673
  };
652
- this.logger = (0, internal_7.createChildLogger)({ logger: this.baseLogger });
653
674
  this.mc = (0, internal_7.createChildMonitoringContext)({
654
- logger: this.logger,
675
+ logger: this.baseLogger,
655
676
  namespace: "ContainerRuntime",
656
677
  });
657
678
  // If we support multiple algorithms in the future, then we would need to manage it here carefully.
@@ -668,19 +689,23 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
668
689
  this.innerDeltaManager = deltaManager;
669
690
  // Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
670
691
  // This makes ContainerRuntime the final gatekeeper for outgoing messages.
671
- this.submitFn = submitFn;
672
- this.submitBatchFn = submitBatchFn;
673
- this.submitSummaryFn = submitSummaryFn;
692
+ // back-compat: ADO #1385: Make this call unconditional in the future
693
+ this.submitSummaryFn =
694
+ submitSummaryFn ??
695
+ ((summaryOp, refseq) => submitFn(internal_3.MessageType.Summarize, summaryOp, false));
674
696
  this.submitSignalFn = submitSignalFn;
675
697
  // TODO: After IContainerContext.options is removed, we'll just create a new blank object {} here.
676
698
  // Values are generally expected to be set from the runtime side.
677
699
  this.options = options ?? {};
678
700
  this.clientDetails = clientDetails;
679
- this.isSummarizerClient = this.clientDetails.type === index_js_4.summarizerClientType;
701
+ const isSummarizerClient = this.clientDetails.type === index_js_4.summarizerClientType;
680
702
  this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
703
+ // eslint-disable-next-line unicorn/consistent-destructuring
681
704
  this._getClientId = () => context.clientId;
705
+ // eslint-disable-next-line unicorn/consistent-destructuring
682
706
  this._getAttachState = () => context.attachState;
683
707
  this.getAbsoluteUrl = async (relativeUrl) => {
708
+ // eslint-disable-next-line unicorn/consistent-destructuring
684
709
  if (context.getAbsoluteUrl === undefined) {
685
710
  throw new Error("Driver does not implement getAbsoluteUrl");
686
711
  }
@@ -693,10 +718,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
693
718
  // customer should observe dirty state on the runtime (the owner of dirty state) directly, rather than on the IContainer.
694
719
  this.on("dirty", () => context.updateDirtyContainerState(true));
695
720
  this.on("saved", () => context.updateDirtyContainerState(false));
696
- // In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
697
- this.disposeFn = disposeFn ?? closeFn;
698
721
  // In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
699
- this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
722
+ this.closeFn = isSummarizerClient ? this.disposeFn : closeFn;
700
723
  let loadSummaryNumber;
701
724
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
702
725
  // get the values from the metadata blob.
@@ -725,18 +748,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
725
748
  eventName: "GCFeatureMatrix",
726
749
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
727
750
  inputs: JSON.stringify({
728
- gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_2.gcGenerationOptionName],
751
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
752
+ gcOptions_gcGeneration: runtimeOptions.gcOptions[index_js_2.gcGenerationOptionName],
729
753
  }),
730
754
  });
731
755
  this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
732
- this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
733
756
  const opGroupingManager = new index_js_3.OpGroupingManager({
734
757
  groupedBatchingEnabled: this.groupedBatchingEnabled,
735
- opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
736
- reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
737
- true,
738
758
  }, this.mc.logger);
739
- const opSplitter = new index_js_3.OpSplitter(chunks, this.submitBatchFn, runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
759
+ const opSplitter = new index_js_3.OpSplitter(chunks, submitBatchFn, runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
740
760
  this.remoteMessageProcessor = new index_js_3.RemoteMessageProcessor(opSplitter, new index_js_3.OpDecompressor(this.mc.logger), opGroupingManager);
741
761
  const pendingRuntimeState = pendingLocalState;
742
762
  this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
@@ -746,7 +766,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
746
766
  reSubmitBatch: this.reSubmitBatch.bind(this),
747
767
  isActiveConnection: () => this.innerDeltaManager.active,
748
768
  isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
749
- }, pendingRuntimeState?.pending, this.logger);
769
+ }, pendingRuntimeState?.pending, this.baseLogger);
750
770
  let outerDeltaManager;
751
771
  this.useDeltaManagerOpsProxy =
752
772
  this.mc.config.getBoolean("Fluid.ContainerRuntime.DeltaManagerOpsProxy") === true;
@@ -761,24 +781,35 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
761
781
  }
762
782
  this._deltaManager = outerDeltaManager;
763
783
  this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
764
- if (this.summaryConfiguration.state === "enabled") {
765
- this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
766
- }
767
- this.summariesDisabled = this.isSummariesDisabled();
768
- this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
769
- this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
784
+ if (summaryConfiguration.state === "enabled") {
785
+ this.validateSummaryHeuristicConfiguration(summaryConfiguration);
786
+ }
787
+ this.summariesDisabled = isSummariesDisabled(summaryConfiguration);
788
+ const { maxOpsSinceLastSummary = 0, initialSummarizerDelayMs = 0 } = isSummariesDisabled(summaryConfiguration)
789
+ ? {}
790
+ : {
791
+ ...summaryConfiguration,
792
+ initialSummarizerDelayMs:
793
+ // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
794
+ // to ISummaryConfiguration in 0.60.
795
+ runtimeOptions.summaryOptions.initialSummarizerDelayMs ??
796
+ summaryConfiguration.initialSummarizerDelayMs,
797
+ };
770
798
  this.maxConsecutiveReconnects =
771
- this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
772
- this.defaultMaxConsecutiveReconnects;
773
- if (this.runtimeOptions.flushMode ===
774
- internal_5.FlushModeExperimental.Async &&
775
- supportedFeatures?.get("referenceSequenceNumbers") !== true) {
799
+ this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? defaultMaxConsecutiveReconnects;
800
+ // If the context has ILayerCompatDetails, it supports referenceSequenceNumbers since that features
801
+ // predates ILayerCompatDetails.
802
+ const referenceSequenceNumbersSupported = maybeLoaderCompatDetails.ILayerCompatDetails === undefined
803
+ ? supportedFeatures?.get("referenceSequenceNumbers") === true
804
+ : true;
805
+ if (runtimeOptions.flushMode === internal_5.FlushModeExperimental.Async &&
806
+ !referenceSequenceNumbersSupported) {
776
807
  // The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
777
808
  this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
778
809
  this._flushMode = internal_5.FlushMode.TurnBased;
779
810
  }
780
811
  else {
781
- this._flushMode = this.runtimeOptions.flushMode;
812
+ this._flushMode = runtimeOptions.flushMode;
782
813
  }
783
814
  this.offlineEnabled =
784
815
  this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad") ?? false;
@@ -793,6 +824,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
793
824
  if (this.offlineEnabled) {
794
825
  this.duplicateBatchDetector = new index_js_3.DuplicateBatchDetector(recentBatchInfo);
795
826
  }
827
+ // eslint-disable-next-line unicorn/consistent-destructuring
796
828
  if (context.attachState === container_definitions_1.AttachState.Attached) {
797
829
  const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
798
830
  if (maxSnapshotCacheDurationMs !== undefined &&
@@ -805,13 +837,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
805
837
  }
806
838
  this.garbageCollector = index_js_2.GarbageCollector.create({
807
839
  runtime: this,
808
- gcOptions: this.runtimeOptions.gcOptions,
840
+ gcOptions: runtimeOptions.gcOptions,
809
841
  baseSnapshot,
810
842
  baseLogger: this.mc.logger,
811
843
  existing,
812
844
  metadata,
813
845
  createContainerMetadata: this.createContainerMetadata,
814
- isSummarizerClient: this.isSummarizerClient,
846
+ isSummarizerClient,
815
847
  getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
816
848
  getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
817
849
  readAndParseBlob: async (id) => (0, internal_4.readAndParse)(this.storage, id),
@@ -825,7 +857,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
825
857
  const summaryReferenceSequenceNumber = baseSnapshot === undefined || metadata?.disableIsolatedChannels === true
826
858
  ? undefined
827
859
  : loadedFromSequenceNumber;
828
- this.summarizerNode = (0, index_js_4.createRootSummarizerNodeWithGC)((0, internal_7.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
860
+ this.summarizerNode = (0, index_js_4.createRootSummarizerNodeWithGC)((0, internal_7.createChildLogger)({ logger: this.baseLogger, namespace: "SummarizerNode" }),
829
861
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
830
862
  async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
831
863
  // Latest change sequence number, no changes since summary applied yet
@@ -885,13 +917,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
885
917
  stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
886
918
  closeContainer: (error) => this.closeFn(error),
887
919
  });
888
- this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, internal_7.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
920
+ this.deltaScheduler = new deltaScheduler_js_1.DeltaScheduler(this.innerDeltaManager, this, (0, internal_7.createChildLogger)({ logger: this.baseLogger, namespace: "DeltaScheduler" }));
921
+ this.inboundBatchAggregator = new inboundBatchAggregator_js_1.InboundBatchAggregator(this.innerDeltaManager, () => this.clientId, (0, internal_7.createChildLogger)({ logger: this.baseLogger, namespace: "InboundBatchAggregator" }));
889
922
  const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
890
- const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
923
+ const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(submitFn, this.innerDeltaManager);
891
924
  this.outbox = new index_js_3.Outbox({
892
925
  shouldSend: () => this.canSendOps(),
893
926
  pendingStateManager: this.pendingStateManager,
894
- submitBatchFn: this.submitBatchFn,
927
+ submitBatchFn,
895
928
  legacySendBatchFn,
896
929
  compressor: new index_js_3.OpCompressor(this.mc.logger),
897
930
  splitter: opSplitter,
@@ -938,7 +971,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
938
971
  const closeSummarizerDelayOverride = this.mc.config.getNumber("Fluid.ContainerRuntime.Test.CloseSummarizerDelayOverrideMs");
939
972
  this.closeSummarizerDelayMs =
940
973
  closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
941
- this.summaryCollection = new index_js_4.SummaryCollection(this.deltaManager, this.logger);
974
+ const summaryCollection = new index_js_4.SummaryCollection(this.deltaManager, this.baseLogger);
942
975
  this.dirtyContainer =
943
976
  this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
944
977
  context.updateDirtyContainerState(this.dirtyContainer);
@@ -947,14 +980,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
947
980
  }
948
981
  else {
949
982
  const orderedClientLogger = (0, internal_7.createChildLogger)({
950
- logger: this.logger,
983
+ logger: this.baseLogger,
951
984
  namespace: "OrderedClientElection",
952
985
  });
953
986
  const orderedClientCollection = new index_js_4.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
954
987
  const orderedClientElectionForSummarizer = new index_js_4.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_4.SummarizerClientElection.isClientEligible, this.mc.config.getBoolean("Fluid.ContainerRuntime.OrderedClientElection.EnablePerformanceEvents"));
955
- this.summarizerClientElection = new index_js_4.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
956
- if (this.isSummarizerClient) {
957
- this._summarizer = new index_js_4.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_4.RunWhileConnectedCoordinator.create(runtime,
988
+ this.summarizerClientElection = new index_js_4.SummarizerClientElection(orderedClientLogger, summaryCollection, orderedClientElectionForSummarizer, maxOpsSinceLastSummary);
989
+ if (isSummarizerClient) {
990
+ // eslint-disable-next-line import/no-deprecated
991
+ this._summarizer = new index_js_4.Summarizer(this /* ISummarizerRuntime */, () => summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, summaryCollection,
992
+ // eslint-disable-next-line import/no-deprecated
993
+ async (runtime) => index_js_4.RunWhileConnectedCoordinator.create(runtime,
958
994
  // Summarization runs in summarizer client and needs access to the real (non-proxy) active
959
995
  // information. The proxy delta manager would always return false for summarizer client.
960
996
  () => this.innerDeltaManager.active));
@@ -963,48 +999,49 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
963
999
  // Only create a SummaryManager and SummarizerClientElection
964
1000
  // if summaries are enabled and we are not the summarizer client.
965
1001
  const defaultAction = () => {
966
- if (this.summaryCollection.opsSinceLastAck > this.maxOpsSinceLastSummary) {
1002
+ if (summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
967
1003
  this.mc.logger.sendTelemetryEvent({ eventName: "SummaryStatus:Behind" });
968
1004
  // unregister default to no log on every op after falling behind
969
1005
  // and register summary ack handler to re-register this handler
970
1006
  // after successful summary
971
- this.summaryCollection.once(internal_3.MessageType.SummaryAck, () => {
1007
+ summaryCollection.once(internal_3.MessageType.SummaryAck, () => {
972
1008
  this.mc.logger.sendTelemetryEvent({
973
1009
  eventName: "SummaryStatus:CaughtUp",
974
1010
  });
975
1011
  // we've caught up, so re-register the default action to monitor for
976
1012
  // falling behind, and unregister ourself
977
- this.summaryCollection.on("default", defaultAction);
1013
+ summaryCollection.on("default", defaultAction);
978
1014
  });
979
- this.summaryCollection.off("default", defaultAction);
1015
+ summaryCollection.off("default", defaultAction);
980
1016
  }
981
1017
  };
982
- this.summaryCollection.on("default", defaultAction);
1018
+ summaryCollection.on("default", defaultAction);
983
1019
  // Create the SummaryManager and mark the initial state
984
1020
  this.summaryManager = new index_js_4.SummaryManager(this.summarizerClientElection, this, // IConnectedState
985
- this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
1021
+ summaryCollection, this.baseLogger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
986
1022
  30 * 1000, // 30 sec max delay
987
1023
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
988
1024
  (0, throttler_js_1.formExponentialFn)({ coefficient: 20, initialDelay: 0 })), {
989
- initialDelayMs: this.initialSummarizerDelayMs,
1025
+ initialDelayMs: initialSummarizerDelayMs,
990
1026
  });
991
1027
  // Forward events from SummaryManager
992
- [
1028
+ for (const eventName of [
993
1029
  "summarize",
994
1030
  "summarizeAllAttemptsFailed",
995
1031
  "summarizerStop",
996
1032
  "summarizerStart",
997
1033
  "summarizerStartupFailed",
998
- ].forEach((eventName) => {
1034
+ ]) {
999
1035
  this.summaryManager?.on(eventName, (...args) => {
1000
1036
  this.emit(eventName, ...args);
1001
1037
  });
1002
- });
1038
+ }
1003
1039
  this.summaryManager.start();
1004
1040
  }
1005
1041
  }
1006
1042
  // logging hardware telemetry
1007
- this.logger.sendTelemetryEvent({
1043
+ this.baseLogger.send({
1044
+ category: "generic",
1008
1045
  eventName: "DeviceSpec",
1009
1046
  ...getDeviceSpec(),
1010
1047
  });
@@ -1016,13 +1053,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1016
1053
  summaryFormatVersion: metadata?.summaryFormatVersion,
1017
1054
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
1018
1055
  gcVersion: metadata?.gcFeature,
1019
- options: JSON.stringify(runtimeOptions),
1056
+ options: JSON.stringify(baseRuntimeOptions),
1020
1057
  idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
1021
- idCompressorMode: this.idCompressorMode,
1058
+ idCompressorMode: this.sessionSchema.idCompressorMode,
1022
1059
  sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
1023
1060
  featureGates: JSON.stringify({
1024
1061
  ...featureGatesForTelemetry,
1025
- disableAttachReorder: this.disableAttachReorder,
1026
1062
  disablePartialFlush,
1027
1063
  closeSummarizerDelayOverride,
1028
1064
  }),
@@ -1030,11 +1066,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1030
1066
  groupedBatchingEnabled: this.groupedBatchingEnabled,
1031
1067
  initialSequenceNumber: this.deltaManager.initialSequenceNumber,
1032
1068
  });
1033
- (0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this._deltaManager, this, this.logger);
1034
- (0, batchTracker_js_1.BindBatchTracker)(this, this.logger);
1069
+ (0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this._deltaManager, this, this.baseLogger);
1070
+ (0, batchTracker_js_1.BindBatchTracker)(this, this.baseLogger);
1035
1071
  this.entryPoint = new internal_2.LazyPromise(async () => {
1036
- if (this.isSummarizerClient) {
1037
- (0, internal_2.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
1072
+ if (this._summarizer !== undefined) {
1038
1073
  return this._summarizer;
1039
1074
  }
1040
1075
  return provideEntryPoint(this);
@@ -1043,8 +1078,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1043
1078
  // saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
1044
1079
  this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
1045
1080
  }
1081
+ // eslint-disable-next-line import/no-deprecated
1046
1082
  onSchemaChange(schema) {
1047
- this.logger.sendTelemetryEvent({
1083
+ this.mc.logger.sendTelemetryEvent({
1048
1084
  eventName: "SchemaChangeAccept",
1049
1085
  sessionRuntimeSchema: JSON.stringify(schema),
1050
1086
  });
@@ -1067,19 +1103,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1067
1103
  deleteChildSummarizerNode(id) {
1068
1104
  return this.summarizerNode.deleteChild(id);
1069
1105
  }
1070
- /* IFluidParentContext APIs that should not be called on Root */
1106
+ // #region `IFluidParentContext` APIs that should not be called on Root
1071
1107
  makeLocallyVisible() {
1072
1108
  (0, internal_2.assert)(false, 0x8eb /* should not be called */);
1073
1109
  }
1074
1110
  setChannelDirty(address) {
1075
1111
  (0, internal_2.assert)(false, 0x909 /* should not be called */);
1076
1112
  }
1113
+ // #endregion
1077
1114
  /**
1078
1115
  * Initializes the state from the base snapshot this container runtime loaded from.
1079
1116
  */
1080
1117
  async initializeBaseState() {
1081
- if (this.idCompressorMode === "on" ||
1082
- (this.idCompressorMode === "delayed" && this.connected)) {
1118
+ if (this.sessionSchema.idCompressorMode === "on" ||
1119
+ (this.sessionSchema.idCompressorMode === "delayed" && this.connected)) {
1083
1120
  this._idCompressor = await this.createIdCompressor();
1084
1121
  // This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
1085
1122
  (0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
@@ -1104,6 +1141,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1104
1141
  this._summarizer?.dispose();
1105
1142
  this.channelCollection.dispose();
1106
1143
  this.pendingStateManager.dispose();
1144
+ this.inboundBatchAggregator.dispose();
1145
+ this.deltaScheduler.dispose();
1107
1146
  this.emit("dispose");
1108
1147
  this.removeAllListeners();
1109
1148
  }
@@ -1120,7 +1159,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1120
1159
  // Lookup up in the cache, if not present then make the network call as multiple datastores could
1121
1160
  // be in same loading group. So, once we have fetched the snapshot for that loading group on
1122
1161
  // any request, then cache that as same group could be requested in future too.
1123
- const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(), async () => {
1162
+ const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(","), async () => {
1124
1163
  (0, internal_2.assert)(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
1125
1164
  loadedFromCache = false;
1126
1165
  return this.storage.getSnapshot({
@@ -1129,7 +1168,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1129
1168
  loadingGroupIds: sortedLoadingGroupIds,
1130
1169
  });
1131
1170
  });
1132
- this.logger.sendTelemetryEvent({
1171
+ this.mc.logger.sendTelemetryEvent({
1133
1172
  eventName: "GroupIdSnapshotFetched",
1134
1173
  details: JSON.stringify({
1135
1174
  fromCache: loadedFromCache,
@@ -1159,7 +1198,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1159
1198
  // another snapshot from which the summarizer loaded and it is behind, then just give up as
1160
1199
  // the summarizer state is not up to date.
1161
1200
  // This should be a recoverable scenario and shouldn't happen as we should process the ack first.
1162
- if (this.isSummarizerClient) {
1201
+ if (this._summarizer !== undefined) {
1163
1202
  throw new Error("Summarizer client behind, loaded newer snapshot with loadingGroupId");
1164
1203
  }
1165
1204
  // We want to catchup from sequenceNumber to targetSequenceNumber
@@ -1221,7 +1260,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1221
1260
  return {
1222
1261
  status: 200,
1223
1262
  mimeType: "fluid/object",
1224
- value: this.summarizer,
1263
+ value: this._summarizer,
1225
1264
  };
1226
1265
  }
1227
1266
  return (0, internal_6.create404Response)(request);
@@ -1276,7 +1315,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1276
1315
  internalId(maybeAlias) {
1277
1316
  return this.channelCollection.internalId(maybeAlias);
1278
1317
  }
1279
- /** Adds the container's metadata to the given summary tree. */
1318
+ /**
1319
+ * Adds the container's metadata to the given summary tree.
1320
+ */
1280
1321
  addMetadataToSummary(summaryTree) {
1281
1322
  // The last message processed at the time of summary. If there are no new messages, use the message from the
1282
1323
  // last summary.
@@ -1285,6 +1326,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1285
1326
  const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
1286
1327
  // Is document schema explicit control on?
1287
1328
  const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl;
1329
+ // eslint-disable-next-line import/no-deprecated
1288
1330
  const metadata = {
1289
1331
  ...this.createContainerMetadata,
1290
1332
  // Increment the summary number for the next summary that will be generated.
@@ -1298,7 +1340,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1298
1340
  // last message's sequence number.
1299
1341
  // See also lastMessageFromMetadata()
1300
1342
  message: explicitSchemaControl
1301
- ? { sequenceNumber: -1 }
1343
+ ? // eslint-disable-next-line import/no-deprecated
1344
+ { sequenceNumber: -1 }
1302
1345
  : message,
1303
1346
  lastMessage: explicitSchemaControl ? message : undefined,
1304
1347
  documentSchema,
@@ -1414,9 +1457,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1414
1457
  switch (opContents.type) {
1415
1458
  case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
1416
1459
  case messageTypes_js_1.ContainerMessageType.Attach:
1417
- case messageTypes_js_1.ContainerMessageType.Alias:
1460
+ case messageTypes_js_1.ContainerMessageType.Alias: {
1418
1461
  return this.channelCollection.applyStashedOp(opContents);
1419
- case messageTypes_js_1.ContainerMessageType.IdAllocation:
1462
+ }
1463
+ case messageTypes_js_1.ContainerMessageType.IdAllocation: {
1420
1464
  // IDs allocation ops in stashed state are ignored because the tip state of the compressor
1421
1465
  // is serialized into the pending state. This is done because generation of new IDs during
1422
1466
  // stashed op application (or, later, resubmit) must generate new IDs and if the compressor
@@ -1426,17 +1470,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1426
1470
  // and the runtime could filter out all ID allocation ops from the stashed state and apply them
1427
1471
  // before applying the rest of the stashed ops. This would accomplish the same thing but with
1428
1472
  // better performance in future incremental stashed state creation.
1429
- (0, internal_2.assert)(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
1473
+ (0, internal_2.assert)(this.sessionSchema.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
1430
1474
  return;
1431
- case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1475
+ }
1476
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange: {
1432
1477
  return;
1433
- case messageTypes_js_1.ContainerMessageType.BlobAttach:
1478
+ }
1479
+ case messageTypes_js_1.ContainerMessageType.BlobAttach: {
1434
1480
  return;
1435
- case messageTypes_js_1.ContainerMessageType.Rejoin:
1481
+ }
1482
+ case messageTypes_js_1.ContainerMessageType.Rejoin: {
1436
1483
  throw new Error("rejoin not expected here");
1437
- case messageTypes_js_1.ContainerMessageType.GC:
1484
+ }
1485
+ case messageTypes_js_1.ContainerMessageType.GC: {
1438
1486
  // GC op is only sent in summarizer which should never have stashed ops.
1439
1487
  throw new internal_7.LoggingError("GC op not expected to be stashed in summarizer");
1488
+ }
1440
1489
  default: {
1441
1490
  const error = getUnknownMessageTypeError(opContents.type, "applyStashedOp" /* codePath */);
1442
1491
  this.closeFn(error);
@@ -1446,7 +1495,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1446
1495
  }
1447
1496
  async loadIdCompressor() {
1448
1497
  if (this._idCompressor === undefined &&
1449
- this.idCompressorMode !== undefined &&
1498
+ this.sessionSchema.idCompressorMode !== undefined &&
1450
1499
  this._loadIdCompressor === undefined) {
1451
1500
  this._loadIdCompressor = this.createIdCompressor()
1452
1501
  .then((compressor) => {
@@ -1460,7 +1509,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1460
1509
  this._idCompressor = compressor;
1461
1510
  })
1462
1511
  .catch((error) => {
1463
- this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
1512
+ this.mc.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
1464
1513
  throw error;
1465
1514
  });
1466
1515
  }
@@ -1471,7 +1520,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1471
1520
  const currentClientId = this._audience.getSelf()?.clientId;
1472
1521
  (0, internal_2.assert)(clientId === currentClientId, 0x977 /* input clientId does not match Audience */);
1473
1522
  (0, internal_2.assert)(this.clientId === currentClientId, 0x978 /* this.clientId does not match Audience */);
1474
- if (connected && this.idCompressorMode === "delayed") {
1523
+ if (connected && this.sessionSchema.idCompressorMode === "delayed") {
1475
1524
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
1476
1525
  this.loadIdCompressor();
1477
1526
  }
@@ -1560,7 +1609,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1560
1609
  // or something different, like a system message.
1561
1610
  const hasModernRuntimeMessageEnvelope = messageCopy.type === internal_3.MessageType.Operation;
1562
1611
  const savedOp = messageCopy.metadata?.savedOp;
1563
- const logLegacyCase = (0, exports.getSingleUseLegacyLogCallback)(this.logger, messageCopy.type);
1612
+ const logLegacyCase = (0, exports.getSingleUseLegacyLogCallback)(this.mc.logger, messageCopy.type);
1564
1613
  let runtimeBatch = hasModernRuntimeMessageEnvelope || isUnpackedRuntimeMessage(messageCopy);
1565
1614
  if (runtimeBatch) {
1566
1615
  // We expect runtime messages to have JSON contents - deserialize it in place.
@@ -1645,7 +1694,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1645
1694
  }
1646
1695
  }
1647
1696
  /**
1648
- * Processes inbound message(s). It calls schedule manager according to the messages' location in the batch.
1697
+ * Processes inbound message(s). It calls delta scheduler according to the messages' location in the batch.
1649
1698
  * @param messagesWithMetadata - messages to process along with their metadata.
1650
1699
  * @param locationInBatch - Are we processing the start and/or end of a batch?
1651
1700
  * @param local - true if the messages were originally generated by the client receiving it.
@@ -1657,19 +1706,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1657
1706
  if (locationInBatch.batchStart) {
1658
1707
  const firstMessage = messagesWithMetadata[0]?.message;
1659
1708
  (0, internal_2.assert)(firstMessage !== undefined, 0xa31 /* Batch must have at least one message */);
1660
- this.scheduleManager.batchBegin(firstMessage);
1709
+ this.emit("batchBegin", firstMessage);
1661
1710
  }
1662
1711
  let error;
1663
1712
  try {
1664
1713
  if (!runtimeBatch) {
1665
- messagesWithMetadata.forEach(({ message }) => {
1714
+ for (const { message } of messagesWithMetadata) {
1666
1715
  this.ensureNoDataModelChanges(() => {
1667
1716
  this.observeNonRuntimeMessage(message);
1668
1717
  });
1669
- });
1718
+ }
1670
1719
  return;
1671
1720
  }
1672
- // Helper that updates a message's minimum sequence number to the minimum sequence number that container
1721
+ // Updates a message's minimum sequence number to the minimum sequence number that container
1673
1722
  // runtime is tracking and sets _processedClientSequenceNumber. It returns the updated message.
1674
1723
  const updateSequenceNumbers = (message) => {
1675
1724
  // Set the minimum sequence number to the containerRuntime's understanding of minimum sequence number.
@@ -1700,7 +1749,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1700
1749
  }
1701
1750
  let bunchedMessagesContent = [];
1702
1751
  let previousMessage;
1703
- // Helper that processes the previous bunch of messages.
1752
+ // Process the previous bunch of messages.
1704
1753
  const sendBunchedMessages = () => {
1705
1754
  (0, internal_2.assert)(previousMessage !== undefined, 0xa67 /* previous message must exist */);
1706
1755
  this.ensureNoDataModelChanges(() => {
@@ -1734,15 +1783,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1734
1783
  this.emit("op", message, true /* runtimeMessage */);
1735
1784
  }
1736
1785
  }
1737
- catch (e) {
1738
- error = e;
1786
+ catch (error_) {
1787
+ error = error_;
1739
1788
  throw error;
1740
1789
  }
1741
1790
  finally {
1742
1791
  if (locationInBatch.batchEnd) {
1743
1792
  const lastMessage = messagesWithMetadata[messagesWithMetadata.length - 1]?.message;
1744
1793
  (0, internal_2.assert)(lastMessage !== undefined, 0xa32 /* Batch must have at least one message */);
1745
- this.scheduleManager.batchEnd(error, lastMessage);
1794
+ this.emit("batchEnd", error, lastMessage);
1746
1795
  }
1747
1796
  }
1748
1797
  }
@@ -1792,30 +1841,39 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1792
1841
  switch (message.type) {
1793
1842
  case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
1794
1843
  case messageTypes_js_1.ContainerMessageType.Attach:
1795
- case messageTypes_js_1.ContainerMessageType.Alias:
1844
+ case messageTypes_js_1.ContainerMessageType.Alias: {
1796
1845
  // Remove the metadata from the message before sending it to the channel collection. The metadata
1797
1846
  // is added by the container runtime and is not part of the message that the channel collection and
1798
1847
  // layers below it expect.
1799
1848
  this.channelCollection.processMessages({ envelope: message, messagesContent, local });
1800
1849
  break;
1801
- case messageTypes_js_1.ContainerMessageType.BlobAttach:
1850
+ }
1851
+ case messageTypes_js_1.ContainerMessageType.BlobAttach: {
1802
1852
  this.blobManager.processBlobAttachMessage(message, local);
1803
1853
  break;
1804
- case messageTypes_js_1.ContainerMessageType.IdAllocation:
1854
+ }
1855
+ case messageTypes_js_1.ContainerMessageType.IdAllocation: {
1805
1856
  this.processIdCompressorMessages(contents, savedOp);
1806
1857
  break;
1807
- case messageTypes_js_1.ContainerMessageType.GC:
1858
+ }
1859
+ case messageTypes_js_1.ContainerMessageType.GC: {
1808
1860
  this.garbageCollector.processMessages(contents, message.timestamp, local);
1809
1861
  break;
1810
- case messageTypes_js_1.ContainerMessageType.ChunkedOp:
1862
+ }
1863
+ case messageTypes_js_1.ContainerMessageType.ChunkedOp: {
1811
1864
  // From observability POV, we should not expose the rest of the system (including "op" events on object) to these messages.
1812
1865
  // Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
1813
1866
  (0, internal_2.assert)(false, 0x93d /* should not even get here */);
1814
- case messageTypes_js_1.ContainerMessageType.Rejoin:
1867
+ }
1868
+ case messageTypes_js_1.ContainerMessageType.Rejoin: {
1815
1869
  break;
1816
- case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1817
- this.documentsSchemaController.processDocumentSchemaMessages(contents, local, message.sequenceNumber);
1870
+ }
1871
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange: {
1872
+ this.documentsSchemaController.processDocumentSchemaMessages(
1873
+ // eslint-disable-next-line import/no-deprecated
1874
+ contents, local, message.sequenceNumber);
1818
1875
  break;
1876
+ }
1819
1877
  default: {
1820
1878
  const error = getUnknownMessageTypeError(message.type, "validateAndProcessRuntimeMessage" /* codePath */, message);
1821
1879
  this.closeFn(error);
@@ -1833,7 +1891,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1833
1891
  // Some other client turned on the id compressor. If we have not turned it on,
1834
1892
  // put it in a pending queue and delay finalization.
1835
1893
  if (this._idCompressor === undefined) {
1836
- (0, internal_2.assert)(this.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
1894
+ (0, internal_2.assert)(this.sessionSchema.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
1837
1895
  this.pendingIdCompressorOps.push(range);
1838
1896
  }
1839
1897
  else {
@@ -1867,7 +1925,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1867
1925
  * Updates signal telemetry including emitting telemetry events.
1868
1926
  */
1869
1927
  processSignalForTelemetry(envelope) {
1870
- const { clientBroadcastSignalSequenceNumber } = envelope;
1928
+ const { clientBroadcastSignalSequenceNumber, contents: envelopeContents, address: envelopeAddress, } = envelope;
1871
1929
  if (clientBroadcastSignalSequenceNumber === undefined) {
1872
1930
  return;
1873
1931
  }
@@ -1905,8 +1963,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1905
1963
  };
1906
1964
  // Only log `contents.type` when address is for container to avoid
1907
1965
  // chance that contents type is customer data.
1908
- if (envelope.address === undefined) {
1909
- details.contentsType = envelope.contents.type; // Type of signal that was received out of order.
1966
+ if (envelopeAddress === undefined) {
1967
+ details.contentsType = envelopeContents.type; // Type of signal that was received out of order.
1910
1968
  }
1911
1969
  this.mc.logger.sendTelemetryEvent({
1912
1970
  eventName: "SignalOutOfOrder",
@@ -1987,8 +2045,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1987
2045
  try {
1988
2046
  checkpoint.rollback((message) => this.rollback(message.contents, message.localOpMetadata));
1989
2047
  }
1990
- catch (err) {
1991
- const error2 = (0, internal_7.wrapError)(err, (message) => {
2048
+ catch (error_) {
2049
+ const error2 = (0, internal_7.wrapError)(error_, (message) => {
1992
2050
  return internal_7.DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
1993
2051
  });
1994
2052
  this.closeFn(error2);
@@ -2049,15 +2107,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2049
2107
  return this.channelCollection.createDetachedDataStore(pkg, loadingGroupId);
2050
2108
  }
2051
2109
  async createDataStore(pkg, loadingGroupId) {
2052
- const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], undefined, // props
2053
- loadingGroupId);
2054
- return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
2055
- }
2056
- /**
2057
- * @deprecated 0.16 Issue #1537, #3631
2058
- */
2059
- async _createDataStoreWithProps(pkg, props) {
2060
- const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
2110
+ const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], loadingGroupId);
2061
2111
  return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
2062
2112
  }
2063
2113
  canSendOps() {
@@ -2084,7 +2134,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2084
2134
  get isDirty() {
2085
2135
  return this.dirtyContainer;
2086
2136
  }
2087
- isContainerMessageDirtyable({ type, contents }) {
2137
+ isContainerMessageDirtyable({ type, contents, }) {
2088
2138
  // Certain container runtime messages should not mark the container dirty such as the old built-in
2089
2139
  // AgentScheduler and Garbage collector messages.
2090
2140
  switch (type) {
@@ -2107,8 +2157,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2107
2157
  case messageTypes_js_1.ContainerMessageType.GC: {
2108
2158
  return false;
2109
2159
  }
2110
- default:
2160
+ default: {
2111
2161
  break;
2162
+ }
2112
2163
  }
2113
2164
  return true;
2114
2165
  }
@@ -2137,7 +2188,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2137
2188
  clientBroadcastSignalSequenceNumber;
2138
2189
  }
2139
2190
  // We should not track the round trip of a new signal in the case we are already tracking one.
2140
- if (clientBroadcastSignalSequenceNumber % this.defaultTelemetrySignalSampleCount === 1 &&
2191
+ if (clientBroadcastSignalSequenceNumber % defaultTelemetrySignalSampleCount === 1 &&
2141
2192
  this._signalTracking.roundTripSignalSequenceNumber === undefined) {
2142
2193
  this._signalTracking.signalTimestamp = Date.now();
2143
2194
  this._signalTracking.roundTripSignalSequenceNumber =
@@ -2203,6 +2254,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2203
2254
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
2204
2255
  return summarizeResult.summary;
2205
2256
  }
2257
+ /**
2258
+ * Builds the Summary tree including all the channels and the container state.
2259
+ *
2260
+ * @remarks - Unfortunately, this function is accessed in a non-typesafe way by a legacy first-party partner,
2261
+ * so until we can provide a proper API for their scenario, we need to ensure this function doesn't change.
2262
+ */
2206
2263
  async summarizeInternal(fullTree, trackState, telemetryContext) {
2207
2264
  const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
2208
2265
  // Wrap data store summaries in .channels subtree.
@@ -2283,8 +2340,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2283
2340
  */
2284
2341
  deleteSweepReadyNodes(sweepReadyRoutes) {
2285
2342
  const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
2286
- const deletedRoutes = this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes);
2287
- return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
2343
+ return [
2344
+ ...this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes),
2345
+ ...this.blobManager.deleteSweepReadyNodes(blobManagerRoutes),
2346
+ ];
2288
2347
  }
2289
2348
  /**
2290
2349
  * This is called to update objects that are tombstones.
@@ -2310,10 +2369,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2310
2369
  * Returns the type of the GC node. Currently, there are nodes that belong to the root ("/"), data stores or
2311
2370
  * blob manager.
2312
2371
  */
2372
+ // eslint-disable-next-line import/no-deprecated
2313
2373
  getNodeType(nodePath) {
2314
2374
  if ((0, index_js_1.isBlobPath)(nodePath)) {
2375
+ // eslint-disable-next-line import/no-deprecated
2315
2376
  return index_js_2.GCNodeType.Blob;
2316
2377
  }
2378
+ // eslint-disable-next-line import/no-deprecated
2317
2379
  return this.channelCollection.getGCNodeType(nodePath) ?? index_js_2.GCNodeType.Other;
2318
2380
  }
2319
2381
  /**
@@ -2327,13 +2389,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2327
2389
  return ["_gcRoot"];
2328
2390
  }
2329
2391
  switch (this.getNodeType(nodePath)) {
2330
- case index_js_2.GCNodeType.Blob:
2392
+ // eslint-disable-next-line import/no-deprecated
2393
+ case index_js_2.GCNodeType.Blob: {
2331
2394
  return [index_js_1.blobManagerBasePath];
2395
+ }
2396
+ // eslint-disable-next-line import/no-deprecated
2332
2397
  case index_js_2.GCNodeType.DataStore:
2333
- case index_js_2.GCNodeType.SubDataStore:
2398
+ // eslint-disable-next-line import/no-deprecated
2399
+ case index_js_2.GCNodeType.SubDataStore: {
2334
2400
  return this.channelCollection.getDataStorePackagePath(nodePath);
2335
- default:
2401
+ }
2402
+ default: {
2336
2403
  (0, internal_2.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
2404
+ }
2337
2405
  }
2338
2406
  }
2339
2407
  /**
@@ -2395,8 +2463,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2395
2463
  * op processing, updating SummarizerNode state tracking, and garbage collection.
2396
2464
  * @param options - options controlling how the summary is generated or submitted
2397
2465
  */
2466
+ // eslint-disable-next-line import/no-deprecated
2398
2467
  async submitSummary(options) {
2399
- const { fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
2468
+ const { cancellationToken, fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
2400
2469
  // The summary number for this summary. This will be updated during the summary process, so get it now and
2401
2470
  // use it for all events logged during this summary.
2402
2471
  const summaryNumber = this.nextSummaryNumber;
@@ -2480,7 +2549,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2480
2549
  eventName: "LatestSummaryRefSeqNumMismatch",
2481
2550
  details: {
2482
2551
  ...startSummaryResult,
2483
- mismatchNumbers: Array.from(startSummaryResult.mismatchNumbers),
2552
+ mismatchNumbers: [...startSummaryResult.mismatchNumbers],
2484
2553
  },
2485
2554
  });
2486
2555
  if (shouldValidatePreSummaryState && !finalAttempt) {
@@ -2500,7 +2569,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2500
2569
  // summarizer to reconnect in the future.
2501
2570
  // Also checking for cancellation is a must as summary process may be abandoned for other reasons,
2502
2571
  // like loss of connectivity for main (interactive) client.
2503
- if (options.cancellationToken.cancelled) {
2572
+ if (cancellationToken.cancelled) {
2504
2573
  return { continue: false, error: "disconnected" };
2505
2574
  }
2506
2575
  // That said, we rely on submitSystemMessage() that today only works in connected state.
@@ -2613,7 +2682,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2613
2682
  };
2614
2683
  let handle;
2615
2684
  try {
2616
- handle = await this.storage.uploadSummaryWithContext(summarizeResult.summary, summaryContext);
2685
+ handle = await this.storage.uploadSummaryWithContext(summaryTree, summaryContext);
2617
2686
  }
2618
2687
  catch (error) {
2619
2688
  return {
@@ -2735,13 +2804,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2735
2804
  return this.pendingMessagesCount !== 0;
2736
2805
  }
2737
2806
  updateDocumentDirtyState(dirty) {
2738
- if (this.attachState !== container_definitions_1.AttachState.Attached) {
2739
- (0, internal_2.assert)(dirty, 0x3d2 /* Non-attached container is dirty */);
2740
- }
2741
- else {
2807
+ if (this.attachState === container_definitions_1.AttachState.Attached) {
2742
2808
  // Other way is not true = see this.isContainerMessageDirtyable()
2743
2809
  (0, internal_2.assert)(!dirty || this.hasPendingMessages(), 0x3d3 /* if doc is dirty, there has to be pending ops */);
2744
2810
  }
2811
+ else {
2812
+ (0, internal_2.assert)(dirty, 0x3d2 /* Non-attached container is dirty */);
2813
+ }
2745
2814
  if (this.dirtyContainer === dirty) {
2746
2815
  return;
2747
2816
  }
@@ -2750,7 +2819,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2750
2819
  this.emit(dirty ? "dirty" : "saved");
2751
2820
  }
2752
2821
  }
2753
- submitMessage(type, contents, localOpMetadata = undefined) {
2822
+ submitMessage(type,
2823
+ // TODO: better typing
2824
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
2825
+ contents, localOpMetadata = undefined) {
2826
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
2754
2827
  this.submit({ type, contents }, localOpMetadata);
2755
2828
  }
2756
2829
  async uploadBlob(blob, signal) {
@@ -2799,7 +2872,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2799
2872
  // on this callback to do actual sending.
2800
2873
  const schemaChangeMessage = this.documentsSchemaController.maybeSendSchemaMessage();
2801
2874
  if (schemaChangeMessage) {
2802
- this.logger.sendTelemetryEvent({
2875
+ this.mc.logger.sendTelemetryEvent({
2803
2876
  eventName: "SchemaChangeProposal",
2804
2877
  refSeq: schemaChangeMessage.refSeq,
2805
2878
  version: schemaChangeMessage.version,
@@ -2851,6 +2924,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2851
2924
  return;
2852
2925
  }
2853
2926
  this.flushTaskExists = true;
2927
+ // TODO: hoist this out of the function scope to save unnecessary allocations
2928
+ // eslint-disable-next-line unicorn/consistent-function-scoping -- Separate `flush` method already exists in outer scope
2854
2929
  const flush = () => {
2855
2930
  this.flushTaskExists = false;
2856
2931
  try {
@@ -2861,22 +2936,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2861
2936
  }
2862
2937
  };
2863
2938
  switch (this.flushMode) {
2864
- case internal_5.FlushMode.TurnBased:
2939
+ case internal_5.FlushMode.TurnBased: {
2865
2940
  // When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
2866
2941
  // batch at the end of the turn
2867
2942
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
2868
2943
  Promise.resolve().then(flush);
2869
2944
  break;
2945
+ }
2870
2946
  // FlushModeExperimental is experimental and not exposed directly in the runtime APIs
2871
- case internal_5.FlushModeExperimental.Async:
2947
+ case internal_5.FlushModeExperimental.Async: {
2872
2948
  // When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
2873
2949
  // batch when all micro-tasks are complete.
2874
2950
  // Compared to TurnBased, this flush mode will capture more ops into the same batch.
2875
2951
  setTimeout(flush, 0);
2876
2952
  break;
2877
- default:
2953
+ }
2954
+ default: {
2878
2955
  (0, internal_2.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
2879
2956
  break;
2957
+ }
2880
2958
  }
2881
2959
  }
2882
2960
  submitSummaryMessage(contents, referenceSequenceNumber) {
@@ -2884,10 +2962,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2884
2962
  (0, internal_2.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
2885
2963
  // System message should not be sent in the middle of the batch.
2886
2964
  (0, internal_2.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
2887
- // back-compat: ADO #1385: Make this call unconditional in the future
2888
- return this.submitSummaryFn !== undefined
2889
- ? this.submitSummaryFn(contents, referenceSequenceNumber)
2890
- : this.submitFn(internal_3.MessageType.Summarize, contents, false);
2965
+ return this.submitSummaryFn(contents, referenceSequenceNumber);
2891
2966
  }
2892
2967
  /**
2893
2968
  * Throw an error if the runtime is closed. Methods that are expected to potentially
@@ -2927,15 +3002,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2927
3002
  * @param localOpMetadata - The local metadata associated with the original message.
2928
3003
  */
2929
3004
  reSubmitCore(message, localOpMetadata, opMetadata) {
2930
- (0, internal_2.assert)(!this.isSummarizerClient, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
3005
+ (0, internal_2.assert)(this._summarizer === undefined, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
2931
3006
  switch (message.type) {
2932
3007
  case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
2933
3008
  case messageTypes_js_1.ContainerMessageType.Attach:
2934
- case messageTypes_js_1.ContainerMessageType.Alias:
3009
+ case messageTypes_js_1.ContainerMessageType.Alias: {
2935
3010
  // For Operations, call resubmitDataStoreOp which will find the right store
2936
3011
  // and trigger resubmission on it.
2937
3012
  this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
2938
3013
  break;
3014
+ }
2939
3015
  case messageTypes_js_1.ContainerMessageType.IdAllocation: {
2940
3016
  // Allocation ops are never resubmitted/rebased. This is because they require special handling to
2941
3017
  // avoid being submitted out of order. For example, if the pending state manager contained
@@ -2946,20 +3022,24 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2946
3022
  // all pending IDs. The resubmitted allocation ops are then ignored here.
2947
3023
  break;
2948
3024
  }
2949
- case messageTypes_js_1.ContainerMessageType.BlobAttach:
3025
+ case messageTypes_js_1.ContainerMessageType.BlobAttach: {
2950
3026
  this.blobManager.reSubmit(opMetadata);
2951
3027
  break;
2952
- case messageTypes_js_1.ContainerMessageType.Rejoin:
3028
+ }
3029
+ case messageTypes_js_1.ContainerMessageType.Rejoin: {
2953
3030
  this.submit(message);
2954
3031
  break;
2955
- case messageTypes_js_1.ContainerMessageType.GC:
3032
+ }
3033
+ case messageTypes_js_1.ContainerMessageType.GC: {
2956
3034
  this.submit(message);
2957
3035
  break;
2958
- case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
3036
+ }
3037
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange: {
2959
3038
  // There is no need to resend this message. Document schema controller will properly resend it again (if needed)
2960
3039
  // on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
2961
3040
  // send any ops, as some other client already changed schema.
2962
3041
  break;
3042
+ }
2963
3043
  default: {
2964
3044
  const error = getUnknownMessageTypeError(message.type, "reSubmitCore" /* codePath */);
2965
3045
  this.closeFn(error);
@@ -2971,16 +3051,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2971
3051
  // Need to parse from string for back-compat
2972
3052
  const { type, contents } = this.parseLocalOpContent(content);
2973
3053
  switch (type) {
2974
- case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
3054
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp: {
2975
3055
  // For operations, call rollbackDataStoreOp which will find the right store
2976
3056
  // and trigger rollback on it.
2977
3057
  this.channelCollection.rollback(type, contents, localOpMetadata);
2978
3058
  break;
2979
- default:
3059
+ }
3060
+ default: {
2980
3061
  throw new Error(`Can't rollback ${type}`);
3062
+ }
2981
3063
  }
2982
3064
  }
2983
- /** Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck */
3065
+ /**
3066
+ * Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck
3067
+ */
3068
+ // eslint-disable-next-line import/no-deprecated
2984
3069
  async refreshLatestSummaryAck(options) {
2985
3070
  const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
2986
3071
  // proposalHandle is always passed from RunningSummarizer.
@@ -3050,15 +3135,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
3050
3135
  snapshotTree = snapshot.snapshotTree;
3051
3136
  }
3052
3137
  else {
3053
- const versions = await this.storage.getVersions(null, 1, scenarioName, internal_3.FetchSource.noCache);
3138
+ const versions = await this.storage.getVersions(
3139
+ // eslint-disable-next-line unicorn/no-null
3140
+ null, 1, scenarioName, internal_3.FetchSource.noCache);
3054
3141
  (0, internal_2.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
3055
3142
  snapshotTree = await this.storage.getSnapshotTree(versions[0]);
3056
3143
  (0, internal_2.assert)(!!snapshotTree, 0x138 /* "Failed to get snapshot from storage" */);
3057
3144
  props.snapshotVersion = versions[0].id;
3058
3145
  }
3059
3146
  props.getSnapshotDuration = trace.trace().duration;
3060
- const readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
3061
- const snapshotRefSeq = await (0, internal_6.seqFromTree)(snapshotTree, readAndParseBlob);
3147
+ const snapshotRefSeq = await (0, internal_6.seqFromTree)(snapshotTree, this.readAndParseBlob);
3062
3148
  props.snapshotRefSeq = snapshotRefSeq;
3063
3149
  props.newerSnapshotPresent = snapshotRefSeq >= targetRefSeq;
3064
3150
  perfEvent.end({ details: props });
@@ -3111,32 +3197,32 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
3111
3197
  : internal_7.PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
3112
3198
  }
3113
3199
  summarizeOnDemand(options) {
3114
- if (this.isSummarizerClient) {
3115
- return this.summarizer.summarizeOnDemand(options);
3200
+ if (this._summarizer !== undefined) {
3201
+ return this._summarizer.summarizeOnDemand(options);
3116
3202
  }
3117
- else if (this.summaryManager !== undefined) {
3118
- return this.summaryManager.summarizeOnDemand(options);
3119
- }
3120
- else {
3203
+ else if (this.summaryManager === undefined) {
3121
3204
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
3122
3205
  // disableSummaries is turned on. We are throwing instead of returning a failure here,
3123
3206
  // because it is a misuse of the API rather than an expected failure.
3124
3207
  throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
3125
3208
  }
3209
+ else {
3210
+ return this.summaryManager.summarizeOnDemand(options);
3211
+ }
3126
3212
  }
3127
3213
  enqueueSummarize(options) {
3128
- if (this.isSummarizerClient) {
3129
- return this.summarizer.enqueueSummarize(options);
3130
- }
3131
- else if (this.summaryManager !== undefined) {
3132
- return this.summaryManager.enqueueSummarize(options);
3214
+ if (this._summarizer !== undefined) {
3215
+ return this._summarizer.enqueueSummarize(options);
3133
3216
  }
3134
- else {
3217
+ else if (this.summaryManager === undefined) {
3135
3218
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
3136
3219
  // generateSummaries is turned off. We are throwing instead of returning a failure here,
3137
3220
  // because it is a misuse of the API rather than an expected failure.
3138
3221
  throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
3139
3222
  }
3223
+ else {
3224
+ return this.summaryManager.enqueueSummarize(options);
3225
+ }
3140
3226
  }
3141
3227
  /**
3142
3228
  * Forms a function that will create and retrieve a Summarizer.