@fluidframework/container-runtime 2.0.0-rc.2.0.2 → 2.0.0-rc.3.0.1

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 (554) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/api-report/container-runtime.api.md +471 -52
  3. package/dist/batchTracker.d.ts +1 -1
  4. package/dist/batchTracker.d.ts.map +1 -1
  5. package/dist/batchTracker.js +4 -4
  6. package/dist/batchTracker.js.map +1 -1
  7. package/dist/blobManager.d.ts +33 -30
  8. package/dist/blobManager.d.ts.map +1 -1
  9. package/dist/blobManager.js +82 -107
  10. package/dist/blobManager.js.map +1 -1
  11. package/dist/channelCollection.d.ts +27 -22
  12. package/dist/channelCollection.d.ts.map +1 -1
  13. package/dist/channelCollection.js +155 -165
  14. package/dist/channelCollection.js.map +1 -1
  15. package/dist/connectionTelemetry.d.ts +3 -3
  16. package/dist/connectionTelemetry.d.ts.map +1 -1
  17. package/dist/connectionTelemetry.js +17 -17
  18. package/dist/connectionTelemetry.js.map +1 -1
  19. package/dist/containerHandleContext.d.ts.map +1 -1
  20. package/dist/containerHandleContext.js +2 -2
  21. package/dist/containerHandleContext.js.map +1 -1
  22. package/dist/containerRuntime.d.ts +42 -39
  23. package/dist/containerRuntime.d.ts.map +1 -1
  24. package/dist/containerRuntime.js +425 -292
  25. package/dist/containerRuntime.js.map +1 -1
  26. package/dist/dataStore.d.ts +1 -1
  27. package/dist/dataStore.d.ts.map +1 -1
  28. package/dist/dataStore.js +8 -8
  29. package/dist/dataStore.js.map +1 -1
  30. package/dist/dataStoreContext.d.ts +58 -19
  31. package/dist/dataStoreContext.d.ts.map +1 -1
  32. package/dist/dataStoreContext.js +169 -114
  33. package/dist/dataStoreContext.js.map +1 -1
  34. package/dist/dataStoreContexts.d.ts +1 -0
  35. package/dist/dataStoreContexts.d.ts.map +1 -1
  36. package/dist/dataStoreContexts.js +12 -11
  37. package/dist/dataStoreContexts.js.map +1 -1
  38. package/dist/dataStoreRegistry.d.ts +5 -1
  39. package/dist/dataStoreRegistry.d.ts.map +1 -1
  40. package/dist/dataStoreRegistry.js +4 -4
  41. package/dist/dataStoreRegistry.js.map +1 -1
  42. package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
  43. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
  44. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  45. package/dist/deltaScheduler.d.ts +1 -1
  46. package/dist/deltaScheduler.d.ts.map +1 -1
  47. package/dist/deltaScheduler.js +6 -6
  48. package/dist/deltaScheduler.js.map +1 -1
  49. package/dist/error.d.ts +1 -1
  50. package/dist/error.d.ts.map +1 -1
  51. package/dist/error.js +4 -4
  52. package/dist/error.js.map +1 -1
  53. package/dist/gc/garbageCollection.d.ts +3 -2
  54. package/dist/gc/garbageCollection.d.ts.map +1 -1
  55. package/dist/gc/garbageCollection.js +23 -23
  56. package/dist/gc/garbageCollection.js.map +1 -1
  57. package/dist/gc/gcConfigs.d.ts +2 -2
  58. package/dist/gc/gcConfigs.d.ts.map +1 -1
  59. package/dist/gc/gcConfigs.js +4 -5
  60. package/dist/gc/gcConfigs.js.map +1 -1
  61. package/dist/gc/gcDefinitions.d.ts +4 -5
  62. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  63. package/dist/gc/gcDefinitions.js.map +1 -1
  64. package/dist/gc/gcHelpers.d.ts +5 -1
  65. package/dist/gc/gcHelpers.d.ts.map +1 -1
  66. package/dist/gc/gcHelpers.js +21 -12
  67. package/dist/gc/gcHelpers.js.map +1 -1
  68. package/dist/gc/gcSummaryStateTracker.d.ts +2 -2
  69. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  70. package/dist/gc/gcSummaryStateTracker.js +11 -11
  71. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  72. package/dist/gc/gcTelemetry.d.ts +2 -1
  73. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  74. package/dist/gc/gcTelemetry.js +11 -9
  75. package/dist/gc/gcTelemetry.js.map +1 -1
  76. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  77. package/dist/gc/gcUnreferencedStateTracker.js +6 -6
  78. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  79. package/dist/gc/index.d.ts +1 -1
  80. package/dist/gc/index.d.ts.map +1 -1
  81. package/dist/gc/index.js +2 -1
  82. package/dist/gc/index.js.map +1 -1
  83. package/dist/index.d.ts +5 -2
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +12 -2
  86. package/dist/index.js.map +1 -1
  87. package/dist/legacy.d.ts +91 -0
  88. package/dist/messageTypes.d.ts +11 -5
  89. package/dist/messageTypes.d.ts.map +1 -1
  90. package/dist/messageTypes.js +4 -0
  91. package/dist/messageTypes.js.map +1 -1
  92. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  93. package/dist/opLifecycle/batchManager.js.map +1 -1
  94. package/dist/opLifecycle/definitions.d.ts +2 -20
  95. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  96. package/dist/opLifecycle/definitions.js.map +1 -1
  97. package/dist/opLifecycle/index.d.ts +3 -3
  98. package/dist/opLifecycle/index.d.ts.map +1 -1
  99. package/dist/opLifecycle/index.js +3 -1
  100. package/dist/opLifecycle/index.js.map +1 -1
  101. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  102. package/dist/opLifecycle/opCompressor.js +5 -6
  103. package/dist/opLifecycle/opCompressor.js.map +1 -1
  104. package/dist/opLifecycle/opDecompressor.d.ts +15 -4
  105. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  106. package/dist/opLifecycle/opDecompressor.js +62 -63
  107. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  108. package/dist/opLifecycle/opGroupingManager.d.ts +2 -1
  109. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  110. package/dist/opLifecycle/opGroupingManager.js +14 -16
  111. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  112. package/dist/opLifecycle/opSplitter.d.ts +12 -4
  113. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  114. package/dist/opLifecycle/opSplitter.js +63 -53
  115. package/dist/opLifecycle/opSplitter.js.map +1 -1
  116. package/dist/opLifecycle/outbox.d.ts +2 -1
  117. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  118. package/dist/opLifecycle/outbox.js +30 -29
  119. package/dist/opLifecycle/outbox.js.map +1 -1
  120. package/dist/opLifecycle/remoteMessageProcessor.d.ts +8 -0
  121. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  122. package/dist/opLifecycle/remoteMessageProcessor.js +36 -32
  123. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  124. package/dist/packageVersion.d.ts +1 -1
  125. package/dist/packageVersion.js +1 -1
  126. package/dist/packageVersion.js.map +1 -1
  127. package/dist/pendingStateManager.d.ts +1 -1
  128. package/dist/pendingStateManager.d.ts.map +1 -1
  129. package/dist/pendingStateManager.js +18 -18
  130. package/dist/pendingStateManager.js.map +1 -1
  131. package/dist/public.d.ts +12 -0
  132. package/dist/scheduleManager.d.ts +1 -1
  133. package/dist/scheduleManager.d.ts.map +1 -1
  134. package/dist/scheduleManager.js +28 -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 +390 -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 +12 -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/internal.d.ts +11 -0
  203. package/legacy.d.ts +11 -0
  204. package/lib/batchTracker.d.ts +1 -1
  205. package/lib/batchTracker.d.ts.map +1 -1
  206. package/lib/batchTracker.js +2 -2
  207. package/lib/batchTracker.js.map +1 -1
  208. package/lib/blobManager.d.ts +33 -30
  209. package/lib/blobManager.d.ts.map +1 -1
  210. package/lib/blobManager.js +48 -73
  211. package/lib/blobManager.js.map +1 -1
  212. package/lib/channelCollection.d.ts +27 -22
  213. package/lib/channelCollection.d.ts.map +1 -1
  214. package/lib/channelCollection.js +96 -106
  215. package/lib/channelCollection.js.map +1 -1
  216. package/lib/connectionTelemetry.d.ts +3 -3
  217. package/lib/connectionTelemetry.d.ts.map +1 -1
  218. package/lib/connectionTelemetry.js +3 -3
  219. package/lib/connectionTelemetry.js.map +1 -1
  220. package/lib/containerHandleContext.d.ts.map +1 -1
  221. package/lib/containerHandleContext.js +1 -1
  222. package/lib/containerHandleContext.js.map +1 -1
  223. package/lib/containerRuntime.d.ts +42 -39
  224. package/lib/containerRuntime.d.ts.map +1 -1
  225. package/lib/containerRuntime.js +276 -141
  226. package/lib/containerRuntime.js.map +1 -1
  227. package/lib/dataStore.d.ts +1 -1
  228. package/lib/dataStore.d.ts.map +1 -1
  229. package/lib/dataStore.js +3 -3
  230. package/lib/dataStore.js.map +1 -1
  231. package/lib/dataStoreContext.d.ts +58 -19
  232. package/lib/dataStoreContext.d.ts.map +1 -1
  233. package/lib/dataStoreContext.js +107 -52
  234. package/lib/dataStoreContext.js.map +1 -1
  235. package/lib/dataStoreContexts.d.ts +1 -0
  236. package/lib/dataStoreContexts.d.ts.map +1 -1
  237. package/lib/dataStoreContexts.js +3 -2
  238. package/lib/dataStoreContexts.js.map +1 -1
  239. package/lib/dataStoreRegistry.d.ts +5 -1
  240. package/lib/dataStoreRegistry.d.ts.map +1 -1
  241. package/lib/dataStoreRegistry.js +1 -1
  242. package/lib/dataStoreRegistry.js.map +1 -1
  243. package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
  244. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
  245. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  246. package/lib/deltaScheduler.d.ts +1 -1
  247. package/lib/deltaScheduler.d.ts.map +1 -1
  248. package/lib/deltaScheduler.js +1 -1
  249. package/lib/deltaScheduler.js.map +1 -1
  250. package/lib/error.d.ts +1 -1
  251. package/lib/error.d.ts.map +1 -1
  252. package/lib/error.js +2 -2
  253. package/lib/error.js.map +1 -1
  254. package/lib/gc/garbageCollection.d.ts +3 -2
  255. package/lib/gc/garbageCollection.d.ts.map +1 -1
  256. package/lib/gc/garbageCollection.js +8 -8
  257. package/lib/gc/garbageCollection.js.map +1 -1
  258. package/lib/gc/gcConfigs.d.ts +2 -2
  259. package/lib/gc/gcConfigs.d.ts.map +1 -1
  260. package/lib/gc/gcConfigs.js +4 -5
  261. package/lib/gc/gcConfigs.js.map +1 -1
  262. package/lib/gc/gcDefinitions.d.ts +4 -5
  263. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  264. package/lib/gc/gcDefinitions.js.map +1 -1
  265. package/lib/gc/gcHelpers.d.ts +5 -1
  266. package/lib/gc/gcHelpers.d.ts.map +1 -1
  267. package/lib/gc/gcHelpers.js +10 -2
  268. package/lib/gc/gcHelpers.js.map +1 -1
  269. package/lib/gc/gcSummaryStateTracker.d.ts +2 -2
  270. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  271. package/lib/gc/gcSummaryStateTracker.js +2 -2
  272. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  273. package/lib/gc/gcTelemetry.d.ts +2 -1
  274. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  275. package/lib/gc/gcTelemetry.js +4 -2
  276. package/lib/gc/gcTelemetry.js.map +1 -1
  277. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  278. package/lib/gc/gcUnreferencedStateTracker.js +2 -2
  279. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  280. package/lib/gc/index.d.ts +1 -1
  281. package/lib/gc/index.d.ts.map +1 -1
  282. package/lib/gc/index.js +1 -1
  283. package/lib/gc/index.js.map +1 -1
  284. package/lib/index.d.ts +5 -2
  285. package/lib/index.d.ts.map +1 -1
  286. package/lib/index.js +5 -2
  287. package/lib/index.js.map +1 -1
  288. package/lib/legacy.d.ts +91 -0
  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 +19 -18
  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 -32
  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/public.d.ts +12 -0
  333. package/lib/scheduleManager.d.ts +1 -1
  334. package/lib/scheduleManager.d.ts.map +1 -1
  335. package/lib/scheduleManager.js +7 -3
  336. package/lib/scheduleManager.js.map +1 -1
  337. package/lib/storageServiceWithAttachBlobs.d.ts +2 -2
  338. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -1
  339. package/lib/storageServiceWithAttachBlobs.js +1 -1
  340. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  341. package/lib/summary/documentSchema.d.ts +209 -0
  342. package/lib/summary/documentSchema.d.ts.map +1 -0
  343. package/lib/summary/documentSchema.js +386 -0
  344. package/lib/summary/documentSchema.js.map +1 -0
  345. package/lib/summary/index.d.ts +2 -1
  346. package/lib/summary/index.d.ts.map +1 -1
  347. package/lib/summary/index.js +1 -0
  348. package/lib/summary/index.js.map +1 -1
  349. package/lib/summary/orderedClientElection.d.ts +2 -2
  350. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  351. package/lib/summary/orderedClientElection.js +7 -2
  352. package/lib/summary/orderedClientElection.js.map +1 -1
  353. package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -1
  354. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  355. package/lib/summary/runWhileConnectedCoordinator.js +1 -1
  356. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  357. package/lib/summary/runningSummarizer.d.ts +3 -3
  358. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  359. package/lib/summary/runningSummarizer.js +3 -3
  360. package/lib/summary/runningSummarizer.js.map +1 -1
  361. package/lib/summary/summarizer.d.ts +3 -2
  362. package/lib/summary/summarizer.d.ts.map +1 -1
  363. package/lib/summary/summarizer.js +3 -3
  364. package/lib/summary/summarizer.js.map +1 -1
  365. package/lib/summary/summarizerClientElection.d.ts +2 -2
  366. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  367. package/lib/summary/summarizerClientElection.js.map +1 -1
  368. package/lib/summary/summarizerHeuristics.d.ts +1 -1
  369. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  370. package/lib/summary/summarizerHeuristics.js +1 -1
  371. package/lib/summary/summarizerHeuristics.js.map +1 -1
  372. package/lib/summary/summarizerNode/summarizerNode.d.ts +3 -2
  373. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  374. package/lib/summary/summarizerNode/summarizerNode.js +5 -5
  375. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  376. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
  377. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  378. package/lib/summary/summarizerNode/summarizerNodeUtils.js +1 -1
  379. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  380. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -1
  381. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  382. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
  383. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  384. package/lib/summary/summarizerTypes.d.ts +5 -3
  385. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  386. package/lib/summary/summarizerTypes.js.map +1 -1
  387. package/lib/summary/summaryCollection.d.ts +2 -2
  388. package/lib/summary/summaryCollection.d.ts.map +1 -1
  389. package/lib/summary/summaryCollection.js +1 -1
  390. package/lib/summary/summaryCollection.js.map +1 -1
  391. package/lib/summary/summaryFormat.d.ts +6 -17
  392. package/lib/summary/summaryFormat.d.ts.map +1 -1
  393. package/lib/summary/summaryFormat.js +3 -3
  394. package/lib/summary/summaryFormat.js.map +1 -1
  395. package/lib/summary/summaryGenerator.d.ts +4 -3
  396. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  397. package/lib/summary/summaryGenerator.js +4 -4
  398. package/lib/summary/summaryGenerator.js.map +1 -1
  399. package/lib/summary/summaryManager.d.ts +1 -1
  400. package/lib/summary/summaryManager.d.ts.map +1 -1
  401. package/lib/summary/summaryManager.js +9 -8
  402. package/lib/summary/summaryManager.js.map +1 -1
  403. package/package.json +57 -65
  404. package/src/batchTracker.ts +4 -3
  405. package/src/blobManager.ts +100 -77
  406. package/src/channelCollection.ts +180 -165
  407. package/src/connectionTelemetry.ts +12 -12
  408. package/src/containerHandleContext.ts +3 -2
  409. package/src/containerRuntime.ts +481 -277
  410. package/src/dataStore.ts +9 -4
  411. package/src/dataStoreContext.ts +195 -93
  412. package/src/dataStoreContexts.ts +5 -2
  413. package/src/dataStoreRegistry.ts +3 -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 +21 -20
  418. package/src/gc/gcConfigs.ts +15 -18
  419. package/src/gc/gcDefinitions.ts +6 -8
  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 +22 -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 +90 -100
  433. package/src/opLifecycle/opGroupingManager.ts +12 -14
  434. package/src/opLifecycle/opSplitter.ts +76 -48
  435. package/src/opLifecycle/outbox.ts +30 -38
  436. package/src/opLifecycle/remoteMessageProcessor.ts +43 -55
  437. package/src/packageVersion.ts +1 -1
  438. package/src/pendingStateManager.ts +6 -6
  439. package/src/scheduleManager.ts +10 -8
  440. package/src/storageServiceWithAttachBlobs.ts +2 -2
  441. package/src/summary/documentSchema.ts +631 -0
  442. package/src/summary/index.ts +10 -1
  443. package/src/summary/orderedClientElection.ts +7 -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/api-extractor-cjs.json +0 -8
  458. package/dist/container-runtime-alpha.d.ts +0 -1753
  459. package/dist/container-runtime-beta.d.ts +0 -268
  460. package/dist/container-runtime-public.d.ts +0 -268
  461. package/dist/container-runtime-untrimmed.d.ts +0 -1893
  462. package/lib/container-runtime-alpha.d.ts +0 -1753
  463. package/lib/container-runtime-beta.d.ts +0 -268
  464. package/lib/container-runtime-public.d.ts +0 -268
  465. package/lib/container-runtime-untrimmed.d.ts +0 -1893
  466. package/lib/test/batchTracker.spec.js +0 -88
  467. package/lib/test/batchTracker.spec.js.map +0 -1
  468. package/lib/test/blobManager.spec.js +0 -835
  469. package/lib/test/blobManager.spec.js.map +0 -1
  470. package/lib/test/channelCollection.spec.js +0 -141
  471. package/lib/test/channelCollection.spec.js.map +0 -1
  472. package/lib/test/containerRuntime.spec.js +0 -1748
  473. package/lib/test/containerRuntime.spec.js.map +0 -1
  474. package/lib/test/dataStoreContext.spec.js +0 -801
  475. package/lib/test/dataStoreContext.spec.js.map +0 -1
  476. package/lib/test/dataStoreCreation.spec.js +0 -312
  477. package/lib/test/dataStoreCreation.spec.js.map +0 -1
  478. package/lib/test/dataStoreRegistry.spec.js +0 -26
  479. package/lib/test/dataStoreRegistry.spec.js.map +0 -1
  480. package/lib/test/fuzz/fuzzUtils.js +0 -66
  481. package/lib/test/fuzz/fuzzUtils.js.map +0 -1
  482. package/lib/test/fuzz/summarizer.fuzz.spec.js +0 -31
  483. package/lib/test/fuzz/summarizer.fuzz.spec.js.map +0 -1
  484. package/lib/test/fuzz/summarizerFuzzMocks.js +0 -162
  485. package/lib/test/fuzz/summarizerFuzzMocks.js.map +0 -1
  486. package/lib/test/fuzz/summarizerFuzzSuite.js +0 -106
  487. package/lib/test/fuzz/summarizerFuzzSuite.js.map +0 -1
  488. package/lib/test/gc/garbageCollection.spec.js +0 -1465
  489. package/lib/test/gc/garbageCollection.spec.js.map +0 -1
  490. package/lib/test/gc/gcConfigs.spec.js +0 -690
  491. package/lib/test/gc/gcConfigs.spec.js.map +0 -1
  492. package/lib/test/gc/gcHelpers.spec.js +0 -110
  493. package/lib/test/gc/gcHelpers.spec.js.map +0 -1
  494. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js +0 -68
  495. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js.map +0 -1
  496. package/lib/test/gc/gcStats.spec.js +0 -391
  497. package/lib/test/gc/gcStats.spec.js.map +0 -1
  498. package/lib/test/gc/gcSummaryStateTracker.spec.js +0 -228
  499. package/lib/test/gc/gcSummaryStateTracker.spec.js.map +0 -1
  500. package/lib/test/gc/gcTelemetry.spec.js +0 -530
  501. package/lib/test/gc/gcTelemetry.spec.js.map +0 -1
  502. package/lib/test/gc/gcUnitTestHelpers.js +0 -29
  503. package/lib/test/gc/gcUnitTestHelpers.js.map +0 -1
  504. package/lib/test/gc/gcUnreferencedStateTracker.spec.js +0 -192
  505. package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +0 -1
  506. package/lib/test/getPendingBlobs.spec.js +0 -193
  507. package/lib/test/getPendingBlobs.spec.js.map +0 -1
  508. package/lib/test/hardwareStats.spec.js +0 -93
  509. package/lib/test/hardwareStats.spec.js.map +0 -1
  510. package/lib/test/index.js +0 -6
  511. package/lib/test/index.js.map +0 -1
  512. package/lib/test/opLifecycle/OpGroupingManager.spec.js +0 -225
  513. package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +0 -1
  514. package/lib/test/opLifecycle/batchManager.spec.js +0 -189
  515. package/lib/test/opLifecycle/batchManager.spec.js.map +0 -1
  516. package/lib/test/opLifecycle/opCompressor.spec.js +0 -74
  517. package/lib/test/opLifecycle/opCompressor.spec.js.map +0 -1
  518. package/lib/test/opLifecycle/opDecompressor.spec.js +0 -218
  519. package/lib/test/opLifecycle/opDecompressor.spec.js.map +0 -1
  520. package/lib/test/opLifecycle/opSplitter.spec.js +0 -272
  521. package/lib/test/opLifecycle/opSplitter.spec.js.map +0 -1
  522. package/lib/test/opLifecycle/outbox.spec.js +0 -675
  523. package/lib/test/opLifecycle/outbox.spec.js.map +0 -1
  524. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +0 -196
  525. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +0 -1
  526. package/lib/test/pendingStateManager.spec.js +0 -329
  527. package/lib/test/pendingStateManager.spec.js.map +0 -1
  528. package/lib/test/scheduleManager.spec.js +0 -270
  529. package/lib/test/scheduleManager.spec.js.map +0 -1
  530. package/lib/test/summarizerNode.spec.js +0 -326
  531. package/lib/test/summarizerNode.spec.js.map +0 -1
  532. package/lib/test/summarizerNodeWithGc.spec.js +0 -318
  533. package/lib/test/summarizerNodeWithGc.spec.js.map +0 -1
  534. package/lib/test/summary/orderedClientElection.spec.js +0 -535
  535. package/lib/test/summary/orderedClientElection.spec.js.map +0 -1
  536. package/lib/test/summary/runningSummarizer.spec.js +0 -1349
  537. package/lib/test/summary/runningSummarizer.spec.js.map +0 -1
  538. package/lib/test/summary/summarizer.spec.js +0 -29
  539. package/lib/test/summary/summarizer.spec.js.map +0 -1
  540. package/lib/test/summary/summarizerClientElection.spec.js +0 -436
  541. package/lib/test/summary/summarizerClientElection.spec.js.map +0 -1
  542. package/lib/test/summary/summarizerHeuristics.spec.js +0 -289
  543. package/lib/test/summary/summarizerHeuristics.spec.js.map +0 -1
  544. package/lib/test/summary/summaryCollection.spec.js +0 -200
  545. package/lib/test/summary/summaryCollection.spec.js.map +0 -1
  546. package/lib/test/summary/summaryManager.spec.js +0 -430
  547. package/lib/test/summary/summaryManager.spec.js.map +0 -1
  548. package/lib/test/summary/testQuorumClients.js +0 -34
  549. package/lib/test/summary/testQuorumClients.js.map +0 -1
  550. package/lib/test/throttler.spec.js +0 -175
  551. package/lib/test/throttler.spec.js.map +0 -1
  552. package/lib/test/types/validateContainerRuntimePrevious.generated.js +0 -180
  553. package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +0 -1
  554. /package/{dist → lib}/tsdoc-metadata.json +0 -0
@@ -1,29 +1,36 @@
1
- import { AttachState, LoaderHeader, } from "@fluidframework/container-definitions";
2
- import { assert, Deferred, delay, LazyPromise, PromiseCache } from "@fluidframework/core-utils";
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
3
5
  import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
4
- import { createChildLogger, createChildMonitoringContext, DataCorruptionError, DataProcessingError, GenericError, raiseConnectedEvent, PerformanceEvent, TaggedLoggerAdapter, wrapError, UsageError, LoggingError, createSampledLogger, loggerToMonitoringContext, } from "@fluidframework/telemetry-utils";
5
- import { DriverHeader, FetchSource, } from "@fluidframework/driver-definitions";
6
- import { readAndParse } from "@fluidframework/driver-utils";
6
+ import { AttachState, } from "@fluidframework/container-definitions";
7
+ import { LoaderHeader, } from "@fluidframework/container-definitions/internal";
8
+ import { assert, Deferred, LazyPromise, PromiseCache, delay, } from "@fluidframework/core-utils/internal";
9
+ import { DriverHeader, FetchSource, } from "@fluidframework/driver-definitions/internal";
10
+ import { readAndParse } from "@fluidframework/driver-utils/internal";
7
11
  import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
8
- import { FlushMode, FlushModeExperimental, gcTreeKey, channelsTreeName, } from "@fluidframework/runtime-definitions";
9
- import { addBlobToSummary, addSummarizeResultToSummary, RequestParser, create404Response, exceptionToResponse, GCDataBuilder, seqFromTree, calculateStats, TelemetryContext, responseToException, } from "@fluidframework/runtime-utils";
12
+ import { FlushMode, FlushModeExperimental, channelsTreeName, gcTreeKey, } from "@fluidframework/runtime-definitions/internal";
13
+ import { GCDataBuilder, RequestParser, TelemetryContext, addBlobToSummary, addSummarizeResultToSummary, calculateStats, create404Response, exceptionToResponse, responseToException, seqFromTree, } from "@fluidframework/runtime-utils/internal";
14
+ import { DataCorruptionError, DataProcessingError, GenericError, LoggingError, PerformanceEvent,
15
+ // eslint-disable-next-line import/no-deprecated
16
+ TaggedLoggerAdapter, UsageError, createChildLogger, createChildMonitoringContext, createSampledLogger, loggerToMonitoringContext, raiseConnectedEvent, wrapError, } from "@fluidframework/telemetry-utils/internal";
10
17
  import { v4 as uuid } from "uuid";
11
- import { ContainerFluidHandleContext } from "./containerHandleContext.js";
12
- import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
13
- import { ReportOpPerfTelemetry } from "./connectionTelemetry.js";
14
- import { PendingStateManager, } from "./pendingStateManager.js";
15
- import { pkgVersion } from "./packageVersion.js";
18
+ import { BindBatchTracker } from "./batchTracker.js";
16
19
  import { BlobManager } from "./blobManager.js";
17
20
  import { ChannelCollection, getSummaryForDatastores, wrapContext } from "./channelCollection.js";
18
- import { aliasBlobName, blobsTreeName, chunksBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, idCompressorBlobName, metadataBlobName, Summarizer, SummaryManager, wrapSummaryInChannelsTree, SummaryCollection, OrderedClientCollection, OrderedClientElection, SummarizerClientElection, summarizerClientType, RunWhileConnectedCoordinator, RetriableSummaryError, rootHasIsolatedChannels, } from "./summary/index.js";
19
- import { formExponentialFn, Throttler } from "./throttler.js";
20
- import { GarbageCollector, GCNodeType, gcGenerationOptionName, } from "./gc/index.js";
21
+ import { ReportOpPerfTelemetry } from "./connectionTelemetry.js";
22
+ import { ContainerFluidHandleContext } from "./containerHandleContext.js";
21
23
  import { channelToDataStore } from "./dataStore.js";
22
- import { BindBatchTracker } from "./batchTracker.js";
23
- import { ScheduleManager } from "./scheduleManager.js";
24
- import { OpCompressor, OpDecompressor, Outbox, OpSplitter, RemoteMessageProcessor, OpGroupingManager, getLongStack, } from "./opLifecycle/index.js";
24
+ import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
25
25
  import { DeltaManagerSummarizerProxy } from "./deltaManagerSummarizerProxy.js";
26
+ import { GCNodeType, GarbageCollector, gcGenerationOptionName, } from "./gc/index.js";
26
27
  import { ContainerMessageType, } from "./messageTypes.js";
28
+ import { OpCompressor, OpDecompressor, OpGroupingManager, OpSplitter, Outbox, RemoteMessageProcessor, getLongStack, } from "./opLifecycle/index.js";
29
+ import { pkgVersion } from "./packageVersion.js";
30
+ import { PendingStateManager, } from "./pendingStateManager.js";
31
+ import { ScheduleManager } from "./scheduleManager.js";
32
+ import { DocumentsSchemaController, OrderedClientCollection, OrderedClientElection, RetriableSummaryError, RunWhileConnectedCoordinator, Summarizer, SummarizerClientElection, SummaryCollection, SummaryManager, aliasBlobName, blobsTreeName, chunksBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, idCompressorBlobName, metadataBlobName, rootHasIsolatedChannels, summarizerClientType, wrapSummaryInChannelsTree, } from "./summary/index.js";
33
+ import { Throttler, formExponentialFn } from "./throttler.js";
27
34
  /**
28
35
  * Utility to implement compat behaviors given an unknown message type
29
36
  * The parameters are typed to support compile-time enforcement of handling all known types/behaviors
@@ -78,6 +85,11 @@ export var CompressionAlgorithms;
78
85
  (function (CompressionAlgorithms) {
79
86
  CompressionAlgorithms["lz4"] = "lz4";
80
87
  })(CompressionAlgorithms || (CompressionAlgorithms = {}));
88
+ /** @alpha */
89
+ export const disabledCompressionConfig = {
90
+ minimumBatchSizeInBytes: Infinity,
91
+ compressionAlgorithm: CompressionAlgorithms.lz4,
92
+ };
81
93
  const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
82
94
  const defaultFlushMode = FlushMode.TurnBased;
83
95
  // The actual limit is 1Mb (socket.io and Kafka limits)
@@ -101,26 +113,12 @@ export const defaultPendingOpsRetryDelayMs = 1000;
101
113
  * This delay's goal is to prevent tight restart loops
102
114
  */
103
115
  const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
104
- /**
105
- * @deprecated use ContainerRuntimeMessageType instead
106
- * @internal
107
- */
108
- export var RuntimeMessage;
109
- (function (RuntimeMessage) {
110
- RuntimeMessage["FluidDataStoreOp"] = "component";
111
- RuntimeMessage["Attach"] = "attach";
112
- RuntimeMessage["ChunkedOp"] = "chunkedOp";
113
- RuntimeMessage["BlobAttach"] = "blobAttach";
114
- RuntimeMessage["Rejoin"] = "rejoin";
115
- RuntimeMessage["Alias"] = "alias";
116
- RuntimeMessage["Operation"] = "op";
117
- })(RuntimeMessage || (RuntimeMessage = {}));
118
116
  /**
119
117
  * @deprecated please use version in driver-utils
120
118
  * @internal
121
119
  */
122
120
  export function isRuntimeMessage(message) {
123
- return Object.values(RuntimeMessage).includes(message.type);
121
+ return Object.values(ContainerMessageType).includes(message.type);
124
122
  }
125
123
  /**
126
124
  * Legacy ID for the built-in AgentScheduler. To minimize disruption while removing it, retaining this as a
@@ -194,6 +192,17 @@ async function createSummarizer(loader, url) {
194
192
  }
195
193
  return fluidObject.ISummarizer;
196
194
  }
195
+ /**
196
+ * Extract last message from the snapshot metadata.
197
+ * Uses legacy property if not using explicit schema control, otherwise uses the new property.
198
+ * This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
199
+ * Please see addMetadataToSummary() as well
200
+ */
201
+ function lastMessageFromMetadata(metadata) {
202
+ return metadata?.documentSchema?.runtime?.explicitSchemaControl
203
+ ? metadata?.lastMessage
204
+ : metadata?.message;
205
+ }
197
206
  /**
198
207
  * Represents the runtime of the container. Contains helper functions/state of the container.
199
208
  * It will define the store level mappings.
@@ -221,6 +230,7 @@ export class ContainerRuntime extends TypedEventEmitter {
221
230
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
222
231
  const backCompatContext = context;
223
232
  const passLogger = backCompatContext.taggedLogger ??
233
+ // eslint-disable-next-line import/no-deprecated
224
234
  new TaggedLoggerAdapter(backCompatContext.logger);
225
235
  const logger = createChildLogger({
226
236
  logger: passLogger,
@@ -231,7 +241,7 @@ export class ContainerRuntime extends TypedEventEmitter {
231
241
  },
232
242
  });
233
243
  const mc = loggerToMonitoringContext(logger);
234
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = "off", chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
244
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, explicitSchemaControl = false, } = runtimeOptions;
235
245
  const registry = new FluidDataStoreRegistry(registryEntries);
236
246
  const tryFetchBlob = async (blobName) => {
237
247
  const blobId = context.baseSnapshot?.blobs[blobName];
@@ -256,14 +266,21 @@ export class ContainerRuntime extends TypedEventEmitter {
256
266
  assert(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
257
267
  return readAndParse(context.storage, id);
258
268
  });
269
+ const messageAtLastSummary = lastMessageFromMetadata(metadata);
259
270
  // Verify summary runtime sequence number matches protocol sequence number.
260
- const runtimeSequenceNumber = metadata?.message?.sequenceNumber;
271
+ const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
261
272
  // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
262
273
  if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
263
274
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
264
275
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
265
276
  if (loadSequenceNumberVerification !== "bypass" &&
266
277
  runtimeSequenceNumber !== protocolSequenceNumber) {
278
+ // Message to OCEs:
279
+ // You can hit this error with runtimeSequenceNumber === -1 in < 2.0 RC3 builds.
280
+ // This would indicate that explicit schema control is enabled in current (2.0 RC3+) builds and it
281
+ // results in addMetadataToSummary() creating a poison pill for older runtimes in the form of a -1 sequence number.
282
+ // Older runtimes do not understand new schema, and thus could corrupt document if they proceed, thus we are using
283
+ // this poison pill to prevent them from proceeding.
267
284
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
268
285
  const error = new DataCorruptionError(
269
286
  // pre-0.58 error message: SummaryMetadataMismatch
@@ -276,8 +293,20 @@ export class ContainerRuntime extends TypedEventEmitter {
276
293
  }
277
294
  }
278
295
  }
296
+ let desiredIdCompressorMode;
297
+ switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
298
+ case true:
299
+ desiredIdCompressorMode = "on";
300
+ break;
301
+ case false:
302
+ desiredIdCompressorMode = undefined;
303
+ break;
304
+ default:
305
+ desiredIdCompressorMode = enableRuntimeIdCompressor;
306
+ break;
307
+ }
279
308
  // Enabling the IdCompressor is a one-way operation and we only want to
280
- // allow new containers to turn it on
309
+ // allow new containers to turn it on.
281
310
  let idCompressorMode;
282
311
  if (existing) {
283
312
  // This setting has to be sticky for correctness:
@@ -286,28 +315,30 @@ export class ContainerRuntime extends TypedEventEmitter {
286
315
  // 2) if it's ON, then all sessions should load compressor right away
287
316
  // 3) Same logic applies for "delayed" mode
288
317
  // Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
289
- // We could do "off" -> "on" transtition too, if all clients start loading compressor (but not using it initially) and do so for a while -
290
- // this will allow clients to eventually to disregard "off" setting (when it's safe so) and start using compressor in future sessions.
318
+ // We could do "off" -> "on" transition too, if all clients start loading compressor (but not using it initially) and
319
+ // do so for a while - this will allow clients to eventually disregard "off" setting (when it's safe so) and start
320
+ // using compressor in future sessions.
291
321
  // Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
292
- idCompressorMode = metadata?.idCompressorMode ?? "off";
322
+ idCompressorMode = metadata?.documentSchema?.runtime
323
+ ?.idCompressorMode;
324
+ // This is the only exception to the rule above - we have proper plumbing to load ID compressor on schema change
325
+ // event. It is loaded async (relative to op processing), so this conversion is only safe for off -> delayed conversion!
326
+ // Clients do not expect ID compressor ops unless ID compressor is On for them, and that could be achieved only through
327
+ // explicit schema change, i.e. only if explicitSchemaControl is on.
328
+ // Note: it would be better if we throw on combination of options (explicitSchemaControl = off, desiredIdCompressorMode === "delayed")
329
+ // that is not supported. But our service tests are oblivious to these problems and throwing here will cause a ton of failures
330
+ // We ignored incompatible ID compressor changes from the start (they were sticky), so that's not a new problem being introduced...
331
+ if (idCompressorMode === undefined &&
332
+ desiredIdCompressorMode === "delayed" &&
333
+ explicitSchemaControl) {
334
+ idCompressorMode = desiredIdCompressorMode;
335
+ }
293
336
  }
294
337
  else {
295
- // FG overwrite
296
- const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
297
- switch (enabled) {
298
- case true:
299
- idCompressorMode = "on";
300
- break;
301
- case false:
302
- idCompressorMode = "off";
303
- break;
304
- default:
305
- idCompressorMode = enableRuntimeIdCompressor;
306
- break;
307
- }
338
+ idCompressorMode = desiredIdCompressorMode;
308
339
  }
309
340
  const createIdCompressorFn = async () => {
310
- const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor");
341
+ const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor/internal");
311
342
  /**
312
343
  * Because the IdCompressor emits so much telemetry, this function is used to sample
313
344
  * approximately 5% of all clients. Only the given percentage of sessions will emit telemetry.
@@ -332,6 +363,25 @@ export class ContainerRuntime extends TypedEventEmitter {
332
363
  return createIdCompressor(compressorLogger);
333
364
  }
334
365
  };
366
+ const disableGroupedBatching = mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
367
+ const disableCompression = mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
368
+ const compressionLz4 = disableCompression !== true &&
369
+ compressionOptions.minimumBatchSizeInBytes !== Infinity &&
370
+ compressionOptions.compressionAlgorithm === "lz4";
371
+ const opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
372
+ const documentSchemaController = new DocumentsSchemaController(existing, metadata?.documentSchema, {
373
+ explicitSchemaControl,
374
+ compressionLz4,
375
+ idCompressorMode,
376
+ opGroupingEnabled,
377
+ disallowedVersions: [],
378
+ }, (schema) => {
379
+ runtime.onSchemaChange(schema);
380
+ });
381
+ const featureGatesForTelemetry = {
382
+ disableGroupedBatching,
383
+ disableCompression,
384
+ };
335
385
  const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
336
386
  summaryOptions,
337
387
  gcOptions,
@@ -340,10 +390,19 @@ export class ContainerRuntime extends TypedEventEmitter {
340
390
  compressionOptions,
341
391
  maxBatchSizeInBytes,
342
392
  chunkSizeInBytes,
343
- enableRuntimeIdCompressor,
393
+ // Requires<> drops undefined from IdCompressorType
394
+ enableRuntimeIdCompressor: enableRuntimeIdCompressor,
344
395
  enableOpReentryCheck,
345
396
  enableGroupedBatching,
346
- }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, idCompressorMode, provideEntryPoint, requestHandler, undefined);
397
+ explicitSchemaControl,
398
+ }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined);
399
+ runtime.blobManager.trackPendingStashedUploads().then(() => {
400
+ // make sure we didn't reconnect before the promise resolved
401
+ if (runtime.delayConnectClientId !== undefined && !runtime.disposed) {
402
+ runtime.delayConnectClientId = undefined;
403
+ runtime.setConnectionStateCore(true, runtime.delayConnectClientId);
404
+ }
405
+ }, (error) => runtime.closeFn(error));
347
406
  // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
348
407
  // or zero. This must be done before Container replays saved ops.
349
408
  await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
@@ -372,6 +431,12 @@ export class ContainerRuntime extends TypedEventEmitter {
372
431
  get attachState() {
373
432
  return this._getAttachState();
374
433
  }
434
+ get documentSchema() {
435
+ return this.documentsSchemaController.sessionSchema.runtime;
436
+ }
437
+ get idCompressorMode() {
438
+ return this.documentSchema.idCompressorMode;
439
+ }
375
440
  /**
376
441
  * See IContainerRuntimeBase.idCompressor() for details.
377
442
  */
@@ -452,7 +517,7 @@ export class ContainerRuntime extends TypedEventEmitter {
452
517
  return this.garbageCollector.throwOnTombstoneUsage;
453
518
  }
454
519
  /***/
455
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, idCompressorMode, provideEntryPoint, requestHandler, summaryConfiguration = {
520
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, summaryConfiguration = {
456
521
  // the defaults
457
522
  ...DefaultSummaryConfiguration,
458
523
  // the runtime configuration overrides
@@ -466,18 +531,13 @@ export class ContainerRuntime extends TypedEventEmitter {
466
531
  this.logger = logger;
467
532
  this._storage = _storage;
468
533
  this.createIdCompressor = createIdCompressor;
469
- this.idCompressorMode = idCompressorMode;
534
+ this.documentsSchemaController = documentsSchemaController;
470
535
  this.requestHandler = requestHandler;
471
536
  this.summaryConfiguration = summaryConfiguration;
472
537
  this.imminentClosure = false;
473
538
  // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
474
539
  // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
475
540
  this.pendingIdCompressorOps = [];
476
- /**
477
- * True if we have ID compressor loading in-flight (async operation). Useful only for
478
- * this.idCompressorMode === "delayed" mode
479
- */
480
- this.compressorLoadInitiated = false;
481
541
  this.defaultMaxConsecutiveReconnects = 7;
482
542
  this._orderSequentiallyCalls = 0;
483
543
  this.flushTaskExists = false;
@@ -507,6 +567,20 @@ export class ContainerRuntime extends TypedEventEmitter {
507
567
  expiry: { policy: "absolute", durationMs: 60000 },
508
568
  });
509
569
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
570
+ this.mc = createChildMonitoringContext({
571
+ logger: this.logger,
572
+ namespace: "ContainerRuntime",
573
+ });
574
+ // If we support multiple algorithms in the future, then we would need to manage it here carefully.
575
+ // We can use runtimeOptions.compressionOptions.compressionAlgorithm, but only if it's in the schema list!
576
+ // If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
577
+ // compression.
578
+ const compressionOptions = {
579
+ minimumBatchSizeInBytes: this.documentSchema.compressionLz4
580
+ ? runtimeOptions.compressionOptions.minimumBatchSizeInBytes
581
+ : Number.POSITIVE_INFINITY,
582
+ compressionAlgorithm: CompressionAlgorithms.lz4,
583
+ };
510
584
  this.innerDeltaManager = deltaManager;
511
585
  this.deltaManager = new DeltaManagerSummarizerProxy(this.innerDeltaManager);
512
586
  // Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
@@ -540,10 +614,6 @@ export class ContainerRuntime extends TypedEventEmitter {
540
614
  this.disposeFn = disposeFn ?? closeFn;
541
615
  // In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
542
616
  this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
543
- this.mc = createChildMonitoringContext({
544
- logger: this.logger,
545
- namespace: "ContainerRuntime",
546
- });
547
617
  let loadSummaryNumber;
548
618
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
549
619
  // get the values from the metadata blob.
@@ -564,7 +634,7 @@ export class ContainerRuntime extends TypedEventEmitter {
564
634
  loadSummaryNumber = 0;
565
635
  }
566
636
  this.nextSummaryNumber = loadSummaryNumber + 1;
567
- this.messageAtLastSummary = metadata?.message;
637
+ this.messageAtLastSummary = lastMessageFromMetadata(metadata);
568
638
  // Note that we only need to pull the *initial* connected state from the context.
569
639
  // Later updates come through calls to setConnectionState.
570
640
  this._connected = connected;
@@ -667,32 +737,38 @@ export class ContainerRuntime extends TypedEventEmitter {
667
737
  return this.submitSignalFn(envelope2, targetClientId);
668
738
  };
669
739
  this.channelCollection = new ChannelCollection(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);
670
- this.blobManager = new BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
671
- if (!this.disposed) {
672
- this.submit({ type: ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
673
- localId,
674
- blobId,
675
- });
676
- }
677
- }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState?.pendingAttachmentBlobs, (error) => this.closeFn(error));
740
+ this.blobManager = new BlobManager({
741
+ routeContext: this.handleContext,
742
+ snapshot: blobManagerSnapshot,
743
+ getStorage: () => this.storage,
744
+ sendBlobAttachOp: (localId, blobId) => {
745
+ if (!this.disposed) {
746
+ this.submit({ type: ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
747
+ localId,
748
+ blobId,
749
+ });
750
+ }
751
+ },
752
+ blobRequested: (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"),
753
+ isBlobDeleted: (blobPath) => this.garbageCollector.isNodeDeleted(blobPath),
754
+ runtime: this,
755
+ stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
756
+ closeContainer: (error) => this.closeFn(error),
757
+ });
678
758
  this.scheduleManager = new ScheduleManager(this.innerDeltaManager, this, () => this.clientId, createChildLogger({ logger: this.logger, namespace: "ScheduleManager" }));
679
759
  this.pendingStateManager = new PendingStateManager({
680
760
  applyStashedOp: this.applyStashedOp.bind(this),
681
761
  clientId: () => this.clientId,
682
762
  close: this.closeFn,
683
763
  connected: () => this.connected,
684
- reSubmit: this.reSubmit.bind(this),
764
+ reSubmit: (message) => {
765
+ this.reSubmit(message);
766
+ this.flush();
767
+ },
685
768
  reSubmitBatch: this.reSubmitBatch.bind(this),
686
769
  isActiveConnection: () => this.innerDeltaManager.active,
687
770
  isAttached: () => this.attachState !== AttachState.Detached,
688
771
  }, pendingRuntimeState?.pending, this.logger);
689
- const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
690
- const compressionOptions = disableCompression === true
691
- ? {
692
- minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
693
- compressionAlgorithm: CompressionAlgorithms.lz4,
694
- }
695
- : runtimeOptions.compressionOptions;
696
772
  const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
697
773
  const legacySendBatchFn = makeLegacySendBatchFn(this.submitFn, this.innerDeltaManager);
698
774
  this.outbox = new Outbox({
@@ -797,10 +873,10 @@ export class ContainerRuntime extends TypedEventEmitter {
797
873
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
798
874
  gcVersion: metadata?.gcFeature,
799
875
  options: JSON.stringify(runtimeOptions),
800
- idCompressorModeMetadata: metadata?.idCompressorMode,
876
+ idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
801
877
  idCompressorMode: this.idCompressorMode,
802
878
  featureGates: JSON.stringify({
803
- disableCompression,
879
+ ...featureGatesForTelemetry,
804
880
  disableOpReentryCheck,
805
881
  disableChunking,
806
882
  disableAttachReorder: this.disableAttachReorder,
@@ -823,15 +899,33 @@ export class ContainerRuntime extends TypedEventEmitter {
823
899
  // saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
824
900
  this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
825
901
  }
902
+ onSchemaChange(schema) {
903
+ // Most of the settings will be picked up only by new sessions (i.e. after reload).
904
+ // We can make it better in the future (i.e. start to use op compression right away), but for simplicity
905
+ // this is not done.
906
+ // But ID compressor is special. It's possible, that in future, we will remove "stickiness" of ID compressor setting
907
+ // and will allow to start using it. If that were to happen, we want to ensure that we do not break eventual consistency
908
+ // promises. To do so, we need to initialize id compressor right away.
909
+ // As it's implemented right now (with async initialization), this will only work for "off" -> "delayed" transitions.
910
+ // Anything else is too risky, and requires ability to initialize ID compressor synchronously!
911
+ if (schema.runtime.idCompressorMode !== undefined) {
912
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
913
+ this.loadIdCompressor();
914
+ }
915
+ }
826
916
  getCreateChildSummarizerNodeFn(id, createParam) {
827
917
  return (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn);
828
918
  }
829
919
  deleteChildSummarizerNode(id) {
830
920
  return this.summarizerNode.deleteChild(id);
831
921
  }
922
+ /* IFluidParentContext APIs that should not be called on Root */
832
923
  makeLocallyVisible() {
833
924
  assert(false, 0x8eb /* should not be called */);
834
925
  }
926
+ setChannelDirty(address) {
927
+ assert(false, 0x909 /* should not be called */);
928
+ }
835
929
  /**
836
930
  * Initializes the state from the base snapshot this container runtime loaded from.
837
931
  */
@@ -1036,18 +1130,30 @@ export class ContainerRuntime extends TypedEventEmitter {
1036
1130
  }
1037
1131
  /** Adds the container's metadata to the given summary tree. */
1038
1132
  addMetadataToSummary(summaryTree) {
1133
+ // The last message processed at the time of summary. If there are no new messages, use the message from the
1134
+ // last summary.
1135
+ const message = extractSummaryMetadataMessage(this.deltaManager.lastMessage) ??
1136
+ this.messageAtLastSummary;
1137
+ const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
1138
+ // Is document schema explicit control on?
1139
+ const explitiSchemaControl = documentSchema?.runtime.explicitSchemaControl;
1039
1140
  const metadata = {
1040
1141
  ...this.createContainerMetadata,
1041
1142
  // Increment the summary number for the next summary that will be generated.
1042
1143
  summaryNumber: this.nextSummaryNumber++,
1043
1144
  summaryFormatVersion: 1,
1044
1145
  ...this.garbageCollector.getMetadata(),
1045
- // The last message processed at the time of summary. If there are no new messages, use the message from the
1046
- // last summary.
1047
- message: extractSummaryMetadataMessage(this.deltaManager.lastMessage) ??
1048
- this.messageAtLastSummary,
1049
1146
  telemetryDocumentId: this.telemetryDocumentId,
1050
- idCompressorMode: this.idCompressorMode,
1147
+ // If explicit document schema control is not on, use legacy way to supply last message (using 'message' property).
1148
+ // Otherwise use new 'lastMessage' property, but also put content into the 'message' property that cases old
1149
+ // runtimes (that preceed document schema control capabilities) to close container on load due to mismatch in
1150
+ // last message's sequence number.
1151
+ // See also lastMessageFromMetadata()
1152
+ message: explitiSchemaControl
1153
+ ? { sequenceNumber: -1 }
1154
+ : message,
1155
+ lastMessage: explitiSchemaControl ? message : undefined,
1156
+ documentSchema,
1051
1157
  };
1052
1158
  addBlobToSummary(summaryTree, metadataBlobName, JSON.stringify(metadata));
1053
1159
  }
@@ -1108,14 +1214,8 @@ export class ContainerRuntime extends TypedEventEmitter {
1108
1214
  }
1109
1215
  return this.consecutiveReconnects < this.maxConsecutiveReconnects;
1110
1216
  }
1111
- resetReconnectCount(message) {
1112
- // Chunked ops don't count towards making progress as they are sent
1113
- // in their own batches before the originating batch is sent.
1114
- // Therefore, receiving them while attempting to send the originating batch
1115
- // does not mean that the container is making any progress.
1116
- if (message?.type !== ContainerMessageType.ChunkedOp) {
1117
- this.consecutiveReconnects = 0;
1118
- }
1217
+ resetReconnectCount() {
1218
+ this.consecutiveReconnects = 0;
1119
1219
  }
1120
1220
  replayPendingStates() {
1121
1221
  // We need to be able to send ops to replay states
@@ -1164,7 +1264,18 @@ export class ContainerRuntime extends TypedEventEmitter {
1164
1264
  case ContainerMessageType.Alias:
1165
1265
  return this.channelCollection.applyStashedOp(opContents);
1166
1266
  case ContainerMessageType.IdAllocation:
1167
- assert(this.idCompressorMode !== "off", 0x8f1 /* ID compressor should be in use */);
1267
+ // IDs allocation ops in stashed state are ignored because the tip state of the compressor
1268
+ // is serialized into the pending state. This is done because generation of new IDs during
1269
+ // stashed op application (or, later, resubmit) must generate new IDs and if the compressor
1270
+ // was loaded from a state serialized at the same time as the summary tree in the stashed state
1271
+ // then it would generate IDs that collide with any in later stashed ops.
1272
+ // In the future, IdCompressor could be extended to have an "applyStashedOp" or similar method
1273
+ // and the runtime could filter out all ID allocation ops from the stashed state and apply them
1274
+ // before applying the rest of the stashed ops. This would accomplish the same thing but with
1275
+ // better performance in future incremental stashed state creation.
1276
+ assert(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
1277
+ return;
1278
+ case ContainerMessageType.DocumentSchemaChange:
1168
1279
  return;
1169
1280
  case ContainerMessageType.BlobAttach:
1170
1281
  return;
@@ -1195,12 +1306,14 @@ export class ContainerRuntime extends TypedEventEmitter {
1195
1306
  }
1196
1307
  }
1197
1308
  }
1198
- setConnectionState(connected, clientId) {
1199
- if (connected && this.idCompressorMode === "delayed" && !this.compressorLoadInitiated) {
1200
- this.compressorLoadInitiated = true;
1201
- this.createIdCompressor()
1309
+ async loadIdCompressor() {
1310
+ if (this._idCompressor === undefined &&
1311
+ this.idCompressorMode !== undefined &&
1312
+ this._loadIdCompressor === undefined) {
1313
+ this._loadIdCompressor = this.createIdCompressor()
1202
1314
  .then((compressor) => {
1203
1315
  this._idCompressor = compressor;
1316
+ // Finalize any ranges we received while the compressor was turned off.
1204
1317
  for (const range of this.pendingIdCompressorOps) {
1205
1318
  this._idCompressor.finalizeCreationRange(range);
1206
1319
  }
@@ -1208,8 +1321,16 @@ export class ContainerRuntime extends TypedEventEmitter {
1208
1321
  })
1209
1322
  .catch((error) => {
1210
1323
  this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
1324
+ throw error;
1211
1325
  });
1212
1326
  }
1327
+ return this._loadIdCompressor;
1328
+ }
1329
+ setConnectionState(connected, clientId) {
1330
+ if (connected && this.idCompressorMode === "delayed") {
1331
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1332
+ this.loadIdCompressor();
1333
+ }
1213
1334
  if (connected === false && this.delayConnectClientId !== undefined) {
1214
1335
  this.delayConnectClientId = undefined;
1215
1336
  this.mc.logger.sendTelemetryEvent({
@@ -1218,21 +1339,17 @@ export class ContainerRuntime extends TypedEventEmitter {
1218
1339
  // Don't propagate "disconnected" event because we didn't propagate the previous "connected" event
1219
1340
  return;
1220
1341
  }
1342
+ if (!connected) {
1343
+ this.documentsSchemaController.onDisconnect();
1344
+ }
1221
1345
  // If there are stashed blobs in the pending state, we need to delay
1222
1346
  // propagation of the "connected" event until we have uploaded them to
1223
1347
  // ensure we don't submit ops referencing a blob that has not been uploaded
1224
1348
  const connecting = connected && !this._connected;
1225
- if (connecting && this.blobManager.hasPendingStashedBlobs()) {
1349
+ if (connecting && this.blobManager.hasPendingStashedUploads()) {
1226
1350
  assert(!this.delayConnectClientId, 0x791 /* Connect event delay must be canceled before subsequent connect event */);
1227
1351
  assert(!!clientId, 0x792 /* Must have clientId when connecting */);
1228
1352
  this.delayConnectClientId = clientId;
1229
- this.blobManager.processStashedChanges().then(() => {
1230
- // make sure we didn't reconnect before the promise resolved
1231
- if (this.delayConnectClientId === clientId && !this.disposed) {
1232
- this.delayConnectClientId = undefined;
1233
- this.setConnectionStateCore(connected, clientId);
1234
- }
1235
- }, (error) => this.closeFn(error));
1236
1353
  return;
1237
1354
  }
1238
1355
  this.setConnectionStateCore(connected, clientId);
@@ -1320,10 +1437,13 @@ export class ContainerRuntime extends TypedEventEmitter {
1320
1437
  this.scheduleManager.beforeOpProcessing(message);
1321
1438
  this._processedClientSequenceNumber = message.clientSequenceNumber;
1322
1439
  try {
1440
+ // See commit that added this assert for more details.
1441
+ // These calls should be made for all but chunked ops:
1442
+ // 1) this.pendingStateManager.processPendingLocalMessage() below
1443
+ // 2) this.resetReconnectCount() below
1444
+ assert(message.type !== ContainerMessageType.ChunkedOp, 0x93b /* we should never get here with chunked ops */);
1323
1445
  let localOpMetadata;
1324
- if (local &&
1325
- messageWithContext.modernRuntimeMessage &&
1326
- message.type !== ContainerMessageType.ChunkedOp) {
1446
+ if (local && messageWithContext.modernRuntimeMessage) {
1327
1447
  localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
1328
1448
  }
1329
1449
  // If there are no more pending messages after processing a local message,
@@ -1338,7 +1458,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1338
1458
  // If we have processed a local op, this means that the container is
1339
1459
  // making progress and we can reset the counter for how many times
1340
1460
  // we have consecutively replayed the pending states
1341
- this.resetReconnectCount(message);
1461
+ this.resetReconnectCount();
1342
1462
  }
1343
1463
  }
1344
1464
  catch (e) {
@@ -1372,7 +1492,10 @@ export class ContainerRuntime extends TypedEventEmitter {
1372
1492
  messageWithContext.message.metadata?.savedOp ===
1373
1493
  true)) {
1374
1494
  const range = messageWithContext.message.contents;
1495
+ // Some other client turned on the id compressor. If we have not turned it on,
1496
+ // put it in a pending queue and delay finalization.
1375
1497
  if (this._idCompressor === undefined) {
1498
+ assert(this.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
1376
1499
  this.pendingIdCompressorOps.push(range);
1377
1500
  }
1378
1501
  else {
@@ -1384,8 +1507,14 @@ export class ContainerRuntime extends TypedEventEmitter {
1384
1507
  this.garbageCollector.processMessage(messageWithContext.message, local);
1385
1508
  break;
1386
1509
  case ContainerMessageType.ChunkedOp:
1510
+ // From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
1511
+ // Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
1512
+ assert(false, 0x93d /* should not even get here */);
1387
1513
  case ContainerMessageType.Rejoin:
1388
1514
  break;
1515
+ case ContainerMessageType.DocumentSchemaChange:
1516
+ this.documentsSchemaController.processDocumentSchemaOp(messageWithContext.message.contents, messageWithContext.local, messageWithContext.message.sequenceNumber);
1517
+ break;
1389
1518
  default: {
1390
1519
  // If we didn't necessarily expect a runtime message type, then no worries - just return
1391
1520
  // e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
@@ -1559,10 +1688,10 @@ export class ContainerRuntime extends TypedEventEmitter {
1559
1688
  return channel.entryPoint;
1560
1689
  }
1561
1690
  createDetachedDataStore(pkg, loadingGroupId) {
1562
- return this.channelCollection.createDetachedDataStoreCore(pkg, loadingGroupId);
1691
+ return this.channelCollection.createDetachedDataStore(pkg, loadingGroupId);
1563
1692
  }
1564
1693
  async createDataStore(pkg, loadingGroupId) {
1565
- const context = this.channelCollection._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], undefined, // props
1694
+ const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], undefined, // props
1566
1695
  loadingGroupId);
1567
1696
  return channelToDataStore(await context.realize(), context.id, this.channelCollection, this.mc.logger);
1568
1697
  }
@@ -1570,7 +1699,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1570
1699
  * @deprecated 0.16 Issue #1537, #3631
1571
1700
  */
1572
1701
  async _createDataStoreWithProps(pkg, props) {
1573
- const context = this.channelCollection._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
1702
+ const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
1574
1703
  return channelToDataStore(await context.realize(), context.id, this.channelCollection, this.mc.logger);
1575
1704
  }
1576
1705
  canSendOps() {
@@ -1615,6 +1744,8 @@ export class ContainerRuntime extends TypedEventEmitter {
1615
1744
  }
1616
1745
  break;
1617
1746
  }
1747
+ case ContainerMessageType.IdAllocation:
1748
+ case ContainerMessageType.DocumentSchemaChange:
1618
1749
  case ContainerMessageType.GC: {
1619
1750
  return false;
1620
1751
  }
@@ -1641,7 +1772,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1641
1772
  /**
1642
1773
  * Submits the signal to be sent to other clients.
1643
1774
  * @param type - Type of the signal.
1644
- * @param content - Content of the signal.
1775
+ * @param content - Content of the signal. Should be a JSON serializable object or primitive.
1645
1776
  * @param targetClientId - When specified, the signal is only sent to the provided client id.
1646
1777
  */
1647
1778
  submitSignal(type, content, targetClientId) {
@@ -1677,6 +1808,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1677
1808
  // We can finalize any allocated IDs since we're the only client
1678
1809
  const idRange = this._idCompressor?.takeNextCreationRange();
1679
1810
  if (idRange !== undefined) {
1811
+ assert(idRange.ids === undefined || idRange.ids.firstGenCount === 1, 0x93e /* No other ranges should be taken while container is detached. */);
1680
1812
  this._idCompressor?.finalizeCreationRange(idRange);
1681
1813
  }
1682
1814
  const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
@@ -1690,6 +1822,8 @@ export class ContainerRuntime extends TypedEventEmitter {
1690
1822
  // Wrap data store summaries in .channels subtree.
1691
1823
  wrapSummaryInChannelsTree(summarizeResult);
1692
1824
  const pathPartsForChildren = [channelsTreeName];
1825
+ // Ensure that ID compressor had a chance to load, if we are using delayed mode.
1826
+ await this.loadIdCompressor();
1693
1827
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
1694
1828
  return {
1695
1829
  ...summarizeResult,
@@ -1765,21 +1899,6 @@ export class ContainerRuntime extends TypedEventEmitter {
1765
1899
  const { dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(usedRoutes);
1766
1900
  this.channelCollection.updateUsedRoutes(dataStoreRoutes);
1767
1901
  }
1768
- /**
1769
- * This is called to update objects whose routes are unused.
1770
- * @param unusedRoutes - Data store and attachment blob routes that are unused in this Container.
1771
- */
1772
- updateUnusedRoutes(unusedRoutes) {
1773
- const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(unusedRoutes);
1774
- this.blobManager.updateUnusedRoutes(blobManagerRoutes);
1775
- this.channelCollection.updateUnusedRoutes(dataStoreRoutes);
1776
- }
1777
- /**
1778
- * @deprecated Replaced by deleteSweepReadyNodes.
1779
- */
1780
- deleteUnusedNodes(unusedRoutes) {
1781
- throw new Error("deleteUnusedRoutes should not be called");
1782
- }
1783
1902
  /**
1784
1903
  * After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
1785
1904
  * @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.
@@ -2247,19 +2366,18 @@ export class ContainerRuntime extends TypedEventEmitter {
2247
2366
  const idAllocationBatchMessage = {
2248
2367
  contents: JSON.stringify(idAllocationMessage),
2249
2368
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2250
- metadata: undefined,
2251
- localOpMetadata: undefined,
2252
- type: ContainerMessageType.IdAllocation,
2253
2369
  };
2254
2370
  this.outbox.submitIdAllocation(idAllocationBatchMessage);
2255
2371
  }
2256
2372
  }
2257
2373
  }
2258
- submit(containerRuntimeMessage, localOpMetadata = undefined, metadata = undefined) {
2374
+ submit(containerRuntimeMessage, localOpMetadata = undefined, metadata) {
2259
2375
  this.verifyNotClosed();
2260
2376
  this.verifyCanSubmitOps();
2261
2377
  // There should be no ops in detached container state!
2262
2378
  assert(this.attachState !== AttachState.Detached, 0x132 /* "sending ops in detached container" */);
2379
+ assert(metadata === undefined ||
2380
+ containerRuntimeMessage.type === ContainerMessageType.BlobAttach, 0x93f /* metadata */);
2263
2381
  const serializedContent = JSON.stringify(containerRuntimeMessage);
2264
2382
  // Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
2265
2383
  // container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
@@ -2272,7 +2390,6 @@ export class ContainerRuntime extends TypedEventEmitter {
2272
2390
  const type = containerRuntimeMessage.type;
2273
2391
  const message = {
2274
2392
  contents: serializedContent,
2275
- type,
2276
2393
  metadata,
2277
2394
  localOpMetadata,
2278
2395
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -2287,6 +2404,20 @@ export class ContainerRuntime extends TypedEventEmitter {
2287
2404
  }
2288
2405
  else {
2289
2406
  this.submitIdAllocationOpIfNeeded();
2407
+ // Allow document schema controller to send a message if it needs to propose change in document schema.
2408
+ // If it needs to send a message, it will call provided callback with payload of such message and rely
2409
+ // on this callback to do actual sending.
2410
+ const contents = this.documentsSchemaController.maybeSendSchemaMessage();
2411
+ if (contents) {
2412
+ const msg = {
2413
+ type: ContainerMessageType.DocumentSchemaChange,
2414
+ contents,
2415
+ };
2416
+ this.outbox.submit({
2417
+ contents: JSON.stringify(msg),
2418
+ referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2419
+ });
2420
+ }
2290
2421
  // If this is attach message for new data store, and we are in a batch, send this op out of order
2291
2422
  // Is it safe:
2292
2423
  // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
@@ -2458,6 +2589,11 @@ export class ContainerRuntime extends TypedEventEmitter {
2458
2589
  case ContainerMessageType.GC:
2459
2590
  this.submit(message);
2460
2591
  break;
2592
+ case ContainerMessageType.DocumentSchemaChange:
2593
+ // There is no need to resend this message. Document schema controller will properly resend it again (if needed)
2594
+ // on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
2595
+ // send any ops, as some other client already changed schema.
2596
+ break;
2461
2597
  default: {
2462
2598
  // This case should be very rare - it would imply an op was stashed from a
2463
2599
  // future version of runtime code and now is being applied on an older version.
@@ -2660,8 +2796,7 @@ export class ContainerRuntime extends TypedEventEmitter {
2660
2796
  }
2661
2797
  }
2662
2798
  get groupedBatchingEnabled() {
2663
- const killSwitch = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
2664
- return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
2799
+ return this.documentSchema.opGroupingEnabled === true;
2665
2800
  }
2666
2801
  }
2667
2802
  //# sourceMappingURL=containerRuntime.js.map