@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
@@ -1,32 +1,36 @@
1
1
  "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
2
6
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
7
+ exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
8
+ const client_utils_1 = require("@fluid-internal/client-utils");
4
9
  const container_definitions_1 = require("@fluidframework/container-definitions");
5
10
  const core_utils_1 = require("@fluidframework/core-utils");
6
- const client_utils_1 = require("@fluid-internal/client-utils");
7
- const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
8
11
  const driver_definitions_1 = require("@fluidframework/driver-definitions");
9
12
  const driver_utils_1 = require("@fluidframework/driver-utils");
10
13
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
11
14
  const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
12
15
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
16
+ const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
13
17
  const uuid_1 = require("uuid");
14
- const containerHandleContext_js_1 = require("./containerHandleContext.js");
15
- const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
16
- const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
17
- const pendingStateManager_js_1 = require("./pendingStateManager.js");
18
- const packageVersion_js_1 = require("./packageVersion.js");
18
+ const batchTracker_js_1 = require("./batchTracker.js");
19
19
  const blobManager_js_1 = require("./blobManager.js");
20
20
  const channelCollection_js_1 = require("./channelCollection.js");
21
- const index_js_1 = require("./summary/index.js");
22
- const throttler_js_1 = require("./throttler.js");
23
- const index_js_2 = require("./gc/index.js");
21
+ const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
22
+ const containerHandleContext_js_1 = require("./containerHandleContext.js");
24
23
  const dataStore_js_1 = require("./dataStore.js");
25
- const batchTracker_js_1 = require("./batchTracker.js");
26
- const scheduleManager_js_1 = require("./scheduleManager.js");
27
- const index_js_3 = require("./opLifecycle/index.js");
24
+ const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
28
25
  const deltaManagerSummarizerProxy_js_1 = require("./deltaManagerSummarizerProxy.js");
26
+ const index_js_1 = require("./gc/index.js");
29
27
  const messageTypes_js_1 = require("./messageTypes.js");
28
+ const index_js_2 = require("./opLifecycle/index.js");
29
+ const packageVersion_js_1 = require("./packageVersion.js");
30
+ const pendingStateManager_js_1 = require("./pendingStateManager.js");
31
+ const scheduleManager_js_1 = require("./scheduleManager.js");
32
+ const index_js_3 = require("./summary/index.js");
33
+ const throttler_js_1 = require("./throttler.js");
30
34
  /**
31
35
  * Utility to implement compat behaviors given an unknown message type
32
36
  * The parameters are typed to support compile-time enforcement of handling all known types/behaviors
@@ -81,6 +85,11 @@ var CompressionAlgorithms;
81
85
  (function (CompressionAlgorithms) {
82
86
  CompressionAlgorithms["lz4"] = "lz4";
83
87
  })(CompressionAlgorithms || (exports.CompressionAlgorithms = CompressionAlgorithms = {}));
88
+ /** @alpha */
89
+ exports.disabledCompressionConfig = {
90
+ minimumBatchSizeInBytes: Infinity,
91
+ compressionAlgorithm: CompressionAlgorithms.lz4,
92
+ };
84
93
  const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
85
94
  const defaultFlushMode = runtime_definitions_1.FlushMode.TurnBased;
86
95
  // The actual limit is 1Mb (socket.io and Kafka limits)
@@ -104,26 +113,12 @@ exports.defaultPendingOpsRetryDelayMs = 1000;
104
113
  * This delay's goal is to prevent tight restart loops
105
114
  */
106
115
  const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
107
- /**
108
- * @deprecated use ContainerRuntimeMessageType instead
109
- * @internal
110
- */
111
- var RuntimeMessage;
112
- (function (RuntimeMessage) {
113
- RuntimeMessage["FluidDataStoreOp"] = "component";
114
- RuntimeMessage["Attach"] = "attach";
115
- RuntimeMessage["ChunkedOp"] = "chunkedOp";
116
- RuntimeMessage["BlobAttach"] = "blobAttach";
117
- RuntimeMessage["Rejoin"] = "rejoin";
118
- RuntimeMessage["Alias"] = "alias";
119
- RuntimeMessage["Operation"] = "op";
120
- })(RuntimeMessage || (exports.RuntimeMessage = RuntimeMessage = {}));
121
116
  /**
122
117
  * @deprecated please use version in driver-utils
123
118
  * @internal
124
119
  */
125
120
  function isRuntimeMessage(message) {
126
- return Object.values(RuntimeMessage).includes(message.type);
121
+ return Object.values(messageTypes_js_1.ContainerMessageType).includes(message.type);
127
122
  }
128
123
  exports.isRuntimeMessage = isRuntimeMessage;
129
124
  /**
@@ -172,7 +167,7 @@ async function createSummarizer(loader, url) {
172
167
  [container_definitions_1.LoaderHeader.cache]: false,
173
168
  [container_definitions_1.LoaderHeader.clientDetails]: {
174
169
  capabilities: { interactive: false },
175
- type: index_js_1.summarizerClientType,
170
+ type: index_js_3.summarizerClientType,
176
171
  },
177
172
  [driver_definitions_1.DriverHeader.summarizingClient]: true,
178
173
  [container_definitions_1.LoaderHeader.reconnect]: false,
@@ -200,6 +195,17 @@ async function createSummarizer(loader, url) {
200
195
  }
201
196
  return fluidObject.ISummarizer;
202
197
  }
198
+ /**
199
+ * Extract last message from the snapshot metadata.
200
+ * Uses legacy property if not using explicit schema control, otherwise uses the new property.
201
+ * This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
202
+ * Please see addMetadataToSummary() as well
203
+ */
204
+ function lastMessageFromMetadata(metadata) {
205
+ return metadata?.documentSchema?.runtime?.explicitSchemaControl
206
+ ? metadata?.lastMessage
207
+ : metadata?.message;
208
+ }
203
209
  /**
204
210
  * Represents the runtime of the container. Contains helper functions/state of the container.
205
211
  * It will define the store level mappings.
@@ -237,7 +243,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
237
243
  },
238
244
  });
239
245
  const mc = (0, telemetry_utils_1.loggerToMonitoringContext)(logger);
240
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = "off", chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
246
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, explicitSchemaControl = false, } = runtimeOptions;
241
247
  const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
242
248
  const tryFetchBlob = async (blobName) => {
243
249
  const blobId = context.baseSnapshot?.blobs[blobName];
@@ -249,27 +255,34 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
249
255
  }
250
256
  };
251
257
  const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
252
- tryFetchBlob(index_js_1.chunksBlobName),
253
- tryFetchBlob(index_js_1.metadataBlobName),
254
- tryFetchBlob(index_js_1.electedSummarizerBlobName),
255
- tryFetchBlob(index_js_1.aliasBlobName),
256
- tryFetchBlob(index_js_1.idCompressorBlobName),
258
+ tryFetchBlob(index_js_3.chunksBlobName),
259
+ tryFetchBlob(index_js_3.metadataBlobName),
260
+ tryFetchBlob(index_js_3.electedSummarizerBlobName),
261
+ tryFetchBlob(index_js_3.aliasBlobName),
262
+ tryFetchBlob(index_js_3.idCompressorBlobName),
257
263
  ]);
258
264
  // read snapshot blobs needed for BlobManager to load
259
- const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_1.blobsTreeName], async (id) => {
265
+ const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_3.blobsTreeName], async (id) => {
260
266
  // IContainerContext storage api return type still has undefined in 0.39 package version.
261
267
  // So once we release 0.40 container-defn package we can remove this check.
262
268
  (0, core_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
263
269
  return (0, driver_utils_1.readAndParse)(context.storage, id);
264
270
  });
271
+ const messageAtLastSummary = lastMessageFromMetadata(metadata);
265
272
  // Verify summary runtime sequence number matches protocol sequence number.
266
- const runtimeSequenceNumber = metadata?.message?.sequenceNumber;
273
+ const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
267
274
  // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
268
275
  if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
269
276
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
270
277
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
271
278
  if (loadSequenceNumberVerification !== "bypass" &&
272
279
  runtimeSequenceNumber !== protocolSequenceNumber) {
280
+ // Message to OCEs:
281
+ // You can hit this error with runtimeSequenceNumber === -1 in < 2.0 RC3 builds.
282
+ // This would indicate that explicit schema control is enabled in current (2.0 RC3+) builds and it
283
+ // results in addMetadataToSummary() creating a poison pill for older runtimes in the form of a -1 sequence number.
284
+ // Older runtimes do not understand new schema, and thus could corrupt document if they proceed, thus we are using
285
+ // this poison pill to prevent them from proceeding.
273
286
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
274
287
  const error = new telemetry_utils_1.DataCorruptionError(
275
288
  // pre-0.58 error message: SummaryMetadataMismatch
@@ -283,7 +296,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
283
296
  }
284
297
  }
285
298
  // Enabling the IdCompressor is a one-way operation and we only want to
286
- // allow new containers to turn it on
299
+ // allow new containers to turn it on.
287
300
  let idCompressorMode;
288
301
  if (existing) {
289
302
  // This setting has to be sticky for correctness:
@@ -292,20 +305,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
292
305
  // 2) if it's ON, then all sessions should load compressor right away
293
306
  // 3) Same logic applies for "delayed" mode
294
307
  // Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
295
- // We could do "off" -> "on" transtition too, if all clients start loading compressor (but not using it initially) and do so for a while -
296
- // this will allow clients to eventually to disregard "off" setting (when it's safe so) and start using compressor in future sessions.
308
+ // We could do "off" -> "on" transition too, if all clients start loading compressor (but not using it initially) and
309
+ // do so for a while - this will allow clients to eventually to disregard "off" setting (when it's safe so) and start
310
+ // using compressor in future sessions.
297
311
  // Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
298
- idCompressorMode = metadata?.idCompressorMode ?? "off";
312
+ idCompressorMode = metadata?.documentSchema?.runtime
313
+ ?.idCompressorMode;
299
314
  }
300
315
  else {
301
- // FG overwrite
302
- const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
303
- switch (enabled) {
316
+ switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
304
317
  case true:
305
318
  idCompressorMode = "on";
306
319
  break;
307
320
  case false:
308
- idCompressorMode = "off";
321
+ idCompressorMode = undefined;
309
322
  break;
310
323
  default:
311
324
  idCompressorMode = enableRuntimeIdCompressor;
@@ -338,6 +351,24 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
338
351
  return createIdCompressor(compressorLogger);
339
352
  }
340
353
  };
354
+ const disableGroupedBatching = mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
355
+ const disableCompression = mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
356
+ const compressionLz4 = disableCompression !== true &&
357
+ compressionOptions.minimumBatchSizeInBytes !== Infinity &&
358
+ compressionOptions.compressionAlgorithm === "lz4";
359
+ const opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
360
+ const documentSchemaController = new index_js_3.DocumentsSchemaController(existing, metadata?.documentSchema, {
361
+ explicitSchemaControl,
362
+ compressionLz4,
363
+ idCompressorMode,
364
+ opGroupingEnabled,
365
+ }, (schema) => {
366
+ runtime.onSchemaChange(schema);
367
+ });
368
+ const featureGatesForTelemetry = {
369
+ disableGroupedBatching,
370
+ disableCompression,
371
+ };
341
372
  const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
342
373
  summaryOptions,
343
374
  gcOptions,
@@ -346,10 +377,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
346
377
  compressionOptions,
347
378
  maxBatchSizeInBytes,
348
379
  chunkSizeInBytes,
349
- enableRuntimeIdCompressor,
380
+ // Requires<> drops undefined from IdCompressorType
381
+ enableRuntimeIdCompressor: enableRuntimeIdCompressor,
350
382
  enableOpReentryCheck,
351
383
  enableGroupedBatching,
352
- }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, idCompressorMode, provideEntryPoint, requestHandler, undefined);
384
+ explicitSchemaControl,
385
+ }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined);
353
386
  // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
354
387
  // or zero. This must be done before Container replays saved ops.
355
388
  await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
@@ -378,6 +411,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
378
411
  get attachState() {
379
412
  return this._getAttachState();
380
413
  }
414
+ get documentSchema() {
415
+ return this.documentsSchemaController.sessionSchema.runtime;
416
+ }
417
+ get idCompressorMode() {
418
+ return this.documentSchema.idCompressorMode;
419
+ }
381
420
  /**
382
421
  * See IContainerRuntimeBase.idCompressor() for details.
383
422
  */
@@ -458,7 +497,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
458
497
  return this.garbageCollector.throwOnTombstoneUsage;
459
498
  }
460
499
  /***/
461
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, idCompressorMode, provideEntryPoint, requestHandler, summaryConfiguration = {
500
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, summaryConfiguration = {
462
501
  // the defaults
463
502
  ...exports.DefaultSummaryConfiguration,
464
503
  // the runtime configuration overrides
@@ -472,18 +511,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
472
511
  this.logger = logger;
473
512
  this._storage = _storage;
474
513
  this.createIdCompressor = createIdCompressor;
475
- this.idCompressorMode = idCompressorMode;
514
+ this.documentsSchemaController = documentsSchemaController;
476
515
  this.requestHandler = requestHandler;
477
516
  this.summaryConfiguration = summaryConfiguration;
478
517
  this.imminentClosure = false;
479
518
  // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
480
519
  // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
481
520
  this.pendingIdCompressorOps = [];
482
- /**
483
- * True if we have ID compressor loading in-flight (async operation). Useful only for
484
- * this.idCompressorMode === "delayed" mode
485
- */
486
- this.compressorLoadInitiated = false;
487
521
  this.defaultMaxConsecutiveReconnects = 7;
488
522
  this._orderSequentiallyCalls = 0;
489
523
  this.flushTaskExists = false;
@@ -513,6 +547,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
513
547
  expiry: { policy: "absolute", durationMs: 60000 },
514
548
  });
515
549
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
550
+ this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
551
+ logger: this.logger,
552
+ namespace: "ContainerRuntime",
553
+ });
554
+ // If we support multiple algorithms in the future, then we would need to manage it here carefully.
555
+ // We can use runtimeOptions.compressionOptions.compressionAlgorithm, but only if it's in the schema list!
556
+ // If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
557
+ // compression.
558
+ const compressionOptions = {
559
+ minimumBatchSizeInBytes: this.documentSchema.compressionLz4
560
+ ? runtimeOptions.compressionOptions.minimumBatchSizeInBytes
561
+ : Number.POSITIVE_INFINITY,
562
+ compressionAlgorithm: CompressionAlgorithms.lz4,
563
+ };
516
564
  this.innerDeltaManager = deltaManager;
517
565
  this.deltaManager = new deltaManagerSummarizerProxy_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
518
566
  // Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
@@ -525,7 +573,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
525
573
  // Values are generally expected to be set from the runtime side.
526
574
  this.options = options ?? {};
527
575
  this.clientDetails = clientDetails;
528
- this.isSummarizerClient = this.clientDetails.type === index_js_1.summarizerClientType;
576
+ this.isSummarizerClient = this.clientDetails.type === index_js_3.summarizerClientType;
529
577
  this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
530
578
  this._getClientId = () => context.clientId;
531
579
  this._getAttachState = () => context.attachState;
@@ -546,10 +594,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
546
594
  this.disposeFn = disposeFn ?? closeFn;
547
595
  // In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
548
596
  this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
549
- this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
550
- logger: this.logger,
551
- namespace: "ContainerRuntime",
552
- });
553
597
  let loadSummaryNumber;
554
598
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
555
599
  // get the values from the metadata blob.
@@ -570,7 +614,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
570
614
  loadSummaryNumber = 0;
571
615
  }
572
616
  this.nextSummaryNumber = loadSummaryNumber + 1;
573
- this.messageAtLastSummary = metadata?.message;
617
+ this.messageAtLastSummary = lastMessageFromMetadata(metadata);
574
618
  // Note that we only need to pull the *initial* connected state from the context.
575
619
  // Later updates come through calls to setConnectionState.
576
620
  this._connected = connected;
@@ -578,20 +622,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
578
622
  eventName: "GCFeatureMatrix",
579
623
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
580
624
  inputs: JSON.stringify({
581
- gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_2.gcGenerationOptionName],
625
+ gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_1.gcGenerationOptionName],
582
626
  }),
583
627
  });
584
628
  this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
585
629
  this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
586
630
  const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
587
- const opGroupingManager = new index_js_3.OpGroupingManager({
631
+ const opGroupingManager = new index_js_2.OpGroupingManager({
588
632
  groupedBatchingEnabled: this.groupedBatchingEnabled,
589
633
  opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
590
634
  reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
591
635
  true,
592
636
  }, this.mc.logger);
593
- const opSplitter = new index_js_3.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
594
- this.remoteMessageProcessor = new index_js_3.RemoteMessageProcessor(opSplitter, new index_js_3.OpDecompressor(this.mc.logger), opGroupingManager);
637
+ const opSplitter = new index_js_2.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
638
+ this.remoteMessageProcessor = new index_js_2.RemoteMessageProcessor(opSplitter, new index_js_2.OpDecompressor(this.mc.logger), opGroupingManager);
595
639
  this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
596
640
  if (this.summaryConfiguration.state === "enabled") {
597
641
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
@@ -627,7 +671,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
627
671
  throw new telemetry_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
628
672
  }
629
673
  }
630
- this.garbageCollector = index_js_2.GarbageCollector.create({
674
+ this.garbageCollector = index_js_1.GarbageCollector.create({
631
675
  runtime: this,
632
676
  gcOptions: this.runtimeOptions.gcOptions,
633
677
  baseSnapshot,
@@ -643,7 +687,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
643
687
  sessionExpiryTimerStarted: pendingRuntimeState?.sessionExpiryTimerStarted,
644
688
  });
645
689
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
646
- this.summarizerNode = (0, index_js_1.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
690
+ this.summarizerNode = (0, index_js_3.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
647
691
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
648
692
  async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
649
693
  // Latest change sequence number, no changes since summary applied yet
@@ -687,26 +731,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
687
731
  clientId: () => this.clientId,
688
732
  close: this.closeFn,
689
733
  connected: () => this.connected,
690
- reSubmit: this.reSubmit.bind(this),
734
+ reSubmit: (message) => {
735
+ this.reSubmit(message);
736
+ this.flush();
737
+ },
691
738
  reSubmitBatch: this.reSubmitBatch.bind(this),
692
739
  isActiveConnection: () => this.innerDeltaManager.active,
693
740
  isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
694
741
  }, pendingRuntimeState?.pending, this.logger);
695
- const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
696
- const compressionOptions = disableCompression === true
697
- ? {
698
- minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
699
- compressionAlgorithm: CompressionAlgorithms.lz4,
700
- }
701
- : runtimeOptions.compressionOptions;
702
742
  const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
703
743
  const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
704
- this.outbox = new index_js_3.Outbox({
744
+ this.outbox = new index_js_2.Outbox({
705
745
  shouldSend: () => this.canSendOps(),
706
746
  pendingStateManager: this.pendingStateManager,
707
747
  submitBatchFn: this.submitBatchFn,
708
748
  legacySendBatchFn,
709
- compressor: new index_js_3.OpCompressor(this.mc.logger),
749
+ compressor: new index_js_2.OpCompressor(this.mc.logger),
710
750
  splitter: opSplitter,
711
751
  config: {
712
752
  compressionOptions,
@@ -733,7 +773,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
733
773
  this.closeSummarizerDelayMs = closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
734
774
  this.validateSummaryBeforeUpload =
735
775
  this.mc.config.getBoolean("Fluid.Summarizer.ValidateSummaryBeforeUpload") ?? false;
736
- this.summaryCollection = new index_js_1.SummaryCollection(this.deltaManager, this.logger);
776
+ this.summaryCollection = new index_js_3.SummaryCollection(this.deltaManager, this.logger);
737
777
  this.dirtyContainer =
738
778
  this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
739
779
  context.updateDirtyContainerState(this.dirtyContainer);
@@ -745,16 +785,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
745
785
  logger: this.logger,
746
786
  namespace: "OrderedClientElection",
747
787
  });
748
- const orderedClientCollection = new index_js_1.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
749
- const orderedClientElectionForSummarizer = new index_js_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_1.SummarizerClientElection.isClientEligible);
750
- this.summarizerClientElection = new index_js_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
788
+ const orderedClientCollection = new index_js_3.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
789
+ const orderedClientElectionForSummarizer = new index_js_3.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_3.SummarizerClientElection.isClientEligible);
790
+ this.summarizerClientElection = new index_js_3.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
751
791
  if (this.isSummarizerClient) {
752
- this._summarizer = new index_js_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_1.RunWhileConnectedCoordinator.create(runtime,
792
+ this._summarizer = new index_js_3.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_3.RunWhileConnectedCoordinator.create(runtime,
753
793
  // Summarization runs in summarizer client and needs access to the real (non-proxy) active
754
794
  // information. The proxy delta manager would always return false for summarizer client.
755
795
  () => this.innerDeltaManager.active));
756
796
  }
757
- else if (index_js_1.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
797
+ else if (index_js_3.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
758
798
  // Only create a SummaryManager and SummarizerClientElection
759
799
  // if summaries are enabled and we are not the summarizer client.
760
800
  const defaultAction = () => {
@@ -776,7 +816,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
776
816
  };
777
817
  this.summaryCollection.on("default", defaultAction);
778
818
  // Create the SummaryManager and mark the initial state
779
- this.summaryManager = new index_js_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
819
+ this.summaryManager = new index_js_3.SummaryManager(this.summarizerClientElection, this, // IConnectedState
780
820
  this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
781
821
  30 * 1000, // 30 sec max delay
782
822
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
@@ -803,10 +843,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
803
843
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
804
844
  gcVersion: metadata?.gcFeature,
805
845
  options: JSON.stringify(runtimeOptions),
806
- idCompressorModeMetadata: metadata?.idCompressorMode,
846
+ idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
807
847
  idCompressorMode: this.idCompressorMode,
808
848
  featureGates: JSON.stringify({
809
- disableCompression,
849
+ ...featureGatesForTelemetry,
810
850
  disableOpReentryCheck,
811
851
  disableChunking,
812
852
  disableAttachReorder: this.disableAttachReorder,
@@ -829,6 +869,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
829
869
  // saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
830
870
  this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
831
871
  }
872
+ onSchemaChange(schema) {
873
+ // Most of the settings will be picked up only by new sessions (i.e. after reload).
874
+ // We can make it better in the future (i.e. start to use op compression right away), but for simplicity
875
+ // this is not done.
876
+ // But ID compressor is special. It's possible, that in future, we will remove "stickiness" of ID compressor setting
877
+ // and will allow to start using it. If that were to happen, we want to ensure that we do not break eventual consistency
878
+ // promises. To do so, we need to initialize id compressor right away.
879
+ // As it's implemented right now (with async initialization), this will only work for "off" -> "delayed" transitions.
880
+ // Anything else is too risky, and requires ability to initialize ID compressor synchronously!
881
+ if (schema.runtime.idCompressorMode !== undefined) {
882
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
883
+ this.loadIdCompressor();
884
+ }
885
+ }
832
886
  getCreateChildSummarizerNodeFn(id, createParam) {
833
887
  return (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn);
834
888
  }
@@ -840,7 +894,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
840
894
  (0, core_utils_1.assert)(false, 0x8eb /* should not be called */);
841
895
  }
842
896
  setChannelDirty(address) {
843
- (0, core_utils_1.assert)(false, "should not be called");
897
+ (0, core_utils_1.assert)(false, 0x909 /* should not be called */);
844
898
  }
845
899
  /**
846
900
  * Initializes the state from the base snapshot this container runtime loaded from.
@@ -905,7 +959,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
905
959
  }),
906
960
  });
907
961
  // Find the snapshotTree inside the returned snapshot based on the path as given in the request.
908
- const hasIsolatedChannels = (0, index_js_1.rootHasIsolatedChannels)(this.metadata);
962
+ const hasIsolatedChannels = (0, index_js_3.rootHasIsolatedChannels)(this.metadata);
909
963
  const snapshotTreeForPath = this.getSnapshotTreeForPath(snapshot.snapshotTree, pathParts, hasIsolatedChannels);
910
964
  (0, core_utils_1.assert)(snapshotTreeForPath !== undefined, 0x8ef /* no snapshotTree for the path */);
911
965
  const snapshotSeqNumber = snapshot.sequenceNumber;
@@ -1046,44 +1100,56 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1046
1100
  }
1047
1101
  /** Adds the container's metadata to the given summary tree. */
1048
1102
  addMetadataToSummary(summaryTree) {
1103
+ // The last message processed at the time of summary. If there are no new messages, use the message from the
1104
+ // last summary.
1105
+ const message = (0, index_js_3.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
1106
+ this.messageAtLastSummary;
1107
+ const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
1108
+ // Is document schema explicit control on?
1109
+ const explitiSchemaControl = documentSchema?.runtime.explicitSchemaControl;
1049
1110
  const metadata = {
1050
1111
  ...this.createContainerMetadata,
1051
1112
  // Increment the summary number for the next summary that will be generated.
1052
1113
  summaryNumber: this.nextSummaryNumber++,
1053
1114
  summaryFormatVersion: 1,
1054
1115
  ...this.garbageCollector.getMetadata(),
1055
- // The last message processed at the time of summary. If there are no new messages, use the message from the
1056
- // last summary.
1057
- message: (0, index_js_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
1058
- this.messageAtLastSummary,
1059
1116
  telemetryDocumentId: this.telemetryDocumentId,
1060
- idCompressorMode: this.idCompressorMode,
1117
+ // If explicit document schema control is not on, use legacy way to supply last message (using 'message' property).
1118
+ // Otherwise use new 'lastMessage' property, but also put content into the 'message' property that cases old
1119
+ // runtimes (that preceed document schema control capabilities) to close container on load due to mismatch in
1120
+ // last message's sequence number.
1121
+ // See also lastMessageFromMetadata()
1122
+ message: explitiSchemaControl
1123
+ ? { sequenceNumber: -1 }
1124
+ : message,
1125
+ lastMessage: explitiSchemaControl ? message : undefined,
1126
+ documentSchema,
1061
1127
  };
1062
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.metadataBlobName, JSON.stringify(metadata));
1128
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.metadataBlobName, JSON.stringify(metadata));
1063
1129
  }
1064
1130
  addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
1065
1131
  this.addMetadataToSummary(summaryTree);
1066
1132
  if (this._idCompressor) {
1067
1133
  const idCompressorState = JSON.stringify(this._idCompressor.serialize(false));
1068
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.idCompressorBlobName, idCompressorState);
1134
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.idCompressorBlobName, idCompressorState);
1069
1135
  }
1070
1136
  if (this.remoteMessageProcessor.partialMessages.size > 0) {
1071
1137
  const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
1072
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.chunksBlobName, content);
1138
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.chunksBlobName, content);
1073
1139
  }
1074
1140
  const dataStoreAliases = this.channelCollection.aliases;
1075
1141
  if (dataStoreAliases.size > 0) {
1076
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
1142
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.aliasBlobName, JSON.stringify([...dataStoreAliases]));
1077
1143
  }
1078
1144
  if (this.summarizerClientElection) {
1079
1145
  const electedSummarizerContent = JSON.stringify(this.summarizerClientElection?.serialize());
1080
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.electedSummarizerBlobName, electedSummarizerContent);
1146
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.electedSummarizerBlobName, electedSummarizerContent);
1081
1147
  }
1082
1148
  const blobManagerSummary = this.blobManager.summarize();
1083
1149
  // Some storage (like git) doesn't allow empty tree, so we can omit it.
1084
1150
  // and the blob manager can handle the tree not existing when loading
1085
1151
  if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
1086
- (0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, index_js_1.blobsTreeName, blobManagerSummary);
1152
+ (0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, index_js_3.blobsTreeName, blobManagerSummary);
1087
1153
  }
1088
1154
  const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
1089
1155
  if (gcSummary !== undefined) {
@@ -1118,14 +1184,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1118
1184
  }
1119
1185
  return this.consecutiveReconnects < this.maxConsecutiveReconnects;
1120
1186
  }
1121
- resetReconnectCount(message) {
1122
- // Chunked ops don't count towards making progress as they are sent
1123
- // in their own batches before the originating batch is sent.
1124
- // Therefore, receiving them while attempting to send the originating batch
1125
- // does not mean that the container is making any progress.
1126
- if (message?.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp) {
1127
- this.consecutiveReconnects = 0;
1128
- }
1187
+ resetReconnectCount() {
1188
+ this.consecutiveReconnects = 0;
1129
1189
  }
1130
1190
  replayPendingStates() {
1131
1191
  // We need to be able to send ops to replay states
@@ -1174,7 +1234,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1174
1234
  case messageTypes_js_1.ContainerMessageType.Alias:
1175
1235
  return this.channelCollection.applyStashedOp(opContents);
1176
1236
  case messageTypes_js_1.ContainerMessageType.IdAllocation:
1177
- (0, core_utils_1.assert)(this.idCompressorMode !== "off", 0x8f1 /* ID compressor should be in use */);
1237
+ (0, core_utils_1.assert)(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
1238
+ return;
1239
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1178
1240
  return;
1179
1241
  case messageTypes_js_1.ContainerMessageType.BlobAttach:
1180
1242
  return;
@@ -1205,10 +1267,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1205
1267
  }
1206
1268
  }
1207
1269
  }
1208
- setConnectionState(connected, clientId) {
1209
- if (connected && this.idCompressorMode === "delayed" && !this.compressorLoadInitiated) {
1210
- this.compressorLoadInitiated = true;
1211
- this.createIdCompressor()
1270
+ async loadIdCompressor() {
1271
+ if (this._idCompressor === undefined &&
1272
+ this.idCompressorMode !== undefined &&
1273
+ this._loadIdCompressor === undefined) {
1274
+ this._loadIdCompressor = this.createIdCompressor()
1212
1275
  .then((compressor) => {
1213
1276
  this._idCompressor = compressor;
1214
1277
  for (const range of this.pendingIdCompressorOps) {
@@ -1218,8 +1281,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1218
1281
  })
1219
1282
  .catch((error) => {
1220
1283
  this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
1284
+ throw error;
1221
1285
  });
1222
1286
  }
1287
+ return this._loadIdCompressor;
1288
+ }
1289
+ setConnectionState(connected, clientId) {
1290
+ if (connected && this.idCompressorMode === "delayed") {
1291
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1292
+ this.loadIdCompressor();
1293
+ }
1223
1294
  if (connected === false && this.delayConnectClientId !== undefined) {
1224
1295
  this.delayConnectClientId = undefined;
1225
1296
  this.mc.logger.sendTelemetryEvent({
@@ -1228,6 +1299,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1228
1299
  // Don't propagate "disconnected" event because we didn't propagate the previous "connected" event
1229
1300
  return;
1230
1301
  }
1302
+ if (!connected) {
1303
+ this.documentsSchemaController.onDisconnect();
1304
+ }
1231
1305
  // If there are stashed blobs in the pending state, we need to delay
1232
1306
  // propagation of the "connected" event until we have uploaded them to
1233
1307
  // ensure we don't submit ops referencing a blob that has not been uploaded
@@ -1330,10 +1404,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1330
1404
  this.scheduleManager.beforeOpProcessing(message);
1331
1405
  this._processedClientSequenceNumber = message.clientSequenceNumber;
1332
1406
  try {
1407
+ // See commit that added this assert for more details.
1408
+ // These calls should be made for all but chunked ops:
1409
+ // 1) this.pendingStateManager.processPendingLocalMessage() below
1410
+ // 2) this.resetReconnectCount() below
1411
+ (0, core_utils_1.assert)(message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp, "we should never get here with chunked ops");
1333
1412
  let localOpMetadata;
1334
- if (local &&
1335
- messageWithContext.modernRuntimeMessage &&
1336
- message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp) {
1413
+ if (local && messageWithContext.modernRuntimeMessage) {
1337
1414
  localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
1338
1415
  }
1339
1416
  // If there are no more pending messages after processing a local message,
@@ -1348,7 +1425,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1348
1425
  // If we have processed a local op, this means that the container is
1349
1426
  // making progress and we can reset the counter for how many times
1350
1427
  // we have consecutively replayed the pending states
1351
- this.resetReconnectCount(message);
1428
+ this.resetReconnectCount();
1352
1429
  }
1353
1430
  }
1354
1431
  catch (e) {
@@ -1394,8 +1471,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1394
1471
  this.garbageCollector.processMessage(messageWithContext.message, local);
1395
1472
  break;
1396
1473
  case messageTypes_js_1.ContainerMessageType.ChunkedOp:
1474
+ // From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
1475
+ // Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
1476
+ (0, core_utils_1.assert)(false, "should not even get here");
1397
1477
  case messageTypes_js_1.ContainerMessageType.Rejoin:
1398
1478
  break;
1479
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1480
+ this.documentsSchemaController.processDocumentSchemaOp(messageWithContext.message.contents, messageWithContext.local, messageWithContext.message.sequenceNumber);
1481
+ break;
1399
1482
  default: {
1400
1483
  // If we didn't necessarily expect a runtime message type, then no worries - just return
1401
1484
  // e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
@@ -1625,6 +1708,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1625
1708
  }
1626
1709
  break;
1627
1710
  }
1711
+ case messageTypes_js_1.ContainerMessageType.IdAllocation:
1712
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
1628
1713
  case messageTypes_js_1.ContainerMessageType.GC: {
1629
1714
  return false;
1630
1715
  }
@@ -1691,15 +1776,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1691
1776
  }
1692
1777
  const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
1693
1778
  // Wrap data store summaries in .channels subtree.
1694
- (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1779
+ (0, index_js_3.wrapSummaryInChannelsTree)(summarizeResult);
1695
1780
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
1696
1781
  return summarizeResult.summary;
1697
1782
  }
1698
1783
  async summarizeInternal(fullTree, trackState, telemetryContext) {
1699
1784
  const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
1700
1785
  // Wrap data store summaries in .channels subtree.
1701
- (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1786
+ (0, index_js_3.wrapSummaryInChannelsTree)(summarizeResult);
1702
1787
  const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
1788
+ // Ensure that ID compressor had a chance to load, if we are using delayed mode.
1789
+ await this.loadIdCompressor();
1703
1790
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
1704
1791
  return {
1705
1792
  ...summarizeResult,
@@ -1812,9 +1899,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1812
1899
  */
1813
1900
  getNodeType(nodePath) {
1814
1901
  if (this.isBlobPath(nodePath)) {
1815
- return index_js_2.GCNodeType.Blob;
1902
+ return index_js_1.GCNodeType.Blob;
1816
1903
  }
1817
- return this.channelCollection.getGCNodeType(nodePath) ?? index_js_2.GCNodeType.Other;
1904
+ return this.channelCollection.getGCNodeType(nodePath) ?? index_js_1.GCNodeType.Other;
1818
1905
  }
1819
1906
  /**
1820
1907
  * Called by GC to retrieve the package path of the node with the given path. The node should belong to a
@@ -1827,10 +1914,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1827
1914
  return ["_gcRoot"];
1828
1915
  }
1829
1916
  switch (this.getNodeType(nodePath)) {
1830
- case index_js_2.GCNodeType.Blob:
1917
+ case index_js_1.GCNodeType.Blob:
1831
1918
  return [blobManager_js_1.BlobManager.basePath];
1832
- case index_js_2.GCNodeType.DataStore:
1833
- case index_js_2.GCNodeType.SubDataStore:
1919
+ case index_js_1.GCNodeType.DataStore:
1920
+ case index_js_1.GCNodeType.SubDataStore:
1834
1921
  return this.channelCollection.getDataStorePackagePath(nodePath);
1835
1922
  default:
1836
1923
  (0, core_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
@@ -2042,7 +2129,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2042
2129
  const validateResult = this.summarizerNode.validateSummary();
2043
2130
  if (!validateResult.success) {
2044
2131
  const { success, ...loggingProps } = validateResult;
2045
- const error = new index_js_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
2132
+ const error = new index_js_3.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
2046
2133
  return {
2047
2134
  stage: "base",
2048
2135
  referenceSequenceNumber: summaryRefSeqNum,
@@ -2189,7 +2276,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2189
2276
  // based on telemetry while we decide on a stable number.
2190
2277
  const retryDelayMs = this.mc.config.getNumber("Fluid.Summarizer.PendingOpsRetryDelayMs") ??
2191
2278
  exports.defaultPendingOpsRetryDelayMs;
2192
- const error = new index_js_1.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2279
+ const error = new index_js_3.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2193
2280
  count: this.pendingMessagesCount,
2194
2281
  beforeGenerate: beforeSummaryGeneration,
2195
2282
  });
@@ -2242,19 +2329,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2242
2329
  const idAllocationBatchMessage = {
2243
2330
  contents: JSON.stringify(idAllocationMessage),
2244
2331
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2245
- metadata: undefined,
2246
- localOpMetadata: undefined,
2247
- type: messageTypes_js_1.ContainerMessageType.IdAllocation,
2248
2332
  };
2249
2333
  this.outbox.submitIdAllocation(idAllocationBatchMessage);
2250
2334
  }
2251
2335
  }
2252
2336
  }
2253
- submit(containerRuntimeMessage, localOpMetadata = undefined, metadata = undefined) {
2337
+ submit(containerRuntimeMessage, localOpMetadata = undefined, metadata) {
2254
2338
  this.verifyNotClosed();
2255
2339
  this.verifyCanSubmitOps();
2256
2340
  // There should be no ops in detached container state!
2257
2341
  (0, core_utils_1.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
2342
+ (0, core_utils_1.assert)(metadata === undefined ||
2343
+ containerRuntimeMessage.type === messageTypes_js_1.ContainerMessageType.BlobAttach, "metadata");
2258
2344
  const serializedContent = JSON.stringify(containerRuntimeMessage);
2259
2345
  // Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
2260
2346
  // container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
@@ -2267,7 +2353,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2267
2353
  const type = containerRuntimeMessage.type;
2268
2354
  const message = {
2269
2355
  contents: serializedContent,
2270
- type,
2271
2356
  metadata,
2272
2357
  localOpMetadata,
2273
2358
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -2282,6 +2367,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2282
2367
  }
2283
2368
  else {
2284
2369
  this.submitIdAllocationOpIfNeeded();
2370
+ // Allow document schema controller to send a message if it needs to propose change in document schema.
2371
+ // If it needs to send a message, it will call provided callback with payload of such message and rely
2372
+ // on this callback to do actual sending.
2373
+ this.documentsSchemaController.onMessageSent((contents) => {
2374
+ const msg = {
2375
+ type: messageTypes_js_1.ContainerMessageType.DocumentSchemaChange,
2376
+ contents,
2377
+ };
2378
+ this.outbox.submit({
2379
+ contents: JSON.stringify(msg),
2380
+ referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2381
+ });
2382
+ });
2285
2383
  // If this is attach message for new data store, and we are in a batch, send this op out of order
2286
2384
  // Is it safe:
2287
2385
  // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
@@ -2388,7 +2486,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2388
2486
  if (this.opReentryCallsToReport > 0) {
2389
2487
  this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
2390
2488
  // We need to capture the call stack in order to inspect the source of this usage pattern
2391
- (0, index_js_3.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2489
+ (0, index_js_2.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2392
2490
  this.opReentryCallsToReport--;
2393
2491
  }
2394
2492
  // Creating ops while processing ops can lead
@@ -2453,6 +2551,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2453
2551
  case messageTypes_js_1.ContainerMessageType.GC:
2454
2552
  this.submit(message);
2455
2553
  break;
2554
+ case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
2555
+ // There is no need to resend this message. Document schema controller will properly resend it again (if needed)
2556
+ // on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
2557
+ // send any ops, as some other client already changed schema.
2558
+ break;
2456
2559
  default: {
2457
2560
  // This case should be very rare - it would imply an op was stashed from a
2458
2561
  // future version of runtime code and now is being applied on an older version.
@@ -2655,8 +2758,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2655
2758
  }
2656
2759
  }
2657
2760
  get groupedBatchingEnabled() {
2658
- const killSwitch = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
2659
- return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
2761
+ return this.documentSchema.opGroupingEnabled === true;
2660
2762
  }
2661
2763
  }
2662
2764
  exports.ContainerRuntime = ContainerRuntime;