@fluidframework/container-runtime 2.0.0-dev-rc.2.0.0.245554 → 2.0.0-dev-rc.3.0.0.250606

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 (459) hide show
  1. package/api-report/container-runtime.api.md +81 -27
  2. package/dist/batchTracker.d.ts +1 -1
  3. package/dist/batchTracker.d.ts.map +1 -1
  4. package/dist/batchTracker.js +2 -2
  5. package/dist/batchTracker.js.map +1 -1
  6. package/dist/blobManager.d.ts +3 -3
  7. package/dist/blobManager.d.ts.map +1 -1
  8. package/dist/blobManager.js +3 -3
  9. package/dist/blobManager.js.map +1 -1
  10. package/dist/channelCollection.d.ts +6 -5
  11. package/dist/channelCollection.d.ts.map +1 -1
  12. package/dist/channelCollection.js +57 -19
  13. package/dist/channelCollection.js.map +1 -1
  14. package/dist/connectionTelemetry.d.ts +2 -2
  15. package/dist/connectionTelemetry.d.ts.map +1 -1
  16. package/dist/connectionTelemetry.js +3 -3
  17. package/dist/connectionTelemetry.js.map +1 -1
  18. package/dist/container-runtime-alpha.d.ts +205 -12
  19. package/dist/container-runtime-beta.d.ts +16 -3
  20. package/dist/container-runtime-public.d.ts +16 -3
  21. package/dist/container-runtime-untrimmed.d.ts +207 -26
  22. package/dist/containerHandleContext.d.ts.map +1 -1
  23. package/dist/containerHandleContext.js.map +1 -1
  24. package/dist/containerRuntime.d.ts +32 -26
  25. package/dist/containerRuntime.d.ts.map +1 -1
  26. package/dist/containerRuntime.js +235 -133
  27. package/dist/containerRuntime.js.map +1 -1
  28. package/dist/dataStore.d.ts +1 -1
  29. package/dist/dataStore.d.ts.map +1 -1
  30. package/dist/dataStore.js +2 -2
  31. package/dist/dataStore.js.map +1 -1
  32. package/dist/dataStoreContext.d.ts +4 -4
  33. package/dist/dataStoreContext.d.ts.map +1 -1
  34. package/dist/dataStoreContext.js +18 -18
  35. package/dist/dataStoreContext.js.map +1 -1
  36. package/dist/dataStoreContexts.d.ts.map +1 -1
  37. package/dist/dataStoreContexts.js.map +1 -1
  38. package/dist/dataStoreRegistry.d.ts +4 -0
  39. package/dist/dataStoreRegistry.d.ts.map +1 -1
  40. package/dist/dataStoreRegistry.js +2 -2
  41. package/dist/dataStoreRegistry.js.map +1 -1
  42. package/dist/deltaScheduler.d.ts +1 -1
  43. package/dist/deltaScheduler.d.ts.map +1 -1
  44. package/dist/deltaScheduler.js +1 -1
  45. package/dist/deltaScheduler.js.map +1 -1
  46. package/dist/gc/garbageCollection.d.ts +1 -1
  47. package/dist/gc/garbageCollection.d.ts.map +1 -1
  48. package/dist/gc/garbageCollection.js +1 -1
  49. package/dist/gc/garbageCollection.js.map +1 -1
  50. package/dist/gc/gcConfigs.d.ts +1 -1
  51. package/dist/gc/gcConfigs.d.ts.map +1 -1
  52. package/dist/gc/gcConfigs.js.map +1 -1
  53. package/dist/gc/gcDefinitions.d.ts +1 -1
  54. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  55. package/dist/gc/gcDefinitions.js.map +1 -1
  56. package/dist/gc/gcHelpers.d.ts.map +1 -1
  57. package/dist/gc/gcHelpers.js.map +1 -1
  58. package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
  59. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  60. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  61. package/dist/gc/gcTelemetry.d.ts +1 -1
  62. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  63. package/dist/gc/gcTelemetry.js.map +1 -1
  64. package/dist/index.d.ts +2 -2
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +4 -2
  67. package/dist/index.js.map +1 -1
  68. package/dist/messageTypes.d.ts +11 -5
  69. package/dist/messageTypes.d.ts.map +1 -1
  70. package/dist/messageTypes.js +4 -0
  71. package/dist/messageTypes.js.map +1 -1
  72. package/dist/opLifecycle/definitions.d.ts +1 -19
  73. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  74. package/dist/opLifecycle/definitions.js.map +1 -1
  75. package/dist/opLifecycle/index.d.ts +3 -3
  76. package/dist/opLifecycle/index.d.ts.map +1 -1
  77. package/dist/opLifecycle/index.js +3 -1
  78. package/dist/opLifecycle/index.js.map +1 -1
  79. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  80. package/dist/opLifecycle/opCompressor.js +2 -3
  81. package/dist/opLifecycle/opCompressor.js.map +1 -1
  82. package/dist/opLifecycle/opDecompressor.d.ts +15 -4
  83. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  84. package/dist/opLifecycle/opDecompressor.js +60 -61
  85. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  86. package/dist/opLifecycle/opGroupingManager.d.ts +2 -1
  87. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  88. package/dist/opLifecycle/opGroupingManager.js +9 -11
  89. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  90. package/dist/opLifecycle/opSplitter.d.ts +11 -3
  91. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  92. package/dist/opLifecycle/opSplitter.js +48 -38
  93. package/dist/opLifecycle/opSplitter.js.map +1 -1
  94. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  95. package/dist/opLifecycle/outbox.js +18 -17
  96. package/dist/opLifecycle/outbox.js.map +1 -1
  97. package/dist/opLifecycle/remoteMessageProcessor.d.ts +8 -0
  98. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  99. package/dist/opLifecycle/remoteMessageProcessor.js +36 -32
  100. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  101. package/dist/packageVersion.d.ts +1 -1
  102. package/dist/packageVersion.js +1 -1
  103. package/dist/packageVersion.js.map +1 -1
  104. package/dist/pendingStateManager.d.ts +1 -1
  105. package/dist/pendingStateManager.d.ts.map +1 -1
  106. package/dist/pendingStateManager.js.map +1 -1
  107. package/dist/scheduleManager.d.ts +1 -1
  108. package/dist/scheduleManager.d.ts.map +1 -1
  109. package/dist/scheduleManager.js +6 -2
  110. package/dist/scheduleManager.js.map +1 -1
  111. package/dist/summary/documentSchema.d.ts +178 -0
  112. package/dist/summary/documentSchema.d.ts.map +1 -0
  113. package/dist/summary/documentSchema.js +345 -0
  114. package/dist/summary/documentSchema.js.map +1 -0
  115. package/dist/summary/index.d.ts +2 -1
  116. package/dist/summary/index.d.ts.map +1 -1
  117. package/dist/summary/index.js +4 -1
  118. package/dist/summary/index.js.map +1 -1
  119. package/dist/summary/orderedClientElection.d.ts +2 -2
  120. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  121. package/dist/summary/orderedClientElection.js +7 -2
  122. package/dist/summary/orderedClientElection.js.map +1 -1
  123. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
  124. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  125. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  126. package/dist/summary/runningSummarizer.d.ts +2 -2
  127. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  128. package/dist/summary/runningSummarizer.js +2 -2
  129. package/dist/summary/runningSummarizer.js.map +1 -1
  130. package/dist/summary/summarizer.d.ts +2 -2
  131. package/dist/summary/summarizer.d.ts.map +1 -1
  132. package/dist/summary/summarizer.js +2 -2
  133. package/dist/summary/summarizer.js.map +1 -1
  134. package/dist/summary/summarizerClientElection.d.ts +2 -2
  135. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  136. package/dist/summary/summarizerClientElection.js.map +1 -1
  137. package/dist/summary/summarizerHeuristics.d.ts +1 -1
  138. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  139. package/dist/summary/summarizerHeuristics.js.map +1 -1
  140. package/dist/summary/summarizerNode/summarizerNode.d.ts +2 -2
  141. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  142. package/dist/summary/summarizerNode/summarizerNode.js +3 -3
  143. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  144. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  145. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  146. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  147. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
  148. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  149. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
  150. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  151. package/dist/summary/summarizerTypes.d.ts +3 -3
  152. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  153. package/dist/summary/summarizerTypes.js.map +1 -1
  154. package/dist/summary/summaryCollection.d.ts +2 -2
  155. package/dist/summary/summaryCollection.d.ts.map +1 -1
  156. package/dist/summary/summaryCollection.js +1 -1
  157. package/dist/summary/summaryCollection.js.map +1 -1
  158. package/dist/summary/summaryFormat.d.ts +5 -16
  159. package/dist/summary/summaryFormat.d.ts.map +1 -1
  160. package/dist/summary/summaryFormat.js.map +1 -1
  161. package/dist/summary/summaryGenerator.d.ts +2 -2
  162. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  163. package/dist/summary/summaryGenerator.js +2 -2
  164. package/dist/summary/summaryGenerator.js.map +1 -1
  165. package/dist/summary/summaryManager.d.ts +1 -1
  166. package/dist/summary/summaryManager.d.ts.map +1 -1
  167. package/dist/summary/summaryManager.js +2 -2
  168. package/dist/summary/summaryManager.js.map +1 -1
  169. package/lib/batchTracker.d.ts +1 -1
  170. package/lib/batchTracker.d.ts.map +1 -1
  171. package/lib/batchTracker.js +2 -2
  172. package/lib/batchTracker.js.map +1 -1
  173. package/lib/blobManager.d.ts +3 -3
  174. package/lib/blobManager.d.ts.map +1 -1
  175. package/lib/blobManager.js +5 -5
  176. package/lib/blobManager.js.map +1 -1
  177. package/lib/channelCollection.d.ts +6 -5
  178. package/lib/channelCollection.d.ts.map +1 -1
  179. package/lib/channelCollection.js +59 -21
  180. package/lib/channelCollection.js.map +1 -1
  181. package/lib/connectionTelemetry.d.ts +2 -2
  182. package/lib/connectionTelemetry.d.ts.map +1 -1
  183. package/lib/connectionTelemetry.js +3 -3
  184. package/lib/connectionTelemetry.js.map +1 -1
  185. package/lib/container-runtime-alpha.d.ts +205 -12
  186. package/lib/container-runtime-beta.d.ts +16 -3
  187. package/lib/container-runtime-public.d.ts +16 -3
  188. package/lib/container-runtime-untrimmed.d.ts +207 -26
  189. package/lib/containerHandleContext.d.ts.map +1 -1
  190. package/lib/containerHandleContext.js.map +1 -1
  191. package/lib/containerRuntime.d.ts +32 -26
  192. package/lib/containerRuntime.d.ts.map +1 -1
  193. package/lib/containerRuntime.js +197 -95
  194. package/lib/containerRuntime.js.map +1 -1
  195. package/lib/dataStore.d.ts +1 -1
  196. package/lib/dataStore.d.ts.map +1 -1
  197. package/lib/dataStore.js +2 -2
  198. package/lib/dataStore.js.map +1 -1
  199. package/lib/dataStoreContext.d.ts +4 -4
  200. package/lib/dataStoreContext.d.ts.map +1 -1
  201. package/lib/dataStoreContext.js +3 -3
  202. package/lib/dataStoreContext.js.map +1 -1
  203. package/lib/dataStoreContexts.d.ts.map +1 -1
  204. package/lib/dataStoreContexts.js.map +1 -1
  205. package/lib/dataStoreRegistry.d.ts +4 -0
  206. package/lib/dataStoreRegistry.d.ts.map +1 -1
  207. package/lib/dataStoreRegistry.js.map +1 -1
  208. package/lib/deltaScheduler.d.ts +1 -1
  209. package/lib/deltaScheduler.d.ts.map +1 -1
  210. package/lib/deltaScheduler.js +1 -1
  211. package/lib/deltaScheduler.js.map +1 -1
  212. package/lib/gc/garbageCollection.d.ts +1 -1
  213. package/lib/gc/garbageCollection.d.ts.map +1 -1
  214. package/lib/gc/garbageCollection.js +3 -3
  215. package/lib/gc/garbageCollection.js.map +1 -1
  216. package/lib/gc/gcConfigs.d.ts +1 -1
  217. package/lib/gc/gcConfigs.d.ts.map +1 -1
  218. package/lib/gc/gcConfigs.js +1 -1
  219. package/lib/gc/gcConfigs.js.map +1 -1
  220. package/lib/gc/gcDefinitions.d.ts +1 -1
  221. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  222. package/lib/gc/gcDefinitions.js.map +1 -1
  223. package/lib/gc/gcHelpers.d.ts.map +1 -1
  224. package/lib/gc/gcHelpers.js.map +1 -1
  225. package/lib/gc/gcSummaryStateTracker.d.ts +1 -1
  226. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  227. package/lib/gc/gcSummaryStateTracker.js +1 -1
  228. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  229. package/lib/gc/gcTelemetry.d.ts +1 -1
  230. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  231. package/lib/gc/gcTelemetry.js +1 -1
  232. package/lib/gc/gcTelemetry.js.map +1 -1
  233. package/lib/index.d.ts +2 -2
  234. package/lib/index.d.ts.map +1 -1
  235. package/lib/index.js +2 -2
  236. package/lib/index.js.map +1 -1
  237. package/lib/messageTypes.d.ts +11 -5
  238. package/lib/messageTypes.d.ts.map +1 -1
  239. package/lib/messageTypes.js +4 -0
  240. package/lib/messageTypes.js.map +1 -1
  241. package/lib/opLifecycle/definitions.d.ts +1 -19
  242. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  243. package/lib/opLifecycle/definitions.js.map +1 -1
  244. package/lib/opLifecycle/index.d.ts +3 -3
  245. package/lib/opLifecycle/index.d.ts.map +1 -1
  246. package/lib/opLifecycle/index.js +2 -2
  247. package/lib/opLifecycle/index.js.map +1 -1
  248. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  249. package/lib/opLifecycle/opCompressor.js +2 -3
  250. package/lib/opLifecycle/opCompressor.js.map +1 -1
  251. package/lib/opLifecycle/opDecompressor.d.ts +15 -4
  252. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  253. package/lib/opLifecycle/opDecompressor.js +60 -61
  254. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  255. package/lib/opLifecycle/opGroupingManager.d.ts +2 -1
  256. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  257. package/lib/opLifecycle/opGroupingManager.js +7 -10
  258. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  259. package/lib/opLifecycle/opSplitter.d.ts +11 -3
  260. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  261. package/lib/opLifecycle/opSplitter.js +46 -37
  262. package/lib/opLifecycle/opSplitter.js.map +1 -1
  263. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  264. package/lib/opLifecycle/outbox.js +18 -17
  265. package/lib/opLifecycle/outbox.js.map +1 -1
  266. package/lib/opLifecycle/remoteMessageProcessor.d.ts +8 -0
  267. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  268. package/lib/opLifecycle/remoteMessageProcessor.js +36 -32
  269. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  270. package/lib/packageVersion.d.ts +1 -1
  271. package/lib/packageVersion.js +1 -1
  272. package/lib/packageVersion.js.map +1 -1
  273. package/lib/pendingStateManager.d.ts +1 -1
  274. package/lib/pendingStateManager.d.ts.map +1 -1
  275. package/lib/pendingStateManager.js.map +1 -1
  276. package/lib/scheduleManager.d.ts +1 -1
  277. package/lib/scheduleManager.d.ts.map +1 -1
  278. package/lib/scheduleManager.js +6 -2
  279. package/lib/scheduleManager.js.map +1 -1
  280. package/lib/summary/documentSchema.d.ts +178 -0
  281. package/lib/summary/documentSchema.d.ts.map +1 -0
  282. package/lib/summary/documentSchema.js +341 -0
  283. package/lib/summary/documentSchema.js.map +1 -0
  284. package/lib/summary/index.d.ts +2 -1
  285. package/lib/summary/index.d.ts.map +1 -1
  286. package/lib/summary/index.js +1 -0
  287. package/lib/summary/index.js.map +1 -1
  288. package/lib/summary/orderedClientElection.d.ts +2 -2
  289. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  290. package/lib/summary/orderedClientElection.js +7 -2
  291. package/lib/summary/orderedClientElection.js.map +1 -1
  292. package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -1
  293. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  294. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  295. package/lib/summary/runningSummarizer.d.ts +2 -2
  296. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  297. package/lib/summary/runningSummarizer.js +3 -3
  298. package/lib/summary/runningSummarizer.js.map +1 -1
  299. package/lib/summary/summarizer.d.ts +2 -2
  300. package/lib/summary/summarizer.d.ts.map +1 -1
  301. package/lib/summary/summarizer.js +3 -3
  302. package/lib/summary/summarizer.js.map +1 -1
  303. package/lib/summary/summarizerClientElection.d.ts +2 -2
  304. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  305. package/lib/summary/summarizerClientElection.js.map +1 -1
  306. package/lib/summary/summarizerHeuristics.d.ts +1 -1
  307. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  308. package/lib/summary/summarizerHeuristics.js.map +1 -1
  309. package/lib/summary/summarizerNode/summarizerNode.d.ts +2 -2
  310. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  311. package/lib/summary/summarizerNode/summarizerNode.js +4 -4
  312. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  313. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  314. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  315. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  316. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
  317. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  318. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
  319. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  320. package/lib/summary/summarizerTypes.d.ts +3 -3
  321. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  322. package/lib/summary/summarizerTypes.js.map +1 -1
  323. package/lib/summary/summaryCollection.d.ts +2 -2
  324. package/lib/summary/summaryCollection.d.ts.map +1 -1
  325. package/lib/summary/summaryCollection.js +1 -1
  326. package/lib/summary/summaryCollection.js.map +1 -1
  327. package/lib/summary/summaryFormat.d.ts +5 -16
  328. package/lib/summary/summaryFormat.d.ts.map +1 -1
  329. package/lib/summary/summaryFormat.js +1 -1
  330. package/lib/summary/summaryFormat.js.map +1 -1
  331. package/lib/summary/summaryGenerator.d.ts +2 -2
  332. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  333. package/lib/summary/summaryGenerator.js +3 -3
  334. package/lib/summary/summaryGenerator.js.map +1 -1
  335. package/lib/summary/summaryManager.d.ts +1 -1
  336. package/lib/summary/summaryManager.d.ts.map +1 -1
  337. package/lib/summary/summaryManager.js +2 -2
  338. package/lib/summary/summaryManager.js.map +1 -1
  339. package/lib/test/blobManager.spec.js +3 -3
  340. package/lib/test/blobManager.spec.js.map +1 -1
  341. package/lib/test/containerRuntime.spec.js +6 -4
  342. package/lib/test/containerRuntime.spec.js.map +1 -1
  343. package/lib/test/dataStoreContext.spec.js +4 -4
  344. package/lib/test/dataStoreContext.spec.js.map +1 -1
  345. package/lib/test/dataStoreCreation.spec.js +1 -1
  346. package/lib/test/dataStoreCreation.spec.js.map +1 -1
  347. package/lib/test/dataStoreRegistry.spec.js.map +1 -1
  348. package/lib/test/documentSchema.spec.js +282 -0
  349. package/lib/test/documentSchema.spec.js.map +1 -0
  350. package/lib/test/fuzz/fuzzUtils.js +11 -7
  351. package/lib/test/fuzz/fuzzUtils.js.map +1 -1
  352. package/lib/test/fuzz/summarizer.fuzz.spec.js +9 -7
  353. package/lib/test/fuzz/summarizer.fuzz.spec.js.map +1 -1
  354. package/lib/test/fuzz/summarizerFuzzMocks.js +43 -25
  355. package/lib/test/fuzz/summarizerFuzzMocks.js.map +1 -1
  356. package/lib/test/fuzz/summarizerFuzzSuite.js +7 -4
  357. package/lib/test/fuzz/summarizerFuzzSuite.js.map +1 -1
  358. package/lib/test/gc/garbageCollection.spec.js +5 -5
  359. package/lib/test/gc/garbageCollection.spec.js.map +1 -1
  360. package/lib/test/gc/gcConfigs.spec.js +2 -2
  361. package/lib/test/gc/gcConfigs.spec.js.map +1 -1
  362. package/lib/test/gc/gcHelpers.spec.js.map +1 -1
  363. package/lib/test/gc/gcStats.spec.js +2 -2
  364. package/lib/test/gc/gcStats.spec.js.map +1 -1
  365. package/lib/test/gc/gcSummaryStateTracker.spec.js +1 -1
  366. package/lib/test/gc/gcSummaryStateTracker.spec.js.map +1 -1
  367. package/lib/test/gc/gcTelemetry.spec.js +3 -3
  368. package/lib/test/gc/gcTelemetry.spec.js.map +1 -1
  369. package/lib/test/gc/gcUnreferencedStateTracker.spec.js +1 -1
  370. package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +1 -1
  371. package/lib/test/getPendingBlobs.spec.js +1 -1
  372. package/lib/test/getPendingBlobs.spec.js.map +1 -1
  373. package/lib/test/hardwareStats.spec.js +1 -1
  374. package/lib/test/hardwareStats.spec.js.map +1 -1
  375. package/lib/test/opLifecycle/OpGroupingManager.spec.js +95 -118
  376. package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +1 -1
  377. package/lib/test/opLifecycle/batchManager.spec.js +1 -1
  378. package/lib/test/opLifecycle/batchManager.spec.js.map +1 -1
  379. package/lib/test/opLifecycle/opCompressor.spec.js +0 -1
  380. package/lib/test/opLifecycle/opCompressor.spec.js.map +1 -1
  381. package/lib/test/opLifecycle/opDecompressor.spec.js +60 -55
  382. package/lib/test/opLifecycle/opDecompressor.spec.js.map +1 -1
  383. package/lib/test/opLifecycle/opSplitter.spec.js +56 -41
  384. package/lib/test/opLifecycle/opSplitter.spec.js.map +1 -1
  385. package/lib/test/opLifecycle/outbox.spec.js +118 -10
  386. package/lib/test/opLifecycle/outbox.spec.js.map +1 -1
  387. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +115 -91
  388. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +1 -1
  389. package/lib/test/pendingStateManager.spec.js +1 -1
  390. package/lib/test/pendingStateManager.spec.js.map +1 -1
  391. package/lib/test/scheduleManager.spec.js +1 -1
  392. package/lib/test/scheduleManager.spec.js.map +1 -1
  393. package/lib/test/summarizerNode.spec.js +1 -1
  394. package/lib/test/summarizerNode.spec.js.map +1 -1
  395. package/lib/test/summarizerNodeWithGc.spec.js +1 -1
  396. package/lib/test/summarizerNodeWithGc.spec.js.map +1 -1
  397. package/lib/test/summary/runningSummarizer.spec.js +4 -4
  398. package/lib/test/summary/runningSummarizer.spec.js.map +1 -1
  399. package/lib/test/summary/summarizer.spec.js.map +1 -1
  400. package/lib/test/summary/summarizerClientElection.spec.js +2 -2
  401. package/lib/test/summary/summarizerClientElection.spec.js.map +1 -1
  402. package/lib/test/summary/summarizerHeuristics.spec.js +1 -1
  403. package/lib/test/summary/summarizerHeuristics.spec.js.map +1 -1
  404. package/lib/test/summary/summaryCollection.spec.js +1 -1
  405. package/lib/test/summary/summaryCollection.spec.js.map +1 -1
  406. package/lib/test/summary/summaryManager.spec.js +3 -3
  407. package/lib/test/summary/summaryManager.spec.js.map +1 -1
  408. package/lib/test/throttler.spec.js +1 -1
  409. package/lib/test/throttler.spec.js.map +1 -1
  410. package/lib/test/types/validateContainerRuntimePrevious.generated.js +6 -4
  411. package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +1 -1
  412. package/package.json +35 -21
  413. package/src/batchTracker.ts +3 -3
  414. package/src/blobManager.ts +15 -15
  415. package/src/channelCollection.ts +90 -44
  416. package/src/connectionTelemetry.ts +10 -10
  417. package/src/containerHandleContext.ts +1 -1
  418. package/src/containerRuntime.ts +375 -213
  419. package/src/dataStore.ts +2 -2
  420. package/src/dataStoreContext.ts +19 -19
  421. package/src/dataStoreContexts.ts +2 -2
  422. package/src/dataStoreRegistry.ts +2 -1
  423. package/src/deltaScheduler.ts +1 -1
  424. package/src/gc/garbageCollection.ts +12 -12
  425. package/src/gc/gcConfigs.ts +11 -11
  426. package/src/gc/gcDefinitions.ts +2 -2
  427. package/src/gc/gcHelpers.ts +2 -2
  428. package/src/gc/gcSummaryStateTracker.ts +4 -4
  429. package/src/gc/gcTelemetry.ts +6 -6
  430. package/src/index.ts +8 -1
  431. package/src/messageTypes.ts +18 -5
  432. package/src/opLifecycle/README.md +89 -0
  433. package/src/opLifecycle/definitions.ts +1 -20
  434. package/src/opLifecycle/index.ts +3 -9
  435. package/src/opLifecycle/opCompressor.ts +4 -5
  436. package/src/opLifecycle/opDecompressor.ts +83 -100
  437. package/src/opLifecycle/opGroupingManager.ts +9 -12
  438. package/src/opLifecycle/opSplitter.ts +73 -47
  439. package/src/opLifecycle/outbox.ts +26 -37
  440. package/src/opLifecycle/remoteMessageProcessor.ts +41 -55
  441. package/src/packageVersion.ts +1 -1
  442. package/src/pendingStateManager.ts +2 -2
  443. package/src/scheduleManager.ts +8 -7
  444. package/src/summary/documentSchema.ts +553 -0
  445. package/src/summary/index.ts +10 -1
  446. package/src/summary/orderedClientElection.ts +7 -5
  447. package/src/summary/runWhileConnectedCoordinator.ts +1 -1
  448. package/src/summary/runningSummarizer.ts +19 -19
  449. package/src/summary/summarizer.ts +14 -14
  450. package/src/summary/summarizerClientElection.ts +2 -2
  451. package/src/summary/summarizerHeuristics.ts +2 -2
  452. package/src/summary/summarizerNode/summarizerNode.ts +15 -15
  453. package/src/summary/summarizerNode/summarizerNodeUtils.ts +1 -1
  454. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +4 -4
  455. package/src/summary/summarizerTypes.ts +3 -3
  456. package/src/summary/summaryCollection.ts +3 -3
  457. package/src/summary/summaryFormat.ts +8 -19
  458. package/src/summary/summaryGenerator.ts +10 -10
  459. package/src/summary/summaryManager.ts +4 -4
@@ -2,53 +2,35 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+
6
+ import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
5
7
  import {
6
- ITelemetryBaseLogger,
7
- FluidObject,
8
- IFluidHandle,
9
- IFluidHandleContext,
10
- IRequest,
11
- IResponse,
12
- IProvideFluidHandleContext,
13
- ISignalEnvelope,
14
- } from "@fluidframework/core-interfaces";
15
- import {
8
+ AttachState,
16
9
  IAudience,
17
10
  IBatchMessage,
18
11
  IContainerContext,
19
- IDeltaManager,
20
- IRuntime,
21
12
  ICriticalContainerError,
22
- AttachState,
13
+ IDeltaManager,
14
+ IGetPendingLocalStateProps,
23
15
  ILoader,
16
+ IRuntime,
24
17
  LoaderHeader,
25
- IGetPendingLocalStateProps,
26
18
  } from "@fluidframework/container-definitions";
27
19
  import {
28
20
  IContainerRuntime,
29
21
  IContainerRuntimeEvents,
30
22
  } from "@fluidframework/container-runtime-definitions";
31
- import { assert, Deferred, delay, LazyPromise, PromiseCache } from "@fluidframework/core-utils";
32
- import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
33
23
  import {
34
- createChildLogger,
35
- createChildMonitoringContext,
36
- DataCorruptionError,
37
- DataProcessingError,
38
- GenericError,
39
- raiseConnectedEvent,
40
- PerformanceEvent,
41
- TaggedLoggerAdapter,
42
- MonitoringContext,
43
- wrapError,
44
- ITelemetryLoggerExt,
45
- UsageError,
46
- LoggingError,
47
- createSampledLogger,
48
- IEventSampler,
49
- type ITelemetryGenericEventExt,
50
- loggerToMonitoringContext,
51
- } from "@fluidframework/telemetry-utils";
24
+ FluidObject,
25
+ IFluidHandle,
26
+ IFluidHandleContext,
27
+ IProvideFluidHandleContext,
28
+ IRequest,
29
+ IResponse,
30
+ ISignalEnvelope,
31
+ ITelemetryBaseLogger,
32
+ } from "@fluidframework/core-interfaces";
33
+ import { assert, Deferred, LazyPromise, PromiseCache, delay } from "@fluidframework/core-utils";
52
34
  import {
53
35
  DriverHeader,
54
36
  FetchSource,
@@ -56,6 +38,13 @@ import {
56
38
  type ISnapshot,
57
39
  } from "@fluidframework/driver-definitions";
58
40
  import { readAndParse } from "@fluidframework/driver-utils";
41
+ import type {
42
+ IIdCompressor,
43
+ IIdCompressorCore,
44
+ IdCreationRange,
45
+ SerializedIdCompressorWithNoSession,
46
+ SerializedIdCompressorWithOngoingSession,
47
+ } from "@fluidframework/id-compressor";
59
48
  import {
60
49
  IClientDetails,
61
50
  IDocumentMessage,
@@ -69,134 +58,150 @@ import {
69
58
  SummaryType,
70
59
  } from "@fluidframework/protocol-definitions";
71
60
  import {
61
+ CreateChildSummarizerNodeParam,
72
62
  FlushMode,
73
63
  FlushModeExperimental,
74
- gcTreeKey,
75
- InboundAttachMessage,
64
+ IDataStore,
65
+ IEnvelope,
76
66
  IFluidDataStoreContextDetached,
77
67
  IFluidDataStoreRegistry,
78
68
  IGarbageCollectionData,
79
69
  IInboundSignalMessage,
80
- NamedFluidDataStoreRegistryEntries,
81
- ISummaryTreeWithStats,
82
70
  ISummarizeInternalResult,
83
- CreateChildSummarizerNodeParam,
71
+ ISummaryTreeWithStats,
72
+ ITelemetryContext,
73
+ InboundAttachMessage,
74
+ NamedFluidDataStoreRegistryEntries,
84
75
  SummarizeInternalFn,
85
76
  channelsTreeName,
86
- IDataStore,
87
- ITelemetryContext,
88
- IEnvelope,
77
+ gcTreeKey,
89
78
  } from "@fluidframework/runtime-definitions";
90
- import type {
91
- SerializedIdCompressorWithNoSession,
92
- IIdCompressor,
93
- IIdCompressorCore,
94
- SerializedIdCompressorWithOngoingSession,
95
- IdCreationRange,
96
- } from "@fluidframework/id-compressor";
97
79
  import {
80
+ GCDataBuilder,
81
+ ReadAndParseBlob,
82
+ RequestParser,
83
+ TelemetryContext,
98
84
  addBlobToSummary,
99
85
  addSummarizeResultToSummary,
100
- RequestParser,
86
+ calculateStats,
101
87
  create404Response,
102
88
  exceptionToResponse,
103
- GCDataBuilder,
104
- seqFromTree,
105
- calculateStats,
106
- TelemetryContext,
107
- ReadAndParseBlob,
108
89
  responseToException,
90
+ seqFromTree,
109
91
  } from "@fluidframework/runtime-utils";
110
- import { v4 as uuid } from "uuid";
111
- import { ContainerFluidHandleContext } from "./containerHandleContext.js";
112
- import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
113
- import { ReportOpPerfTelemetry, IPerfSignalReport } from "./connectionTelemetry.js";
114
92
  import {
115
- IPendingBatchMessage,
116
- IPendingLocalState,
117
- PendingStateManager,
118
- } from "./pendingStateManager.js";
119
- import { pkgVersion } from "./packageVersion.js";
93
+ DataCorruptionError,
94
+ DataProcessingError,
95
+ GenericError,
96
+ IEventSampler,
97
+ type ITelemetryGenericEventExt,
98
+ ITelemetryLoggerExt,
99
+ LoggingError,
100
+ MonitoringContext,
101
+ PerformanceEvent,
102
+ TaggedLoggerAdapter,
103
+ UsageError,
104
+ createChildLogger,
105
+ createChildMonitoringContext,
106
+ createSampledLogger,
107
+ loggerToMonitoringContext,
108
+ raiseConnectedEvent,
109
+ wrapError,
110
+ } from "@fluidframework/telemetry-utils";
111
+ import { v4 as uuid } from "uuid";
112
+ import { BindBatchTracker } from "./batchTracker.js";
120
113
  import { BlobManager, IBlobManagerLoadInfo, IPendingBlobs } from "./blobManager.js";
121
114
  import { ChannelCollection, getSummaryForDatastores, wrapContext } from "./channelCollection.js";
115
+ import { IPerfSignalReport, ReportOpPerfTelemetry } from "./connectionTelemetry.js";
116
+ import { ContainerFluidHandleContext } from "./containerHandleContext.js";
117
+ import { channelToDataStore } from "./dataStore.js";
118
+ import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
119
+ import { DeltaManagerSummarizerProxy } from "./deltaManagerSummarizerProxy.js";
122
120
  import {
123
- aliasBlobName,
124
- blobsTreeName,
125
- chunksBlobName,
126
- createRootSummarizerNodeWithGC,
127
- electedSummarizerBlobName,
128
- extractSummaryMetadataMessage,
129
- IContainerRuntimeMetadata,
130
- ICreateContainerMetadata,
131
- idCompressorBlobName,
132
- IRootSummarizerNodeWithGC,
133
- ISummaryMetadataMessage,
134
- metadataBlobName,
135
- Summarizer,
136
- SummaryManager,
137
- wrapSummaryInChannelsTree,
138
- SummaryCollection,
139
- ISerializedElection,
140
- OrderedClientCollection,
141
- OrderedClientElection,
142
- SummarizerClientElection,
143
- summarizerClientType,
144
- SubmitSummaryResult,
145
- IConnectableRuntime,
146
- IGeneratedSummaryStats,
147
- ISubmitSummaryOptions,
148
- ISummarizerInternalsProvider,
149
- ISummarizerRuntime,
150
- IRefreshSummaryAckOptions,
151
- RunWhileConnectedCoordinator,
152
- IGenerateSummaryTreeResult,
153
- RetriableSummaryError,
154
- IOnDemandSummarizeOptions,
155
- ISummarizeResults,
156
- IEnqueueSummarizeOptions,
157
- EnqueueSummarizeResult,
158
- ISummarizerEvents,
159
- IBaseSummarizeResult,
160
- ISummarizer,
161
- rootHasIsolatedChannels,
162
- IdCompressorMode,
163
- } from "./summary/index.js";
164
- import { formExponentialFn, Throttler } from "./throttler.js";
165
- import {
166
- GarbageCollector,
167
121
  GCNodeType,
168
- gcGenerationOptionName,
169
- IGarbageCollector,
122
+ GarbageCollector,
170
123
  IGCRuntimeOptions,
171
124
  IGCStats,
125
+ IGarbageCollector,
126
+ gcGenerationOptionName,
172
127
  } from "./gc/index.js";
173
- import { channelToDataStore } from "./dataStore.js";
174
- import { BindBatchTracker } from "./batchTracker.js";
175
- import { ScheduleManager } from "./scheduleManager.js";
128
+ import {
129
+ ContainerMessageType,
130
+ type ContainerRuntimeDocumentSchemaMessage,
131
+ ContainerRuntimeGCMessage,
132
+ type ContainerRuntimeIdAllocationMessage,
133
+ type InboundSequencedContainerRuntimeMessage,
134
+ type InboundSequencedContainerRuntimeMessageOrSystemMessage,
135
+ type LocalContainerRuntimeMessage,
136
+ type OutboundContainerRuntimeMessage,
137
+ type UnknownContainerRuntimeMessage,
138
+ } from "./messageTypes.js";
139
+ import { IBatchMetadata, IIdAllocationMetadata } from "./metadata.js";
176
140
  import {
177
141
  BatchMessage,
178
142
  IBatch,
179
143
  IBatchCheckpoint,
180
144
  OpCompressor,
181
145
  OpDecompressor,
182
- Outbox,
146
+ OpGroupingManager,
183
147
  OpSplitter,
148
+ Outbox,
184
149
  RemoteMessageProcessor,
185
- OpGroupingManager,
186
150
  getLongStack,
187
151
  } from "./opLifecycle/index.js";
188
- import { DeltaManagerSummarizerProxy } from "./deltaManagerSummarizerProxy.js";
189
- import { IBatchMetadata, IIdAllocationMetadata } from "./metadata.js";
152
+ import { pkgVersion } from "./packageVersion.js";
190
153
  import {
191
- ContainerMessageType,
192
- type InboundSequencedContainerRuntimeMessage,
193
- type InboundSequencedContainerRuntimeMessageOrSystemMessage,
194
- type ContainerRuntimeIdAllocationMessage,
195
- type LocalContainerRuntimeMessage,
196
- type OutboundContainerRuntimeMessage,
197
- type UnknownContainerRuntimeMessage,
198
- ContainerRuntimeGCMessage,
199
- } from "./messageTypes.js";
154
+ IPendingBatchMessage,
155
+ IPendingLocalState,
156
+ PendingStateManager,
157
+ } from "./pendingStateManager.js";
158
+ import { ScheduleManager } from "./scheduleManager.js";
159
+ import {
160
+ DocumentsSchemaController,
161
+ EnqueueSummarizeResult,
162
+ IBaseSummarizeResult,
163
+ IConnectableRuntime,
164
+ IContainerRuntimeMetadata,
165
+ ICreateContainerMetadata,
166
+ IDocumentSchemaChangeMessage,
167
+ type IDocumentSchemaCurrent,
168
+ IEnqueueSummarizeOptions,
169
+ IGenerateSummaryTreeResult,
170
+ IGeneratedSummaryStats,
171
+ IOnDemandSummarizeOptions,
172
+ IRefreshSummaryAckOptions,
173
+ IRootSummarizerNodeWithGC,
174
+ ISerializedElection,
175
+ ISubmitSummaryOptions,
176
+ ISummarizeResults,
177
+ ISummarizer,
178
+ ISummarizerEvents,
179
+ ISummarizerInternalsProvider,
180
+ ISummarizerRuntime,
181
+ ISummaryMetadataMessage,
182
+ IdCompressorMode,
183
+ OrderedClientCollection,
184
+ OrderedClientElection,
185
+ RetriableSummaryError,
186
+ RunWhileConnectedCoordinator,
187
+ SubmitSummaryResult,
188
+ Summarizer,
189
+ SummarizerClientElection,
190
+ SummaryCollection,
191
+ SummaryManager,
192
+ aliasBlobName,
193
+ blobsTreeName,
194
+ chunksBlobName,
195
+ createRootSummarizerNodeWithGC,
196
+ electedSummarizerBlobName,
197
+ extractSummaryMetadataMessage,
198
+ idCompressorBlobName,
199
+ metadataBlobName,
200
+ rootHasIsolatedChannels,
201
+ summarizerClientType,
202
+ wrapSummaryInChannelsTree,
203
+ } from "./summary/index.js";
204
+ import { Throttler, formExponentialFn } from "./throttler.js";
200
205
 
201
206
  /**
202
207
  * Utility to implement compat behaviors given an unknown message type
@@ -415,7 +420,7 @@ export interface IContainerRuntimeOptions {
415
420
  * If specified, when in FlushMode.TurnBased, if the size of the ops between JS turns exceeds this value,
416
421
  * an error will be thrown and the container will close.
417
422
  *
418
- * If unspecified, the limit is 950 * 1024.
423
+ * If unspecified, the limit is 700Kb.
419
424
  *
420
425
  * 'Infinity' will disable any limit.
421
426
  *
@@ -464,6 +469,15 @@ export interface IContainerRuntimeOptions {
464
469
  * @experimental Not ready for use.
465
470
  */
466
471
  readonly enableGroupedBatching?: boolean;
472
+
473
+ /**
474
+ * When this property is set to true, it requires runtime to control is document schema properly through ops
475
+ * The benefit of this mode is that clients who do not understand schema will fail in predictable way, with predictable message,
476
+ * and will not attempt to limp along, which could cause data corruptions and crashes in random places.
477
+ * When this property is not set (or set to false), runtime operates in legacy mode, where new features (modifying document schema)
478
+ * are engaged as they become available, without giving legacy clients any chance to fail predictably.
479
+ */
480
+ readonly explicitSchemaControl?: boolean;
467
481
  }
468
482
 
469
483
  /**
@@ -504,6 +518,12 @@ export enum CompressionAlgorithms {
504
518
  lz4 = "lz4",
505
519
  }
506
520
 
521
+ /** @alpha */
522
+ export const disabledCompressionConfig: ICompressionRuntimeOptions = {
523
+ minimumBatchSizeInBytes: Infinity,
524
+ compressionAlgorithm: CompressionAlgorithms.lz4,
525
+ };
526
+
507
527
  /**
508
528
  * @deprecated
509
529
  * Untagged logger is unsupported going forward. There are old loaders with old ContainerContexts that only
@@ -570,26 +590,12 @@ export const defaultPendingOpsRetryDelayMs = 1000;
570
590
  */
571
591
  const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
572
592
 
573
- /**
574
- * @deprecated use ContainerRuntimeMessageType instead
575
- * @internal
576
- */
577
- export enum RuntimeMessage {
578
- FluidDataStoreOp = "component",
579
- Attach = "attach",
580
- ChunkedOp = "chunkedOp",
581
- BlobAttach = "blobAttach",
582
- Rejoin = "rejoin",
583
- Alias = "alias",
584
- Operation = "op",
585
- }
586
-
587
593
  /**
588
594
  * @deprecated please use version in driver-utils
589
595
  * @internal
590
596
  */
591
597
  export function isRuntimeMessage(message: ISequencedDocumentMessage): boolean {
592
- return (Object.values(RuntimeMessage) as string[]).includes(message.type);
598
+ return (Object.values(ContainerMessageType) as string[]).includes(message.type);
593
599
  }
594
600
 
595
601
  /**
@@ -696,6 +702,18 @@ async function createSummarizer(loader: ILoader, url: string): Promise<ISummariz
696
702
  return fluidObject.ISummarizer;
697
703
  }
698
704
 
705
+ /**
706
+ * Extract last message from the snapshot metadata.
707
+ * Uses legacy property if not using explicit schema control, otherwise uses the new property.
708
+ * This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
709
+ * Please see addMetadataToSummary() as well
710
+ */
711
+ function lastMessageFromMetadata(metadata: IContainerRuntimeMetadata | undefined) {
712
+ return metadata?.documentSchema?.runtime?.explicitSchemaControl
713
+ ? metadata?.lastMessage
714
+ : metadata?.message;
715
+ }
716
+
699
717
  /**
700
718
  * Represents the runtime of the container. Contains helper functions/state of the container.
701
719
  * It will define the store level mappings.
@@ -742,7 +760,7 @@ export class ContainerRuntime
742
760
  existing,
743
761
  requestHandler,
744
762
  provideEntryPoint,
745
- runtimeOptions = {},
763
+ runtimeOptions = {} satisfies IContainerRuntimeOptions,
746
764
  containerScope = {},
747
765
  containerRuntimeCtor = ContainerRuntime,
748
766
  } = params;
@@ -771,10 +789,11 @@ export class ContainerRuntime
771
789
  flushMode = defaultFlushMode,
772
790
  compressionOptions = defaultCompressionConfig,
773
791
  maxBatchSizeInBytes = defaultMaxBatchSizeInBytes,
774
- enableRuntimeIdCompressor = "off",
792
+ enableRuntimeIdCompressor,
775
793
  chunkSizeInBytes = defaultChunkSizeInBytes,
776
794
  enableOpReentryCheck = false,
777
795
  enableGroupedBatching = false,
796
+ explicitSchemaControl = false,
778
797
  } = runtimeOptions;
779
798
 
780
799
  const registry = new FluidDataStoreRegistry(registryEntries);
@@ -815,8 +834,10 @@ export class ContainerRuntime
815
834
  },
816
835
  );
817
836
 
837
+ const messageAtLastSummary = lastMessageFromMetadata(metadata);
838
+
818
839
  // Verify summary runtime sequence number matches protocol sequence number.
819
- const runtimeSequenceNumber = metadata?.message?.sequenceNumber;
840
+ const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
820
841
  // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
821
842
  if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
822
843
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
@@ -825,6 +846,13 @@ export class ContainerRuntime
825
846
  loadSequenceNumberVerification !== "bypass" &&
826
847
  runtimeSequenceNumber !== protocolSequenceNumber
827
848
  ) {
849
+ // Message to OCEs:
850
+ // You can hit this error with runtimeSequenceNumber === -1 in < 2.0 RC3 builds.
851
+ // This would indicate that explicit schema control is enabled in current (2.0 RC3+) builds and it
852
+ // results in addMetadataToSummary() creating a poison pill for older runtimes in the form of a -1 sequence number.
853
+ // Older runtimes do not understand new schema, and thus could corrupt document if they proceed, thus we are using
854
+ // this poison pill to prevent them from proceeding.
855
+
828
856
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
829
857
  const error = new DataCorruptionError(
830
858
  // pre-0.58 error message: SummaryMetadataMismatch
@@ -841,7 +869,7 @@ export class ContainerRuntime
841
869
  }
842
870
 
843
871
  // Enabling the IdCompressor is a one-way operation and we only want to
844
- // allow new containers to turn it on
872
+ // allow new containers to turn it on.
845
873
  let idCompressorMode: IdCompressorMode;
846
874
  if (existing) {
847
875
  // This setting has to be sticky for correctness:
@@ -850,19 +878,19 @@ export class ContainerRuntime
850
878
  // 2) if it's ON, then all sessions should load compressor right away
851
879
  // 3) Same logic applies for "delayed" mode
852
880
  // Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
853
- // We could do "off" -> "on" transtition too, if all clients start loading compressor (but not using it initially) and do so for a while -
854
- // this will allow clients to eventually to disregard "off" setting (when it's safe so) and start using compressor in future sessions.
881
+ // We could do "off" -> "on" transition too, if all clients start loading compressor (but not using it initially) and
882
+ // do so for a while - this will allow clients to eventually to disregard "off" setting (when it's safe so) and start
883
+ // using compressor in future sessions.
855
884
  // Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
856
- idCompressorMode = metadata?.idCompressorMode ?? "off";
885
+ idCompressorMode = metadata?.documentSchema?.runtime
886
+ ?.idCompressorMode as IdCompressorMode;
857
887
  } else {
858
- // FG overwrite
859
- const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
860
- switch (enabled) {
888
+ switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
861
889
  case true:
862
890
  idCompressorMode = "on";
863
891
  break;
864
892
  case false:
865
- idCompressorMode = "off";
893
+ idCompressorMode = undefined;
866
894
  break;
867
895
  default:
868
896
  idCompressorMode = enableRuntimeIdCompressor;
@@ -907,6 +935,38 @@ export class ContainerRuntime
907
935
  }
908
936
  };
909
937
 
938
+ const disableGroupedBatching = mc.config.getBoolean(
939
+ "Fluid.ContainerRuntime.DisableGroupedBatching",
940
+ );
941
+ const disableCompression = mc.config.getBoolean(
942
+ "Fluid.ContainerRuntime.CompressionDisabled",
943
+ );
944
+ const compressionLz4 =
945
+ disableCompression !== true &&
946
+ compressionOptions.minimumBatchSizeInBytes !== Infinity &&
947
+ compressionOptions.compressionAlgorithm === "lz4";
948
+
949
+ const opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
950
+
951
+ const documentSchemaController = new DocumentsSchemaController(
952
+ existing,
953
+ metadata?.documentSchema,
954
+ {
955
+ explicitSchemaControl,
956
+ compressionLz4,
957
+ idCompressorMode,
958
+ opGroupingEnabled,
959
+ },
960
+ (schema) => {
961
+ runtime.onSchemaChange(schema);
962
+ },
963
+ );
964
+
965
+ const featureGatesForTelemetry: Record<string, boolean | number | undefined> = {
966
+ disableGroupedBatching,
967
+ disableCompression,
968
+ };
969
+
910
970
  const runtime = new containerRuntimeCtor(
911
971
  context,
912
972
  registry,
@@ -922,9 +982,11 @@ export class ContainerRuntime
922
982
  compressionOptions,
923
983
  maxBatchSizeInBytes,
924
984
  chunkSizeInBytes,
925
- enableRuntimeIdCompressor,
985
+ // Requires<> drops undefined from IdCompressorType
986
+ enableRuntimeIdCompressor: enableRuntimeIdCompressor as "on" | "delayed",
926
987
  enableOpReentryCheck,
927
988
  enableGroupedBatching,
989
+ explicitSchemaControl,
928
990
  },
929
991
  containerScope,
930
992
  logger,
@@ -932,7 +994,8 @@ export class ContainerRuntime
932
994
  blobManagerSnapshot,
933
995
  context.storage,
934
996
  createIdCompressorFn,
935
- idCompressorMode,
997
+ documentSchemaController,
998
+ featureGatesForTelemetry,
936
999
  provideEntryPoint,
937
1000
  requestHandler,
938
1001
  undefined, // summaryConfiguration
@@ -982,7 +1045,7 @@ export class ContainerRuntime
982
1045
  summaryOp: ISummaryContent,
983
1046
  referenceSequenceNumber?: number,
984
1047
  ) => number;
985
- private readonly submitSignalFn: (content: any, targetClientId?: string) => void;
1048
+ private readonly submitSignalFn: (content: ISignalEnvelope, targetClientId?: string) => void;
986
1049
  public readonly disposeFn: (error?: ICriticalContainerError) => void;
987
1050
  public readonly closeFn: (error?: ICriticalContainerError) => void;
988
1051
 
@@ -1003,6 +1066,10 @@ export class ContainerRuntime
1003
1066
  return this._getAttachState();
1004
1067
  }
1005
1068
 
1069
+ public get documentSchema() {
1070
+ return this.documentsSchemaController.sessionSchema.runtime;
1071
+ }
1072
+
1006
1073
  private _idCompressor: (IIdCompressor & IIdCompressorCore) | undefined;
1007
1074
 
1008
1075
  // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
@@ -1015,6 +1082,9 @@ export class ContainerRuntime
1015
1082
  // In such case we have to process all ops, including those marked with saveOp === true.
1016
1083
  private readonly skipSavedCompressorOps: boolean;
1017
1084
 
1085
+ public get idCompressorMode() {
1086
+ return this.documentSchema.idCompressorMode;
1087
+ }
1018
1088
  /**
1019
1089
  * See IContainerRuntimeBase.idCompressor() for details.
1020
1090
  */
@@ -1036,7 +1106,7 @@ export class ContainerRuntime
1036
1106
  * True if we have ID compressor loading in-flight (async operation). Useful only for
1037
1107
  * this.idCompressorMode === "delayed" mode
1038
1108
  */
1039
- protected compressorLoadInitiated = false;
1109
+ protected _loadIdCompressor: Promise<void> | undefined;
1040
1110
 
1041
1111
  /**
1042
1112
  * See IContainerRuntimeBase.generateDocumentUniqueId() for details.
@@ -1258,7 +1328,8 @@ export class ContainerRuntime
1258
1328
  blobManagerSnapshot: IBlobManagerLoadInfo,
1259
1329
  private readonly _storage: IDocumentStorageService,
1260
1330
  private readonly createIdCompressor: () => Promise<IIdCompressor & IIdCompressorCore>,
1261
- private readonly idCompressorMode: IdCompressorMode,
1331
+ private readonly documentsSchemaController: DocumentsSchemaController,
1332
+ featureGatesForTelemetry: Record<string, boolean | number | undefined>,
1262
1333
  provideEntryPoint: (containerRuntime: IContainerRuntime) => Promise<FluidObject>,
1263
1334
  private readonly requestHandler?: (
1264
1335
  request: IRequest,
@@ -1292,6 +1363,22 @@ export class ContainerRuntime
1292
1363
  supportedFeatures,
1293
1364
  } = context;
1294
1365
 
1366
+ this.mc = createChildMonitoringContext({
1367
+ logger: this.logger,
1368
+ namespace: "ContainerRuntime",
1369
+ });
1370
+
1371
+ // If we support multiple algorithms in the future, then we would need to manage it here carefully.
1372
+ // We can use runtimeOptions.compressionOptions.compressionAlgorithm, but only if it's in the schema list!
1373
+ // If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
1374
+ // compression.
1375
+ const compressionOptions: ICompressionRuntimeOptions = {
1376
+ minimumBatchSizeInBytes: this.documentSchema.compressionLz4
1377
+ ? runtimeOptions.compressionOptions.minimumBatchSizeInBytes
1378
+ : Number.POSITIVE_INFINITY,
1379
+ compressionAlgorithm: CompressionAlgorithms.lz4,
1380
+ };
1381
+
1295
1382
  this.innerDeltaManager = deltaManager;
1296
1383
  this.deltaManager = new DeltaManagerSummarizerProxy(this.innerDeltaManager);
1297
1384
 
@@ -1329,11 +1416,6 @@ export class ContainerRuntime
1329
1416
  // In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
1330
1417
  this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
1331
1418
 
1332
- this.mc = createChildMonitoringContext({
1333
- logger: this.logger,
1334
- namespace: "ContainerRuntime",
1335
- });
1336
-
1337
1419
  let loadSummaryNumber: number;
1338
1420
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
1339
1421
  // get the values from the metadata blob.
@@ -1354,7 +1436,7 @@ export class ContainerRuntime
1354
1436
  }
1355
1437
  this.nextSummaryNumber = loadSummaryNumber + 1;
1356
1438
 
1357
- this.messageAtLastSummary = metadata?.message;
1439
+ this.messageAtLastSummary = lastMessageFromMetadata(metadata);
1358
1440
 
1359
1441
  // Note that we only need to pull the *initial* connected state from the context.
1360
1442
  // Later updates come through calls to setConnectionState.
@@ -1570,7 +1652,10 @@ export class ContainerRuntime
1570
1652
  clientId: () => this.clientId,
1571
1653
  close: this.closeFn,
1572
1654
  connected: () => this.connected,
1573
- reSubmit: this.reSubmit.bind(this),
1655
+ reSubmit: (message: IPendingBatchMessage) => {
1656
+ this.reSubmit(message);
1657
+ this.flush();
1658
+ },
1574
1659
  reSubmitBatch: this.reSubmitBatch.bind(this),
1575
1660
  isActiveConnection: () => this.innerDeltaManager.active,
1576
1661
  isAttached: () => this.attachState !== AttachState.Detached,
@@ -1579,17 +1664,6 @@ export class ContainerRuntime
1579
1664
  this.logger,
1580
1665
  );
1581
1666
 
1582
- const disableCompression = this.mc.config.getBoolean(
1583
- "Fluid.ContainerRuntime.CompressionDisabled",
1584
- );
1585
- const compressionOptions =
1586
- disableCompression === true
1587
- ? {
1588
- minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
1589
- compressionAlgorithm: CompressionAlgorithms.lz4,
1590
- }
1591
- : runtimeOptions.compressionOptions;
1592
-
1593
1667
  const disablePartialFlush = this.mc.config.getBoolean(
1594
1668
  "Fluid.ContainerRuntime.DisablePartialFlush",
1595
1669
  );
@@ -1743,10 +1817,10 @@ export class ContainerRuntime
1743
1817
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
1744
1818
  gcVersion: metadata?.gcFeature,
1745
1819
  options: JSON.stringify(runtimeOptions),
1746
- idCompressorModeMetadata: metadata?.idCompressorMode,
1820
+ idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
1747
1821
  idCompressorMode: this.idCompressorMode,
1748
1822
  featureGates: JSON.stringify({
1749
- disableCompression,
1823
+ ...featureGatesForTelemetry,
1750
1824
  disableOpReentryCheck,
1751
1825
  disableChunking,
1752
1826
  disableAttachReorder: this.disableAttachReorder,
@@ -1776,6 +1850,21 @@ export class ContainerRuntime
1776
1850
  this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
1777
1851
  }
1778
1852
 
1853
+ public onSchemaChange(schema: IDocumentSchemaCurrent) {
1854
+ // Most of the settings will be picked up only by new sessions (i.e. after reload).
1855
+ // We can make it better in the future (i.e. start to use op compression right away), but for simplicity
1856
+ // this is not done.
1857
+ // But ID compressor is special. It's possible, that in future, we will remove "stickiness" of ID compressor setting
1858
+ // and will allow to start using it. If that were to happen, we want to ensure that we do not break eventual consistency
1859
+ // promises. To do so, we need to initialize id compressor right away.
1860
+ // As it's implemented right now (with async initialization), this will only work for "off" -> "delayed" transitions.
1861
+ // Anything else is too risky, and requires ability to initialize ID compressor synchronously!
1862
+ if (schema.runtime.idCompressorMode !== undefined) {
1863
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1864
+ this.loadIdCompressor();
1865
+ }
1866
+ }
1867
+
1779
1868
  public getCreateChildSummarizerNodeFn(id: string, createParam: CreateChildSummarizerNodeParam) {
1780
1869
  return (
1781
1870
  summarizeInternal: SummarizeInternalFn,
@@ -1800,7 +1889,7 @@ export class ContainerRuntime
1800
1889
  }
1801
1890
 
1802
1891
  public setChannelDirty(address: string) {
1803
- assert(false, "should not be called");
1892
+ assert(false, 0x909 /* should not be called */);
1804
1893
  }
1805
1894
 
1806
1895
  /**
@@ -2058,20 +2147,38 @@ export class ContainerRuntime
2058
2147
 
2059
2148
  /** Adds the container's metadata to the given summary tree. */
2060
2149
  private addMetadataToSummary(summaryTree: ISummaryTreeWithStats) {
2150
+ // The last message processed at the time of summary. If there are no new messages, use the message from the
2151
+ // last summary.
2152
+ const message =
2153
+ extractSummaryMetadataMessage(this.deltaManager.lastMessage) ??
2154
+ this.messageAtLastSummary;
2155
+
2156
+ const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(
2157
+ this.deltaManager.lastSequenceNumber,
2158
+ );
2159
+
2160
+ // Is document schema explicit control on?
2161
+ const explitiSchemaControl = documentSchema?.runtime.explicitSchemaControl;
2162
+
2061
2163
  const metadata: IContainerRuntimeMetadata = {
2062
2164
  ...this.createContainerMetadata,
2063
2165
  // Increment the summary number for the next summary that will be generated.
2064
2166
  summaryNumber: this.nextSummaryNumber++,
2065
2167
  summaryFormatVersion: 1,
2066
2168
  ...this.garbageCollector.getMetadata(),
2067
- // The last message processed at the time of summary. If there are no new messages, use the message from the
2068
- // last summary.
2069
- message:
2070
- extractSummaryMetadataMessage(this.deltaManager.lastMessage) ??
2071
- this.messageAtLastSummary,
2072
2169
  telemetryDocumentId: this.telemetryDocumentId,
2073
- idCompressorMode: this.idCompressorMode,
2170
+ // If explicit document schema control is not on, use legacy way to supply last message (using 'message' property).
2171
+ // Otherwise use new 'lastMessage' property, but also put content into the 'message' property that cases old
2172
+ // runtimes (that preceed document schema control capabilities) to close container on load due to mismatch in
2173
+ // last message's sequence number.
2174
+ // See also lastMessageFromMetadata()
2175
+ message: explitiSchemaControl
2176
+ ? ({ sequenceNumber: -1 } as any as ISummaryMetadataMessage)
2177
+ : message,
2178
+ lastMessage: explitiSchemaControl ? message : undefined,
2179
+ documentSchema,
2074
2180
  };
2181
+
2075
2182
  addBlobToSummary(summaryTree, metadataBlobName, JSON.stringify(metadata));
2076
2183
  }
2077
2184
 
@@ -2150,14 +2257,8 @@ export class ContainerRuntime
2150
2257
  return this.consecutiveReconnects < this.maxConsecutiveReconnects;
2151
2258
  }
2152
2259
 
2153
- private resetReconnectCount(message?: ISequencedDocumentMessage) {
2154
- // Chunked ops don't count towards making progress as they are sent
2155
- // in their own batches before the originating batch is sent.
2156
- // Therefore, receiving them while attempting to send the originating batch
2157
- // does not mean that the container is making any progress.
2158
- if (message?.type !== ContainerMessageType.ChunkedOp) {
2159
- this.consecutiveReconnects = 0;
2160
- }
2260
+ private resetReconnectCount() {
2261
+ this.consecutiveReconnects = 0;
2161
2262
  }
2162
2263
 
2163
2264
  private replayPendingStates() {
@@ -2213,7 +2314,12 @@ export class ContainerRuntime
2213
2314
  case ContainerMessageType.Alias:
2214
2315
  return this.channelCollection.applyStashedOp(opContents);
2215
2316
  case ContainerMessageType.IdAllocation:
2216
- assert(this.idCompressorMode !== "off", 0x8f1 /* ID compressor should be in use */);
2317
+ assert(
2318
+ this.idCompressorMode !== undefined,
2319
+ 0x8f1 /* ID compressor should be in use */,
2320
+ );
2321
+ return;
2322
+ case ContainerMessageType.DocumentSchemaChange:
2217
2323
  return;
2218
2324
  case ContainerMessageType.BlobAttach:
2219
2325
  return;
@@ -2250,10 +2356,13 @@ export class ContainerRuntime
2250
2356
  }
2251
2357
  }
2252
2358
 
2253
- public setConnectionState(connected: boolean, clientId?: string) {
2254
- if (connected && this.idCompressorMode === "delayed" && !this.compressorLoadInitiated) {
2255
- this.compressorLoadInitiated = true;
2256
- this.createIdCompressor()
2359
+ private async loadIdCompressor() {
2360
+ if (
2361
+ this._idCompressor === undefined &&
2362
+ this.idCompressorMode !== undefined &&
2363
+ this._loadIdCompressor === undefined
2364
+ ) {
2365
+ this._loadIdCompressor = this.createIdCompressor()
2257
2366
  .then((compressor) => {
2258
2367
  this._idCompressor = compressor;
2259
2368
  for (const range of this.pendingIdCompressorOps) {
@@ -2263,8 +2372,17 @@ export class ContainerRuntime
2263
2372
  })
2264
2373
  .catch((error) => {
2265
2374
  this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
2375
+ throw error;
2266
2376
  });
2267
2377
  }
2378
+ return this._loadIdCompressor;
2379
+ }
2380
+
2381
+ public setConnectionState(connected: boolean, clientId?: string) {
2382
+ if (connected && this.idCompressorMode === "delayed") {
2383
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
2384
+ this.loadIdCompressor();
2385
+ }
2268
2386
  if (connected === false && this.delayConnectClientId !== undefined) {
2269
2387
  this.delayConnectClientId = undefined;
2270
2388
  this.mc.logger.sendTelemetryEvent({
@@ -2274,6 +2392,10 @@ export class ContainerRuntime
2274
2392
  return;
2275
2393
  }
2276
2394
 
2395
+ if (!connected) {
2396
+ this.documentsSchemaController.onDisconnect();
2397
+ }
2398
+
2277
2399
  // If there are stashed blobs in the pending state, we need to delay
2278
2400
  // propagation of the "connected" event until we have uploaded them to
2279
2401
  // ensure we don't submit ops referencing a blob that has not been uploaded
@@ -2413,12 +2535,17 @@ export class ContainerRuntime
2413
2535
  this._processedClientSequenceNumber = message.clientSequenceNumber;
2414
2536
 
2415
2537
  try {
2538
+ // See commit that added this assert for more details.
2539
+ // These calls should be made for all but chunked ops:
2540
+ // 1) this.pendingStateManager.processPendingLocalMessage() below
2541
+ // 2) this.resetReconnectCount() below
2542
+ assert(
2543
+ message.type !== ContainerMessageType.ChunkedOp,
2544
+ "we should never get here with chunked ops",
2545
+ );
2546
+
2416
2547
  let localOpMetadata: unknown;
2417
- if (
2418
- local &&
2419
- messageWithContext.modernRuntimeMessage &&
2420
- message.type !== ContainerMessageType.ChunkedOp
2421
- ) {
2548
+ if (local && messageWithContext.modernRuntimeMessage) {
2422
2549
  localOpMetadata = this.pendingStateManager.processPendingLocalMessage(
2423
2550
  messageWithContext.message,
2424
2551
  );
@@ -2440,7 +2567,7 @@ export class ContainerRuntime
2440
2567
  // If we have processed a local op, this means that the container is
2441
2568
  // making progress and we can reset the counter for how many times
2442
2569
  // we have consecutively replayed the pending states
2443
- this.resetReconnectCount(message);
2570
+ this.resetReconnectCount();
2444
2571
  }
2445
2572
  } catch (e) {
2446
2573
  this.scheduleManager.afterOpProcessing(e, message);
@@ -2496,8 +2623,18 @@ export class ContainerRuntime
2496
2623
  this.garbageCollector.processMessage(messageWithContext.message, local);
2497
2624
  break;
2498
2625
  case ContainerMessageType.ChunkedOp:
2626
+ // From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
2627
+ // Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
2628
+ assert(false, "should not even get here");
2499
2629
  case ContainerMessageType.Rejoin:
2500
2630
  break;
2631
+ case ContainerMessageType.DocumentSchemaChange:
2632
+ this.documentsSchemaController.processDocumentSchemaOp(
2633
+ messageWithContext.message.contents,
2634
+ messageWithContext.local,
2635
+ messageWithContext.message.sequenceNumber,
2636
+ );
2637
+ break;
2501
2638
  default: {
2502
2639
  // If we didn't necessarily expect a runtime message type, then no worries - just return
2503
2640
  // e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
@@ -2816,6 +2953,8 @@ export class ContainerRuntime
2816
2953
  }
2817
2954
  break;
2818
2955
  }
2956
+ case ContainerMessageType.IdAllocation:
2957
+ case ContainerMessageType.DocumentSchemaChange:
2819
2958
  case ContainerMessageType.GC: {
2820
2959
  return false;
2821
2960
  }
@@ -2933,6 +3072,9 @@ export class ContainerRuntime
2933
3072
  wrapSummaryInChannelsTree(summarizeResult);
2934
3073
  const pathPartsForChildren = [channelsTreeName];
2935
3074
 
3075
+ // Ensure that ID compressor had a chance to load, if we are using delayed mode.
3076
+ await this.loadIdCompressor();
3077
+
2936
3078
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
2937
3079
  return {
2938
3080
  ...summarizeResult,
@@ -3666,9 +3808,6 @@ export class ContainerRuntime
3666
3808
  const idAllocationBatchMessage: BatchMessage = {
3667
3809
  contents: JSON.stringify(idAllocationMessage),
3668
3810
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
3669
- metadata: undefined,
3670
- localOpMetadata: undefined,
3671
- type: ContainerMessageType.IdAllocation,
3672
3811
  };
3673
3812
  this.outbox.submitIdAllocation(idAllocationBatchMessage);
3674
3813
  }
@@ -3678,7 +3817,7 @@ export class ContainerRuntime
3678
3817
  private submit(
3679
3818
  containerRuntimeMessage: OutboundContainerRuntimeMessage,
3680
3819
  localOpMetadata: unknown = undefined,
3681
- metadata: Record<string, unknown> | undefined = undefined,
3820
+ metadata?: { localId: string; blobId?: string },
3682
3821
  ): void {
3683
3822
  this.verifyNotClosed();
3684
3823
  this.verifyCanSubmitOps();
@@ -3689,6 +3828,12 @@ export class ContainerRuntime
3689
3828
  0x132 /* "sending ops in detached container" */,
3690
3829
  );
3691
3830
 
3831
+ assert(
3832
+ metadata === undefined ||
3833
+ containerRuntimeMessage.type === ContainerMessageType.BlobAttach,
3834
+ "metadata",
3835
+ );
3836
+
3692
3837
  const serializedContent = JSON.stringify(containerRuntimeMessage);
3693
3838
 
3694
3839
  // Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
@@ -3703,7 +3848,6 @@ export class ContainerRuntime
3703
3848
  const type = containerRuntimeMessage.type;
3704
3849
  const message: BatchMessage = {
3705
3850
  contents: serializedContent,
3706
- type,
3707
3851
  metadata,
3708
3852
  localOpMetadata,
3709
3853
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -3719,6 +3863,22 @@ export class ContainerRuntime
3719
3863
  } else {
3720
3864
  this.submitIdAllocationOpIfNeeded();
3721
3865
 
3866
+ // Allow document schema controller to send a message if it needs to propose change in document schema.
3867
+ // If it needs to send a message, it will call provided callback with payload of such message and rely
3868
+ // on this callback to do actual sending.
3869
+ this.documentsSchemaController.onMessageSent(
3870
+ (contents: IDocumentSchemaChangeMessage) => {
3871
+ const msg: ContainerRuntimeDocumentSchemaMessage = {
3872
+ type: ContainerMessageType.DocumentSchemaChange,
3873
+ contents,
3874
+ };
3875
+ this.outbox.submit({
3876
+ contents: JSON.stringify(msg),
3877
+ referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
3878
+ });
3879
+ },
3880
+ );
3881
+
3722
3882
  // If this is attach message for new data store, and we are in a batch, send this op out of order
3723
3883
  // Is it safe:
3724
3884
  // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
@@ -3919,6 +4079,11 @@ export class ContainerRuntime
3919
4079
  case ContainerMessageType.GC:
3920
4080
  this.submit(message);
3921
4081
  break;
4082
+ case ContainerMessageType.DocumentSchemaChange:
4083
+ // There is no need to resend this message. Document schema controller will properly resend it again (if needed)
4084
+ // on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
4085
+ // send any ops, as some other client already changed schema.
4086
+ break;
3922
4087
  default: {
3923
4088
  // This case should be very rare - it would imply an op was stashed from a
3924
4089
  // future version of runtime code and now is being applied on an older version.
@@ -4208,9 +4373,6 @@ export class ContainerRuntime
4208
4373
  }
4209
4374
 
4210
4375
  private get groupedBatchingEnabled(): boolean {
4211
- const killSwitch = this.mc.config.getBoolean(
4212
- "Fluid.ContainerRuntime.DisableGroupedBatching",
4213
- );
4214
- return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
4376
+ return this.documentSchema.opGroupingEnabled === true;
4215
4377
  }
4216
4378
  }