@fluidframework/container-runtime 2.20.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 (333) hide show
  1. package/.eslintrc.cjs +36 -6
  2. package/CHANGELOG.md +38 -0
  3. package/api-report/container-runtime.legacy.alpha.api.md +31 -31
  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.map +1 -1
  9. package/dist/blobManager/blobManager.js +14 -11
  10. package/dist/blobManager/blobManager.js.map +1 -1
  11. package/dist/blobManager/blobManagerSnapSum.d.ts +1 -0
  12. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  13. package/dist/blobManager/blobManagerSnapSum.js +7 -5
  14. package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
  15. package/dist/channelCollection.d.ts.map +1 -1
  16. package/dist/channelCollection.js +63 -41
  17. package/dist/channelCollection.js.map +1 -1
  18. package/dist/connectionTelemetry.d.ts +2 -2
  19. package/dist/connectionTelemetry.d.ts.map +1 -1
  20. package/dist/connectionTelemetry.js +4 -4
  21. package/dist/connectionTelemetry.js.map +1 -1
  22. package/dist/containerRuntime.d.ts +14 -30
  23. package/dist/containerRuntime.d.ts.map +1 -1
  24. package/dist/containerRuntime.js +264 -194
  25. package/dist/containerRuntime.js.map +1 -1
  26. package/dist/dataStore.js +6 -3
  27. package/dist/dataStore.js.map +1 -1
  28. package/dist/dataStoreContext.d.ts.map +1 -1
  29. package/dist/dataStoreContext.js +16 -11
  30. package/dist/dataStoreContext.js.map +1 -1
  31. package/dist/dataStoreContexts.d.ts.map +1 -1
  32. package/dist/dataStoreContexts.js +1 -0
  33. package/dist/dataStoreContexts.js.map +1 -1
  34. package/dist/deltaScheduler.d.ts.map +1 -1
  35. package/dist/deltaScheduler.js +5 -5
  36. package/dist/deltaScheduler.js.map +1 -1
  37. package/dist/gc/garbageCollection.d.ts.map +1 -1
  38. package/dist/gc/garbageCollection.js +36 -14
  39. package/dist/gc/garbageCollection.js.map +1 -1
  40. package/dist/gc/gcConfigs.d.ts.map +1 -1
  41. package/dist/gc/gcConfigs.js +2 -0
  42. package/dist/gc/gcConfigs.js.map +1 -1
  43. package/dist/gc/gcDefinitions.d.ts +8 -0
  44. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  45. package/dist/gc/gcDefinitions.js +1 -0
  46. package/dist/gc/gcDefinitions.js.map +1 -1
  47. package/dist/gc/gcHelpers.d.ts.map +1 -1
  48. package/dist/gc/gcHelpers.js +8 -5
  49. package/dist/gc/gcHelpers.js.map +1 -1
  50. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  51. package/dist/gc/gcSummaryStateTracker.js +2 -1
  52. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  53. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  54. package/dist/gc/gcTelemetry.js +29 -15
  55. package/dist/gc/gcTelemetry.js.map +1 -1
  56. package/dist/inboundBatchAggregator.js +3 -3
  57. package/dist/inboundBatchAggregator.js.map +1 -1
  58. package/dist/layerCompatState.d.ts +19 -0
  59. package/dist/layerCompatState.d.ts.map +1 -0
  60. package/dist/layerCompatState.js +64 -0
  61. package/dist/layerCompatState.js.map +1 -0
  62. package/dist/messageTypes.d.ts.map +1 -1
  63. package/dist/messageTypes.js.map +1 -1
  64. package/dist/opLifecycle/duplicateBatchDetector.js +2 -2
  65. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  66. package/dist/opLifecycle/opCompressor.d.ts +3 -2
  67. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  68. package/dist/opLifecycle/opCompressor.js +13 -19
  69. package/dist/opLifecycle/opCompressor.js.map +1 -1
  70. package/dist/opLifecycle/opDecompressor.d.ts +3 -0
  71. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  72. package/dist/opLifecycle/opDecompressor.js +4 -1
  73. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  74. package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
  75. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  76. package/dist/opLifecycle/opGroupingManager.js +5 -3
  77. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  78. package/dist/opLifecycle/opSplitter.d.ts +13 -10
  79. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  80. package/dist/opLifecycle/opSplitter.js +14 -11
  81. package/dist/opLifecycle/opSplitter.js.map +1 -1
  82. package/dist/opLifecycle/outbox.d.ts +3 -3
  83. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  84. package/dist/opLifecycle/outbox.js +11 -15
  85. package/dist/opLifecycle/outbox.js.map +1 -1
  86. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  87. package/dist/opLifecycle/remoteMessageProcessor.js +3 -1
  88. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  89. package/dist/packageVersion.d.ts +1 -1
  90. package/dist/packageVersion.js +1 -1
  91. package/dist/packageVersion.js.map +1 -1
  92. package/dist/pendingStateManager.d.ts +3 -4
  93. package/dist/pendingStateManager.d.ts.map +1 -1
  94. package/dist/pendingStateManager.js +11 -10
  95. package/dist/pendingStateManager.js.map +1 -1
  96. package/dist/summary/documentSchema.d.ts +7 -0
  97. package/dist/summary/documentSchema.d.ts.map +1 -1
  98. package/dist/summary/documentSchema.js +6 -4
  99. package/dist/summary/documentSchema.js.map +1 -1
  100. package/dist/summary/orderedClientElection.d.ts +1 -0
  101. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  102. package/dist/summary/orderedClientElection.js +13 -11
  103. package/dist/summary/orderedClientElection.js.map +1 -1
  104. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -0
  105. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  106. package/dist/summary/runWhileConnectedCoordinator.js +7 -2
  107. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  108. package/dist/summary/runningSummarizer.d.ts +2 -2
  109. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  110. package/dist/summary/runningSummarizer.js +38 -17
  111. package/dist/summary/runningSummarizer.js.map +1 -1
  112. package/dist/summary/summarizer.d.ts +1 -0
  113. package/dist/summary/summarizer.d.ts.map +1 -1
  114. package/dist/summary/summarizer.js +18 -9
  115. package/dist/summary/summarizer.js.map +1 -1
  116. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  117. package/dist/summary/summarizerClientElection.js +1 -0
  118. package/dist/summary/summarizerClientElection.js.map +1 -1
  119. package/dist/summary/summarizerHeuristics.js +1 -1
  120. package/dist/summary/summarizerHeuristics.js.map +1 -1
  121. package/dist/summary/summarizerNode/index.d.ts.map +1 -1
  122. package/dist/summary/summarizerNode/index.js.map +1 -1
  123. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  124. package/dist/summary/summarizerNode/summarizerNode.js +30 -31
  125. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  126. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
  127. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
  128. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  129. package/dist/summary/summarizerTypes.d.ts +7 -0
  130. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  131. package/dist/summary/summarizerTypes.js.map +1 -1
  132. package/dist/summary/summaryCollection.d.ts +3 -4
  133. package/dist/summary/summaryCollection.d.ts.map +1 -1
  134. package/dist/summary/summaryCollection.js +9 -6
  135. package/dist/summary/summaryCollection.js.map +1 -1
  136. package/dist/summary/summaryFormat.d.ts +4 -1
  137. package/dist/summary/summaryFormat.d.ts.map +1 -1
  138. package/dist/summary/summaryFormat.js +3 -2
  139. package/dist/summary/summaryFormat.js.map +1 -1
  140. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  141. package/dist/summary/summaryGenerator.js +19 -8
  142. package/dist/summary/summaryGenerator.js.map +1 -1
  143. package/dist/summary/summaryManager.d.ts.map +1 -1
  144. package/dist/summary/summaryManager.js +12 -9
  145. package/dist/summary/summaryManager.js.map +1 -1
  146. package/lib/batchTracker.d.ts +1 -2
  147. package/lib/batchTracker.d.ts.map +1 -1
  148. package/lib/batchTracker.js +2 -2
  149. package/lib/batchTracker.js.map +1 -1
  150. package/lib/blobManager/blobManager.d.ts.map +1 -1
  151. package/lib/blobManager/blobManager.js +14 -11
  152. package/lib/blobManager/blobManager.js.map +1 -1
  153. package/lib/blobManager/blobManagerSnapSum.d.ts +1 -0
  154. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  155. package/lib/blobManager/blobManagerSnapSum.js +7 -5
  156. package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
  157. package/lib/channelCollection.d.ts.map +1 -1
  158. package/lib/channelCollection.js +66 -42
  159. package/lib/channelCollection.js.map +1 -1
  160. package/lib/connectionTelemetry.d.ts +2 -2
  161. package/lib/connectionTelemetry.d.ts.map +1 -1
  162. package/lib/connectionTelemetry.js +5 -5
  163. package/lib/connectionTelemetry.js.map +1 -1
  164. package/lib/containerRuntime.d.ts +14 -30
  165. package/lib/containerRuntime.d.ts.map +1 -1
  166. package/lib/containerRuntime.js +271 -196
  167. package/lib/containerRuntime.js.map +1 -1
  168. package/lib/dataStore.js +6 -3
  169. package/lib/dataStore.js.map +1 -1
  170. package/lib/dataStoreContext.d.ts.map +1 -1
  171. package/lib/dataStoreContext.js +16 -11
  172. package/lib/dataStoreContext.js.map +1 -1
  173. package/lib/dataStoreContexts.d.ts.map +1 -1
  174. package/lib/dataStoreContexts.js +1 -0
  175. package/lib/dataStoreContexts.js.map +1 -1
  176. package/lib/deltaScheduler.d.ts.map +1 -1
  177. package/lib/deltaScheduler.js +6 -6
  178. package/lib/deltaScheduler.js.map +1 -1
  179. package/lib/gc/garbageCollection.d.ts.map +1 -1
  180. package/lib/gc/garbageCollection.js +39 -15
  181. package/lib/gc/garbageCollection.js.map +1 -1
  182. package/lib/gc/gcConfigs.d.ts.map +1 -1
  183. package/lib/gc/gcConfigs.js +2 -0
  184. package/lib/gc/gcConfigs.js.map +1 -1
  185. package/lib/gc/gcDefinitions.d.ts +8 -0
  186. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  187. package/lib/gc/gcDefinitions.js +1 -0
  188. package/lib/gc/gcDefinitions.js.map +1 -1
  189. package/lib/gc/gcHelpers.d.ts.map +1 -1
  190. package/lib/gc/gcHelpers.js +8 -5
  191. package/lib/gc/gcHelpers.js.map +1 -1
  192. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  193. package/lib/gc/gcSummaryStateTracker.js +2 -1
  194. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  195. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  196. package/lib/gc/gcTelemetry.js +32 -16
  197. package/lib/gc/gcTelemetry.js.map +1 -1
  198. package/lib/inboundBatchAggregator.js +4 -4
  199. package/lib/inboundBatchAggregator.js.map +1 -1
  200. package/lib/layerCompatState.d.ts +19 -0
  201. package/lib/layerCompatState.d.ts.map +1 -0
  202. package/lib/layerCompatState.js +60 -0
  203. package/lib/layerCompatState.js.map +1 -0
  204. package/lib/messageTypes.d.ts.map +1 -1
  205. package/lib/messageTypes.js.map +1 -1
  206. package/lib/opLifecycle/duplicateBatchDetector.js +2 -2
  207. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  208. package/lib/opLifecycle/opCompressor.d.ts +3 -2
  209. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  210. package/lib/opLifecycle/opCompressor.js +13 -19
  211. package/lib/opLifecycle/opCompressor.js.map +1 -1
  212. package/lib/opLifecycle/opDecompressor.d.ts +3 -0
  213. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  214. package/lib/opLifecycle/opDecompressor.js +4 -1
  215. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  216. package/lib/opLifecycle/opGroupingManager.d.ts +1 -1
  217. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  218. package/lib/opLifecycle/opGroupingManager.js +5 -3
  219. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  220. package/lib/opLifecycle/opSplitter.d.ts +13 -10
  221. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  222. package/lib/opLifecycle/opSplitter.js +14 -11
  223. package/lib/opLifecycle/opSplitter.js.map +1 -1
  224. package/lib/opLifecycle/outbox.d.ts +3 -3
  225. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  226. package/lib/opLifecycle/outbox.js +11 -15
  227. package/lib/opLifecycle/outbox.js.map +1 -1
  228. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  229. package/lib/opLifecycle/remoteMessageProcessor.js +3 -1
  230. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  231. package/lib/packageVersion.d.ts +1 -1
  232. package/lib/packageVersion.js +1 -1
  233. package/lib/packageVersion.js.map +1 -1
  234. package/lib/pendingStateManager.d.ts +3 -4
  235. package/lib/pendingStateManager.d.ts.map +1 -1
  236. package/lib/pendingStateManager.js +12 -11
  237. package/lib/pendingStateManager.js.map +1 -1
  238. package/lib/summary/documentSchema.d.ts +7 -0
  239. package/lib/summary/documentSchema.d.ts.map +1 -1
  240. package/lib/summary/documentSchema.js +6 -4
  241. package/lib/summary/documentSchema.js.map +1 -1
  242. package/lib/summary/orderedClientElection.d.ts +1 -0
  243. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  244. package/lib/summary/orderedClientElection.js +13 -11
  245. package/lib/summary/orderedClientElection.js.map +1 -1
  246. package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -0
  247. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  248. package/lib/summary/runWhileConnectedCoordinator.js +7 -2
  249. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  250. package/lib/summary/runningSummarizer.d.ts +2 -2
  251. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  252. package/lib/summary/runningSummarizer.js +38 -17
  253. package/lib/summary/runningSummarizer.js.map +1 -1
  254. package/lib/summary/summarizer.d.ts +1 -0
  255. package/lib/summary/summarizer.d.ts.map +1 -1
  256. package/lib/summary/summarizer.js +18 -9
  257. package/lib/summary/summarizer.js.map +1 -1
  258. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  259. package/lib/summary/summarizerClientElection.js +1 -0
  260. package/lib/summary/summarizerClientElection.js.map +1 -1
  261. package/lib/summary/summarizerHeuristics.js +1 -1
  262. package/lib/summary/summarizerHeuristics.js.map +1 -1
  263. package/lib/summary/summarizerNode/index.d.ts.map +1 -1
  264. package/lib/summary/summarizerNode/index.js.map +1 -1
  265. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  266. package/lib/summary/summarizerNode/summarizerNode.js +30 -31
  267. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  268. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
  269. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
  270. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  271. package/lib/summary/summarizerTypes.d.ts +7 -0
  272. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  273. package/lib/summary/summarizerTypes.js.map +1 -1
  274. package/lib/summary/summaryCollection.d.ts +3 -4
  275. package/lib/summary/summaryCollection.d.ts.map +1 -1
  276. package/lib/summary/summaryCollection.js +9 -6
  277. package/lib/summary/summaryCollection.js.map +1 -1
  278. package/lib/summary/summaryFormat.d.ts +4 -1
  279. package/lib/summary/summaryFormat.d.ts.map +1 -1
  280. package/lib/summary/summaryFormat.js +2 -2
  281. package/lib/summary/summaryFormat.js.map +1 -1
  282. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  283. package/lib/summary/summaryGenerator.js +19 -8
  284. package/lib/summary/summaryGenerator.js.map +1 -1
  285. package/lib/summary/summaryManager.d.ts.map +1 -1
  286. package/lib/summary/summaryManager.js +12 -9
  287. package/lib/summary/summaryManager.js.map +1 -1
  288. package/package.json +21 -43
  289. package/src/batchTracker.ts +3 -3
  290. package/src/blobManager/blobManager.ts +16 -14
  291. package/src/blobManager/blobManagerSnapSum.ts +8 -8
  292. package/src/channelCollection.ts +63 -44
  293. package/src/connectionTelemetry.ts +12 -6
  294. package/src/containerRuntime.ts +306 -235
  295. package/src/dataStore.ts +6 -3
  296. package/src/dataStoreContext.ts +16 -16
  297. package/src/dataStoreContexts.ts +1 -0
  298. package/src/deltaScheduler.ts +6 -6
  299. package/src/gc/garbageCollection.ts +47 -20
  300. package/src/gc/gcConfigs.ts +9 -1
  301. package/src/gc/gcDefinitions.ts +12 -0
  302. package/src/gc/gcHelpers.ts +9 -4
  303. package/src/gc/gcSummaryStateTracker.ts +3 -1
  304. package/src/gc/gcTelemetry.ts +26 -11
  305. package/src/inboundBatchAggregator.ts +4 -4
  306. package/src/layerCompatState.ts +75 -0
  307. package/src/messageTypes.ts +2 -0
  308. package/src/opLifecycle/README.md +43 -34
  309. package/src/opLifecycle/duplicateBatchDetector.ts +2 -2
  310. package/src/opLifecycle/opCompressor.ts +16 -23
  311. package/src/opLifecycle/opDecompressor.ts +4 -1
  312. package/src/opLifecycle/opGroupingManager.ts +5 -4
  313. package/src/opLifecycle/opSplitter.ts +14 -11
  314. package/src/opLifecycle/outbox.ts +13 -20
  315. package/src/opLifecycle/remoteMessageProcessor.ts +3 -1
  316. package/src/packageVersion.ts +1 -1
  317. package/src/pendingStateManager.ts +15 -10
  318. package/src/summary/documentSchema.ts +11 -4
  319. package/src/summary/orderedClientElection.ts +14 -11
  320. package/src/summary/runWhileConnectedCoordinator.ts +6 -0
  321. package/src/summary/runningSummarizer.ts +43 -19
  322. package/src/summary/summarizer.ts +24 -11
  323. package/src/summary/summarizerClientElection.ts +2 -0
  324. package/src/summary/summarizerHeuristics.ts +1 -1
  325. package/src/summary/summarizerNode/index.ts +1 -0
  326. package/src/summary/summarizerNode/summarizerNode.ts +32 -31
  327. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +4 -4
  328. package/src/summary/summarizerTypes.ts +7 -0
  329. package/src/summary/summaryCollection.ts +19 -8
  330. package/src/summary/summaryFormat.ts +10 -5
  331. package/src/summary/summaryGenerator.ts +25 -10
  332. package/src/summary/summaryManager.ts +14 -12
  333. package/container-runtime.test-files.tar +0 -0
@@ -3,7 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
6
+ import {
7
+ Trace,
8
+ TypedEventEmitter,
9
+ type ILayerCompatDetails,
10
+ type IProvideLayerCompatDetails,
11
+ } from "@fluid-internal/client-utils";
7
12
  import {
8
13
  AttachState,
9
14
  IAudience,
@@ -12,7 +17,6 @@ import {
12
17
  type IAudienceEvents,
13
18
  } from "@fluidframework/container-definitions";
14
19
  import {
15
- IBatchMessage,
16
20
  IContainerContext,
17
21
  IGetPendingLocalStateProps,
18
22
  ILoader,
@@ -34,6 +38,7 @@ import {
34
38
  ITelemetryBaseLogger,
35
39
  } from "@fluidframework/core-interfaces";
36
40
  import {
41
+ type IErrorBase,
37
42
  IFluidHandleContext,
38
43
  type IFluidHandleInternal,
39
44
  IProvideFluidHandleContext,
@@ -142,6 +147,7 @@ import {
142
147
  blobsTreeName,
143
148
  isBlobPath,
144
149
  loadBlobManagerLoadInfo,
150
+ // eslint-disable-next-line import/no-deprecated
145
151
  type IBlobManagerLoadInfo,
146
152
  } from "./blobManager/index.js";
147
153
  import {
@@ -159,15 +165,18 @@ import {
159
165
  } from "./deltaManagerProxies.js";
160
166
  import { DeltaScheduler } from "./deltaScheduler.js";
161
167
  import {
168
+ // eslint-disable-next-line import/no-deprecated
162
169
  GCNodeType,
163
170
  GarbageCollector,
164
171
  IGCRuntimeOptions,
172
+ // eslint-disable-next-line import/no-deprecated
165
173
  IGCStats,
166
174
  IGarbageCollector,
167
175
  gcGenerationOptionName,
168
176
  type GarbageCollectionMessage,
169
177
  } from "./gc/index.js";
170
178
  import { InboundBatchAggregator } from "./inboundBatchAggregator.js";
179
+ import { RuntimeCompatDetails, validateLoaderCompatibility } from "./layerCompatState.js";
171
180
  import {
172
181
  ContainerMessageType,
173
182
  type ContainerRuntimeDocumentSchemaMessage,
@@ -202,26 +211,38 @@ import {
202
211
  PendingStateManager,
203
212
  } from "./pendingStateManager.js";
204
213
  import {
214
+ // eslint-disable-next-line import/no-deprecated
205
215
  DocumentsSchemaController,
206
216
  EnqueueSummarizeResult,
207
217
  IBaseSummarizeResult,
218
+ // eslint-disable-next-line import/no-deprecated
208
219
  IConnectableRuntime,
220
+ // eslint-disable-next-line import/no-deprecated
209
221
  IContainerRuntimeMetadata,
222
+ // eslint-disable-next-line import/no-deprecated
210
223
  ICreateContainerMetadata,
224
+ // eslint-disable-next-line import/no-deprecated
211
225
  type IDocumentSchemaChangeMessage,
226
+ // eslint-disable-next-line import/no-deprecated
212
227
  type IDocumentSchemaCurrent,
213
228
  IEnqueueSummarizeOptions,
214
229
  IGenerateSummaryTreeResult,
215
230
  IGeneratedSummaryStats,
216
231
  IOnDemandSummarizeOptions,
232
+ // eslint-disable-next-line import/no-deprecated
217
233
  IRefreshSummaryAckOptions,
218
234
  IRootSummarizerNodeWithGC,
235
+ // eslint-disable-next-line import/no-deprecated
219
236
  ISerializedElection,
237
+ // eslint-disable-next-line import/no-deprecated
220
238
  ISubmitSummaryOptions,
221
239
  ISummarizeResults,
222
240
  ISummarizer,
241
+ // eslint-disable-next-line import/no-deprecated
223
242
  ISummarizerInternalsProvider,
243
+ // eslint-disable-next-line import/no-deprecated
224
244
  ISummarizerRuntime,
245
+ // eslint-disable-next-line import/no-deprecated
225
246
  ISummaryMetadataMessage,
226
247
  IdCompressorMode,
227
248
  OrderedClientCollection,
@@ -229,6 +250,7 @@ import {
229
250
  RetriableSummaryError,
230
251
  RunWhileConnectedCoordinator,
231
252
  SubmitSummaryResult,
253
+ // eslint-disable-next-line import/no-deprecated
232
254
  Summarizer,
233
255
  SummarizerClientElection,
234
256
  SummaryCollection,
@@ -244,6 +266,7 @@ import {
244
266
  rootHasIsolatedChannels,
245
267
  summarizerClientType,
246
268
  wrapSummaryInChannelsTree,
269
+ // eslint-disable-next-line import/no-deprecated
247
270
  type IDocumentSchemaFeatures,
248
271
  } from "./summary/index.js";
249
272
  import { Throttler, formExponentialFn } from "./throttler.js";
@@ -389,6 +412,12 @@ export type ISummaryConfiguration =
389
412
  | ISummaryConfigurationDisableHeuristics
390
413
  | ISummaryConfigurationHeuristics;
391
414
 
415
+ export function isSummariesDisabled(
416
+ config: ISummaryConfiguration,
417
+ ): config is ISummaryConfigurationDisableSummarizer {
418
+ return config.state === "disabled";
419
+ }
420
+
392
421
  /**
393
422
  * @legacy
394
423
  * @alpha
@@ -414,7 +443,7 @@ export const DefaultSummaryConfiguration: ISummaryConfiguration = {
414
443
 
415
444
  nonRuntimeOpWeight: 0.1,
416
445
 
417
- runtimeOpWeight: 1.0,
446
+ runtimeOpWeight: 1,
418
447
 
419
448
  nonRuntimeHeuristicThreshold: 20,
420
449
  };
@@ -560,6 +589,7 @@ export interface IContainerRuntimeOptionsInternal extends IContainerRuntimeOptio
560
589
  * Error responses when requesting a deleted object will have this header set to true
561
590
  * @legacy
562
591
  * @alpha
592
+ * @deprecated This type will be moved to internal in 2.30. External usage is not necessary or supported.
563
593
  */
564
594
  export const DeletedResponseHeaderKey = "wasDeleted";
565
595
  /**
@@ -611,7 +641,7 @@ export enum CompressionAlgorithms {
611
641
  * @alpha
612
642
  */
613
643
  export const disabledCompressionConfig: ICompressionRuntimeOptions = {
614
- minimumBatchSizeInBytes: Infinity,
644
+ minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
615
645
  compressionAlgorithm: CompressionAlgorithms.lz4,
616
646
  };
617
647
 
@@ -713,7 +743,9 @@ export function getDeviceSpec(): {
713
743
  hardwareConcurrency: navigator.hardwareConcurrency,
714
744
  };
715
745
  }
716
- } catch {}
746
+ } catch {
747
+ // Eat the error
748
+ }
717
749
  return {};
718
750
  }
719
751
 
@@ -774,19 +806,18 @@ async function createSummarizer(loader: ILoader, url: string): Promise<ISummariz
774
806
 
775
807
  // Older containers may not have the "getEntryPoint" API
776
808
  // ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
777
- if (resolvedContainer.getEntryPoint !== undefined) {
778
- fluidObject = await resolvedContainer.getEntryPoint();
779
- } else {
780
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment
781
- const response = await (resolvedContainer as any).request({
809
+ if (resolvedContainer.getEntryPoint === undefined) {
810
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
811
+ const response = (await (resolvedContainer as any).request({
782
812
  url: `/${summarizerRequestUrl}`,
783
- });
784
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
813
+ })) as IResponse;
785
814
  if (response.status !== 200 || response.mimeType !== "fluid/object") {
786
815
  throw responseToException(response, request);
787
816
  }
788
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
817
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
789
818
  fluidObject = response.value;
819
+ } else {
820
+ fluidObject = await resolvedContainer.getEntryPoint();
790
821
  }
791
822
 
792
823
  if (fluidObject?.ISummarizer === undefined) {
@@ -802,7 +833,9 @@ async function createSummarizer(loader: ILoader, url: string): Promise<ISummariz
802
833
  * Please see addMetadataToSummary() as well
803
834
  */
804
835
  function lastMessageFromMetadata(
836
+ // eslint-disable-next-line import/no-deprecated
805
837
  metadata: IContainerRuntimeMetadata | undefined,
838
+ // eslint-disable-next-line import/no-deprecated
806
839
  ): ISummaryMetadataMessage | undefined {
807
840
  return metadata?.documentSchema?.runtime?.explicitSchemaControl
808
841
  ? metadata?.lastMessage
@@ -822,6 +855,7 @@ export let getSingleUseLegacyLogCallback = (logger: ITelemetryLoggerExt, type: s
822
855
  });
823
856
 
824
857
  // Now that we've logged, prevent future logging (globally).
858
+ // eslint-disable-next-line unicorn/consistent-function-scoping
825
859
  getSingleUseLegacyLogCallback = () => () => {};
826
860
  };
827
861
  };
@@ -877,6 +911,10 @@ export async function loadContainerRuntime(
877
911
  return ContainerRuntime.loadRuntime(params);
878
912
  }
879
913
 
914
+ const defaultMaxConsecutiveReconnects = 7;
915
+
916
+ const defaultTelemetrySignalSampleCount = 100;
917
+
880
918
  /**
881
919
  * Represents the runtime of the container. Contains helper functions/state of the container.
882
920
  * It will define the store level mappings.
@@ -888,9 +926,12 @@ export class ContainerRuntime
888
926
  implements
889
927
  IContainerRuntime,
890
928
  IRuntime,
929
+ // eslint-disable-next-line import/no-deprecated
891
930
  ISummarizerRuntime,
931
+ // eslint-disable-next-line import/no-deprecated
892
932
  ISummarizerInternalsProvider,
893
- IProvideFluidHandleContext
933
+ IProvideFluidHandleContext,
934
+ IProvideLayerCompatDetails
894
935
  {
895
936
  /**
896
937
  * Load the stores from a snapshot and returns the runtime.
@@ -991,7 +1032,9 @@ export class ContainerRuntime
991
1032
  tryFetchBlob<ReturnType<DuplicateBatchDetector["getRecentBatchInfoForSummary"]>>(
992
1033
  recentBatchInfoBlobName,
993
1034
  ),
1035
+ // eslint-disable-next-line import/no-deprecated
994
1036
  tryFetchBlob<IContainerRuntimeMetadata>(metadataBlobName),
1037
+ // eslint-disable-next-line import/no-deprecated
995
1038
  tryFetchBlob<ISerializedElection>(electedSummarizerBlobName),
996
1039
  tryFetchBlob<[string, string][]>(aliasBlobName),
997
1040
  tryFetchBlob<SerializedIdCompressorWithNoSession>(idCompressorBlobName),
@@ -1008,6 +1051,7 @@ export class ContainerRuntime
1008
1051
  // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
1009
1052
  if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
1010
1053
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
1054
+ // eslint-disable-next-line unicorn/no-lonely-if -- Separate if statements make flow easier to parse
1011
1055
  if (
1012
1056
  loadSequenceNumberVerification !== "bypass" &&
1013
1057
  runtimeSequenceNumber !== protocolSequenceNumber
@@ -1036,15 +1080,18 @@ export class ContainerRuntime
1036
1080
 
1037
1081
  let desiredIdCompressorMode: IdCompressorMode;
1038
1082
  switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
1039
- case true:
1083
+ case true: {
1040
1084
  desiredIdCompressorMode = "on";
1041
1085
  break;
1042
- case false:
1086
+ }
1087
+ case false: {
1043
1088
  desiredIdCompressorMode = undefined;
1044
1089
  break;
1045
- default:
1090
+ }
1091
+ default: {
1046
1092
  desiredIdCompressorMode = enableRuntimeIdCompressor;
1047
1093
  break;
1094
+ }
1048
1095
  }
1049
1096
 
1050
1097
  // Enabling the IdCompressor is a one-way operation and we only want to
@@ -1108,21 +1155,22 @@ export class ContainerRuntime
1108
1155
  pendingLocalState.pendingIdCompressorState,
1109
1156
  compressorLogger,
1110
1157
  );
1111
- } else if (serializedIdCompressor !== undefined) {
1158
+ } else if (serializedIdCompressor === undefined) {
1159
+ return createIdCompressor(compressorLogger);
1160
+ } else {
1112
1161
  return deserializeIdCompressor(
1113
1162
  serializedIdCompressor,
1114
1163
  createSessionId(),
1115
1164
  compressorLogger,
1116
1165
  );
1117
- } else {
1118
- return createIdCompressor(compressorLogger);
1119
1166
  }
1120
1167
  };
1121
1168
 
1122
1169
  const compressionLz4 =
1123
- compressionOptions.minimumBatchSizeInBytes !== Infinity &&
1170
+ compressionOptions.minimumBatchSizeInBytes !== Number.POSITIVE_INFINITY &&
1124
1171
  compressionOptions.compressionAlgorithm === "lz4";
1125
1172
 
1173
+ // eslint-disable-next-line import/no-deprecated
1126
1174
  const documentSchemaController = new DocumentsSchemaController(
1127
1175
  existing,
1128
1176
  protocolSequenceNumber,
@@ -1190,7 +1238,7 @@ export class ContainerRuntime
1190
1238
  runtime.setConnectionStateCore(true, runtime.delayConnectClientId);
1191
1239
  }
1192
1240
  },
1193
- (error) => runtime.closeFn(error),
1241
+ (error: IErrorBase) => runtime.closeFn(error),
1194
1242
  );
1195
1243
 
1196
1244
  // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
@@ -1221,18 +1269,6 @@ export class ContainerRuntime
1221
1269
  return this;
1222
1270
  }
1223
1271
 
1224
- private readonly submitFn: (
1225
- type: MessageType,
1226
- contents: unknown,
1227
- batch: boolean,
1228
- appData?: unknown,
1229
- ) => number;
1230
- /**
1231
- * Although current IContainerContext guarantees submitBatchFn, it is not available on older loaders.
1232
- */
1233
- private readonly submitBatchFn:
1234
- | ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)
1235
- | undefined;
1236
1272
  private readonly submitSummaryFn: (
1237
1273
  summaryOp: ISummaryContent,
1238
1274
  referenceSequenceNumber?: number,
@@ -1272,9 +1308,11 @@ export class ContainerRuntime
1272
1308
  * this op roundtrips, compression will be On. Client can't send compressed ops until it's change in schema.
1273
1309
  */
1274
1310
  public get sessionSchema(): {
1311
+ // eslint-disable-next-line import/no-deprecated
1275
1312
  [P in keyof IDocumentSchemaFeatures]?: IDocumentSchemaFeatures[P] extends boolean
1276
1313
  ? true
1277
- : IDocumentSchemaFeatures[P];
1314
+ : // eslint-disable-next-line import/no-deprecated
1315
+ IDocumentSchemaFeatures[P];
1278
1316
  } {
1279
1317
  return this.documentsSchemaController.sessionSchema.runtime;
1280
1318
  }
@@ -1291,9 +1329,6 @@ export class ContainerRuntime
1291
1329
  // In such case we have to process all ops, including those marked with savedOp === true.
1292
1330
  private readonly skipSavedCompressorOps: boolean;
1293
1331
 
1294
- public get idCompressorMode(): IdCompressorMode {
1295
- return this.sessionSchema.idCompressorMode;
1296
- }
1297
1332
  /**
1298
1333
  * {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.idCompressor}
1299
1334
  */
@@ -1302,7 +1337,7 @@ export class ContainerRuntime
1302
1337
  // If container uses delayed mode, then we can only expose generateDocumentUniqueId() and nothing else.
1303
1338
  // That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
1304
1339
  // to reason over such things as session ID space.
1305
- if (this.idCompressorMode === "on") {
1340
+ if (this.sessionSchema.idCompressorMode === "on") {
1306
1341
  assert(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
1307
1342
  return this._idCompressor;
1308
1343
  }
@@ -1310,7 +1345,7 @@ export class ContainerRuntime
1310
1345
 
1311
1346
  /**
1312
1347
  * True if we have ID compressor loading in-flight (async operation). Useful only for
1313
- * this.idCompressorMode === "delayed" mode
1348
+ * this.sessionSchema.idCompressorMode === "delayed" mode
1314
1349
  */
1315
1350
  protected _loadIdCompressor: Promise<void> | undefined;
1316
1351
 
@@ -1354,14 +1389,10 @@ export class ContainerRuntime
1354
1389
  * do not create it (see SummarizerClientElection.clientDetailsPermitElection() for details)
1355
1390
  */
1356
1391
  private readonly summaryManager?: SummaryManager;
1357
- private readonly summaryCollection: SummaryCollection;
1358
1392
 
1359
1393
  private readonly summarizerNode: IRootSummarizerNodeWithGC;
1360
1394
 
1361
- private readonly logger: ITelemetryLoggerExt;
1362
-
1363
1395
  private readonly maxConsecutiveReconnects: number;
1364
- private readonly defaultMaxConsecutiveReconnects = 7;
1365
1396
 
1366
1397
  private _orderSequentiallyCalls: number = 0;
1367
1398
  private readonly _flushMode: FlushMode;
@@ -1415,10 +1446,8 @@ export class ContainerRuntime
1415
1446
 
1416
1447
  private dirtyContainer: boolean;
1417
1448
  private emitDirtyDocumentEvent = true;
1418
- private readonly disableAttachReorder: boolean | undefined;
1419
1449
  private readonly useDeltaManagerOpsProxy: boolean;
1420
1450
  private readonly closeSummarizerDelayMs: number;
1421
- private readonly defaultTelemetrySignalSampleCount = 100;
1422
1451
  private readonly _signalTracking: IPerfSignalReport = {
1423
1452
  totalSignalsSentInLatencyWindow: 0,
1424
1453
  signalsLost: 0,
@@ -1436,6 +1465,7 @@ export class ContainerRuntime
1436
1465
  * It is the main entry point for summary work.
1437
1466
  * It is created only by summarizing container (i.e. one with clientType === "summarizer")
1438
1467
  */
1468
+ // eslint-disable-next-line import/no-deprecated
1439
1469
  private readonly _summarizer?: Summarizer;
1440
1470
  private readonly deltaScheduler: DeltaScheduler;
1441
1471
  private readonly inboundBatchAggregator: InboundBatchAggregator;
@@ -1451,37 +1481,12 @@ export class ContainerRuntime
1451
1481
  /**
1452
1482
  * The last message processed at the time of the last summary.
1453
1483
  */
1484
+ // eslint-disable-next-line import/no-deprecated
1454
1485
  private messageAtLastSummary: ISummaryMetadataMessage | undefined;
1455
1486
 
1456
- private get summarizer(): Summarizer {
1457
- assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
1458
- return this._summarizer;
1459
- }
1460
-
1461
1487
  private readonly summariesDisabled: boolean;
1462
- private isSummariesDisabled(): boolean {
1463
- return this.summaryConfiguration.state === "disabled";
1464
- }
1465
-
1466
- private readonly maxOpsSinceLastSummary: number;
1467
- private getMaxOpsSinceLastSummary(): number {
1468
- return this.summaryConfiguration.state !== "disabled"
1469
- ? this.summaryConfiguration.maxOpsSinceLastSummary
1470
- : 0;
1471
- }
1472
-
1473
- private readonly initialSummarizerDelayMs: number;
1474
- private getInitialSummarizerDelayMs(): number {
1475
- // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
1476
- // to ISummaryConfiguration in 0.60.
1477
- if (this.runtimeOptions.summaryOptions.initialSummarizerDelayMs !== undefined) {
1478
- return this.runtimeOptions.summaryOptions.initialSummarizerDelayMs;
1479
- }
1480
- return this.summaryConfiguration.state !== "disabled"
1481
- ? this.summaryConfiguration.initialSummarizerDelayMs
1482
- : 0;
1483
- }
1484
1488
 
1489
+ // eslint-disable-next-line import/no-deprecated
1485
1490
  private readonly createContainerMetadata: ICreateContainerMetadata;
1486
1491
  /**
1487
1492
  * The summary number of the next summary that will be generated for this container. This is incremented every time
@@ -1513,11 +1518,6 @@ export class ContainerRuntime
1513
1518
  */
1514
1519
  private readonly telemetryDocumentId: string;
1515
1520
 
1516
- /**
1517
- * Whether this client is the summarizer client itself (type is summarizerClientType)
1518
- */
1519
- private readonly isSummarizerClient: boolean;
1520
-
1521
1521
  /**
1522
1522
  * The id of the version used to initially load this runtime, or undefined if it's newly created.
1523
1523
  */
@@ -1538,27 +1538,30 @@ export class ContainerRuntime
1538
1538
  expiry: { policy: "absolute", durationMs: 60000 },
1539
1539
  });
1540
1540
 
1541
- /**
1542
- * The options to apply to this ContainerRuntime instance (including internal options hidden from the public API)
1543
- */
1544
- private readonly runtimeOptions: Readonly<Required<IContainerRuntimeOptionsInternal>>;
1541
+ public get ILayerCompatDetails(): ILayerCompatDetails {
1542
+ return RuntimeCompatDetails;
1543
+ }
1545
1544
 
1546
1545
  /***/
1547
1546
  protected constructor(
1548
1547
  context: IContainerContext,
1549
1548
  private readonly registry: IFluidDataStoreRegistry,
1549
+ // eslint-disable-next-line import/no-deprecated
1550
1550
  private readonly metadata: IContainerRuntimeMetadata | undefined,
1551
+ // eslint-disable-next-line import/no-deprecated
1551
1552
  electedSummarizerData: ISerializedElection | undefined,
1552
1553
  chunks: [string, string[]][],
1553
1554
  dataStoreAliasMap: [string, string][],
1554
- runtimeOptions: Readonly<Required<IContainerRuntimeOptions>>,
1555
+ baseRuntimeOptions: Readonly<Required<IContainerRuntimeOptions>>,
1555
1556
  private readonly containerScope: FluidObject,
1556
1557
  // Create a custom ITelemetryBaseLogger to output telemetry events.
1557
1558
  public readonly baseLogger: ITelemetryBaseLogger,
1558
1559
  existing: boolean,
1560
+ // eslint-disable-next-line import/no-deprecated
1559
1561
  blobManagerSnapshot: IBlobManagerLoadInfo,
1560
1562
  private readonly _storage: IDocumentStorageService,
1561
1563
  private readonly createIdCompressor: () => Promise<IIdCompressor & IIdCompressorCore>,
1564
+ // eslint-disable-next-line import/no-deprecated
1562
1565
  private readonly documentsSchemaController: DocumentsSchemaController,
1563
1566
  featureGatesForTelemetry: Record<string, boolean | number | undefined>,
1564
1567
  provideEntryPoint: (containerRuntime: IContainerRuntime) => Promise<FluidObject>,
@@ -1566,11 +1569,12 @@ export class ContainerRuntime
1566
1569
  request: IRequest,
1567
1570
  runtime: IContainerRuntime,
1568
1571
  ) => Promise<IResponse>,
1569
- private readonly summaryConfiguration: ISummaryConfiguration = {
1572
+ // eslint-disable-next-line unicorn/no-object-as-default-parameter
1573
+ summaryConfiguration: ISummaryConfiguration = {
1570
1574
  // the defaults
1571
1575
  ...DefaultSummaryConfiguration,
1572
1576
  // the runtime configuration overrides
1573
- ...runtimeOptions.summaryOptions?.summaryConfigOverrides,
1577
+ ...baseRuntimeOptions.summaryOptions?.summaryConfigOverrides,
1574
1578
  },
1575
1579
  recentBatchInfo?: [number, string][],
1576
1580
  ) {
@@ -1596,14 +1600,19 @@ export class ContainerRuntime
1596
1600
  snapshotWithContents,
1597
1601
  } = context;
1598
1602
 
1603
+ // In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
1604
+ this.disposeFn = disposeFn ?? closeFn;
1605
+
1606
+ const maybeLoaderCompatDetails = context as FluidObject<ILayerCompatDetails>;
1607
+ validateLoaderCompatibility(maybeLoaderCompatDetails.ILayerCompatDetails, this.disposeFn);
1608
+
1599
1609
  // Backfill in defaults for the internal runtimeOptions, since they may not be present on the provided runtimeOptions object
1600
- this.runtimeOptions = {
1610
+ const runtimeOptions = {
1601
1611
  flushMode: defaultFlushMode,
1602
- ...runtimeOptions,
1612
+ ...baseRuntimeOptions,
1603
1613
  };
1604
- this.logger = createChildLogger({ logger: this.baseLogger });
1605
1614
  this.mc = createChildMonitoringContext({
1606
- logger: this.logger,
1615
+ logger: this.baseLogger,
1607
1616
  namespace: "ContainerRuntime",
1608
1617
  });
1609
1618
 
@@ -1623,20 +1632,24 @@ export class ContainerRuntime
1623
1632
 
1624
1633
  // Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
1625
1634
  // This makes ContainerRuntime the final gatekeeper for outgoing messages.
1626
- this.submitFn = submitFn;
1627
- this.submitBatchFn = submitBatchFn;
1628
- this.submitSummaryFn = submitSummaryFn;
1635
+ // back-compat: ADO #1385: Make this call unconditional in the future
1636
+ this.submitSummaryFn =
1637
+ submitSummaryFn ??
1638
+ ((summaryOp, refseq) => submitFn(MessageType.Summarize, summaryOp, false));
1629
1639
  this.submitSignalFn = submitSignalFn;
1630
1640
 
1631
1641
  // TODO: After IContainerContext.options is removed, we'll just create a new blank object {} here.
1632
1642
  // Values are generally expected to be set from the runtime side.
1633
1643
  this.options = options ?? {};
1634
1644
  this.clientDetails = clientDetails;
1635
- this.isSummarizerClient = this.clientDetails.type === summarizerClientType;
1645
+ const isSummarizerClient = this.clientDetails.type === summarizerClientType;
1636
1646
  this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
1647
+ // eslint-disable-next-line unicorn/consistent-destructuring
1637
1648
  this._getClientId = () => context.clientId;
1649
+ // eslint-disable-next-line unicorn/consistent-destructuring
1638
1650
  this._getAttachState = () => context.attachState;
1639
1651
  this.getAbsoluteUrl = async (relativeUrl: string) => {
1652
+ // eslint-disable-next-line unicorn/consistent-destructuring
1640
1653
  if (context.getAbsoluteUrl === undefined) {
1641
1654
  throw new Error("Driver does not implement getAbsoluteUrl");
1642
1655
  }
@@ -1650,10 +1663,8 @@ export class ContainerRuntime
1650
1663
  this.on("dirty", () => context.updateDirtyContainerState(true));
1651
1664
  this.on("saved", () => context.updateDirtyContainerState(false));
1652
1665
 
1653
- // In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
1654
- this.disposeFn = disposeFn ?? closeFn;
1655
1666
  // In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
1656
- this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
1667
+ this.closeFn = isSummarizerClient ? this.disposeFn : closeFn;
1657
1668
 
1658
1669
  let loadSummaryNumber: number;
1659
1670
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
@@ -1686,28 +1697,22 @@ export class ContainerRuntime
1686
1697
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
1687
1698
  inputs: JSON.stringify({
1688
1699
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1689
- gcOptions_gcGeneration: this.runtimeOptions.gcOptions[gcGenerationOptionName],
1700
+ gcOptions_gcGeneration: runtimeOptions.gcOptions[gcGenerationOptionName],
1690
1701
  }),
1691
1702
  });
1692
1703
 
1693
1704
  this.telemetryDocumentId = metadata?.telemetryDocumentId ?? uuid();
1694
1705
 
1695
- this.disableAttachReorder = this.mc.config.getBoolean(
1696
- "Fluid.ContainerRuntime.disableAttachOpReorder",
1697
- );
1698
-
1699
1706
  const opGroupingManager = new OpGroupingManager(
1700
1707
  {
1701
1708
  groupedBatchingEnabled: this.groupedBatchingEnabled,
1702
- opCountThreshold:
1703
- this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
1704
1709
  },
1705
1710
  this.mc.logger,
1706
1711
  );
1707
1712
 
1708
1713
  const opSplitter = new OpSplitter(
1709
1714
  chunks,
1710
- this.submitBatchFn,
1715
+ submitBatchFn,
1711
1716
  runtimeOptions.chunkSizeInBytes,
1712
1717
  runtimeOptions.maxBatchSizeInBytes,
1713
1718
  this.mc.logger,
@@ -1730,7 +1735,7 @@ export class ContainerRuntime
1730
1735
  isAttached: () => this.attachState !== AttachState.Detached,
1731
1736
  },
1732
1737
  pendingRuntimeState?.pending,
1733
- this.logger,
1738
+ this.baseLogger,
1734
1739
  );
1735
1740
 
1736
1741
  let outerDeltaManager: IDeltaManagerFull;
@@ -1756,28 +1761,42 @@ export class ContainerRuntime
1756
1761
 
1757
1762
  this.handleContext = new ContainerFluidHandleContext("", this);
1758
1763
 
1759
- if (this.summaryConfiguration.state === "enabled") {
1760
- this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
1764
+ if (summaryConfiguration.state === "enabled") {
1765
+ this.validateSummaryHeuristicConfiguration(summaryConfiguration);
1761
1766
  }
1762
1767
 
1763
- this.summariesDisabled = this.isSummariesDisabled();
1764
- this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
1765
- this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
1768
+ this.summariesDisabled = isSummariesDisabled(summaryConfiguration);
1769
+ const { maxOpsSinceLastSummary = 0, initialSummarizerDelayMs = 0 } = isSummariesDisabled(
1770
+ summaryConfiguration,
1771
+ )
1772
+ ? {}
1773
+ : {
1774
+ ...summaryConfiguration,
1775
+ initialSummarizerDelayMs:
1776
+ // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
1777
+ // to ISummaryConfiguration in 0.60.
1778
+ runtimeOptions.summaryOptions.initialSummarizerDelayMs ??
1779
+ summaryConfiguration.initialSummarizerDelayMs,
1780
+ };
1766
1781
 
1767
1782
  this.maxConsecutiveReconnects =
1768
- this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
1769
- this.defaultMaxConsecutiveReconnects;
1770
-
1783
+ this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? defaultMaxConsecutiveReconnects;
1784
+
1785
+ // If the context has ILayerCompatDetails, it supports referenceSequenceNumbers since that features
1786
+ // predates ILayerCompatDetails.
1787
+ const referenceSequenceNumbersSupported =
1788
+ maybeLoaderCompatDetails.ILayerCompatDetails === undefined
1789
+ ? supportedFeatures?.get("referenceSequenceNumbers") === true
1790
+ : true;
1771
1791
  if (
1772
- this.runtimeOptions.flushMode ===
1773
- (FlushModeExperimental.Async as unknown as FlushMode) &&
1774
- supportedFeatures?.get("referenceSequenceNumbers") !== true
1792
+ runtimeOptions.flushMode === (FlushModeExperimental.Async as unknown as FlushMode) &&
1793
+ !referenceSequenceNumbersSupported
1775
1794
  ) {
1776
1795
  // The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
1777
1796
  this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
1778
1797
  this._flushMode = FlushMode.TurnBased;
1779
1798
  } else {
1780
- this._flushMode = this.runtimeOptions.flushMode;
1799
+ this._flushMode = runtimeOptions.flushMode;
1781
1800
  }
1782
1801
  this.offlineEnabled =
1783
1802
  this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad") ?? false;
@@ -1795,6 +1814,7 @@ export class ContainerRuntime
1795
1814
  this.duplicateBatchDetector = new DuplicateBatchDetector(recentBatchInfo);
1796
1815
  }
1797
1816
 
1817
+ // eslint-disable-next-line unicorn/consistent-destructuring
1798
1818
  if (context.attachState === AttachState.Attached) {
1799
1819
  const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
1800
1820
  if (
@@ -1810,13 +1830,13 @@ export class ContainerRuntime
1810
1830
 
1811
1831
  this.garbageCollector = GarbageCollector.create({
1812
1832
  runtime: this,
1813
- gcOptions: this.runtimeOptions.gcOptions,
1833
+ gcOptions: runtimeOptions.gcOptions,
1814
1834
  baseSnapshot,
1815
1835
  baseLogger: this.mc.logger,
1816
1836
  existing,
1817
1837
  metadata,
1818
1838
  createContainerMetadata: this.createContainerMetadata,
1819
- isSummarizerClient: this.isSummarizerClient,
1839
+ isSummarizerClient,
1820
1840
  getNodePackagePath: async (nodePath: string) => this.getGCNodePackagePath(nodePath),
1821
1841
  getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
1822
1842
  readAndParseBlob: async <T>(id: string) => readAndParse<T>(this.storage, id),
@@ -1833,7 +1853,7 @@ export class ContainerRuntime
1833
1853
  ? undefined
1834
1854
  : loadedFromSequenceNumber;
1835
1855
  this.summarizerNode = createRootSummarizerNodeWithGC(
1836
- createChildLogger({ logger: this.logger, namespace: "SummarizerNode" }),
1856
+ createChildLogger({ logger: this.baseLogger, namespace: "SummarizerNode" }),
1837
1857
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
1838
1858
  async (fullTree: boolean, trackState: boolean, telemetryContext?: ITelemetryContext) =>
1839
1859
  this.summarizeInternal(fullTree, trackState, telemetryContext),
@@ -1928,25 +1948,25 @@ export class ContainerRuntime
1928
1948
  this.deltaScheduler = new DeltaScheduler(
1929
1949
  this.innerDeltaManager,
1930
1950
  this,
1931
- createChildLogger({ logger: this.logger, namespace: "DeltaScheduler" }),
1951
+ createChildLogger({ logger: this.baseLogger, namespace: "DeltaScheduler" }),
1932
1952
  );
1933
1953
 
1934
1954
  this.inboundBatchAggregator = new InboundBatchAggregator(
1935
1955
  this.innerDeltaManager,
1936
1956
  () => this.clientId,
1937
- createChildLogger({ logger: this.logger, namespace: "InboundBatchAggregator" }),
1957
+ createChildLogger({ logger: this.baseLogger, namespace: "InboundBatchAggregator" }),
1938
1958
  );
1939
1959
 
1940
1960
  const disablePartialFlush = this.mc.config.getBoolean(
1941
1961
  "Fluid.ContainerRuntime.DisablePartialFlush",
1942
1962
  );
1943
1963
 
1944
- const legacySendBatchFn = makeLegacySendBatchFn(this.submitFn, this.innerDeltaManager);
1964
+ const legacySendBatchFn = makeLegacySendBatchFn(submitFn, this.innerDeltaManager);
1945
1965
 
1946
1966
  this.outbox = new Outbox({
1947
1967
  shouldSend: () => this.canSendOps(),
1948
1968
  pendingStateManager: this.pendingStateManager,
1949
- submitBatchFn: this.submitBatchFn,
1969
+ submitBatchFn,
1950
1970
  legacySendBatchFn,
1951
1971
  compressor: new OpCompressor(this.mc.logger),
1952
1972
  splitter: opSplitter,
@@ -2003,7 +2023,7 @@ export class ContainerRuntime
2003
2023
  );
2004
2024
  this.closeSummarizerDelayMs =
2005
2025
  closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
2006
- this.summaryCollection = new SummaryCollection(this.deltaManager, this.logger);
2026
+ const summaryCollection = new SummaryCollection(this.deltaManager, this.baseLogger);
2007
2027
 
2008
2028
  this.dirtyContainer =
2009
2029
  this.attachState !== AttachState.Attached || this.hasPendingMessages();
@@ -2013,7 +2033,7 @@ export class ContainerRuntime
2013
2033
  this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
2014
2034
  } else {
2015
2035
  const orderedClientLogger = createChildLogger({
2016
- logger: this.logger,
2036
+ logger: this.baseLogger,
2017
2037
  namespace: "OrderedClientElection",
2018
2038
  });
2019
2039
  const orderedClientCollection = new OrderedClientCollection(
@@ -2033,18 +2053,20 @@ export class ContainerRuntime
2033
2053
 
2034
2054
  this.summarizerClientElection = new SummarizerClientElection(
2035
2055
  orderedClientLogger,
2036
- this.summaryCollection,
2056
+ summaryCollection,
2037
2057
  orderedClientElectionForSummarizer,
2038
- this.maxOpsSinceLastSummary,
2058
+ maxOpsSinceLastSummary,
2039
2059
  );
2040
2060
 
2041
- if (this.isSummarizerClient) {
2061
+ if (isSummarizerClient) {
2062
+ // eslint-disable-next-line import/no-deprecated
2042
2063
  this._summarizer = new Summarizer(
2043
2064
  this /* ISummarizerRuntime */,
2044
- () => this.summaryConfiguration,
2065
+ () => summaryConfiguration,
2045
2066
  this /* ISummarizerInternalsProvider */,
2046
2067
  this.handleContext,
2047
- this.summaryCollection,
2068
+ summaryCollection,
2069
+ // eslint-disable-next-line import/no-deprecated
2048
2070
  async (runtime: IConnectableRuntime) =>
2049
2071
  RunWhileConnectedCoordinator.create(
2050
2072
  runtime,
@@ -2057,31 +2079,31 @@ export class ContainerRuntime
2057
2079
  // Only create a SummaryManager and SummarizerClientElection
2058
2080
  // if summaries are enabled and we are not the summarizer client.
2059
2081
  const defaultAction = (): void => {
2060
- if (this.summaryCollection.opsSinceLastAck > this.maxOpsSinceLastSummary) {
2082
+ if (summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
2061
2083
  this.mc.logger.sendTelemetryEvent({ eventName: "SummaryStatus:Behind" });
2062
2084
  // unregister default to no log on every op after falling behind
2063
2085
  // and register summary ack handler to re-register this handler
2064
2086
  // after successful summary
2065
- this.summaryCollection.once(MessageType.SummaryAck, () => {
2087
+ summaryCollection.once(MessageType.SummaryAck, () => {
2066
2088
  this.mc.logger.sendTelemetryEvent({
2067
2089
  eventName: "SummaryStatus:CaughtUp",
2068
2090
  });
2069
2091
  // we've caught up, so re-register the default action to monitor for
2070
2092
  // falling behind, and unregister ourself
2071
- this.summaryCollection.on("default", defaultAction);
2093
+ summaryCollection.on("default", defaultAction);
2072
2094
  });
2073
- this.summaryCollection.off("default", defaultAction);
2095
+ summaryCollection.off("default", defaultAction);
2074
2096
  }
2075
2097
  };
2076
2098
 
2077
- this.summaryCollection.on("default", defaultAction);
2099
+ summaryCollection.on("default", defaultAction);
2078
2100
 
2079
2101
  // Create the SummaryManager and mark the initial state
2080
2102
  this.summaryManager = new SummaryManager(
2081
2103
  this.summarizerClientElection,
2082
2104
  this, // IConnectedState
2083
- this.summaryCollection,
2084
- this.logger,
2105
+ summaryCollection,
2106
+ this.baseLogger,
2085
2107
  this.formCreateSummarizerFn(loader),
2086
2108
  new Throttler(
2087
2109
  60 * 1000, // 60 sec delay window
@@ -2090,28 +2112,29 @@ export class ContainerRuntime
2090
2112
  formExponentialFn({ coefficient: 20, initialDelay: 0 }),
2091
2113
  ),
2092
2114
  {
2093
- initialDelayMs: this.initialSummarizerDelayMs,
2115
+ initialDelayMs: initialSummarizerDelayMs,
2094
2116
  },
2095
2117
  );
2096
2118
  // Forward events from SummaryManager
2097
- [
2119
+ for (const eventName of [
2098
2120
  "summarize",
2099
2121
  "summarizeAllAttemptsFailed",
2100
2122
  "summarizerStop",
2101
2123
  "summarizerStart",
2102
2124
  "summarizerStartupFailed",
2103
- ].forEach((eventName) => {
2104
- this.summaryManager?.on(eventName, (...args: any[]) => {
2125
+ ]) {
2126
+ this.summaryManager?.on(eventName, (...args: unknown[]) => {
2105
2127
  this.emit(eventName, ...args);
2106
2128
  });
2107
- });
2129
+ }
2108
2130
 
2109
2131
  this.summaryManager.start();
2110
2132
  }
2111
2133
  }
2112
2134
 
2113
2135
  // logging hardware telemetry
2114
- this.logger.sendTelemetryEvent({
2136
+ this.baseLogger.send({
2137
+ category: "generic",
2115
2138
  eventName: "DeviceSpec",
2116
2139
  ...getDeviceSpec(),
2117
2140
  });
@@ -2124,13 +2147,12 @@ export class ContainerRuntime
2124
2147
  summaryFormatVersion: metadata?.summaryFormatVersion,
2125
2148
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
2126
2149
  gcVersion: metadata?.gcFeature,
2127
- options: JSON.stringify(runtimeOptions),
2150
+ options: JSON.stringify(baseRuntimeOptions),
2128
2151
  idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
2129
- idCompressorMode: this.idCompressorMode,
2152
+ idCompressorMode: this.sessionSchema.idCompressorMode,
2130
2153
  sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
2131
2154
  featureGates: JSON.stringify({
2132
2155
  ...featureGatesForTelemetry,
2133
- disableAttachReorder: this.disableAttachReorder,
2134
2156
  disablePartialFlush,
2135
2157
  closeSummarizerDelayOverride,
2136
2158
  }),
@@ -2139,15 +2161,11 @@ export class ContainerRuntime
2139
2161
  initialSequenceNumber: this.deltaManager.initialSequenceNumber,
2140
2162
  });
2141
2163
 
2142
- ReportOpPerfTelemetry(this.clientId, this._deltaManager, this, this.logger);
2143
- BindBatchTracker(this, this.logger);
2164
+ ReportOpPerfTelemetry(this.clientId, this._deltaManager, this, this.baseLogger);
2165
+ BindBatchTracker(this, this.baseLogger);
2144
2166
 
2145
2167
  this.entryPoint = new LazyPromise(async () => {
2146
- if (this.isSummarizerClient) {
2147
- assert(
2148
- this._summarizer !== undefined,
2149
- 0x5bf /* Summarizer object is undefined in a summarizer client */,
2150
- );
2168
+ if (this._summarizer !== undefined) {
2151
2169
  return this._summarizer;
2152
2170
  }
2153
2171
  return provideEntryPoint(this);
@@ -2158,8 +2176,9 @@ export class ContainerRuntime
2158
2176
  this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
2159
2177
  }
2160
2178
 
2179
+ // eslint-disable-next-line import/no-deprecated
2161
2180
  public onSchemaChange(schema: IDocumentSchemaCurrent): void {
2162
- this.logger.sendTelemetryEvent({
2181
+ this.mc.logger.sendTelemetryEvent({
2163
2182
  eventName: "SchemaChangeAccept",
2164
2183
  sessionRuntimeSchema: JSON.stringify(schema),
2165
2184
  });
@@ -2216,8 +2235,8 @@ export class ContainerRuntime
2216
2235
  */
2217
2236
  private async initializeBaseState(): Promise<void> {
2218
2237
  if (
2219
- this.idCompressorMode === "on" ||
2220
- (this.idCompressorMode === "delayed" && this.connected)
2238
+ this.sessionSchema.idCompressorMode === "on" ||
2239
+ (this.sessionSchema.idCompressorMode === "delayed" && this.connected)
2221
2240
  ) {
2222
2241
  this._idCompressor = await this.createIdCompressor();
2223
2242
  // This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
@@ -2276,7 +2295,7 @@ export class ContainerRuntime
2276
2295
  // be in same loading group. So, once we have fetched the snapshot for that loading group on
2277
2296
  // any request, then cache that as same group could be requested in future too.
2278
2297
  const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(
2279
- sortedLoadingGroupIds.join(),
2298
+ sortedLoadingGroupIds.join(","),
2280
2299
  async () => {
2281
2300
  assert(
2282
2301
  this.storage.getSnapshot !== undefined,
@@ -2291,7 +2310,7 @@ export class ContainerRuntime
2291
2310
  },
2292
2311
  );
2293
2312
 
2294
- this.logger.sendTelemetryEvent({
2313
+ this.mc.logger.sendTelemetryEvent({
2295
2314
  eventName: "GroupIdSnapshotFetched",
2296
2315
  details: JSON.stringify({
2297
2316
  fromCache: loadedFromCache,
@@ -2332,7 +2351,7 @@ export class ContainerRuntime
2332
2351
  // another snapshot from which the summarizer loaded and it is behind, then just give up as
2333
2352
  // the summarizer state is not up to date.
2334
2353
  // This should be a recoverable scenario and shouldn't happen as we should process the ack first.
2335
- if (this.isSummarizerClient) {
2354
+ if (this._summarizer !== undefined) {
2336
2355
  throw new Error("Summarizer client behind, loaded newer snapshot with loadingGroupId");
2337
2356
  }
2338
2357
 
@@ -2403,7 +2422,7 @@ export class ContainerRuntime
2403
2422
  return {
2404
2423
  status: 200,
2405
2424
  mimeType: "fluid/object",
2406
- value: this.summarizer,
2425
+ value: this._summarizer,
2407
2426
  };
2408
2427
  }
2409
2428
  return create404Response(request);
@@ -2481,6 +2500,7 @@ export class ContainerRuntime
2481
2500
  // Is document schema explicit control on?
2482
2501
  const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl;
2483
2502
 
2503
+ // eslint-disable-next-line import/no-deprecated
2484
2504
  const metadata: IContainerRuntimeMetadata = {
2485
2505
  ...this.createContainerMetadata,
2486
2506
  // Increment the summary number for the next summary that will be generated.
@@ -2494,7 +2514,8 @@ export class ContainerRuntime
2494
2514
  // last message's sequence number.
2495
2515
  // See also lastMessageFromMetadata()
2496
2516
  message: explicitSchemaControl
2497
- ? ({ sequenceNumber: -1 } as unknown as ISummaryMetadataMessage)
2517
+ ? // eslint-disable-next-line import/no-deprecated
2518
+ ({ sequenceNumber: -1 } as unknown as ISummaryMetadataMessage)
2498
2519
  : message,
2499
2520
  lastMessage: explicitSchemaControl ? message : undefined,
2500
2521
  documentSchema,
@@ -2639,9 +2660,10 @@ export class ContainerRuntime
2639
2660
  switch (opContents.type) {
2640
2661
  case ContainerMessageType.FluidDataStoreOp:
2641
2662
  case ContainerMessageType.Attach:
2642
- case ContainerMessageType.Alias:
2663
+ case ContainerMessageType.Alias: {
2643
2664
  return this.channelCollection.applyStashedOp(opContents);
2644
- case ContainerMessageType.IdAllocation:
2665
+ }
2666
+ case ContainerMessageType.IdAllocation: {
2645
2667
  // IDs allocation ops in stashed state are ignored because the tip state of the compressor
2646
2668
  // is serialized into the pending state. This is done because generation of new IDs during
2647
2669
  // stashed op application (or, later, resubmit) must generate new IDs and if the compressor
@@ -2652,19 +2674,24 @@ export class ContainerRuntime
2652
2674
  // before applying the rest of the stashed ops. This would accomplish the same thing but with
2653
2675
  // better performance in future incremental stashed state creation.
2654
2676
  assert(
2655
- this.idCompressorMode !== undefined,
2677
+ this.sessionSchema.idCompressorMode !== undefined,
2656
2678
  0x8f1 /* ID compressor should be in use */,
2657
2679
  );
2658
2680
  return;
2659
- case ContainerMessageType.DocumentSchemaChange:
2681
+ }
2682
+ case ContainerMessageType.DocumentSchemaChange: {
2660
2683
  return;
2661
- case ContainerMessageType.BlobAttach:
2684
+ }
2685
+ case ContainerMessageType.BlobAttach: {
2662
2686
  return;
2663
- case ContainerMessageType.Rejoin:
2687
+ }
2688
+ case ContainerMessageType.Rejoin: {
2664
2689
  throw new Error("rejoin not expected here");
2665
- case ContainerMessageType.GC:
2690
+ }
2691
+ case ContainerMessageType.GC: {
2666
2692
  // GC op is only sent in summarizer which should never have stashed ops.
2667
2693
  throw new LoggingError("GC op not expected to be stashed in summarizer");
2694
+ }
2668
2695
  default: {
2669
2696
  const error = getUnknownMessageTypeError(
2670
2697
  opContents.type,
@@ -2679,7 +2706,7 @@ export class ContainerRuntime
2679
2706
  private async loadIdCompressor(): Promise<void | undefined> {
2680
2707
  if (
2681
2708
  this._idCompressor === undefined &&
2682
- this.idCompressorMode !== undefined &&
2709
+ this.sessionSchema.idCompressorMode !== undefined &&
2683
2710
  this._loadIdCompressor === undefined
2684
2711
  ) {
2685
2712
  this._loadIdCompressor = this.createIdCompressor()
@@ -2694,7 +2721,7 @@ export class ContainerRuntime
2694
2721
  this._idCompressor = compressor;
2695
2722
  })
2696
2723
  .catch((error) => {
2697
- this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
2724
+ this.mc.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
2698
2725
  throw error;
2699
2726
  });
2700
2727
  }
@@ -2710,7 +2737,7 @@ export class ContainerRuntime
2710
2737
  0x978 /* this.clientId does not match Audience */,
2711
2738
  );
2712
2739
 
2713
- if (connected && this.idCompressorMode === "delayed") {
2740
+ if (connected && this.sessionSchema.idCompressorMode === "delayed") {
2714
2741
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
2715
2742
  this.loadIdCompressor();
2716
2743
  }
@@ -2832,7 +2859,7 @@ export class ContainerRuntime
2832
2859
  // or something different, like a system message.
2833
2860
  const hasModernRuntimeMessageEnvelope = messageCopy.type === MessageType.Operation;
2834
2861
  const savedOp = (messageCopy.metadata as ISavedOpMetadata)?.savedOp;
2835
- const logLegacyCase = getSingleUseLegacyLogCallback(this.logger, messageCopy.type);
2862
+ const logLegacyCase = getSingleUseLegacyLogCallback(this.mc.logger, messageCopy.type);
2836
2863
 
2837
2864
  let runtimeBatch: boolean =
2838
2865
  hasModernRuntimeMessageEnvelope || isUnpackedRuntimeMessage(messageCopy);
@@ -2987,11 +3014,11 @@ export class ContainerRuntime
2987
3014
  let error: unknown;
2988
3015
  try {
2989
3016
  if (!runtimeBatch) {
2990
- messagesWithMetadata.forEach(({ message }) => {
3017
+ for (const { message } of messagesWithMetadata) {
2991
3018
  this.ensureNoDataModelChanges(() => {
2992
3019
  this.observeNonRuntimeMessage(message);
2993
3020
  });
2994
- });
3021
+ }
2995
3022
  return;
2996
3023
  }
2997
3024
 
@@ -3076,8 +3103,8 @@ export class ContainerRuntime
3076
3103
  for (const { message } of messagesWithMetadata) {
3077
3104
  this.emit("op", message, true /* runtimeMessage */);
3078
3105
  }
3079
- } catch (e) {
3080
- error = e;
3106
+ } catch (error_) {
3107
+ error = error_;
3081
3108
  throw error;
3082
3109
  } finally {
3083
3110
  if (locationInBatch.batchEnd) {
@@ -3148,38 +3175,46 @@ export class ContainerRuntime
3148
3175
  switch (message.type) {
3149
3176
  case ContainerMessageType.FluidDataStoreOp:
3150
3177
  case ContainerMessageType.Attach:
3151
- case ContainerMessageType.Alias:
3178
+ case ContainerMessageType.Alias: {
3152
3179
  // Remove the metadata from the message before sending it to the channel collection. The metadata
3153
3180
  // is added by the container runtime and is not part of the message that the channel collection and
3154
3181
  // layers below it expect.
3155
3182
  this.channelCollection.processMessages({ envelope: message, messagesContent, local });
3156
3183
  break;
3157
- case ContainerMessageType.BlobAttach:
3184
+ }
3185
+ case ContainerMessageType.BlobAttach: {
3158
3186
  this.blobManager.processBlobAttachMessage(message, local);
3159
3187
  break;
3160
- case ContainerMessageType.IdAllocation:
3188
+ }
3189
+ case ContainerMessageType.IdAllocation: {
3161
3190
  this.processIdCompressorMessages(contents as IdCreationRange[], savedOp);
3162
3191
  break;
3163
- case ContainerMessageType.GC:
3192
+ }
3193
+ case ContainerMessageType.GC: {
3164
3194
  this.garbageCollector.processMessages(
3165
3195
  contents as GarbageCollectionMessage[],
3166
3196
  message.timestamp,
3167
3197
  local,
3168
3198
  );
3169
3199
  break;
3170
- case ContainerMessageType.ChunkedOp:
3200
+ }
3201
+ case ContainerMessageType.ChunkedOp: {
3171
3202
  // From observability POV, we should not expose the rest of the system (including "op" events on object) to these messages.
3172
3203
  // Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
3173
3204
  assert(false, 0x93d /* should not even get here */);
3174
- case ContainerMessageType.Rejoin:
3205
+ }
3206
+ case ContainerMessageType.Rejoin: {
3175
3207
  break;
3176
- case ContainerMessageType.DocumentSchemaChange:
3208
+ }
3209
+ case ContainerMessageType.DocumentSchemaChange: {
3177
3210
  this.documentsSchemaController.processDocumentSchemaMessages(
3211
+ // eslint-disable-next-line import/no-deprecated
3178
3212
  contents as IDocumentSchemaChangeMessage[],
3179
3213
  local,
3180
3214
  message.sequenceNumber,
3181
3215
  );
3182
3216
  break;
3217
+ }
3183
3218
  default: {
3184
3219
  const error = getUnknownMessageTypeError(
3185
3220
  message.type,
@@ -3206,7 +3241,7 @@ export class ContainerRuntime
3206
3241
  // put it in a pending queue and delay finalization.
3207
3242
  if (this._idCompressor === undefined) {
3208
3243
  assert(
3209
- this.idCompressorMode !== undefined,
3244
+ this.sessionSchema.idCompressorMode !== undefined,
3210
3245
  0x93c /* id compressor should be enabled */,
3211
3246
  );
3212
3247
  this.pendingIdCompressorOps.push(range);
@@ -3246,7 +3281,11 @@ export class ContainerRuntime
3246
3281
  * Updates signal telemetry including emitting telemetry events.
3247
3282
  */
3248
3283
  private processSignalForTelemetry(envelope: ISignalEnvelope): void {
3249
- const { clientBroadcastSignalSequenceNumber } = envelope;
3284
+ const {
3285
+ clientBroadcastSignalSequenceNumber,
3286
+ contents: envelopeContents,
3287
+ address: envelopeAddress,
3288
+ } = envelope;
3250
3289
  if (clientBroadcastSignalSequenceNumber === undefined) {
3251
3290
  return;
3252
3291
  }
@@ -3291,8 +3330,8 @@ export class ContainerRuntime
3291
3330
  };
3292
3331
  // Only log `contents.type` when address is for container to avoid
3293
3332
  // chance that contents type is customer data.
3294
- if (envelope.address === undefined) {
3295
- details.contentsType = envelope.contents.type; // Type of signal that was received out of order.
3333
+ if (envelopeAddress === undefined) {
3334
+ details.contentsType = envelopeContents.type; // Type of signal that was received out of order.
3296
3335
  }
3297
3336
  this.mc.logger.sendTelemetryEvent({
3298
3337
  eventName: "SignalOutOfOrder",
@@ -3388,8 +3427,8 @@ export class ContainerRuntime
3388
3427
  checkpoint.rollback((message: BatchMessage) =>
3389
3428
  this.rollback(message.contents, message.localOpMetadata),
3390
3429
  );
3391
- } catch (err) {
3392
- const error2 = wrapError(err, (message) => {
3430
+ } catch (error_) {
3431
+ const error2 = wrapError(error_, (message) => {
3393
3432
  return DataProcessingError.create(
3394
3433
  `RollbackError: ${message}`,
3395
3434
  "checkpointRollback",
@@ -3549,8 +3588,9 @@ export class ContainerRuntime
3549
3588
  case ContainerMessageType.GC: {
3550
3589
  return false;
3551
3590
  }
3552
- default:
3591
+ default: {
3553
3592
  break;
3593
+ }
3554
3594
  }
3555
3595
  return true;
3556
3596
  }
@@ -3593,7 +3633,7 @@ export class ContainerRuntime
3593
3633
 
3594
3634
  // We should not track the round trip of a new signal in the case we are already tracking one.
3595
3635
  if (
3596
- clientBroadcastSignalSequenceNumber % this.defaultTelemetrySignalSampleCount === 1 &&
3636
+ clientBroadcastSignalSequenceNumber % defaultTelemetrySignalSampleCount === 1 &&
3597
3637
  this._signalTracking.roundTripSignalSequenceNumber === undefined
3598
3638
  ) {
3599
3639
  this._signalTracking.signalTimestamp = Date.now();
@@ -3687,6 +3727,12 @@ export class ContainerRuntime
3687
3727
 
3688
3728
  public readonly getAbsoluteUrl: (relativeUrl: string) => Promise<string | undefined>;
3689
3729
 
3730
+ /**
3731
+ * Builds the Summary tree including all the channels and the container state.
3732
+ *
3733
+ * @remarks - Unfortunately, this function is accessed in a non-typesafe way by a legacy first-party partner,
3734
+ * so until we can provide a proper API for their scenario, we need to ensure this function doesn't change.
3735
+ */
3690
3736
  private async summarizeInternal(
3691
3737
  fullTree: boolean,
3692
3738
  trackState: boolean,
@@ -3834,8 +3880,10 @@ export class ContainerRuntime
3834
3880
  const { dataStoreRoutes, blobManagerRoutes } =
3835
3881
  this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
3836
3882
 
3837
- const deletedRoutes = this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes);
3838
- return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
3883
+ return [
3884
+ ...this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes),
3885
+ ...this.blobManager.deleteSweepReadyNodes(blobManagerRoutes),
3886
+ ];
3839
3887
  }
3840
3888
 
3841
3889
  /**
@@ -3864,10 +3912,13 @@ export class ContainerRuntime
3864
3912
  * Returns the type of the GC node. Currently, there are nodes that belong to the root ("/"), data stores or
3865
3913
  * blob manager.
3866
3914
  */
3915
+ // eslint-disable-next-line import/no-deprecated
3867
3916
  public getNodeType(nodePath: string): GCNodeType {
3868
3917
  if (isBlobPath(nodePath)) {
3918
+ // eslint-disable-next-line import/no-deprecated
3869
3919
  return GCNodeType.Blob;
3870
3920
  }
3921
+ // eslint-disable-next-line import/no-deprecated
3871
3922
  return this.channelCollection.getGCNodeType(nodePath) ?? GCNodeType.Other;
3872
3923
  }
3873
3924
 
@@ -3883,13 +3934,19 @@ export class ContainerRuntime
3883
3934
  }
3884
3935
 
3885
3936
  switch (this.getNodeType(nodePath)) {
3886
- case GCNodeType.Blob:
3937
+ // eslint-disable-next-line import/no-deprecated
3938
+ case GCNodeType.Blob: {
3887
3939
  return [blobManagerBasePath];
3940
+ }
3941
+ // eslint-disable-next-line import/no-deprecated
3888
3942
  case GCNodeType.DataStore:
3889
- case GCNodeType.SubDataStore:
3943
+ // eslint-disable-next-line import/no-deprecated
3944
+ case GCNodeType.SubDataStore: {
3890
3945
  return this.channelCollection.getDataStorePackagePath(nodePath);
3891
- default:
3946
+ }
3947
+ default: {
3892
3948
  assert(false, 0x2de /* "Package path requested for unsupported node type." */);
3949
+ }
3893
3950
  }
3894
3951
  }
3895
3952
 
@@ -3935,6 +3992,7 @@ export class ContainerRuntime
3935
3992
  fullGC?: boolean;
3936
3993
  },
3937
3994
  telemetryContext?: ITelemetryContext,
3995
+ // eslint-disable-next-line import/no-deprecated
3938
3996
  ): Promise<IGCStats | undefined> {
3939
3997
  return this.garbageCollector.collectGarbage(options, telemetryContext);
3940
3998
  }
@@ -3977,8 +4035,10 @@ export class ContainerRuntime
3977
4035
  * op processing, updating SummarizerNode state tracking, and garbage collection.
3978
4036
  * @param options - options controlling how the summary is generated or submitted
3979
4037
  */
4038
+ // eslint-disable-next-line import/no-deprecated
3980
4039
  public async submitSummary(options: ISubmitSummaryOptions): Promise<SubmitSummaryResult> {
3981
4040
  const {
4041
+ cancellationToken,
3982
4042
  fullTree = false,
3983
4043
  finalAttempt = false,
3984
4044
  summaryLogger,
@@ -4098,7 +4158,7 @@ export class ContainerRuntime
4098
4158
  eventName: "LatestSummaryRefSeqNumMismatch",
4099
4159
  details: {
4100
4160
  ...startSummaryResult,
4101
- mismatchNumbers: Array.from(startSummaryResult.mismatchNumbers),
4161
+ mismatchNumbers: [...startSummaryResult.mismatchNumbers],
4102
4162
  },
4103
4163
  });
4104
4164
 
@@ -4122,7 +4182,7 @@ export class ContainerRuntime
4122
4182
  // summarizer to reconnect in the future.
4123
4183
  // Also checking for cancellation is a must as summary process may be abandoned for other reasons,
4124
4184
  // like loss of connectivity for main (interactive) client.
4125
- if (options.cancellationToken.cancelled) {
4185
+ if (cancellationToken.cancelled) {
4126
4186
  return { continue: false, error: "disconnected" };
4127
4187
  }
4128
4188
  // That said, we rely on submitSystemMessage() that today only works in connected state.
@@ -4263,10 +4323,7 @@ export class ContainerRuntime
4263
4323
 
4264
4324
  let handle: string;
4265
4325
  try {
4266
- handle = await this.storage.uploadSummaryWithContext(
4267
- summarizeResult.summary,
4268
- summaryContext,
4269
- );
4326
+ handle = await this.storage.uploadSummaryWithContext(summaryTree, summaryContext);
4270
4327
  } catch (error) {
4271
4328
  return {
4272
4329
  stage: "generate",
@@ -4416,14 +4473,14 @@ export class ContainerRuntime
4416
4473
  }
4417
4474
 
4418
4475
  private updateDocumentDirtyState(dirty: boolean): void {
4419
- if (this.attachState !== AttachState.Attached) {
4420
- assert(dirty, 0x3d2 /* Non-attached container is dirty */);
4421
- } else {
4476
+ if (this.attachState === AttachState.Attached) {
4422
4477
  // Other way is not true = see this.isContainerMessageDirtyable()
4423
4478
  assert(
4424
4479
  !dirty || this.hasPendingMessages(),
4425
4480
  0x3d3 /* if doc is dirty, there has to be pending ops */,
4426
4481
  );
4482
+ } else {
4483
+ assert(dirty, 0x3d2 /* Non-attached container is dirty */);
4427
4484
  }
4428
4485
 
4429
4486
  if (this.dirtyContainer === dirty) {
@@ -4520,7 +4577,7 @@ export class ContainerRuntime
4520
4577
  // on this callback to do actual sending.
4521
4578
  const schemaChangeMessage = this.documentsSchemaController.maybeSendSchemaMessage();
4522
4579
  if (schemaChangeMessage) {
4523
- this.logger.sendTelemetryEvent({
4580
+ this.mc.logger.sendTelemetryEvent({
4524
4581
  eventName: "SchemaChangeProposal",
4525
4582
  refSeq: schemaChangeMessage.refSeq,
4526
4583
  version: schemaChangeMessage.version,
@@ -4574,6 +4631,9 @@ export class ContainerRuntime
4574
4631
  }
4575
4632
 
4576
4633
  this.flushTaskExists = true;
4634
+
4635
+ // TODO: hoist this out of the function scope to save unnecessary allocations
4636
+ // eslint-disable-next-line unicorn/consistent-function-scoping -- Separate `flush` method already exists in outer scope
4577
4637
  const flush = (): void => {
4578
4638
  this.flushTaskExists = false;
4579
4639
  try {
@@ -4584,27 +4644,30 @@ export class ContainerRuntime
4584
4644
  };
4585
4645
 
4586
4646
  switch (this.flushMode) {
4587
- case FlushMode.TurnBased:
4647
+ case FlushMode.TurnBased: {
4588
4648
  // When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
4589
4649
  // batch at the end of the turn
4590
4650
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
4591
4651
  Promise.resolve().then(flush);
4592
4652
  break;
4653
+ }
4593
4654
 
4594
4655
  // FlushModeExperimental is experimental and not exposed directly in the runtime APIs
4595
- case FlushModeExperimental.Async as unknown as FlushMode:
4656
+ case FlushModeExperimental.Async as unknown as FlushMode: {
4596
4657
  // When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
4597
4658
  // batch when all micro-tasks are complete.
4598
4659
  // Compared to TurnBased, this flush mode will capture more ops into the same batch.
4599
4660
  setTimeout(flush, 0);
4600
4661
  break;
4662
+ }
4601
4663
 
4602
- default:
4664
+ default: {
4603
4665
  assert(
4604
4666
  this._orderSequentiallyCalls > 0,
4605
4667
  0x587 /* Unreachable unless running under orderSequentially */,
4606
4668
  );
4607
4669
  break;
4670
+ }
4608
4671
  }
4609
4672
  }
4610
4673
 
@@ -4621,10 +4684,7 @@ export class ContainerRuntime
4621
4684
  // System message should not be sent in the middle of the batch.
4622
4685
  assert(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
4623
4686
 
4624
- // back-compat: ADO #1385: Make this call unconditional in the future
4625
- return this.submitSummaryFn !== undefined
4626
- ? this.submitSummaryFn(contents, referenceSequenceNumber)
4627
- : this.submitFn(MessageType.Summarize, contents, false);
4687
+ return this.submitSummaryFn(contents, referenceSequenceNumber);
4628
4688
  }
4629
4689
 
4630
4690
  /**
@@ -4674,17 +4734,18 @@ export class ContainerRuntime
4674
4734
  opMetadata: Record<string, unknown> | undefined,
4675
4735
  ): void {
4676
4736
  assert(
4677
- !this.isSummarizerClient,
4737
+ this._summarizer === undefined,
4678
4738
  0x8f2 /* Summarizer never reconnects so should never resubmit */,
4679
4739
  );
4680
4740
  switch (message.type) {
4681
4741
  case ContainerMessageType.FluidDataStoreOp:
4682
4742
  case ContainerMessageType.Attach:
4683
- case ContainerMessageType.Alias:
4743
+ case ContainerMessageType.Alias: {
4684
4744
  // For Operations, call resubmitDataStoreOp which will find the right store
4685
4745
  // and trigger resubmission on it.
4686
4746
  this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
4687
4747
  break;
4748
+ }
4688
4749
  case ContainerMessageType.IdAllocation: {
4689
4750
  // Allocation ops are never resubmitted/rebased. This is because they require special handling to
4690
4751
  // avoid being submitted out of order. For example, if the pending state manager contained
@@ -4695,20 +4756,24 @@ export class ContainerRuntime
4695
4756
  // all pending IDs. The resubmitted allocation ops are then ignored here.
4696
4757
  break;
4697
4758
  }
4698
- case ContainerMessageType.BlobAttach:
4759
+ case ContainerMessageType.BlobAttach: {
4699
4760
  this.blobManager.reSubmit(opMetadata);
4700
4761
  break;
4701
- case ContainerMessageType.Rejoin:
4762
+ }
4763
+ case ContainerMessageType.Rejoin: {
4702
4764
  this.submit(message);
4703
4765
  break;
4704
- case ContainerMessageType.GC:
4766
+ }
4767
+ case ContainerMessageType.GC: {
4705
4768
  this.submit(message);
4706
4769
  break;
4707
- case ContainerMessageType.DocumentSchemaChange:
4770
+ }
4771
+ case ContainerMessageType.DocumentSchemaChange: {
4708
4772
  // There is no need to resend this message. Document schema controller will properly resend it again (if needed)
4709
4773
  // on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
4710
4774
  // send any ops, as some other client already changed schema.
4711
4775
  break;
4776
+ }
4712
4777
  default: {
4713
4778
  const error = getUnknownMessageTypeError(message.type, "reSubmitCore" /* codePath */);
4714
4779
  this.closeFn(error);
@@ -4721,19 +4786,22 @@ export class ContainerRuntime
4721
4786
  // Need to parse from string for back-compat
4722
4787
  const { type, contents } = this.parseLocalOpContent(content);
4723
4788
  switch (type) {
4724
- case ContainerMessageType.FluidDataStoreOp:
4789
+ case ContainerMessageType.FluidDataStoreOp: {
4725
4790
  // For operations, call rollbackDataStoreOp which will find the right store
4726
4791
  // and trigger rollback on it.
4727
4792
  this.channelCollection.rollback(type, contents, localOpMetadata);
4728
4793
  break;
4729
- default:
4794
+ }
4795
+ default: {
4730
4796
  throw new Error(`Can't rollback ${type}`);
4797
+ }
4731
4798
  }
4732
4799
  }
4733
4800
 
4734
4801
  /**
4735
4802
  * Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck
4736
4803
  */
4804
+ // eslint-disable-next-line import/no-deprecated
4737
4805
  public async refreshLatestSummaryAck(options: IRefreshSummaryAckOptions): Promise<void> {
4738
4806
  const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
4739
4807
  // proposalHandle is always passed from RunningSummarizer.
@@ -4780,6 +4848,9 @@ export class ContainerRuntime
4780
4848
  };
4781
4849
  }
4782
4850
 
4851
+ private readonly readAndParseBlob = async <T>(id: string): Promise<T> =>
4852
+ readAndParse<T>(this.storage, id);
4853
+
4783
4854
  /**
4784
4855
  * Fetches the latest snapshot from storage. If the fetched snapshot is same or newer than the one for which ack
4785
4856
  * was received, close this client. Fetching the snapshot will update the cache for this client so if it's
@@ -4840,6 +4911,7 @@ export class ContainerRuntime
4840
4911
  snapshotTree = snapshot.snapshotTree;
4841
4912
  } else {
4842
4913
  const versions = await this.storage.getVersions(
4914
+ // eslint-disable-next-line unicorn/no-null
4843
4915
  null,
4844
4916
  1,
4845
4917
  scenarioName,
@@ -4855,9 +4927,8 @@ export class ContainerRuntime
4855
4927
  }
4856
4928
 
4857
4929
  props.getSnapshotDuration = trace.trace().duration;
4858
- const readAndParseBlob = async <T>(id: string): Promise<T> =>
4859
- readAndParse<T>(this.storage, id);
4860
- const snapshotRefSeq = await seqFromTree(snapshotTree, readAndParseBlob);
4930
+
4931
+ const snapshotRefSeq = await seqFromTree(snapshotTree, this.readAndParseBlob);
4861
4932
  props.snapshotRefSeq = snapshotRefSeq;
4862
4933
  props.newerSnapshotPresent = snapshotRefSeq >= targetRefSeq;
4863
4934
 
@@ -4937,28 +5008,28 @@ export class ContainerRuntime
4937
5008
  }
4938
5009
 
4939
5010
  public summarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults {
4940
- if (this.isSummarizerClient) {
4941
- return this.summarizer.summarizeOnDemand(options);
4942
- } else if (this.summaryManager !== undefined) {
4943
- return this.summaryManager.summarizeOnDemand(options);
4944
- } else {
5011
+ if (this._summarizer !== undefined) {
5012
+ return this._summarizer.summarizeOnDemand(options);
5013
+ } else if (this.summaryManager === undefined) {
4945
5014
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
4946
5015
  // disableSummaries is turned on. We are throwing instead of returning a failure here,
4947
5016
  // because it is a misuse of the API rather than an expected failure.
4948
5017
  throw new UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
5018
+ } else {
5019
+ return this.summaryManager.summarizeOnDemand(options);
4949
5020
  }
4950
5021
  }
4951
5022
 
4952
5023
  public enqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult {
4953
- if (this.isSummarizerClient) {
4954
- return this.summarizer.enqueueSummarize(options);
4955
- } else if (this.summaryManager !== undefined) {
4956
- return this.summaryManager.enqueueSummarize(options);
4957
- } else {
5024
+ if (this._summarizer !== undefined) {
5025
+ return this._summarizer.enqueueSummarize(options);
5026
+ } else if (this.summaryManager === undefined) {
4958
5027
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
4959
5028
  // generateSummaries is turned off. We are throwing instead of returning a failure here,
4960
5029
  // because it is a misuse of the API rather than an expected failure.
4961
5030
  throw new UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
5031
+ } else {
5032
+ return this.summaryManager.enqueueSummarize(options);
4962
5033
  }
4963
5034
  }
4964
5035