@fluidframework/container-runtime 2.0.0-dev-rc.2.0.0.246488 → 2.0.0-dev-rc.3.0.0.253463

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 (544) hide show
  1. package/api-report/container-runtime.api.md +109 -55
  2. package/dist/batchTracker.d.ts +1 -1
  3. package/dist/batchTracker.d.ts.map +1 -1
  4. package/dist/batchTracker.js +4 -4
  5. package/dist/batchTracker.js.map +1 -1
  6. package/dist/blobManager.d.ts +33 -25
  7. package/dist/blobManager.d.ts.map +1 -1
  8. package/dist/blobManager.js +82 -100
  9. package/dist/blobManager.js.map +1 -1
  10. package/dist/channelCollection.d.ts +7 -6
  11. package/dist/channelCollection.d.ts.map +1 -1
  12. package/dist/channelCollection.js +110 -77
  13. package/dist/channelCollection.js.map +1 -1
  14. package/dist/connectionTelemetry.d.ts +3 -3
  15. package/dist/connectionTelemetry.d.ts.map +1 -1
  16. package/dist/connectionTelemetry.js +17 -17
  17. package/dist/connectionTelemetry.js.map +1 -1
  18. package/dist/container-runtime-alpha.d.ts +263 -41
  19. package/dist/container-runtime-beta.d.ts +44 -30
  20. package/dist/container-runtime-public.d.ts +44 -30
  21. package/dist/container-runtime-untrimmed.d.ts +265 -56
  22. package/dist/containerHandleContext.d.ts.map +1 -1
  23. package/dist/containerHandleContext.js +2 -2
  24. package/dist/containerHandleContext.js.map +1 -1
  25. package/dist/containerRuntime.d.ts +40 -30
  26. package/dist/containerRuntime.d.ts.map +1 -1
  27. package/dist/containerRuntime.js +376 -255
  28. package/dist/containerRuntime.js.map +1 -1
  29. package/dist/dataStore.d.ts +1 -1
  30. package/dist/dataStore.d.ts.map +1 -1
  31. package/dist/dataStore.js +7 -7
  32. package/dist/dataStore.js.map +1 -1
  33. package/dist/dataStoreContext.d.ts +9 -9
  34. package/dist/dataStoreContext.d.ts.map +1 -1
  35. package/dist/dataStoreContext.js +74 -74
  36. package/dist/dataStoreContext.js.map +1 -1
  37. package/dist/dataStoreContexts.d.ts.map +1 -1
  38. package/dist/dataStoreContexts.js +11 -11
  39. package/dist/dataStoreContexts.js.map +1 -1
  40. package/dist/dataStoreRegistry.d.ts +1 -1
  41. package/dist/dataStoreRegistry.d.ts.map +1 -1
  42. package/dist/dataStoreRegistry.js +2 -2
  43. package/dist/dataStoreRegistry.js.map +1 -1
  44. package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
  45. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
  46. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  47. package/dist/deltaScheduler.d.ts +1 -1
  48. package/dist/deltaScheduler.d.ts.map +1 -1
  49. package/dist/deltaScheduler.js +6 -6
  50. package/dist/deltaScheduler.js.map +1 -1
  51. package/dist/error.d.ts +1 -1
  52. package/dist/error.d.ts.map +1 -1
  53. package/dist/error.js +4 -4
  54. package/dist/error.js.map +1 -1
  55. package/dist/gc/garbageCollection.d.ts +3 -2
  56. package/dist/gc/garbageCollection.d.ts.map +1 -1
  57. package/dist/gc/garbageCollection.js +21 -21
  58. package/dist/gc/garbageCollection.js.map +1 -1
  59. package/dist/gc/gcConfigs.d.ts +2 -2
  60. package/dist/gc/gcConfigs.d.ts.map +1 -1
  61. package/dist/gc/gcConfigs.js +4 -5
  62. package/dist/gc/gcConfigs.js.map +1 -1
  63. package/dist/gc/gcDefinitions.d.ts +4 -3
  64. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  65. package/dist/gc/gcDefinitions.js.map +1 -1
  66. package/dist/gc/gcHelpers.d.ts +5 -1
  67. package/dist/gc/gcHelpers.d.ts.map +1 -1
  68. package/dist/gc/gcHelpers.js +21 -12
  69. package/dist/gc/gcHelpers.js.map +1 -1
  70. package/dist/gc/gcSummaryStateTracker.d.ts +2 -2
  71. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  72. package/dist/gc/gcSummaryStateTracker.js +11 -11
  73. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  74. package/dist/gc/gcTelemetry.d.ts +2 -1
  75. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  76. package/dist/gc/gcTelemetry.js +11 -9
  77. package/dist/gc/gcTelemetry.js.map +1 -1
  78. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  79. package/dist/gc/gcUnreferencedStateTracker.js +6 -6
  80. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  81. package/dist/gc/index.d.ts +1 -1
  82. package/dist/gc/index.d.ts.map +1 -1
  83. package/dist/gc/index.js +2 -1
  84. package/dist/gc/index.js.map +1 -1
  85. package/dist/index.d.ts +2 -2
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +4 -2
  88. package/dist/index.js.map +1 -1
  89. package/dist/messageTypes.d.ts +11 -5
  90. package/dist/messageTypes.d.ts.map +1 -1
  91. package/dist/messageTypes.js +4 -0
  92. package/dist/messageTypes.js.map +1 -1
  93. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  94. package/dist/opLifecycle/batchManager.js.map +1 -1
  95. package/dist/opLifecycle/definitions.d.ts +2 -20
  96. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  97. package/dist/opLifecycle/definitions.js.map +1 -1
  98. package/dist/opLifecycle/index.d.ts +3 -3
  99. package/dist/opLifecycle/index.d.ts.map +1 -1
  100. package/dist/opLifecycle/index.js +3 -1
  101. package/dist/opLifecycle/index.js.map +1 -1
  102. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  103. package/dist/opLifecycle/opCompressor.js +5 -6
  104. package/dist/opLifecycle/opCompressor.js.map +1 -1
  105. package/dist/opLifecycle/opDecompressor.d.ts +15 -4
  106. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  107. package/dist/opLifecycle/opDecompressor.js +62 -63
  108. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  109. package/dist/opLifecycle/opGroupingManager.d.ts +2 -1
  110. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  111. package/dist/opLifecycle/opGroupingManager.js +14 -16
  112. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  113. package/dist/opLifecycle/opSplitter.d.ts +12 -4
  114. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  115. package/dist/opLifecycle/opSplitter.js +63 -53
  116. package/dist/opLifecycle/opSplitter.js.map +1 -1
  117. package/dist/opLifecycle/outbox.d.ts +2 -1
  118. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  119. package/dist/opLifecycle/outbox.js +19 -24
  120. package/dist/opLifecycle/outbox.js.map +1 -1
  121. package/dist/opLifecycle/remoteMessageProcessor.d.ts +8 -0
  122. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  123. package/dist/opLifecycle/remoteMessageProcessor.js +36 -35
  124. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  125. package/dist/packageVersion.d.ts +1 -1
  126. package/dist/packageVersion.js +1 -1
  127. package/dist/packageVersion.js.map +1 -1
  128. package/dist/pendingStateManager.d.ts +1 -1
  129. package/dist/pendingStateManager.d.ts.map +1 -1
  130. package/dist/pendingStateManager.js +18 -18
  131. package/dist/pendingStateManager.js.map +1 -1
  132. package/dist/scheduleManager.d.ts +1 -1
  133. package/dist/scheduleManager.d.ts.map +1 -1
  134. package/dist/scheduleManager.js +24 -24
  135. package/dist/scheduleManager.js.map +1 -1
  136. package/dist/storageServiceWithAttachBlobs.d.ts +2 -2
  137. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -1
  138. package/dist/storageServiceWithAttachBlobs.js +2 -2
  139. package/dist/storageServiceWithAttachBlobs.js.map +1 -1
  140. package/dist/summary/documentSchema.d.ts +209 -0
  141. package/dist/summary/documentSchema.d.ts.map +1 -0
  142. package/dist/summary/documentSchema.js +382 -0
  143. package/dist/summary/documentSchema.js.map +1 -0
  144. package/dist/summary/index.d.ts +2 -1
  145. package/dist/summary/index.d.ts.map +1 -1
  146. package/dist/summary/index.js +4 -1
  147. package/dist/summary/index.js.map +1 -1
  148. package/dist/summary/orderedClientElection.d.ts +2 -2
  149. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  150. package/dist/summary/orderedClientElection.js +8 -7
  151. package/dist/summary/orderedClientElection.js.map +1 -1
  152. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
  153. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  154. package/dist/summary/runWhileConnectedCoordinator.js +3 -3
  155. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  156. package/dist/summary/runningSummarizer.d.ts +3 -3
  157. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  158. package/dist/summary/runningSummarizer.js +16 -16
  159. package/dist/summary/runningSummarizer.js.map +1 -1
  160. package/dist/summary/summarizer.d.ts +3 -2
  161. package/dist/summary/summarizer.d.ts.map +1 -1
  162. package/dist/summary/summarizer.js +13 -13
  163. package/dist/summary/summarizer.js.map +1 -1
  164. package/dist/summary/summarizerClientElection.d.ts +2 -2
  165. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  166. package/dist/summary/summarizerClientElection.js.map +1 -1
  167. package/dist/summary/summarizerHeuristics.d.ts +1 -1
  168. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  169. package/dist/summary/summarizerHeuristics.js +2 -2
  170. package/dist/summary/summarizerHeuristics.js.map +1 -1
  171. package/dist/summary/summarizerNode/summarizerNode.d.ts +3 -2
  172. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  173. package/dist/summary/summarizerNode/summarizerNode.js +28 -28
  174. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  175. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
  176. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  177. package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -3
  178. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  179. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -1
  180. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  181. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +14 -14
  182. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  183. package/dist/summary/summarizerTypes.d.ts +5 -3
  184. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  185. package/dist/summary/summarizerTypes.js.map +1 -1
  186. package/dist/summary/summaryCollection.d.ts +2 -2
  187. package/dist/summary/summaryCollection.d.ts.map +1 -1
  188. package/dist/summary/summaryCollection.js +7 -7
  189. package/dist/summary/summaryCollection.js.map +1 -1
  190. package/dist/summary/summaryFormat.d.ts +6 -17
  191. package/dist/summary/summaryFormat.d.ts.map +1 -1
  192. package/dist/summary/summaryFormat.js +8 -8
  193. package/dist/summary/summaryFormat.js.map +1 -1
  194. package/dist/summary/summaryGenerator.d.ts +4 -3
  195. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  196. package/dist/summary/summaryGenerator.js +17 -17
  197. package/dist/summary/summaryGenerator.js.map +1 -1
  198. package/dist/summary/summaryManager.d.ts +1 -1
  199. package/dist/summary/summaryManager.d.ts.map +1 -1
  200. package/dist/summary/summaryManager.js +15 -14
  201. package/dist/summary/summaryManager.js.map +1 -1
  202. package/lib/batchTracker.d.ts +1 -1
  203. package/lib/batchTracker.d.ts.map +1 -1
  204. package/lib/batchTracker.js +2 -2
  205. package/lib/batchTracker.js.map +1 -1
  206. package/lib/blobManager.d.ts +33 -25
  207. package/lib/blobManager.d.ts.map +1 -1
  208. package/lib/blobManager.js +48 -66
  209. package/lib/blobManager.js.map +1 -1
  210. package/lib/channelCollection.d.ts +7 -6
  211. package/lib/channelCollection.d.ts.map +1 -1
  212. package/lib/channelCollection.js +47 -14
  213. package/lib/channelCollection.js.map +1 -1
  214. package/lib/connectionTelemetry.d.ts +3 -3
  215. package/lib/connectionTelemetry.d.ts.map +1 -1
  216. package/lib/connectionTelemetry.js +3 -3
  217. package/lib/connectionTelemetry.js.map +1 -1
  218. package/lib/container-runtime-alpha.d.ts +263 -41
  219. package/lib/container-runtime-beta.d.ts +44 -30
  220. package/lib/container-runtime-public.d.ts +44 -30
  221. package/lib/container-runtime-untrimmed.d.ts +265 -56
  222. package/lib/containerHandleContext.d.ts.map +1 -1
  223. package/lib/containerHandleContext.js +1 -1
  224. package/lib/containerHandleContext.js.map +1 -1
  225. package/lib/containerRuntime.d.ts +40 -30
  226. package/lib/containerRuntime.d.ts.map +1 -1
  227. package/lib/containerRuntime.js +224 -101
  228. package/lib/containerRuntime.js.map +1 -1
  229. package/lib/dataStore.d.ts +1 -1
  230. package/lib/dataStore.d.ts.map +1 -1
  231. package/lib/dataStore.js +2 -2
  232. package/lib/dataStore.js.map +1 -1
  233. package/lib/dataStoreContext.d.ts +9 -9
  234. package/lib/dataStoreContext.d.ts.map +1 -1
  235. package/lib/dataStoreContext.js +8 -8
  236. package/lib/dataStoreContext.js.map +1 -1
  237. package/lib/dataStoreContexts.d.ts.map +1 -1
  238. package/lib/dataStoreContexts.js +2 -2
  239. package/lib/dataStoreContexts.js.map +1 -1
  240. package/lib/dataStoreRegistry.d.ts +1 -1
  241. package/lib/dataStoreRegistry.d.ts.map +1 -1
  242. package/lib/dataStoreRegistry.js +1 -1
  243. package/lib/dataStoreRegistry.js.map +1 -1
  244. package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
  245. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
  246. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  247. package/lib/deltaScheduler.d.ts +1 -1
  248. package/lib/deltaScheduler.d.ts.map +1 -1
  249. package/lib/deltaScheduler.js +1 -1
  250. package/lib/deltaScheduler.js.map +1 -1
  251. package/lib/error.d.ts +1 -1
  252. package/lib/error.d.ts.map +1 -1
  253. package/lib/error.js +2 -2
  254. package/lib/error.js.map +1 -1
  255. package/lib/gc/garbageCollection.d.ts +3 -2
  256. package/lib/gc/garbageCollection.d.ts.map +1 -1
  257. package/lib/gc/garbageCollection.js +6 -6
  258. package/lib/gc/garbageCollection.js.map +1 -1
  259. package/lib/gc/gcConfigs.d.ts +2 -2
  260. package/lib/gc/gcConfigs.d.ts.map +1 -1
  261. package/lib/gc/gcConfigs.js +4 -5
  262. package/lib/gc/gcConfigs.js.map +1 -1
  263. package/lib/gc/gcDefinitions.d.ts +4 -3
  264. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  265. package/lib/gc/gcDefinitions.js.map +1 -1
  266. package/lib/gc/gcHelpers.d.ts +5 -1
  267. package/lib/gc/gcHelpers.d.ts.map +1 -1
  268. package/lib/gc/gcHelpers.js +10 -2
  269. package/lib/gc/gcHelpers.js.map +1 -1
  270. package/lib/gc/gcSummaryStateTracker.d.ts +2 -2
  271. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  272. package/lib/gc/gcSummaryStateTracker.js +2 -2
  273. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  274. package/lib/gc/gcTelemetry.d.ts +2 -1
  275. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  276. package/lib/gc/gcTelemetry.js +4 -2
  277. package/lib/gc/gcTelemetry.js.map +1 -1
  278. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  279. package/lib/gc/gcUnreferencedStateTracker.js +2 -2
  280. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  281. package/lib/gc/index.d.ts +1 -1
  282. package/lib/gc/index.d.ts.map +1 -1
  283. package/lib/gc/index.js +1 -1
  284. package/lib/gc/index.js.map +1 -1
  285. package/lib/index.d.ts +2 -2
  286. package/lib/index.d.ts.map +1 -1
  287. package/lib/index.js +2 -2
  288. package/lib/index.js.map +1 -1
  289. package/lib/messageTypes.d.ts +11 -5
  290. package/lib/messageTypes.d.ts.map +1 -1
  291. package/lib/messageTypes.js +4 -0
  292. package/lib/messageTypes.js.map +1 -1
  293. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  294. package/lib/opLifecycle/batchManager.js.map +1 -1
  295. package/lib/opLifecycle/definitions.d.ts +2 -20
  296. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  297. package/lib/opLifecycle/definitions.js.map +1 -1
  298. package/lib/opLifecycle/index.d.ts +3 -3
  299. package/lib/opLifecycle/index.d.ts.map +1 -1
  300. package/lib/opLifecycle/index.js +2 -2
  301. package/lib/opLifecycle/index.js.map +1 -1
  302. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  303. package/lib/opLifecycle/opCompressor.js +2 -3
  304. package/lib/opLifecycle/opCompressor.js.map +1 -1
  305. package/lib/opLifecycle/opDecompressor.d.ts +15 -4
  306. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  307. package/lib/opLifecycle/opDecompressor.js +61 -62
  308. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  309. package/lib/opLifecycle/opGroupingManager.d.ts +2 -1
  310. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  311. package/lib/opLifecycle/opGroupingManager.js +9 -12
  312. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  313. package/lib/opLifecycle/opSplitter.d.ts +12 -4
  314. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  315. package/lib/opLifecycle/opSplitter.js +47 -38
  316. package/lib/opLifecycle/opSplitter.js.map +1 -1
  317. package/lib/opLifecycle/outbox.d.ts +2 -1
  318. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  319. package/lib/opLifecycle/outbox.js +8 -13
  320. package/lib/opLifecycle/outbox.js.map +1 -1
  321. package/lib/opLifecycle/remoteMessageProcessor.d.ts +8 -0
  322. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  323. package/lib/opLifecycle/remoteMessageProcessor.js +36 -35
  324. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  325. package/lib/packageVersion.d.ts +1 -1
  326. package/lib/packageVersion.js +1 -1
  327. package/lib/packageVersion.js.map +1 -1
  328. package/lib/pendingStateManager.d.ts +1 -1
  329. package/lib/pendingStateManager.d.ts.map +1 -1
  330. package/lib/pendingStateManager.js +2 -2
  331. package/lib/pendingStateManager.js.map +1 -1
  332. package/lib/scheduleManager.d.ts +1 -1
  333. package/lib/scheduleManager.d.ts.map +1 -1
  334. package/lib/scheduleManager.js +3 -3
  335. package/lib/scheduleManager.js.map +1 -1
  336. package/lib/storageServiceWithAttachBlobs.d.ts +2 -2
  337. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -1
  338. package/lib/storageServiceWithAttachBlobs.js +1 -1
  339. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  340. package/lib/summary/documentSchema.d.ts +209 -0
  341. package/lib/summary/documentSchema.d.ts.map +1 -0
  342. package/lib/summary/documentSchema.js +378 -0
  343. package/lib/summary/documentSchema.js.map +1 -0
  344. package/lib/summary/index.d.ts +2 -1
  345. package/lib/summary/index.d.ts.map +1 -1
  346. package/lib/summary/index.js +1 -0
  347. package/lib/summary/index.js.map +1 -1
  348. package/lib/summary/orderedClientElection.d.ts +2 -2
  349. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  350. package/lib/summary/orderedClientElection.js +3 -2
  351. package/lib/summary/orderedClientElection.js.map +1 -1
  352. package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -1
  353. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  354. package/lib/summary/runWhileConnectedCoordinator.js +1 -1
  355. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  356. package/lib/summary/runningSummarizer.d.ts +3 -3
  357. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  358. package/lib/summary/runningSummarizer.js +3 -3
  359. package/lib/summary/runningSummarizer.js.map +1 -1
  360. package/lib/summary/summarizer.d.ts +3 -2
  361. package/lib/summary/summarizer.d.ts.map +1 -1
  362. package/lib/summary/summarizer.js +3 -3
  363. package/lib/summary/summarizer.js.map +1 -1
  364. package/lib/summary/summarizerClientElection.d.ts +2 -2
  365. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  366. package/lib/summary/summarizerClientElection.js.map +1 -1
  367. package/lib/summary/summarizerHeuristics.d.ts +1 -1
  368. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  369. package/lib/summary/summarizerHeuristics.js +1 -1
  370. package/lib/summary/summarizerHeuristics.js.map +1 -1
  371. package/lib/summary/summarizerNode/summarizerNode.d.ts +3 -2
  372. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  373. package/lib/summary/summarizerNode/summarizerNode.js +5 -5
  374. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  375. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
  376. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  377. package/lib/summary/summarizerNode/summarizerNodeUtils.js +1 -1
  378. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  379. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -1
  380. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  381. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
  382. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  383. package/lib/summary/summarizerTypes.d.ts +5 -3
  384. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  385. package/lib/summary/summarizerTypes.js.map +1 -1
  386. package/lib/summary/summaryCollection.d.ts +2 -2
  387. package/lib/summary/summaryCollection.d.ts.map +1 -1
  388. package/lib/summary/summaryCollection.js +1 -1
  389. package/lib/summary/summaryCollection.js.map +1 -1
  390. package/lib/summary/summaryFormat.d.ts +6 -17
  391. package/lib/summary/summaryFormat.d.ts.map +1 -1
  392. package/lib/summary/summaryFormat.js +3 -3
  393. package/lib/summary/summaryFormat.js.map +1 -1
  394. package/lib/summary/summaryGenerator.d.ts +4 -3
  395. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  396. package/lib/summary/summaryGenerator.js +4 -4
  397. package/lib/summary/summaryGenerator.js.map +1 -1
  398. package/lib/summary/summaryManager.d.ts +1 -1
  399. package/lib/summary/summaryManager.d.ts.map +1 -1
  400. package/lib/summary/summaryManager.js +9 -8
  401. package/lib/summary/summaryManager.js.map +1 -1
  402. package/lib/tsdoc-metadata.json +11 -0
  403. package/package.json +34 -32
  404. package/src/batchTracker.ts +4 -3
  405. package/src/blobManager.ts +100 -69
  406. package/src/channelCollection.ts +86 -43
  407. package/src/connectionTelemetry.ts +12 -12
  408. package/src/containerHandleContext.ts +3 -2
  409. package/src/containerRuntime.ts +419 -232
  410. package/src/dataStore.ts +5 -3
  411. package/src/dataStoreContext.ts +32 -29
  412. package/src/dataStoreContexts.ts +4 -2
  413. package/src/dataStoreRegistry.ts +2 -2
  414. package/src/deltaManagerSummarizerProxy.ts +1 -1
  415. package/src/deltaScheduler.ts +2 -1
  416. package/src/error.ts +2 -2
  417. package/src/gc/garbageCollection.ts +19 -18
  418. package/src/gc/gcConfigs.ts +15 -18
  419. package/src/gc/gcDefinitions.ts +6 -6
  420. package/src/gc/gcHelpers.ts +22 -5
  421. package/src/gc/gcSummaryStateTracker.ts +7 -5
  422. package/src/gc/gcTelemetry.ts +13 -7
  423. package/src/gc/gcUnreferencedStateTracker.ts +3 -2
  424. package/src/gc/index.ts +1 -0
  425. package/src/index.ts +8 -1
  426. package/src/messageTypes.ts +20 -6
  427. package/src/opLifecycle/README.md +89 -0
  428. package/src/opLifecycle/batchManager.ts +1 -0
  429. package/src/opLifecycle/definitions.ts +3 -21
  430. package/src/opLifecycle/index.ts +3 -9
  431. package/src/opLifecycle/opCompressor.ts +6 -5
  432. package/src/opLifecycle/opDecompressor.ts +84 -100
  433. package/src/opLifecycle/opGroupingManager.ts +12 -14
  434. package/src/opLifecycle/opSplitter.ts +76 -48
  435. package/src/opLifecycle/outbox.ts +17 -32
  436. package/src/opLifecycle/remoteMessageProcessor.ts +43 -59
  437. package/src/packageVersion.ts +1 -1
  438. package/src/pendingStateManager.ts +6 -6
  439. package/src/scheduleManager.ts +9 -8
  440. package/src/storageServiceWithAttachBlobs.ts +2 -2
  441. package/src/summary/documentSchema.ts +612 -0
  442. package/src/summary/index.ts +10 -1
  443. package/src/summary/orderedClientElection.ts +6 -7
  444. package/src/summary/runWhileConnectedCoordinator.ts +3 -2
  445. package/src/summary/runningSummarizer.ts +22 -20
  446. package/src/summary/summarizer.ts +17 -15
  447. package/src/summary/summarizerClientElection.ts +3 -2
  448. package/src/summary/summarizerHeuristics.ts +4 -2
  449. package/src/summary/summarizerNode/summarizerNode.ts +20 -18
  450. package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -2
  451. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +16 -8
  452. package/src/summary/summarizerTypes.ts +7 -3
  453. package/src/summary/summaryCollection.ts +3 -3
  454. package/src/summary/summaryFormat.ts +14 -26
  455. package/src/summary/summaryGenerator.ts +12 -15
  456. package/src/summary/summaryManager.ts +16 -13
  457. package/lib/test/batchTracker.spec.js +0 -88
  458. package/lib/test/batchTracker.spec.js.map +0 -1
  459. package/lib/test/blobManager.spec.js +0 -835
  460. package/lib/test/blobManager.spec.js.map +0 -1
  461. package/lib/test/channelCollection.spec.js +0 -138
  462. package/lib/test/channelCollection.spec.js.map +0 -1
  463. package/lib/test/containerRuntime.spec.js +0 -1748
  464. package/lib/test/containerRuntime.spec.js.map +0 -1
  465. package/lib/test/dataStoreContext.spec.js +0 -771
  466. package/lib/test/dataStoreContext.spec.js.map +0 -1
  467. package/lib/test/dataStoreCreation.spec.js +0 -303
  468. package/lib/test/dataStoreCreation.spec.js.map +0 -1
  469. package/lib/test/dataStoreRegistry.spec.js +0 -26
  470. package/lib/test/dataStoreRegistry.spec.js.map +0 -1
  471. package/lib/test/fuzz/fuzzUtils.js +0 -66
  472. package/lib/test/fuzz/fuzzUtils.js.map +0 -1
  473. package/lib/test/fuzz/summarizer.fuzz.spec.js +0 -31
  474. package/lib/test/fuzz/summarizer.fuzz.spec.js.map +0 -1
  475. package/lib/test/fuzz/summarizerFuzzMocks.js +0 -162
  476. package/lib/test/fuzz/summarizerFuzzMocks.js.map +0 -1
  477. package/lib/test/fuzz/summarizerFuzzSuite.js +0 -106
  478. package/lib/test/fuzz/summarizerFuzzSuite.js.map +0 -1
  479. package/lib/test/gc/garbageCollection.spec.js +0 -1464
  480. package/lib/test/gc/garbageCollection.spec.js.map +0 -1
  481. package/lib/test/gc/gcConfigs.spec.js +0 -689
  482. package/lib/test/gc/gcConfigs.spec.js.map +0 -1
  483. package/lib/test/gc/gcHelpers.spec.js +0 -110
  484. package/lib/test/gc/gcHelpers.spec.js.map +0 -1
  485. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js +0 -68
  486. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js.map +0 -1
  487. package/lib/test/gc/gcStats.spec.js +0 -390
  488. package/lib/test/gc/gcStats.spec.js.map +0 -1
  489. package/lib/test/gc/gcSummaryStateTracker.spec.js +0 -228
  490. package/lib/test/gc/gcSummaryStateTracker.spec.js.map +0 -1
  491. package/lib/test/gc/gcTelemetry.spec.js +0 -530
  492. package/lib/test/gc/gcTelemetry.spec.js.map +0 -1
  493. package/lib/test/gc/gcUnitTestHelpers.js +0 -29
  494. package/lib/test/gc/gcUnitTestHelpers.js.map +0 -1
  495. package/lib/test/gc/gcUnreferencedStateTracker.spec.js +0 -192
  496. package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +0 -1
  497. package/lib/test/getPendingBlobs.spec.js +0 -193
  498. package/lib/test/getPendingBlobs.spec.js.map +0 -1
  499. package/lib/test/hardwareStats.spec.js +0 -93
  500. package/lib/test/hardwareStats.spec.js.map +0 -1
  501. package/lib/test/index.js +0 -6
  502. package/lib/test/index.js.map +0 -1
  503. package/lib/test/opLifecycle/OpGroupingManager.spec.js +0 -225
  504. package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +0 -1
  505. package/lib/test/opLifecycle/batchManager.spec.js +0 -189
  506. package/lib/test/opLifecycle/batchManager.spec.js.map +0 -1
  507. package/lib/test/opLifecycle/opCompressor.spec.js +0 -74
  508. package/lib/test/opLifecycle/opCompressor.spec.js.map +0 -1
  509. package/lib/test/opLifecycle/opDecompressor.spec.js +0 -218
  510. package/lib/test/opLifecycle/opDecompressor.spec.js.map +0 -1
  511. package/lib/test/opLifecycle/opSplitter.spec.js +0 -272
  512. package/lib/test/opLifecycle/opSplitter.spec.js.map +0 -1
  513. package/lib/test/opLifecycle/outbox.spec.js +0 -675
  514. package/lib/test/opLifecycle/outbox.spec.js.map +0 -1
  515. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +0 -196
  516. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +0 -1
  517. package/lib/test/pendingStateManager.spec.js +0 -329
  518. package/lib/test/pendingStateManager.spec.js.map +0 -1
  519. package/lib/test/scheduleManager.spec.js +0 -270
  520. package/lib/test/scheduleManager.spec.js.map +0 -1
  521. package/lib/test/summarizerNode.spec.js +0 -326
  522. package/lib/test/summarizerNode.spec.js.map +0 -1
  523. package/lib/test/summarizerNodeWithGc.spec.js +0 -318
  524. package/lib/test/summarizerNodeWithGc.spec.js.map +0 -1
  525. package/lib/test/summary/orderedClientElection.spec.js +0 -535
  526. package/lib/test/summary/orderedClientElection.spec.js.map +0 -1
  527. package/lib/test/summary/runningSummarizer.spec.js +0 -1349
  528. package/lib/test/summary/runningSummarizer.spec.js.map +0 -1
  529. package/lib/test/summary/summarizer.spec.js +0 -29
  530. package/lib/test/summary/summarizer.spec.js.map +0 -1
  531. package/lib/test/summary/summarizerClientElection.spec.js +0 -436
  532. package/lib/test/summary/summarizerClientElection.spec.js.map +0 -1
  533. package/lib/test/summary/summarizerHeuristics.spec.js +0 -289
  534. package/lib/test/summary/summarizerHeuristics.spec.js.map +0 -1
  535. package/lib/test/summary/summaryCollection.spec.js +0 -200
  536. package/lib/test/summary/summaryCollection.spec.js.map +0 -1
  537. package/lib/test/summary/summaryManager.spec.js +0 -430
  538. package/lib/test/summary/summaryManager.spec.js.map +0 -1
  539. package/lib/test/summary/testQuorumClients.js +0 -34
  540. package/lib/test/summary/testQuorumClients.js.map +0 -1
  541. package/lib/test/throttler.spec.js +0 -175
  542. package/lib/test/throttler.spec.js.map +0 -1
  543. package/lib/test/types/validateContainerRuntimePrevious.generated.js +0 -180
  544. package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +0 -1
@@ -4,33 +4,34 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
8
- const container_definitions_1 = require("@fluidframework/container-definitions");
9
- const core_utils_1 = require("@fluidframework/core-utils");
7
+ exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
10
8
  const client_utils_1 = require("@fluid-internal/client-utils");
11
- const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
12
- const driver_definitions_1 = require("@fluidframework/driver-definitions");
13
- const driver_utils_1 = require("@fluidframework/driver-utils");
9
+ const container_definitions_1 = require("@fluidframework/container-definitions");
10
+ const internal_1 = require("@fluidframework/container-definitions/internal");
11
+ const internal_2 = require("@fluidframework/core-utils/internal");
12
+ const internal_3 = require("@fluidframework/driver-definitions/internal");
13
+ const internal_4 = require("@fluidframework/driver-utils/internal");
14
14
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
15
- const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
16
- const runtime_utils_1 = require("@fluidframework/runtime-utils");
15
+ const internal_5 = require("@fluidframework/runtime-definitions/internal");
16
+ const internal_6 = require("@fluidframework/runtime-utils/internal");
17
+ const internal_7 = require("@fluidframework/telemetry-utils/internal");
17
18
  const uuid_1 = require("uuid");
18
- const containerHandleContext_js_1 = require("./containerHandleContext.js");
19
- const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
20
- const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
21
- const pendingStateManager_js_1 = require("./pendingStateManager.js");
22
- const packageVersion_js_1 = require("./packageVersion.js");
19
+ const batchTracker_js_1 = require("./batchTracker.js");
23
20
  const blobManager_js_1 = require("./blobManager.js");
24
21
  const channelCollection_js_1 = require("./channelCollection.js");
25
- const index_js_1 = require("./summary/index.js");
26
- const throttler_js_1 = require("./throttler.js");
27
- const index_js_2 = require("./gc/index.js");
22
+ const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
23
+ const containerHandleContext_js_1 = require("./containerHandleContext.js");
28
24
  const dataStore_js_1 = require("./dataStore.js");
29
- const batchTracker_js_1 = require("./batchTracker.js");
30
- const scheduleManager_js_1 = require("./scheduleManager.js");
31
- const index_js_3 = require("./opLifecycle/index.js");
25
+ const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
32
26
  const deltaManagerSummarizerProxy_js_1 = require("./deltaManagerSummarizerProxy.js");
27
+ const index_js_1 = require("./gc/index.js");
33
28
  const messageTypes_js_1 = require("./messageTypes.js");
29
+ const index_js_2 = require("./opLifecycle/index.js");
30
+ const packageVersion_js_1 = require("./packageVersion.js");
31
+ const pendingStateManager_js_1 = require("./pendingStateManager.js");
32
+ const scheduleManager_js_1 = require("./scheduleManager.js");
33
+ const index_js_3 = require("./summary/index.js");
34
+ const throttler_js_1 = require("./throttler.js");
34
35
  /**
35
36
  * Utility to implement compat behaviors given an unknown message type
36
37
  * The parameters are typed to support compile-time enforcement of handling all known types/behaviors
@@ -85,8 +86,13 @@ var CompressionAlgorithms;
85
86
  (function (CompressionAlgorithms) {
86
87
  CompressionAlgorithms["lz4"] = "lz4";
87
88
  })(CompressionAlgorithms || (exports.CompressionAlgorithms = CompressionAlgorithms = {}));
89
+ /** @alpha */
90
+ exports.disabledCompressionConfig = {
91
+ minimumBatchSizeInBytes: Infinity,
92
+ compressionAlgorithm: CompressionAlgorithms.lz4,
93
+ };
88
94
  const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
89
- const defaultFlushMode = runtime_definitions_1.FlushMode.TurnBased;
95
+ const defaultFlushMode = internal_5.FlushMode.TurnBased;
90
96
  // The actual limit is 1Mb (socket.io and Kafka limits)
91
97
  // We can't estimate it fully, as we
92
98
  // - do not know what properties relay service will add
@@ -108,26 +114,12 @@ exports.defaultPendingOpsRetryDelayMs = 1000;
108
114
  * This delay's goal is to prevent tight restart loops
109
115
  */
110
116
  const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
111
- /**
112
- * @deprecated use ContainerRuntimeMessageType instead
113
- * @internal
114
- */
115
- var RuntimeMessage;
116
- (function (RuntimeMessage) {
117
- RuntimeMessage["FluidDataStoreOp"] = "component";
118
- RuntimeMessage["Attach"] = "attach";
119
- RuntimeMessage["ChunkedOp"] = "chunkedOp";
120
- RuntimeMessage["BlobAttach"] = "blobAttach";
121
- RuntimeMessage["Rejoin"] = "rejoin";
122
- RuntimeMessage["Alias"] = "alias";
123
- RuntimeMessage["Operation"] = "op";
124
- })(RuntimeMessage || (exports.RuntimeMessage = RuntimeMessage = {}));
125
117
  /**
126
118
  * @deprecated please use version in driver-utils
127
119
  * @internal
128
120
  */
129
121
  function isRuntimeMessage(message) {
130
- return Object.values(RuntimeMessage).includes(message.type);
122
+ return Object.values(messageTypes_js_1.ContainerMessageType).includes(message.type);
131
123
  }
132
124
  exports.isRuntimeMessage = isRuntimeMessage;
133
125
  /**
@@ -173,13 +165,13 @@ const summarizerRequestUrl = "_summarizer";
173
165
  async function createSummarizer(loader, url) {
174
166
  const request = {
175
167
  headers: {
176
- [container_definitions_1.LoaderHeader.cache]: false,
177
- [container_definitions_1.LoaderHeader.clientDetails]: {
168
+ [internal_1.LoaderHeader.cache]: false,
169
+ [internal_1.LoaderHeader.clientDetails]: {
178
170
  capabilities: { interactive: false },
179
- type: index_js_1.summarizerClientType,
171
+ type: index_js_3.summarizerClientType,
180
172
  },
181
- [driver_definitions_1.DriverHeader.summarizingClient]: true,
182
- [container_definitions_1.LoaderHeader.reconnect]: false,
173
+ [internal_3.DriverHeader.summarizingClient]: true,
174
+ [internal_1.LoaderHeader.reconnect]: false,
183
175
  },
184
176
  url,
185
177
  };
@@ -195,15 +187,26 @@ async function createSummarizer(loader, url) {
195
187
  url: `/${summarizerRequestUrl}`,
196
188
  });
197
189
  if (response.status !== 200 || response.mimeType !== "fluid/object") {
198
- throw (0, runtime_utils_1.responseToException)(response, request);
190
+ throw (0, internal_6.responseToException)(response, request);
199
191
  }
200
192
  fluidObject = response.value;
201
193
  }
202
194
  if (fluidObject?.ISummarizer === undefined) {
203
- throw new telemetry_utils_1.UsageError("Fluid object does not implement ISummarizer");
195
+ throw new internal_7.UsageError("Fluid object does not implement ISummarizer");
204
196
  }
205
197
  return fluidObject.ISummarizer;
206
198
  }
199
+ /**
200
+ * Extract last message from the snapshot metadata.
201
+ * Uses legacy property if not using explicit schema control, otherwise uses the new property.
202
+ * This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
203
+ * Please see addMetadataToSummary() as well
204
+ */
205
+ function lastMessageFromMetadata(metadata) {
206
+ return metadata?.documentSchema?.runtime?.explicitSchemaControl
207
+ ? metadata?.lastMessage
208
+ : metadata?.message;
209
+ }
207
210
  /**
208
211
  * Represents the runtime of the container. Contains helper functions/state of the container.
209
212
  * It will define the store level mappings.
@@ -231,8 +234,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
231
234
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
232
235
  const backCompatContext = context;
233
236
  const passLogger = backCompatContext.taggedLogger ??
234
- new telemetry_utils_1.TaggedLoggerAdapter(backCompatContext.logger);
235
- const logger = (0, telemetry_utils_1.createChildLogger)({
237
+ // eslint-disable-next-line import/no-deprecated
238
+ new internal_7.TaggedLoggerAdapter(backCompatContext.logger);
239
+ const logger = (0, internal_7.createChildLogger)({
236
240
  logger: passLogger,
237
241
  properties: {
238
242
  all: {
@@ -240,42 +244,49 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
240
244
  },
241
245
  },
242
246
  });
243
- const mc = (0, telemetry_utils_1.loggerToMonitoringContext)(logger);
244
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = "off", chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
247
+ const mc = (0, internal_7.loggerToMonitoringContext)(logger);
248
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, explicitSchemaControl = false, } = runtimeOptions;
245
249
  const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
246
250
  const tryFetchBlob = async (blobName) => {
247
251
  const blobId = context.baseSnapshot?.blobs[blobName];
248
252
  if (context.baseSnapshot && blobId) {
249
253
  // IContainerContext storage api return type still has undefined in 0.39 package version.
250
254
  // So once we release 0.40 container-defn package we can remove this check.
251
- (0, core_utils_1.assert)(context.storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
252
- return (0, driver_utils_1.readAndParse)(context.storage, blobId);
255
+ (0, internal_2.assert)(context.storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
256
+ return (0, internal_4.readAndParse)(context.storage, blobId);
253
257
  }
254
258
  };
255
259
  const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
256
- tryFetchBlob(index_js_1.chunksBlobName),
257
- tryFetchBlob(index_js_1.metadataBlobName),
258
- tryFetchBlob(index_js_1.electedSummarizerBlobName),
259
- tryFetchBlob(index_js_1.aliasBlobName),
260
- tryFetchBlob(index_js_1.idCompressorBlobName),
260
+ tryFetchBlob(index_js_3.chunksBlobName),
261
+ tryFetchBlob(index_js_3.metadataBlobName),
262
+ tryFetchBlob(index_js_3.electedSummarizerBlobName),
263
+ tryFetchBlob(index_js_3.aliasBlobName),
264
+ tryFetchBlob(index_js_3.idCompressorBlobName),
261
265
  ]);
262
266
  // read snapshot blobs needed for BlobManager to load
263
- const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_1.blobsTreeName], async (id) => {
267
+ const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_3.blobsTreeName], async (id) => {
264
268
  // IContainerContext storage api return type still has undefined in 0.39 package version.
265
269
  // So once we release 0.40 container-defn package we can remove this check.
266
- (0, core_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
267
- return (0, driver_utils_1.readAndParse)(context.storage, id);
270
+ (0, internal_2.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
271
+ return (0, internal_4.readAndParse)(context.storage, id);
268
272
  });
273
+ const messageAtLastSummary = lastMessageFromMetadata(metadata);
269
274
  // Verify summary runtime sequence number matches protocol sequence number.
270
- const runtimeSequenceNumber = metadata?.message?.sequenceNumber;
275
+ const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
271
276
  // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
272
277
  if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
273
278
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
274
279
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
275
280
  if (loadSequenceNumberVerification !== "bypass" &&
276
281
  runtimeSequenceNumber !== protocolSequenceNumber) {
282
+ // Message to OCEs:
283
+ // You can hit this error with runtimeSequenceNumber === -1 in < 2.0 RC3 builds.
284
+ // This would indicate that explicit schema control is enabled in current (2.0 RC3+) builds and it
285
+ // results in addMetadataToSummary() creating a poison pill for older runtimes in the form of a -1 sequence number.
286
+ // Older runtimes do not understand new schema, and thus could corrupt document if they proceed, thus we are using
287
+ // this poison pill to prevent them from proceeding.
277
288
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
278
- const error = new telemetry_utils_1.DataCorruptionError(
289
+ const error = new internal_7.DataCorruptionError(
279
290
  // pre-0.58 error message: SummaryMetadataMismatch
280
291
  "Summary metadata mismatch", { runtimeVersion: packageVersion_js_1.pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
281
292
  if (loadSequenceNumberVerification === "log") {
@@ -287,7 +298,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
287
298
  }
288
299
  }
289
300
  // Enabling the IdCompressor is a one-way operation and we only want to
290
- // allow new containers to turn it on
301
+ // allow new containers to turn it on.
291
302
  let idCompressorMode;
292
303
  if (existing) {
293
304
  // This setting has to be sticky for correctness:
@@ -296,20 +307,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
296
307
  // 2) if it's ON, then all sessions should load compressor right away
297
308
  // 3) Same logic applies for "delayed" mode
298
309
  // Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
299
- // We could do "off" -> "on" transtition too, if all clients start loading compressor (but not using it initially) and do so for a while -
300
- // this will allow clients to eventually to disregard "off" setting (when it's safe so) and start using compressor in future sessions.
310
+ // We could do "off" -> "on" transition too, if all clients start loading compressor (but not using it initially) and
311
+ // do so for a while - this will allow clients to eventually to disregard "off" setting (when it's safe so) and start
312
+ // using compressor in future sessions.
301
313
  // Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
302
- idCompressorMode = metadata?.idCompressorMode ?? "off";
314
+ idCompressorMode = metadata?.documentSchema?.runtime
315
+ ?.idCompressorMode;
303
316
  }
304
317
  else {
305
- // FG overwrite
306
- const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
307
- switch (enabled) {
318
+ switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
308
319
  case true:
309
320
  idCompressorMode = "on";
310
321
  break;
311
322
  case false:
312
- idCompressorMode = "off";
323
+ idCompressorMode = undefined;
313
324
  break;
314
325
  default:
315
326
  idCompressorMode = enableRuntimeIdCompressor;
@@ -317,7 +328,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
317
328
  }
318
329
  }
319
330
  const createIdCompressorFn = async () => {
320
- const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor");
331
+ const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor/internal");
321
332
  /**
322
333
  * Because the IdCompressor emits so much telemetry, this function is used to sample
323
334
  * approximately 5% of all clients. Only the given percentage of sessions will emit telemetry.
@@ -330,7 +341,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
330
341
  },
331
342
  };
332
343
  })();
333
- const compressorLogger = (0, telemetry_utils_1.createSampledLogger)(logger, idCompressorEventSampler);
344
+ const compressorLogger = (0, internal_7.createSampledLogger)(logger, idCompressorEventSampler);
334
345
  const pendingLocalState = context.pendingLocalState;
335
346
  if (pendingLocalState?.pendingIdCompressorState !== undefined) {
336
347
  return deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
@@ -342,6 +353,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
342
353
  return createIdCompressor(compressorLogger);
343
354
  }
344
355
  };
356
+ const disableGroupedBatching = mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
357
+ const disableCompression = mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
358
+ const compressionLz4 = disableCompression !== true &&
359
+ compressionOptions.minimumBatchSizeInBytes !== Infinity &&
360
+ compressionOptions.compressionAlgorithm === "lz4";
361
+ const opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
362
+ const documentSchemaController = new index_js_3.DocumentsSchemaController(existing, metadata?.documentSchema, {
363
+ explicitSchemaControl,
364
+ compressionLz4,
365
+ idCompressorMode,
366
+ opGroupingEnabled,
367
+ disallowedVersions: [],
368
+ }, (schema) => {
369
+ runtime.onSchemaChange(schema);
370
+ });
371
+ const featureGatesForTelemetry = {
372
+ disableGroupedBatching,
373
+ disableCompression,
374
+ };
345
375
  const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
346
376
  summaryOptions,
347
377
  gcOptions,
@@ -350,10 +380,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
350
380
  compressionOptions,
351
381
  maxBatchSizeInBytes,
352
382
  chunkSizeInBytes,
353
- enableRuntimeIdCompressor,
383
+ // Requires<> drops undefined from IdCompressorType
384
+ enableRuntimeIdCompressor: enableRuntimeIdCompressor,
354
385
  enableOpReentryCheck,
355
386
  enableGroupedBatching,
356
- }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, idCompressorMode, provideEntryPoint, requestHandler, undefined);
387
+ explicitSchemaControl,
388
+ }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined);
389
+ runtime.blobManager.trackPendingStashedUploads().then(() => {
390
+ // make sure we didn't reconnect before the promise resolved
391
+ if (runtime.delayConnectClientId !== undefined && !runtime.disposed) {
392
+ runtime.delayConnectClientId = undefined;
393
+ runtime.setConnectionStateCore(true, runtime.delayConnectClientId);
394
+ }
395
+ }, (error) => runtime.closeFn(error));
357
396
  // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
358
397
  // or zero. This must be done before Container replays saved ops.
359
398
  await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
@@ -382,6 +421,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
382
421
  get attachState() {
383
422
  return this._getAttachState();
384
423
  }
424
+ get documentSchema() {
425
+ return this.documentsSchemaController.sessionSchema.runtime;
426
+ }
427
+ get idCompressorMode() {
428
+ return this.documentSchema.idCompressorMode;
429
+ }
385
430
  /**
386
431
  * See IContainerRuntimeBase.idCompressor() for details.
387
432
  */
@@ -391,7 +436,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
391
436
  // That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
392
437
  // to reason over such things as session ID space.
393
438
  if (this.idCompressorMode === "on") {
394
- (0, core_utils_1.assert)(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
439
+ (0, internal_2.assert)(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
395
440
  return this._idCompressor;
396
441
  }
397
442
  }
@@ -432,7 +477,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
432
477
  return this._disposed;
433
478
  }
434
479
  get summarizer() {
435
- (0, core_utils_1.assert)(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
480
+ (0, internal_2.assert)(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
436
481
  return this._summarizer;
437
482
  }
438
483
  isSummariesDisabled() {
@@ -462,7 +507,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
462
507
  return this.garbageCollector.throwOnTombstoneUsage;
463
508
  }
464
509
  /***/
465
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, idCompressorMode, provideEntryPoint, requestHandler, summaryConfiguration = {
510
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, summaryConfiguration = {
466
511
  // the defaults
467
512
  ...exports.DefaultSummaryConfiguration,
468
513
  // the runtime configuration overrides
@@ -476,18 +521,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
476
521
  this.logger = logger;
477
522
  this._storage = _storage;
478
523
  this.createIdCompressor = createIdCompressor;
479
- this.idCompressorMode = idCompressorMode;
524
+ this.documentsSchemaController = documentsSchemaController;
480
525
  this.requestHandler = requestHandler;
481
526
  this.summaryConfiguration = summaryConfiguration;
482
527
  this.imminentClosure = false;
483
528
  // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
484
529
  // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
485
530
  this.pendingIdCompressorOps = [];
486
- /**
487
- * True if we have ID compressor loading in-flight (async operation). Useful only for
488
- * this.idCompressorMode === "delayed" mode
489
- */
490
- this.compressorLoadInitiated = false;
491
531
  this.defaultMaxConsecutiveReconnects = 7;
492
532
  this._orderSequentiallyCalls = 0;
493
533
  this.flushTaskExists = false;
@@ -513,10 +553,24 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
513
553
  * It a cache for holding mapping for loading groupIds with its snapshot from the service. Add expiry policy of 1 minute.
514
554
  * Starting with 1 min and based on recorded usage we can tweak it later on.
515
555
  */
516
- this.snapshotCacheForLoadingGroupIds = new core_utils_1.PromiseCache({
556
+ this.snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
517
557
  expiry: { policy: "absolute", durationMs: 60000 },
518
558
  });
519
559
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
560
+ this.mc = (0, internal_7.createChildMonitoringContext)({
561
+ logger: this.logger,
562
+ namespace: "ContainerRuntime",
563
+ });
564
+ // If we support multiple algorithms in the future, then we would need to manage it here carefully.
565
+ // We can use runtimeOptions.compressionOptions.compressionAlgorithm, but only if it's in the schema list!
566
+ // If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
567
+ // compression.
568
+ const compressionOptions = {
569
+ minimumBatchSizeInBytes: this.documentSchema.compressionLz4
570
+ ? runtimeOptions.compressionOptions.minimumBatchSizeInBytes
571
+ : Number.POSITIVE_INFINITY,
572
+ compressionAlgorithm: CompressionAlgorithms.lz4,
573
+ };
520
574
  this.innerDeltaManager = deltaManager;
521
575
  this.deltaManager = new deltaManagerSummarizerProxy_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
522
576
  // Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
@@ -529,7 +583,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
529
583
  // Values are generally expected to be set from the runtime side.
530
584
  this.options = options ?? {};
531
585
  this.clientDetails = clientDetails;
532
- this.isSummarizerClient = this.clientDetails.type === index_js_1.summarizerClientType;
586
+ this.isSummarizerClient = this.clientDetails.type === index_js_3.summarizerClientType;
533
587
  this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
534
588
  this._getClientId = () => context.clientId;
535
589
  this._getAttachState = () => context.attachState;
@@ -550,10 +604,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
550
604
  this.disposeFn = disposeFn ?? closeFn;
551
605
  // In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
552
606
  this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
553
- this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
554
- logger: this.logger,
555
- namespace: "ContainerRuntime",
556
- });
557
607
  let loadSummaryNumber;
558
608
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
559
609
  // get the values from the metadata blob.
@@ -574,7 +624,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
574
624
  loadSummaryNumber = 0;
575
625
  }
576
626
  this.nextSummaryNumber = loadSummaryNumber + 1;
577
- this.messageAtLastSummary = metadata?.message;
627
+ this.messageAtLastSummary = lastMessageFromMetadata(metadata);
578
628
  // Note that we only need to pull the *initial* connected state from the context.
579
629
  // Later updates come through calls to setConnectionState.
580
630
  this._connected = connected;
@@ -582,20 +632,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
582
632
  eventName: "GCFeatureMatrix",
583
633
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
584
634
  inputs: JSON.stringify({
585
- gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_2.gcGenerationOptionName],
635
+ gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_1.gcGenerationOptionName],
586
636
  }),
587
637
  });
588
638
  this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
589
639
  this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
590
640
  const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
591
- const opGroupingManager = new index_js_3.OpGroupingManager({
641
+ const opGroupingManager = new index_js_2.OpGroupingManager({
592
642
  groupedBatchingEnabled: this.groupedBatchingEnabled,
593
643
  opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
594
644
  reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
595
645
  true,
596
646
  }, this.mc.logger);
597
- const opSplitter = new index_js_3.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
598
- this.remoteMessageProcessor = new index_js_3.RemoteMessageProcessor(opSplitter, new index_js_3.OpDecompressor(this.mc.logger), opGroupingManager);
647
+ const opSplitter = new index_js_2.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
648
+ this.remoteMessageProcessor = new index_js_2.RemoteMessageProcessor(opSplitter, new index_js_2.OpDecompressor(this.mc.logger), opGroupingManager);
599
649
  this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
600
650
  if (this.summaryConfiguration.state === "enabled") {
601
651
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
@@ -611,11 +661,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
611
661
  this.maxConsecutiveReconnects =
612
662
  this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
613
663
  this.defaultMaxConsecutiveReconnects;
614
- if (runtimeOptions.flushMode === runtime_definitions_1.FlushModeExperimental.Async &&
664
+ if (runtimeOptions.flushMode === internal_5.FlushModeExperimental.Async &&
615
665
  supportedFeatures?.get("referenceSequenceNumbers") !== true) {
616
666
  // The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
617
667
  this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
618
- this._flushMode = runtime_definitions_1.FlushMode.TurnBased;
668
+ this._flushMode = internal_5.FlushMode.TurnBased;
619
669
  }
620
670
  else {
621
671
  this._flushMode = runtimeOptions.flushMode;
@@ -628,10 +678,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
628
678
  // This is a runtime enforcement of what's already explicit in the policy's type itself,
629
679
  // which dictates the value is either undefined or exactly 5 days in ms.
630
680
  // As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
631
- throw new telemetry_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
681
+ throw new internal_7.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
632
682
  }
633
683
  }
634
- this.garbageCollector = index_js_2.GarbageCollector.create({
684
+ this.garbageCollector = index_js_1.GarbageCollector.create({
635
685
  runtime: this,
636
686
  gcOptions: this.runtimeOptions.gcOptions,
637
687
  baseSnapshot,
@@ -642,12 +692,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
642
692
  isSummarizerClient: this.isSummarizerClient,
643
693
  getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
644
694
  getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
645
- readAndParseBlob: async (id) => (0, driver_utils_1.readAndParse)(this.storage, id),
695
+ readAndParseBlob: async (id) => (0, internal_4.readAndParse)(this.storage, id),
646
696
  submitMessage: (message) => this.submit(message),
647
697
  sessionExpiryTimerStarted: pendingRuntimeState?.sessionExpiryTimerStarted,
648
698
  });
649
699
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
650
- this.summarizerNode = (0, index_js_1.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
700
+ this.summarizerNode = (0, index_js_3.createRootSummarizerNodeWithGC)((0, internal_7.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
651
701
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
652
702
  async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
653
703
  // Latest change sequence number, no changes since summary applied yet
@@ -677,15 +727,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
677
727
  return this.submitSignalFn(envelope2, targetClientId);
678
728
  };
679
729
  this.channelCollection = new channelCollection_js_1.ChannelCollection((0, channelCollection_js_1.getSummaryForDatastores)(baseSnapshot, metadata), parentContext, this.mc.logger, (path, reason, timestampMs, packagePath, request, headerData) => this.garbageCollector.nodeUpdated(path, reason, timestampMs, packagePath, request, headerData), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap), async (runtime) => provideEntryPoint);
680
- this.blobManager = new blobManager_js_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
681
- if (!this.disposed) {
682
- this.submit({ type: messageTypes_js_1.ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
683
- localId,
684
- blobId,
685
- });
686
- }
687
- }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState?.pendingAttachmentBlobs, (error) => this.closeFn(error));
688
- this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
730
+ this.blobManager = new blobManager_js_1.BlobManager({
731
+ routeContext: this.handleContext,
732
+ snapshot: blobManagerSnapshot,
733
+ getStorage: () => this.storage,
734
+ sendBlobAttachOp: (localId, blobId) => {
735
+ if (!this.disposed) {
736
+ this.submit({ type: messageTypes_js_1.ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
737
+ localId,
738
+ blobId,
739
+ });
740
+ }
741
+ },
742
+ blobRequested: (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"),
743
+ isBlobDeleted: (blobPath) => this.garbageCollector.isNodeDeleted(blobPath),
744
+ runtime: this,
745
+ stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
746
+ closeContainer: (error) => this.closeFn(error),
747
+ });
748
+ this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, internal_7.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
689
749
  this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
690
750
  applyStashedOp: this.applyStashedOp.bind(this),
691
751
  clientId: () => this.clientId,
@@ -699,21 +759,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
699
759
  isActiveConnection: () => this.innerDeltaManager.active,
700
760
  isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
701
761
  }, pendingRuntimeState?.pending, this.logger);
702
- const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
703
- const compressionOptions = disableCompression === true
704
- ? {
705
- minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
706
- compressionAlgorithm: CompressionAlgorithms.lz4,
707
- }
708
- : runtimeOptions.compressionOptions;
709
762
  const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
710
763
  const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
711
- this.outbox = new index_js_3.Outbox({
764
+ this.outbox = new index_js_2.Outbox({
712
765
  shouldSend: () => this.canSendOps(),
713
766
  pendingStateManager: this.pendingStateManager,
714
767
  submitBatchFn: this.submitBatchFn,
715
768
  legacySendBatchFn,
716
- compressor: new index_js_3.OpCompressor(this.mc.logger),
769
+ compressor: new index_js_2.OpCompressor(this.mc.logger),
717
770
  splitter: opSplitter,
718
771
  config: {
719
772
  compressionOptions,
@@ -740,7 +793,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
740
793
  this.closeSummarizerDelayMs = closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
741
794
  this.validateSummaryBeforeUpload =
742
795
  this.mc.config.getBoolean("Fluid.Summarizer.ValidateSummaryBeforeUpload") ?? false;
743
- this.summaryCollection = new index_js_1.SummaryCollection(this.deltaManager, this.logger);
796
+ this.summaryCollection = new index_js_3.SummaryCollection(this.deltaManager, this.logger);
744
797
  this.dirtyContainer =
745
798
  this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
746
799
  context.updateDirtyContainerState(this.dirtyContainer);
@@ -748,20 +801,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
748
801
  this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
749
802
  }
750
803
  else {
751
- const orderedClientLogger = (0, telemetry_utils_1.createChildLogger)({
804
+ const orderedClientLogger = (0, internal_7.createChildLogger)({
752
805
  logger: this.logger,
753
806
  namespace: "OrderedClientElection",
754
807
  });
755
- const orderedClientCollection = new index_js_1.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
756
- const orderedClientElectionForSummarizer = new index_js_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_1.SummarizerClientElection.isClientEligible);
757
- this.summarizerClientElection = new index_js_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
808
+ const orderedClientCollection = new index_js_3.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
809
+ const orderedClientElectionForSummarizer = new index_js_3.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_3.SummarizerClientElection.isClientEligible);
810
+ this.summarizerClientElection = new index_js_3.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
758
811
  if (this.isSummarizerClient) {
759
- this._summarizer = new index_js_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_1.RunWhileConnectedCoordinator.create(runtime,
812
+ this._summarizer = new index_js_3.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_3.RunWhileConnectedCoordinator.create(runtime,
760
813
  // Summarization runs in summarizer client and needs access to the real (non-proxy) active
761
814
  // information. The proxy delta manager would always return false for summarizer client.
762
815
  () => this.innerDeltaManager.active));
763
816
  }
764
- else if (index_js_1.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
817
+ else if (index_js_3.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
765
818
  // Only create a SummaryManager and SummarizerClientElection
766
819
  // if summaries are enabled and we are not the summarizer client.
767
820
  const defaultAction = () => {
@@ -783,7 +836,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
783
836
  };
784
837
  this.summaryCollection.on("default", defaultAction);
785
838
  // Create the SummaryManager and mark the initial state
786
- this.summaryManager = new index_js_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
839
+ this.summaryManager = new index_js_3.SummaryManager(this.summarizerClientElection, this, // IConnectedState
787
840
  this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
788
841
  30 * 1000, // 30 sec max delay
789
842
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
@@ -810,10 +863,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
810
863
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
811
864
  gcVersion: metadata?.gcFeature,
812
865
  options: JSON.stringify(runtimeOptions),
813
- idCompressorModeMetadata: metadata?.idCompressorMode,
866
+ idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
814
867
  idCompressorMode: this.idCompressorMode,
815
868
  featureGates: JSON.stringify({
816
- disableCompression,
869
+ ...featureGatesForTelemetry,
817
870
  disableOpReentryCheck,
818
871
  disableChunking,
819
872
  disableAttachReorder: this.disableAttachReorder,
@@ -825,9 +878,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
825
878
  });
826
879
  (0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this, this.logger);
827
880
  (0, batchTracker_js_1.BindBatchTracker)(this, this.logger);
828
- this.entryPoint = new core_utils_1.LazyPromise(async () => {
881
+ this.entryPoint = new internal_2.LazyPromise(async () => {
829
882
  if (this.isSummarizerClient) {
830
- (0, core_utils_1.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
883
+ (0, internal_2.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
831
884
  return this._summarizer;
832
885
  }
833
886
  return provideEntryPoint(this);
@@ -836,6 +889,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
836
889
  // saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
837
890
  this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
838
891
  }
892
+ onSchemaChange(schema) {
893
+ // Most of the settings will be picked up only by new sessions (i.e. after reload).
894
+ // We can make it better in the future (i.e. start to use op compression right away), but for simplicity
895
+ // this is not done.
896
+ // But ID compressor is special. It's possible, that in future, we will remove "stickiness" of ID compressor setting
897
+ // and will allow to start using it. If that were to happen, we want to ensure that we do not break eventual consistency
898
+ // promises. To do so, we need to initialize id compressor right away.
899
+ // As it's implemented right now (with async initialization), this will only work for "off" -> "delayed" transitions.
900
+ // Anything else is too risky, and requires ability to initialize ID compressor synchronously!
901
+ if (schema.runtime.idCompressorMode !== undefined) {
902
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
903
+ this.loadIdCompressor();
904
+ }
905
+ }
839
906
  getCreateChildSummarizerNodeFn(id, createParam) {
840
907
  return (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn);
841
908
  }
@@ -844,10 +911,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
844
911
  }
845
912
  /* IFluidParentContext APIs that should not be called on Root */
846
913
  makeLocallyVisible() {
847
- (0, core_utils_1.assert)(false, 0x8eb /* should not be called */);
914
+ (0, internal_2.assert)(false, 0x8eb /* should not be called */);
848
915
  }
849
916
  setChannelDirty(address) {
850
- (0, core_utils_1.assert)(false, 0x909 /* should not be called */);
917
+ (0, internal_2.assert)(false, 0x909 /* should not be called */);
851
918
  }
852
919
  /**
853
920
  * Initializes the state from the base snapshot this container runtime loaded from.
@@ -856,7 +923,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
856
923
  if (this.idCompressorMode === "on" ||
857
924
  (this.idCompressorMode === "delayed" && this.connected)) {
858
925
  // This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
859
- (0, core_utils_1.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
926
+ (0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
860
927
  this._idCompressor = await this.createIdCompressor();
861
928
  }
862
929
  await this.garbageCollector.initializeBaseState();
@@ -890,13 +957,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
890
957
  */
891
958
  async getSnapshotForLoadingGroupId(loadingGroupIds, pathParts) {
892
959
  const sortedLoadingGroupIds = loadingGroupIds.sort();
893
- (0, core_utils_1.assert)(this.storage.getSnapshot !== undefined, 0x8ed /* getSnapshot api should be defined if used */);
960
+ (0, internal_2.assert)(this.storage.getSnapshot !== undefined, 0x8ed /* getSnapshot api should be defined if used */);
894
961
  let loadedFromCache = true;
895
962
  // Lookup up in the cache, if not present then make the network call as multiple datastores could
896
963
  // be in same loading group. So, once we have fetched the snapshot for that loading group on
897
964
  // any request, then cache that as same group could be requested in future too.
898
965
  const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(), async () => {
899
- (0, core_utils_1.assert)(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
966
+ (0, internal_2.assert)(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
900
967
  loadedFromCache = false;
901
968
  return this.storage.getSnapshot({
902
969
  cacheSnapshot: false,
@@ -912,16 +979,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
912
979
  }),
913
980
  });
914
981
  // Find the snapshotTree inside the returned snapshot based on the path as given in the request.
915
- const hasIsolatedChannels = (0, index_js_1.rootHasIsolatedChannels)(this.metadata);
982
+ const hasIsolatedChannels = (0, index_js_3.rootHasIsolatedChannels)(this.metadata);
916
983
  const snapshotTreeForPath = this.getSnapshotTreeForPath(snapshot.snapshotTree, pathParts, hasIsolatedChannels);
917
- (0, core_utils_1.assert)(snapshotTreeForPath !== undefined, 0x8ef /* no snapshotTree for the path */);
984
+ (0, internal_2.assert)(snapshotTreeForPath !== undefined, 0x8ef /* no snapshotTree for the path */);
918
985
  const snapshotSeqNumber = snapshot.sequenceNumber;
919
- (0, core_utils_1.assert)(snapshotSeqNumber !== undefined, 0x8f0 /* snapshotSeqNumber should be present */);
986
+ (0, internal_2.assert)(snapshotSeqNumber !== undefined, 0x8f0 /* snapshotSeqNumber should be present */);
920
987
  // This assert fires if we get a snapshot older than the snapshot we loaded from. This is a service issue.
921
988
  // Snapshots should only move forward. If we observe an older snapshot than the one we loaded from, then likely
922
989
  // the file has been overwritten or service lost data.
923
990
  if (snapshotSeqNumber < this.deltaManager.initialSequenceNumber) {
924
- throw telemetry_utils_1.DataProcessingError.create("Downloaded snapshot older than snapshot we loaded from", "getSnapshotForLoadingGroupId", undefined, {
991
+ throw internal_7.DataProcessingError.create("Downloaded snapshot older than snapshot we loaded from", "getSnapshotForLoadingGroupId", undefined, {
925
992
  loadingGroupIds: sortedLoadingGroupIds.join(","),
926
993
  snapshotSeqNumber,
927
994
  initialSequenceNumber: this.deltaManager.initialSequenceNumber,
@@ -944,7 +1011,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
944
1011
  targetSequenceNumber: snapshotSeqNumber,
945
1012
  sequenceNumber: this.deltaManager.lastSequenceNumber, // This is so we reuse some columns in telemetry
946
1013
  };
947
- const event = telemetry_utils_1.PerformanceEvent.start(this.mc.logger, {
1014
+ const event = internal_7.PerformanceEvent.start(this.mc.logger, {
948
1015
  ...props,
949
1016
  });
950
1017
  // If the inbound deltas queue is paused or disconnected, we expect a reconnect and unpause
@@ -952,7 +1019,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
952
1019
  if (this.deltaManager.inbound.paused) {
953
1020
  props.inboundPaused = this.deltaManager.inbound.paused; // reusing telemetry
954
1021
  }
955
- const defP = new core_utils_1.Deferred();
1022
+ const defP = new internal_2.Deferred();
956
1023
  this.deltaManager.on("op", (message) => {
957
1024
  if (message.sequenceNumber >= snapshotSeqNumber) {
958
1025
  defP.resolve(true);
@@ -975,7 +1042,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
975
1042
  let childTree = snapshotTree;
976
1043
  for (const part of pathParts) {
977
1044
  if (hasIsolatedChannels) {
978
- childTree = childTree?.trees[runtime_definitions_1.channelsTreeName];
1045
+ childTree = childTree?.trees[internal_5.channelsTreeName];
979
1046
  }
980
1047
  childTree = childTree?.trees[part];
981
1048
  }
@@ -989,7 +1056,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
989
1056
  // @ts-expect-error expected to be used by LTS Loaders and Containers
990
1057
  async request(request) {
991
1058
  try {
992
- const parser = runtime_utils_1.RequestParser.create(request);
1059
+ const parser = internal_6.RequestParser.create(request);
993
1060
  const id = parser.pathParts[0];
994
1061
  if (id === summarizerRequestUrl && parser.pathParts.length === 1) {
995
1062
  if (this._summarizer !== undefined) {
@@ -999,16 +1066,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
999
1066
  value: this.summarizer,
1000
1067
  };
1001
1068
  }
1002
- return (0, runtime_utils_1.create404Response)(request);
1069
+ return (0, internal_6.create404Response)(request);
1003
1070
  }
1004
1071
  if (this.requestHandler !== undefined) {
1005
1072
  // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
1006
1073
  return this.requestHandler(parser, this);
1007
1074
  }
1008
- return (0, runtime_utils_1.create404Response)(request);
1075
+ return (0, internal_6.create404Response)(request);
1009
1076
  }
1010
1077
  catch (error) {
1011
- return (0, runtime_utils_1.exceptionToResponse)(error);
1078
+ return (0, internal_6.exceptionToResponse)(error);
1012
1079
  }
1013
1080
  }
1014
1081
  /**
@@ -1017,7 +1084,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1017
1084
  */
1018
1085
  async resolveHandle(request) {
1019
1086
  try {
1020
- const requestParser = runtime_utils_1.RequestParser.create(request);
1087
+ const requestParser = internal_6.RequestParser.create(request);
1021
1088
  const id = requestParser.pathParts[0];
1022
1089
  if (id === "_channels") {
1023
1090
  // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
@@ -1031,15 +1098,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1031
1098
  mimeType: "fluid/object",
1032
1099
  value: blob,
1033
1100
  }
1034
- : (0, runtime_utils_1.create404Response)(request);
1101
+ : (0, internal_6.create404Response)(request);
1035
1102
  }
1036
1103
  else if (requestParser.pathParts.length > 0) {
1037
1104
  return await this.channelCollection.request(request);
1038
1105
  }
1039
- return (0, runtime_utils_1.create404Response)(request);
1106
+ return (0, internal_6.create404Response)(request);
1040
1107
  }
1041
1108
  catch (error) {
1042
- return (0, runtime_utils_1.exceptionToResponse)(error);
1109
+ return (0, internal_6.exceptionToResponse)(error);
1043
1110
  }
1044
1111
  }
1045
1112
  /**
@@ -1053,48 +1120,60 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1053
1120
  }
1054
1121
  /** Adds the container's metadata to the given summary tree. */
1055
1122
  addMetadataToSummary(summaryTree) {
1123
+ // The last message processed at the time of summary. If there are no new messages, use the message from the
1124
+ // last summary.
1125
+ const message = (0, index_js_3.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
1126
+ this.messageAtLastSummary;
1127
+ const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
1128
+ // Is document schema explicit control on?
1129
+ const explitiSchemaControl = documentSchema?.runtime.explicitSchemaControl;
1056
1130
  const metadata = {
1057
1131
  ...this.createContainerMetadata,
1058
1132
  // Increment the summary number for the next summary that will be generated.
1059
1133
  summaryNumber: this.nextSummaryNumber++,
1060
1134
  summaryFormatVersion: 1,
1061
1135
  ...this.garbageCollector.getMetadata(),
1062
- // The last message processed at the time of summary. If there are no new messages, use the message from the
1063
- // last summary.
1064
- message: (0, index_js_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
1065
- this.messageAtLastSummary,
1066
1136
  telemetryDocumentId: this.telemetryDocumentId,
1067
- idCompressorMode: this.idCompressorMode,
1137
+ // If explicit document schema control is not on, use legacy way to supply last message (using 'message' property).
1138
+ // Otherwise use new 'lastMessage' property, but also put content into the 'message' property that cases old
1139
+ // runtimes (that preceed document schema control capabilities) to close container on load due to mismatch in
1140
+ // last message's sequence number.
1141
+ // See also lastMessageFromMetadata()
1142
+ message: explitiSchemaControl
1143
+ ? { sequenceNumber: -1 }
1144
+ : message,
1145
+ lastMessage: explitiSchemaControl ? message : undefined,
1146
+ documentSchema,
1068
1147
  };
1069
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.metadataBlobName, JSON.stringify(metadata));
1148
+ (0, internal_6.addBlobToSummary)(summaryTree, index_js_3.metadataBlobName, JSON.stringify(metadata));
1070
1149
  }
1071
1150
  addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
1072
1151
  this.addMetadataToSummary(summaryTree);
1073
1152
  if (this._idCompressor) {
1074
1153
  const idCompressorState = JSON.stringify(this._idCompressor.serialize(false));
1075
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.idCompressorBlobName, idCompressorState);
1154
+ (0, internal_6.addBlobToSummary)(summaryTree, index_js_3.idCompressorBlobName, idCompressorState);
1076
1155
  }
1077
1156
  if (this.remoteMessageProcessor.partialMessages.size > 0) {
1078
1157
  const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
1079
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.chunksBlobName, content);
1158
+ (0, internal_6.addBlobToSummary)(summaryTree, index_js_3.chunksBlobName, content);
1080
1159
  }
1081
1160
  const dataStoreAliases = this.channelCollection.aliases;
1082
1161
  if (dataStoreAliases.size > 0) {
1083
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
1162
+ (0, internal_6.addBlobToSummary)(summaryTree, index_js_3.aliasBlobName, JSON.stringify([...dataStoreAliases]));
1084
1163
  }
1085
1164
  if (this.summarizerClientElection) {
1086
1165
  const electedSummarizerContent = JSON.stringify(this.summarizerClientElection?.serialize());
1087
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.electedSummarizerBlobName, electedSummarizerContent);
1166
+ (0, internal_6.addBlobToSummary)(summaryTree, index_js_3.electedSummarizerBlobName, electedSummarizerContent);
1088
1167
  }
1089
1168
  const blobManagerSummary = this.blobManager.summarize();
1090
1169
  // Some storage (like git) doesn't allow empty tree, so we can omit it.
1091
1170
  // and the blob manager can handle the tree not existing when loading
1092
1171
  if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
1093
- (0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, index_js_1.blobsTreeName, blobManagerSummary);
1172
+ (0, internal_6.addSummarizeResultToSummary)(summaryTree, index_js_3.blobsTreeName, blobManagerSummary);
1094
1173
  }
1095
1174
  const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
1096
1175
  if (gcSummary !== undefined) {
1097
- (0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, runtime_definitions_1.gcTreeKey, gcSummary);
1176
+ (0, internal_6.addSummarizeResultToSummary)(summaryTree, internal_5.gcTreeKey, gcSummary);
1098
1177
  }
1099
1178
  }
1100
1179
  // Track how many times the container tries to reconnect with pending messages.
@@ -1139,7 +1218,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1139
1218
  // Save the old state, reset to false, disable event emit
1140
1219
  const oldState = this.dirtyContainer;
1141
1220
  this.dirtyContainer = false;
1142
- (0, core_utils_1.assert)(this.emitDirtyDocumentEvent, 0x127 /* "dirty document event not set on replay" */);
1221
+ (0, internal_2.assert)(this.emitDirtyDocumentEvent, 0x127 /* "dirty document event not set on replay" */);
1143
1222
  this.emitDirtyDocumentEvent = false;
1144
1223
  let newState;
1145
1224
  try {
@@ -1161,9 +1240,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1161
1240
  */
1162
1241
  // TODO: markfields: confirm Local- versus Outbound- ContainerRuntimeMessage typing
1163
1242
  parseLocalOpContent(serializedContents) {
1164
- (0, core_utils_1.assert)(serializedContents !== undefined, 0x6d5 /* content must be defined */);
1243
+ (0, internal_2.assert)(serializedContents !== undefined, 0x6d5 /* content must be defined */);
1165
1244
  const message = JSON.parse(serializedContents);
1166
- (0, core_utils_1.assert)(message.type !== undefined, 0x6d6 /* incorrect op content format */);
1245
+ (0, internal_2.assert)(message.type !== undefined, 0x6d6 /* incorrect op content format */);
1167
1246
  return message;
1168
1247
  }
1169
1248
  async applyStashedOp(serializedOpContent) {
@@ -1175,7 +1254,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1175
1254
  case messageTypes_js_1.ContainerMessageType.Alias:
1176
1255
  return this.channelCollection.applyStashedOp(opContents);
1177
1256
  case messageTypes_js_1.ContainerMessageType.IdAllocation:
1178
- (0, core_utils_1.assert)(this.idCompressorMode !== "off", 0x8f1 /* ID compressor should be in use */);
1257
+ // IDs allocation ops in stashed state are ignored because the tip state of the compressor
1258
+ // is serialized into the pending state. This is done because generation of new IDs during
1259
+ // stashed op application (or, later, resubmit) must generate new IDs and if the compressor
1260
+ // was loaded from a state serialized at the same time as the summary tree in the stashed state
1261
+ // then it would generate IDs that collide with any in later stashed ops.
1262
+ // In the future, IdCompressor could be extended to have an "applyStashedOp" or similar method
1263
+ // and the runtime could filter out all ID allocation ops from the stashed state and apply them
1264
+ // before applying the rest of the stashed ops. This would accomplish the same thing but with
1265
+ // better performance in future incremental stashed state creation.
1266
+ (0, internal_2.assert)(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
1267
+ return;
1268
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1179
1269
  return;
1180
1270
  case messageTypes_js_1.ContainerMessageType.BlobAttach:
1181
1271
  return;
@@ -1185,14 +1275,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1185
1275
  throw new Error("rejoin not expected here");
1186
1276
  case messageTypes_js_1.ContainerMessageType.GC:
1187
1277
  // GC op is only sent in summarizer which should never have stashed ops.
1188
- throw new telemetry_utils_1.LoggingError("GC op not expected to be stashed in summarizer");
1278
+ throw new internal_7.LoggingError("GC op not expected to be stashed in summarizer");
1189
1279
  default: {
1190
1280
  // This should be extremely rare for stashed ops.
1191
1281
  // It would require a newer runtime stashing ops and then an older one applying them,
1192
1282
  // e.g. if an app rolled back its container version
1193
1283
  const compatBehavior = opContents.compatDetails?.behavior;
1194
1284
  if (!compatBehaviorAllowsMessageType(opContents.type, compatBehavior)) {
1195
- const error = telemetry_utils_1.DataProcessingError.create("Stashed runtime message of unknown type", "applyStashedOp", undefined /* sequencedMessage */, {
1285
+ const error = internal_7.DataProcessingError.create("Stashed runtime message of unknown type", "applyStashedOp", undefined /* sequencedMessage */, {
1196
1286
  messageDetails: JSON.stringify({
1197
1287
  type: opContents.type,
1198
1288
  compatBehavior,
@@ -1206,12 +1296,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1206
1296
  }
1207
1297
  }
1208
1298
  }
1209
- setConnectionState(connected, clientId) {
1210
- if (connected && this.idCompressorMode === "delayed" && !this.compressorLoadInitiated) {
1211
- this.compressorLoadInitiated = true;
1212
- this.createIdCompressor()
1299
+ async loadIdCompressor() {
1300
+ if (this._idCompressor === undefined &&
1301
+ this.idCompressorMode !== undefined &&
1302
+ this._loadIdCompressor === undefined) {
1303
+ this._loadIdCompressor = this.createIdCompressor()
1213
1304
  .then((compressor) => {
1214
1305
  this._idCompressor = compressor;
1306
+ // Finalize any ranges we received while the compressor was turned off.
1215
1307
  for (const range of this.pendingIdCompressorOps) {
1216
1308
  this._idCompressor.finalizeCreationRange(range);
1217
1309
  }
@@ -1219,8 +1311,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1219
1311
  })
1220
1312
  .catch((error) => {
1221
1313
  this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
1314
+ throw error;
1222
1315
  });
1223
1316
  }
1317
+ return this._loadIdCompressor;
1318
+ }
1319
+ setConnectionState(connected, clientId) {
1320
+ if (connected && this.idCompressorMode === "delayed") {
1321
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1322
+ this.loadIdCompressor();
1323
+ }
1224
1324
  if (connected === false && this.delayConnectClientId !== undefined) {
1225
1325
  this.delayConnectClientId = undefined;
1226
1326
  this.mc.logger.sendTelemetryEvent({
@@ -1229,27 +1329,23 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1229
1329
  // Don't propagate "disconnected" event because we didn't propagate the previous "connected" event
1230
1330
  return;
1231
1331
  }
1332
+ if (!connected) {
1333
+ this.documentsSchemaController.onDisconnect();
1334
+ }
1232
1335
  // If there are stashed blobs in the pending state, we need to delay
1233
1336
  // propagation of the "connected" event until we have uploaded them to
1234
1337
  // ensure we don't submit ops referencing a blob that has not been uploaded
1235
1338
  const connecting = connected && !this._connected;
1236
- if (connecting && this.blobManager.hasPendingStashedBlobs()) {
1237
- (0, core_utils_1.assert)(!this.delayConnectClientId, 0x791 /* Connect event delay must be canceled before subsequent connect event */);
1238
- (0, core_utils_1.assert)(!!clientId, 0x792 /* Must have clientId when connecting */);
1339
+ if (connecting && this.blobManager.hasPendingStashedUploads()) {
1340
+ (0, internal_2.assert)(!this.delayConnectClientId, 0x791 /* Connect event delay must be canceled before subsequent connect event */);
1341
+ (0, internal_2.assert)(!!clientId, 0x792 /* Must have clientId when connecting */);
1239
1342
  this.delayConnectClientId = clientId;
1240
- this.blobManager.processStashedChanges().then(() => {
1241
- // make sure we didn't reconnect before the promise resolved
1242
- if (this.delayConnectClientId === clientId && !this.disposed) {
1243
- this.delayConnectClientId = undefined;
1244
- this.setConnectionStateCore(connected, clientId);
1245
- }
1246
- }, (error) => this.closeFn(error));
1247
1343
  return;
1248
1344
  }
1249
1345
  this.setConnectionStateCore(connected, clientId);
1250
1346
  }
1251
1347
  setConnectionStateCore(connected, clientId) {
1252
- (0, core_utils_1.assert)(!this.delayConnectClientId, 0x394 /* connect event delay must be cleared before propagating connect event */);
1348
+ (0, internal_2.assert)(!this.delayConnectClientId, 0x394 /* connect event delay must be cleared before propagating connect event */);
1253
1349
  this.verifyNotClosed();
1254
1350
  // There might be no change of state due to Container calling this API after loading runtime.
1255
1351
  const changeOfState = this._connected !== connected;
@@ -1267,13 +1363,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1267
1363
  this._perfSignalData.trackingSignalSequenceNumber = undefined;
1268
1364
  }
1269
1365
  else {
1270
- (0, core_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x3cd /* Connection is possible only if container exists in storage */);
1366
+ (0, internal_2.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x3cd /* Connection is possible only if container exists in storage */);
1271
1367
  }
1272
1368
  // Fail while disconnected
1273
1369
  if (reconnection) {
1274
1370
  this.consecutiveReconnects++;
1275
1371
  if (!this.shouldContinueReconnecting()) {
1276
- this.closeFn(telemetry_utils_1.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
1372
+ this.closeFn(internal_7.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
1277
1373
  dataLoss: 1,
1278
1374
  attempts: this.consecutiveReconnects,
1279
1375
  pendingMessages: this.pendingMessagesCount,
@@ -1286,7 +1382,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1286
1382
  }
1287
1383
  this.channelCollection.setConnectionState(connected, clientId);
1288
1384
  this.garbageCollector.setConnectionState(connected, clientId);
1289
- (0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
1385
+ (0, internal_7.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
1290
1386
  }
1291
1387
  async notifyOpReplay(message) {
1292
1388
  await this.pendingStateManager.applyStashedOpsAt(message.sequenceNumber);
@@ -1335,7 +1431,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1335
1431
  // These calls should be made for all but chunked ops:
1336
1432
  // 1) this.pendingStateManager.processPendingLocalMessage() below
1337
1433
  // 2) this.resetReconnectCount() below
1338
- (0, core_utils_1.assert)(message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp, "we should never get here with chunked ops");
1434
+ (0, internal_2.assert)(message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp, "we should never get here with chunked ops");
1339
1435
  let localOpMetadata;
1340
1436
  if (local && messageWithContext.modernRuntimeMessage) {
1341
1437
  localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
@@ -1386,6 +1482,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1386
1482
  messageWithContext.message.metadata?.savedOp ===
1387
1483
  true)) {
1388
1484
  const range = messageWithContext.message.contents;
1485
+ // Some other client turned on the id compressor. If we have not turned it on,
1486
+ // put it in a pending queue and delay finalization.
1389
1487
  if (this._idCompressor === undefined) {
1390
1488
  this.pendingIdCompressorOps.push(range);
1391
1489
  }
@@ -1400,9 +1498,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1400
1498
  case messageTypes_js_1.ContainerMessageType.ChunkedOp:
1401
1499
  // From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
1402
1500
  // Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
1403
- (0, core_utils_1.assert)(false, "should not even get here");
1501
+ (0, internal_2.assert)(false, "should not even get here");
1404
1502
  case messageTypes_js_1.ContainerMessageType.Rejoin:
1405
1503
  break;
1504
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1505
+ this.documentsSchemaController.processDocumentSchemaOp(messageWithContext.message.contents, messageWithContext.local, messageWithContext.message.sequenceNumber);
1506
+ break;
1406
1507
  default: {
1407
1508
  // If we didn't necessarily expect a runtime message type, then no worries - just return
1408
1509
  // e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
@@ -1412,7 +1513,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1412
1513
  const compatBehavior = messageWithContext.message.compatDetails?.behavior;
1413
1514
  if (!compatBehaviorAllowsMessageType(messageWithContext.message.type, compatBehavior)) {
1414
1515
  const { message } = messageWithContext;
1415
- const error = telemetry_utils_1.DataProcessingError.create(
1516
+ const error = internal_7.DataProcessingError.create(
1416
1517
  // Former assert 0x3ce
1417
1518
  "Runtime message of unknown type", "OpProcessing", message, {
1418
1519
  local,
@@ -1496,9 +1597,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1496
1597
  * This method is expected to be called at the end of a batch.
1497
1598
  */
1498
1599
  flush() {
1499
- (0, core_utils_1.assert)(this._orderSequentiallyCalls === 0, 0x24c /* "Cannot call `flush()` from `orderSequentially`'s callback" */);
1600
+ (0, internal_2.assert)(this._orderSequentiallyCalls === 0, 0x24c /* "Cannot call `flush()` from `orderSequentially`'s callback" */);
1500
1601
  this.outbox.flush();
1501
- (0, core_utils_1.assert)(this.outbox.isEmpty, 0x3cf /* reentrancy */);
1602
+ (0, internal_2.assert)(this.outbox.isEmpty, 0x3cf /* reentrancy */);
1502
1603
  }
1503
1604
  /**
1504
1605
  * {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.orderSequentially}
@@ -1523,15 +1624,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1523
1624
  checkpoint.rollback((message) => this.rollback(message.contents, message.localOpMetadata));
1524
1625
  }
1525
1626
  catch (err) {
1526
- const error2 = (0, telemetry_utils_1.wrapError)(err, (message) => {
1527
- return telemetry_utils_1.DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
1627
+ const error2 = (0, internal_7.wrapError)(err, (message) => {
1628
+ return internal_7.DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
1528
1629
  });
1529
1630
  this.closeFn(error2);
1530
1631
  throw error2;
1531
1632
  }
1532
1633
  }
1533
1634
  else {
1534
- this.closeFn((0, telemetry_utils_1.wrapError)(error, (errorMessage) => new telemetry_utils_1.GenericError(`orderSequentially callback exception: ${errorMessage}`, error, {
1635
+ this.closeFn((0, internal_7.wrapError)(error, (errorMessage) => new internal_7.GenericError(`orderSequentially callback exception: ${errorMessage}`, error, {
1535
1636
  orderSequentiallyCalls: this._orderSequentiallyCalls,
1536
1637
  })));
1537
1638
  }
@@ -1541,7 +1642,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1541
1642
  this._orderSequentiallyCalls--;
1542
1643
  }
1543
1644
  // We don't flush on TurnBased since we expect all messages in the same JS turn to be part of the same batch
1544
- if (this.flushMode !== runtime_definitions_1.FlushMode.TurnBased && this._orderSequentiallyCalls === 0) {
1645
+ if (this.flushMode !== internal_5.FlushMode.TurnBased && this._orderSequentiallyCalls === 0) {
1545
1646
  this.flush();
1546
1647
  }
1547
1648
  return result;
@@ -1570,7 +1671,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1570
1671
  }
1571
1672
  const channel = await context.realize();
1572
1673
  if (channel.entryPoint === undefined) {
1573
- throw new telemetry_utils_1.UsageError("entryPoint must be defined on data store runtime for using getAliasedDataStoreEntryPoint");
1674
+ throw new internal_7.UsageError("entryPoint must be defined on data store runtime for using getAliasedDataStoreEntryPoint");
1574
1675
  }
1575
1676
  this.garbageCollector.nodeUpdated(`/${internalId}`, "Loaded", undefined /* timestampMs */, context.packagePath);
1576
1677
  return channel.entryPoint;
@@ -1599,7 +1700,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1599
1700
  * Are we in the middle of batching ops together?
1600
1701
  */
1601
1702
  currentlyBatching() {
1602
- return this.flushMode !== runtime_definitions_1.FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
1703
+ return this.flushMode !== internal_5.FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
1603
1704
  }
1604
1705
  getQuorum() {
1605
1706
  return this._quorum;
@@ -1633,6 +1734,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1633
1734
  break;
1634
1735
  }
1635
1736
  case messageTypes_js_1.ContainerMessageType.IdAllocation:
1737
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1636
1738
  case messageTypes_js_1.ContainerMessageType.GC: {
1637
1739
  return false;
1638
1740
  }
@@ -1659,7 +1761,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1659
1761
  /**
1660
1762
  * Submits the signal to be sent to other clients.
1661
1763
  * @param type - Type of the signal.
1662
- * @param content - Content of the signal.
1764
+ * @param content - Content of the signal. Should be a JSON serializable object or primitive.
1663
1765
  * @param targetClientId - When specified, the signal is only sent to the provided client id.
1664
1766
  */
1665
1767
  submitSignal(type, content, targetClientId) {
@@ -1669,10 +1771,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1669
1771
  }
1670
1772
  setAttachState(attachState) {
1671
1773
  if (attachState === container_definitions_1.AttachState.Attaching) {
1672
- (0, core_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attaching, 0x12d /* "Container Context should already be in attaching state" */);
1774
+ (0, internal_2.assert)(this.attachState === container_definitions_1.AttachState.Attaching, 0x12d /* "Container Context should already be in attaching state" */);
1673
1775
  }
1674
1776
  else {
1675
- (0, core_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x12e /* "Container Context should already be in attached state" */);
1777
+ (0, internal_2.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x12e /* "Container Context should already be in attached state" */);
1676
1778
  this.emit("attached");
1677
1779
  }
1678
1780
  if (attachState === container_definitions_1.AttachState.Attached && !this.hasPendingMessages()) {
@@ -1695,19 +1797,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1695
1797
  // We can finalize any allocated IDs since we're the only client
1696
1798
  const idRange = this._idCompressor?.takeNextCreationRange();
1697
1799
  if (idRange !== undefined) {
1800
+ (0, internal_2.assert)(idRange.ids === undefined || idRange.ids.firstGenCount === 1, "No other ranges should be taken while container is detached.");
1698
1801
  this._idCompressor?.finalizeCreationRange(idRange);
1699
1802
  }
1700
1803
  const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
1701
1804
  // Wrap data store summaries in .channels subtree.
1702
- (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1805
+ (0, index_js_3.wrapSummaryInChannelsTree)(summarizeResult);
1703
1806
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
1704
1807
  return summarizeResult.summary;
1705
1808
  }
1706
1809
  async summarizeInternal(fullTree, trackState, telemetryContext) {
1707
1810
  const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
1708
1811
  // Wrap data store summaries in .channels subtree.
1709
- (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1710
- const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
1812
+ (0, index_js_3.wrapSummaryInChannelsTree)(summarizeResult);
1813
+ const pathPartsForChildren = [internal_5.channelsTreeName];
1814
+ // Ensure that ID compressor had a chance to load, if we are using delayed mode.
1815
+ await this.loadIdCompressor();
1711
1816
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
1712
1817
  return {
1713
1818
  ...summarizeResult,
@@ -1721,7 +1826,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1721
1826
  async summarize(options) {
1722
1827
  this.verifyNotClosed();
1723
1828
  const { fullTree = false, trackState = true, summaryLogger = this.mc.logger, runGC = this.garbageCollector.shouldRunGC, runSweep, fullGC, } = options;
1724
- const telemetryContext = new runtime_utils_1.TelemetryContext();
1829
+ const telemetryContext = new internal_6.TelemetryContext();
1725
1830
  // Add the options that are used to generate this summary to the telemetry context.
1726
1831
  telemetryContext.setMultiple("fluid_Summarize", "Options", {
1727
1832
  fullTree,
@@ -1735,7 +1840,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1735
1840
  await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
1736
1841
  }
1737
1842
  const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
1738
- (0, core_utils_1.assert)(summary.type === protocol_definitions_1.SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
1843
+ (0, internal_2.assert)(summary.type === protocol_definitions_1.SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
1739
1844
  return { stats, summary };
1740
1845
  }
1741
1846
  finally {
@@ -1763,7 +1868,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1763
1868
  * @see IGarbageCollectionRuntime.getGCData
1764
1869
  */
1765
1870
  async getGCData(fullGC) {
1766
- const builder = new runtime_utils_1.GCDataBuilder();
1871
+ const builder = new internal_6.GCDataBuilder();
1767
1872
  const dsGCData = await this.summarizerNode.getGCData(fullGC);
1768
1873
  builder.addNodes(dsGCData.gcNodes);
1769
1874
  const blobsGCData = this.blobManager.getGCData(fullGC);
@@ -1820,9 +1925,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1820
1925
  */
1821
1926
  getNodeType(nodePath) {
1822
1927
  if (this.isBlobPath(nodePath)) {
1823
- return index_js_2.GCNodeType.Blob;
1928
+ return index_js_1.GCNodeType.Blob;
1824
1929
  }
1825
- return this.channelCollection.getGCNodeType(nodePath) ?? index_js_2.GCNodeType.Other;
1930
+ return this.channelCollection.getGCNodeType(nodePath) ?? index_js_1.GCNodeType.Other;
1826
1931
  }
1827
1932
  /**
1828
1933
  * Called by GC to retrieve the package path of the node with the given path. The node should belong to a
@@ -1835,13 +1940,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1835
1940
  return ["_gcRoot"];
1836
1941
  }
1837
1942
  switch (this.getNodeType(nodePath)) {
1838
- case index_js_2.GCNodeType.Blob:
1943
+ case index_js_1.GCNodeType.Blob:
1839
1944
  return [blobManager_js_1.BlobManager.basePath];
1840
- case index_js_2.GCNodeType.DataStore:
1841
- case index_js_2.GCNodeType.SubDataStore:
1945
+ case index_js_1.GCNodeType.DataStore:
1946
+ case index_js_1.GCNodeType.SubDataStore:
1842
1947
  return this.channelCollection.getDataStorePackagePath(nodePath);
1843
1948
  default:
1844
- (0, core_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
1949
+ (0, internal_2.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
1845
1950
  }
1846
1951
  }
1847
1952
  /**
@@ -1902,16 +2007,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1902
2007
  // The summary number for this summary. This will be updated during the summary process, so get it now and
1903
2008
  // use it for all events logged during this summary.
1904
2009
  const summaryNumber = this.nextSummaryNumber;
1905
- const summaryNumberLogger = (0, telemetry_utils_1.createChildLogger)({
2010
+ const summaryNumberLogger = (0, internal_7.createChildLogger)({
1906
2011
  logger: summaryLogger,
1907
2012
  properties: {
1908
2013
  all: { summaryNumber },
1909
2014
  },
1910
2015
  });
1911
- (0, core_utils_1.assert)(this.outbox.isEmpty, 0x3d1 /* Can't trigger summary in the middle of a batch */);
2016
+ (0, internal_2.assert)(this.outbox.isEmpty, 0x3d1 /* Can't trigger summary in the middle of a batch */);
1912
2017
  // We close the summarizer and download a new snapshot and reload the container
1913
2018
  if (refreshLatestAck === true) {
1914
- return this.prefetchLatestSummaryThenClose((0, telemetry_utils_1.createChildLogger)({
2019
+ return this.prefetchLatestSummaryThenClose((0, internal_7.createChildLogger)({
1915
2020
  logger: summaryNumberLogger,
1916
2021
  properties: { all: { safeSummary: true } },
1917
2022
  }));
@@ -1995,7 +2100,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1995
2100
  // That said, we rely on submitSystemMessage() that today only works in connected state.
1996
2101
  // So if we fail here, it either means that RunWhileConnectedCoordinator does not work correctly,
1997
2102
  // OR that design changed and we need to remove this check and fix submitSystemMessage.
1998
- (0, core_utils_1.assert)(this.connected, 0x258 /* "connected" */);
2103
+ (0, internal_2.assert)(this.connected, 0x258 /* "connected" */);
1999
2104
  // Ensure that lastSequenceNumber has not changed after pausing.
2000
2105
  // We need the summary op's reference sequence number to match our summary sequence number,
2001
2106
  // otherwise we'll get the wrong sequence number stamped on the summary's .protocol attributes.
@@ -2005,7 +2110,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2005
2110
  error: `lastSequenceNumber changed before uploading to storage. ${this.deltaManager.lastSequenceNumber} !== ${summaryRefSeqNum}`,
2006
2111
  };
2007
2112
  }
2008
- (0, core_utils_1.assert)(summaryRefSeqNum === this.deltaManager.lastMessage?.sequenceNumber, 0x395 /* it's one and the same thing */);
2113
+ (0, internal_2.assert)(summaryRefSeqNum === this.deltaManager.lastMessage?.sequenceNumber, 0x395 /* it's one and the same thing */);
2009
2114
  if (lastAck !== this.summaryCollection.latestAck) {
2010
2115
  return {
2011
2116
  continue: false,
@@ -2050,7 +2155,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2050
2155
  const validateResult = this.summarizerNode.validateSummary();
2051
2156
  if (!validateResult.success) {
2052
2157
  const { success, ...loggingProps } = validateResult;
2053
- const error = new index_js_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
2158
+ const error = new index_js_3.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
2054
2159
  return {
2055
2160
  stage: "base",
2056
2161
  referenceSequenceNumber: summaryRefSeqNum,
@@ -2069,11 +2174,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2069
2174
  // Counting dataStores and handles
2070
2175
  // Because handles are unchanged dataStores in the current logic,
2071
2176
  // summarized dataStore count is total dataStore count minus handle count
2072
- const dataStoreTree = summaryTree.tree[runtime_definitions_1.channelsTreeName];
2073
- (0, core_utils_1.assert)(dataStoreTree.type === protocol_definitions_1.SummaryType.Tree, 0x1fc /* "summary is not a tree" */);
2177
+ const dataStoreTree = summaryTree.tree[internal_5.channelsTreeName];
2178
+ (0, internal_2.assert)(dataStoreTree.type === protocol_definitions_1.SummaryType.Tree, 0x1fc /* "summary is not a tree" */);
2074
2179
  const handleCount = Object.values(dataStoreTree.tree).filter((value) => value.type === protocol_definitions_1.SummaryType.Handle).length;
2075
- const gcSummaryTreeStats = summaryTree.tree[runtime_definitions_1.gcTreeKey]
2076
- ? (0, runtime_utils_1.calculateStats)(summaryTree.tree[runtime_definitions_1.gcTreeKey])
2180
+ const gcSummaryTreeStats = summaryTree.tree[internal_5.gcTreeKey]
2181
+ ? (0, internal_6.calculateStats)(summaryTree.tree[internal_5.gcTreeKey])
2077
2182
  : undefined;
2078
2183
  const summaryStats = {
2079
2184
  dataStoreCount: this.channelCollection.size,
@@ -2184,7 +2289,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2184
2289
  // the summarizer.
2185
2290
  if (finalAttempt &&
2186
2291
  this.mc.config.getBoolean("Fluid.Summarizer.SkipFailingIncorrectSummary")) {
2187
- const error = telemetry_utils_1.DataProcessingError.create("Pending ops during summarization", "submitSummary", undefined, { pendingMessages: this.pendingMessagesCount });
2292
+ const error = internal_7.DataProcessingError.create("Pending ops during summarization", "submitSummary", undefined, { pendingMessages: this.pendingMessagesCount });
2188
2293
  logger.sendErrorEvent({
2189
2294
  eventName: "SkipFailingIncorrectSummary",
2190
2295
  referenceSequenceNumber,
@@ -2197,7 +2302,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2197
2302
  // based on telemetry while we decide on a stable number.
2198
2303
  const retryDelayMs = this.mc.config.getNumber("Fluid.Summarizer.PendingOpsRetryDelayMs") ??
2199
2304
  exports.defaultPendingOpsRetryDelayMs;
2200
- const error = new index_js_1.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2305
+ const error = new index_js_3.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2201
2306
  count: this.pendingMessagesCount,
2202
2307
  beforeGenerate: beforeSummaryGeneration,
2203
2308
  });
@@ -2217,11 +2322,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2217
2322
  }
2218
2323
  updateDocumentDirtyState(dirty) {
2219
2324
  if (this.attachState !== container_definitions_1.AttachState.Attached) {
2220
- (0, core_utils_1.assert)(dirty, 0x3d2 /* Non-attached container is dirty */);
2325
+ (0, internal_2.assert)(dirty, 0x3d2 /* Non-attached container is dirty */);
2221
2326
  }
2222
2327
  else {
2223
2328
  // Other way is not true = see this.isContainerMessageDirtyable()
2224
- (0, core_utils_1.assert)(!dirty || this.hasPendingMessages(), 0x3d3 /* if doc is dirty, there has to be pending ops */);
2329
+ (0, internal_2.assert)(!dirty || this.hasPendingMessages(), 0x3d3 /* if doc is dirty, there has to be pending ops */);
2225
2330
  }
2226
2331
  if (this.dirtyContainer === dirty) {
2227
2332
  return;
@@ -2250,19 +2355,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2250
2355
  const idAllocationBatchMessage = {
2251
2356
  contents: JSON.stringify(idAllocationMessage),
2252
2357
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2253
- metadata: undefined,
2254
- localOpMetadata: undefined,
2255
- type: messageTypes_js_1.ContainerMessageType.IdAllocation,
2256
2358
  };
2257
2359
  this.outbox.submitIdAllocation(idAllocationBatchMessage);
2258
2360
  }
2259
2361
  }
2260
2362
  }
2261
- submit(containerRuntimeMessage, localOpMetadata = undefined, metadata = undefined) {
2363
+ submit(containerRuntimeMessage, localOpMetadata = undefined, metadata) {
2262
2364
  this.verifyNotClosed();
2263
2365
  this.verifyCanSubmitOps();
2264
2366
  // There should be no ops in detached container state!
2265
- (0, core_utils_1.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
2367
+ (0, internal_2.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
2368
+ (0, internal_2.assert)(metadata === undefined ||
2369
+ containerRuntimeMessage.type === messageTypes_js_1.ContainerMessageType.BlobAttach, "metadata");
2266
2370
  const serializedContent = JSON.stringify(containerRuntimeMessage);
2267
2371
  // Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
2268
2372
  // container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
@@ -2275,7 +2379,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2275
2379
  const type = containerRuntimeMessage.type;
2276
2380
  const message = {
2277
2381
  contents: serializedContent,
2278
- type,
2279
2382
  metadata,
2280
2383
  localOpMetadata,
2281
2384
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -2290,6 +2393,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2290
2393
  }
2291
2394
  else {
2292
2395
  this.submitIdAllocationOpIfNeeded();
2396
+ // Allow document schema controller to send a message if it needs to propose change in document schema.
2397
+ // If it needs to send a message, it will call provided callback with payload of such message and rely
2398
+ // on this callback to do actual sending.
2399
+ const contents = this.documentsSchemaController.maybeSendSchemaMessage();
2400
+ if (contents) {
2401
+ const msg = {
2402
+ type: messageTypes_js_1.ContainerMessageType.DocumentSchemaChange,
2403
+ contents,
2404
+ };
2405
+ this.outbox.submit({
2406
+ contents: JSON.stringify(msg),
2407
+ referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2408
+ });
2409
+ }
2293
2410
  // If this is attach message for new data store, and we are in a batch, send this op out of order
2294
2411
  // Is it safe:
2295
2412
  // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
@@ -2353,29 +2470,29 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2353
2470
  }
2354
2471
  };
2355
2472
  switch (this.flushMode) {
2356
- case runtime_definitions_1.FlushMode.TurnBased:
2473
+ case internal_5.FlushMode.TurnBased:
2357
2474
  // When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
2358
2475
  // batch at the end of the turn
2359
2476
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
2360
2477
  Promise.resolve().then(flush);
2361
2478
  break;
2362
2479
  // FlushModeExperimental is experimental and not exposed directly in the runtime APIs
2363
- case runtime_definitions_1.FlushModeExperimental.Async:
2480
+ case internal_5.FlushModeExperimental.Async:
2364
2481
  // When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
2365
2482
  // batch when all micro-tasks are complete.
2366
2483
  // Compared to TurnBased, this flush mode will capture more ops into the same batch.
2367
2484
  setTimeout(flush, 0);
2368
2485
  break;
2369
2486
  default:
2370
- (0, core_utils_1.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
2487
+ (0, internal_2.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
2371
2488
  break;
2372
2489
  }
2373
2490
  }
2374
2491
  submitSummaryMessage(contents, referenceSequenceNumber) {
2375
2492
  this.verifyNotClosed();
2376
- (0, core_utils_1.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
2493
+ (0, internal_2.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
2377
2494
  // System message should not be sent in the middle of the batch.
2378
- (0, core_utils_1.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
2495
+ (0, internal_2.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
2379
2496
  // back-compat: ADO #1385: Make this call unconditional in the future
2380
2497
  return this.submitSummaryFn !== undefined
2381
2498
  ? this.submitSummaryFn(contents, referenceSequenceNumber)
@@ -2396,7 +2513,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2396
2513
  if (this.opReentryCallsToReport > 0) {
2397
2514
  this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
2398
2515
  // We need to capture the call stack in order to inspect the source of this usage pattern
2399
- (0, index_js_3.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2516
+ (0, index_js_2.getLongStack)(() => new internal_7.UsageError(errorMessage)));
2400
2517
  this.opReentryCallsToReport--;
2401
2518
  }
2402
2519
  // Creating ops while processing ops can lead
@@ -2412,7 +2529,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2412
2529
  // The runtime must enforce op coherence by not allowing ops to be submitted
2413
2530
  // while ops are being processed.
2414
2531
  if (this.enableOpReentryCheck) {
2415
- throw new telemetry_utils_1.UsageError(errorMessage);
2532
+ throw new internal_7.UsageError(errorMessage);
2416
2533
  }
2417
2534
  }
2418
2535
  }
@@ -2437,7 +2554,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2437
2554
  * @param localOpMetadata - The local metadata associated with the original message.
2438
2555
  */
2439
2556
  reSubmitCore(message, localOpMetadata, opMetadata) {
2440
- (0, core_utils_1.assert)(!this.isSummarizerClient, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
2557
+ (0, internal_2.assert)(!this.isSummarizerClient, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
2441
2558
  switch (message.type) {
2442
2559
  case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
2443
2560
  case messageTypes_js_1.ContainerMessageType.Attach:
@@ -2461,6 +2578,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2461
2578
  case messageTypes_js_1.ContainerMessageType.GC:
2462
2579
  this.submit(message);
2463
2580
  break;
2581
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
2582
+ // There is no need to resend this message. Document schema controller will properly resend it again (if needed)
2583
+ // on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
2584
+ // send any ops, as some other client already changed schema.
2585
+ break;
2464
2586
  default: {
2465
2587
  // This case should be very rare - it would imply an op was stashed from a
2466
2588
  // future version of runtime code and now is being applied on an older version.
@@ -2473,7 +2595,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2473
2595
  });
2474
2596
  }
2475
2597
  else {
2476
- const error = telemetry_utils_1.DataProcessingError.create("Resubmitting runtime message of unknown type", "reSubmitCore", undefined /* sequencedMessage */, {
2598
+ const error = internal_7.DataProcessingError.create("Resubmitting runtime message of unknown type", "reSubmitCore", undefined /* sequencedMessage */, {
2477
2599
  messageDetails: JSON.stringify({
2478
2600
  type: message.type,
2479
2601
  compatBehavior,
@@ -2503,8 +2625,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2503
2625
  async refreshLatestSummaryAck(options) {
2504
2626
  const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
2505
2627
  // proposalHandle is always passed from RunningSummarizer.
2506
- (0, core_utils_1.assert)(proposalHandle !== undefined, 0x766 /* proposalHandle should be available */);
2507
- const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
2628
+ (0, internal_2.assert)(proposalHandle !== undefined, 0x766 /* proposalHandle should be available */);
2629
+ const readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
2508
2630
  const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq);
2509
2631
  /**
2510
2632
  * When refreshing a summary ack, this check indicates a new ack of a summary that is newer than the
@@ -2531,7 +2653,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2531
2653
  * @returns a generic summarization error
2532
2654
  */
2533
2655
  async prefetchLatestSummaryThenClose(summaryLogger) {
2534
- const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
2656
+ const readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
2535
2657
  // This is a performance optimization as the same parent is likely to be elected again, and would use its
2536
2658
  // cache to fetch the snapshot instead of the network.
2537
2659
  await this.fetchLatestSnapshotFromStorage(summaryLogger, {
@@ -2547,7 +2669,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2547
2669
  }
2548
2670
  async closeStaleSummarizer() {
2549
2671
  // Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
2550
- await (0, core_utils_1.delay)(this.closeSummarizerDelayMs);
2672
+ await (0, internal_2.delay)(this.closeSummarizerDelayMs);
2551
2673
  this._summarizer?.stop("latestSummaryStateStale");
2552
2674
  this.disposeFn();
2553
2675
  }
@@ -2557,16 +2679,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2557
2679
  * overridden via options.
2558
2680
  */
2559
2681
  async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
2560
- return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
2682
+ return internal_7.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
2561
2683
  const stats = {};
2562
2684
  const trace = client_utils_1.Trace.start();
2563
- const versions = await this.storage.getVersions(null, 1, "prefetchLatestSummaryBeforeClose", driver_definitions_1.FetchSource.noCache);
2564
- (0, core_utils_1.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
2685
+ const versions = await this.storage.getVersions(null, 1, "prefetchLatestSummaryBeforeClose", internal_3.FetchSource.noCache);
2686
+ (0, internal_2.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
2565
2687
  stats.getVersionDuration = trace.trace().duration;
2566
2688
  const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
2567
- (0, core_utils_1.assert)(!!maybeSnapshot, 0x138 /* "Failed to get snapshot from storage" */);
2689
+ (0, internal_2.assert)(!!maybeSnapshot, 0x138 /* "Failed to get snapshot from storage" */);
2568
2690
  stats.getSnapshotDuration = trace.trace().duration;
2569
- const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(maybeSnapshot, readAndParseBlob);
2691
+ const latestSnapshotRefSeq = await (0, internal_6.seqFromTree)(maybeSnapshot, readAndParseBlob);
2570
2692
  stats.snapshotRefSeq = latestSnapshotRefSeq;
2571
2693
  stats.snapshotVersion = versions[0].id;
2572
2694
  perfEvent.end(stats);
@@ -2580,7 +2702,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2580
2702
  getPendingLocalState(props) {
2581
2703
  this.verifyNotClosed();
2582
2704
  if (this._orderSequentiallyCalls !== 0) {
2583
- throw new telemetry_utils_1.UsageError("can't get state during orderSequentially");
2705
+ throw new internal_7.UsageError("can't get state during orderSequentially");
2584
2706
  }
2585
2707
  this.imminentClosure || (this.imminentClosure = props?.notifyImminentClosure ?? false);
2586
2708
  const getSyncState = (pendingAttachmentBlobs) => {
@@ -2612,8 +2734,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2612
2734
  // to close current batch.
2613
2735
  this.flush();
2614
2736
  return props?.notifyImminentClosure === true
2615
- ? telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, perfEvent, async (event) => logAndReturnPendingState(event, getSyncState(await this.blobManager.attachAndGetPendingBlobs(props?.stopBlobAttachingSignal))))
2616
- : telemetry_utils_1.PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
2737
+ ? internal_7.PerformanceEvent.timedExecAsync(this.mc.logger, perfEvent, async (event) => logAndReturnPendingState(event, getSyncState(await this.blobManager.attachAndGetPendingBlobs(props?.stopBlobAttachingSignal))))
2738
+ : internal_7.PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
2617
2739
  }
2618
2740
  summarizeOnDemand(options) {
2619
2741
  if (this.isSummarizerClient) {
@@ -2626,7 +2748,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2626
2748
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
2627
2749
  // disableSummaries is turned on. We are throwing instead of returning a failure here,
2628
2750
  // because it is a misuse of the API rather than an expected failure.
2629
- throw new telemetry_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
2751
+ throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
2630
2752
  }
2631
2753
  }
2632
2754
  enqueueSummarize(options) {
@@ -2640,7 +2762,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2640
2762
  // If we're not the summarizer, and we don't have a summaryManager, we expect that
2641
2763
  // generateSummaries is turned off. We are throwing instead of returning a failure here,
2642
2764
  // because it is a misuse of the API rather than an expected failure.
2643
- throw new telemetry_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
2765
+ throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
2644
2766
  }
2645
2767
  }
2646
2768
  /**
@@ -2655,16 +2777,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2655
2777
  // eslint-disable-next-line no-restricted-syntax
2656
2778
  for (const prop in configuration) {
2657
2779
  if (typeof configuration[prop] === "number" && configuration[prop] < 0) {
2658
- throw new telemetry_utils_1.UsageError(`Summary heuristic configuration property "${prop}" cannot be less than 0`);
2780
+ throw new internal_7.UsageError(`Summary heuristic configuration property "${prop}" cannot be less than 0`);
2659
2781
  }
2660
2782
  }
2661
2783
  if (configuration.minIdleTime > configuration.maxIdleTime) {
2662
- throw new telemetry_utils_1.UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
2784
+ throw new internal_7.UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
2663
2785
  }
2664
2786
  }
2665
2787
  get groupedBatchingEnabled() {
2666
- const killSwitch = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
2667
- return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
2788
+ return this.documentSchema.opGroupingEnabled === true;
2668
2789
  }
2669
2790
  }
2670
2791
  exports.ContainerRuntime = ContainerRuntime;