@fluidframework/container-runtime 2.0.0-dev-rc.2.0.0.246488 → 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 (456) hide show
  1. package/api-report/container-runtime.api.md +78 -25
  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 +5 -5
  11. package/dist/channelCollection.d.ts.map +1 -1
  12. package/dist/channelCollection.js +44 -11
  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 -11
  19. package/dist/container-runtime-beta.d.ts +16 -2
  20. package/dist/container-runtime-public.d.ts +16 -2
  21. package/dist/container-runtime-untrimmed.d.ts +205 -24
  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 +213 -119
  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.map +1 -1
  39. package/dist/dataStoreRegistry.js.map +1 -1
  40. package/dist/deltaScheduler.d.ts +1 -1
  41. package/dist/deltaScheduler.d.ts.map +1 -1
  42. package/dist/deltaScheduler.js +1 -1
  43. package/dist/deltaScheduler.js.map +1 -1
  44. package/dist/gc/garbageCollection.d.ts +1 -1
  45. package/dist/gc/garbageCollection.d.ts.map +1 -1
  46. package/dist/gc/garbageCollection.js +1 -1
  47. package/dist/gc/garbageCollection.js.map +1 -1
  48. package/dist/gc/gcConfigs.d.ts +1 -1
  49. package/dist/gc/gcConfigs.d.ts.map +1 -1
  50. package/dist/gc/gcConfigs.js.map +1 -1
  51. package/dist/gc/gcDefinitions.d.ts +1 -1
  52. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  53. package/dist/gc/gcDefinitions.js.map +1 -1
  54. package/dist/gc/gcHelpers.d.ts.map +1 -1
  55. package/dist/gc/gcHelpers.js.map +1 -1
  56. package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
  57. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  58. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  59. package/dist/gc/gcTelemetry.d.ts +1 -1
  60. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  61. package/dist/gc/gcTelemetry.js.map +1 -1
  62. package/dist/index.d.ts +2 -2
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +4 -2
  65. package/dist/index.js.map +1 -1
  66. package/dist/messageTypes.d.ts +11 -5
  67. package/dist/messageTypes.d.ts.map +1 -1
  68. package/dist/messageTypes.js +4 -0
  69. package/dist/messageTypes.js.map +1 -1
  70. package/dist/opLifecycle/definitions.d.ts +1 -19
  71. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  72. package/dist/opLifecycle/definitions.js.map +1 -1
  73. package/dist/opLifecycle/index.d.ts +3 -3
  74. package/dist/opLifecycle/index.d.ts.map +1 -1
  75. package/dist/opLifecycle/index.js +3 -1
  76. package/dist/opLifecycle/index.js.map +1 -1
  77. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  78. package/dist/opLifecycle/opCompressor.js +2 -3
  79. package/dist/opLifecycle/opCompressor.js.map +1 -1
  80. package/dist/opLifecycle/opDecompressor.d.ts +15 -4
  81. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  82. package/dist/opLifecycle/opDecompressor.js +60 -61
  83. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  84. package/dist/opLifecycle/opGroupingManager.d.ts +2 -1
  85. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  86. package/dist/opLifecycle/opGroupingManager.js +9 -11
  87. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  88. package/dist/opLifecycle/opSplitter.d.ts +11 -3
  89. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  90. package/dist/opLifecycle/opSplitter.js +48 -38
  91. package/dist/opLifecycle/opSplitter.js.map +1 -1
  92. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  93. package/dist/opLifecycle/outbox.js +7 -12
  94. package/dist/opLifecycle/outbox.js.map +1 -1
  95. package/dist/opLifecycle/remoteMessageProcessor.d.ts +8 -0
  96. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  97. package/dist/opLifecycle/remoteMessageProcessor.js +36 -35
  98. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  99. package/dist/packageVersion.d.ts +1 -1
  100. package/dist/packageVersion.js +1 -1
  101. package/dist/packageVersion.js.map +1 -1
  102. package/dist/pendingStateManager.d.ts +1 -1
  103. package/dist/pendingStateManager.d.ts.map +1 -1
  104. package/dist/pendingStateManager.js.map +1 -1
  105. package/dist/scheduleManager.d.ts +1 -1
  106. package/dist/scheduleManager.d.ts.map +1 -1
  107. package/dist/scheduleManager.js +2 -2
  108. package/dist/scheduleManager.js.map +1 -1
  109. package/dist/summary/documentSchema.d.ts +178 -0
  110. package/dist/summary/documentSchema.d.ts.map +1 -0
  111. package/dist/summary/documentSchema.js +345 -0
  112. package/dist/summary/documentSchema.js.map +1 -0
  113. package/dist/summary/index.d.ts +2 -1
  114. package/dist/summary/index.d.ts.map +1 -1
  115. package/dist/summary/index.js +4 -1
  116. package/dist/summary/index.js.map +1 -1
  117. package/dist/summary/orderedClientElection.d.ts +2 -2
  118. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  119. package/dist/summary/orderedClientElection.js +3 -2
  120. package/dist/summary/orderedClientElection.js.map +1 -1
  121. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
  122. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  123. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  124. package/dist/summary/runningSummarizer.d.ts +2 -2
  125. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  126. package/dist/summary/runningSummarizer.js +2 -2
  127. package/dist/summary/runningSummarizer.js.map +1 -1
  128. package/dist/summary/summarizer.d.ts +2 -2
  129. package/dist/summary/summarizer.d.ts.map +1 -1
  130. package/dist/summary/summarizer.js +2 -2
  131. package/dist/summary/summarizer.js.map +1 -1
  132. package/dist/summary/summarizerClientElection.d.ts +2 -2
  133. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  134. package/dist/summary/summarizerClientElection.js.map +1 -1
  135. package/dist/summary/summarizerHeuristics.d.ts +1 -1
  136. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  137. package/dist/summary/summarizerHeuristics.js.map +1 -1
  138. package/dist/summary/summarizerNode/summarizerNode.d.ts +2 -2
  139. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  140. package/dist/summary/summarizerNode/summarizerNode.js +3 -3
  141. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  142. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  143. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  144. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  145. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
  146. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  147. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
  148. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  149. package/dist/summary/summarizerTypes.d.ts +3 -3
  150. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  151. package/dist/summary/summarizerTypes.js.map +1 -1
  152. package/dist/summary/summaryCollection.d.ts +2 -2
  153. package/dist/summary/summaryCollection.d.ts.map +1 -1
  154. package/dist/summary/summaryCollection.js +1 -1
  155. package/dist/summary/summaryCollection.js.map +1 -1
  156. package/dist/summary/summaryFormat.d.ts +5 -16
  157. package/dist/summary/summaryFormat.d.ts.map +1 -1
  158. package/dist/summary/summaryFormat.js.map +1 -1
  159. package/dist/summary/summaryGenerator.d.ts +2 -2
  160. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  161. package/dist/summary/summaryGenerator.js +2 -2
  162. package/dist/summary/summaryGenerator.js.map +1 -1
  163. package/dist/summary/summaryManager.d.ts +1 -1
  164. package/dist/summary/summaryManager.d.ts.map +1 -1
  165. package/dist/summary/summaryManager.js +2 -2
  166. package/dist/summary/summaryManager.js.map +1 -1
  167. package/lib/batchTracker.d.ts +1 -1
  168. package/lib/batchTracker.d.ts.map +1 -1
  169. package/lib/batchTracker.js +2 -2
  170. package/lib/batchTracker.js.map +1 -1
  171. package/lib/blobManager.d.ts +3 -3
  172. package/lib/blobManager.d.ts.map +1 -1
  173. package/lib/blobManager.js +5 -5
  174. package/lib/blobManager.js.map +1 -1
  175. package/lib/channelCollection.d.ts +5 -5
  176. package/lib/channelCollection.d.ts.map +1 -1
  177. package/lib/channelCollection.js +46 -13
  178. package/lib/channelCollection.js.map +1 -1
  179. package/lib/connectionTelemetry.d.ts +2 -2
  180. package/lib/connectionTelemetry.d.ts.map +1 -1
  181. package/lib/connectionTelemetry.js +3 -3
  182. package/lib/connectionTelemetry.js.map +1 -1
  183. package/lib/container-runtime-alpha.d.ts +205 -11
  184. package/lib/container-runtime-beta.d.ts +16 -2
  185. package/lib/container-runtime-public.d.ts +16 -2
  186. package/lib/container-runtime-untrimmed.d.ts +205 -24
  187. package/lib/containerHandleContext.d.ts.map +1 -1
  188. package/lib/containerHandleContext.js.map +1 -1
  189. package/lib/containerRuntime.d.ts +32 -26
  190. package/lib/containerRuntime.d.ts.map +1 -1
  191. package/lib/containerRuntime.js +175 -81
  192. package/lib/containerRuntime.js.map +1 -1
  193. package/lib/dataStore.d.ts +1 -1
  194. package/lib/dataStore.d.ts.map +1 -1
  195. package/lib/dataStore.js +2 -2
  196. package/lib/dataStore.js.map +1 -1
  197. package/lib/dataStoreContext.d.ts +4 -4
  198. package/lib/dataStoreContext.d.ts.map +1 -1
  199. package/lib/dataStoreContext.js +3 -3
  200. package/lib/dataStoreContext.js.map +1 -1
  201. package/lib/dataStoreContexts.d.ts.map +1 -1
  202. package/lib/dataStoreContexts.js.map +1 -1
  203. package/lib/dataStoreRegistry.d.ts.map +1 -1
  204. package/lib/dataStoreRegistry.js.map +1 -1
  205. package/lib/deltaScheduler.d.ts +1 -1
  206. package/lib/deltaScheduler.d.ts.map +1 -1
  207. package/lib/deltaScheduler.js +1 -1
  208. package/lib/deltaScheduler.js.map +1 -1
  209. package/lib/gc/garbageCollection.d.ts +1 -1
  210. package/lib/gc/garbageCollection.d.ts.map +1 -1
  211. package/lib/gc/garbageCollection.js +3 -3
  212. package/lib/gc/garbageCollection.js.map +1 -1
  213. package/lib/gc/gcConfigs.d.ts +1 -1
  214. package/lib/gc/gcConfigs.d.ts.map +1 -1
  215. package/lib/gc/gcConfigs.js +1 -1
  216. package/lib/gc/gcConfigs.js.map +1 -1
  217. package/lib/gc/gcDefinitions.d.ts +1 -1
  218. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  219. package/lib/gc/gcDefinitions.js.map +1 -1
  220. package/lib/gc/gcHelpers.d.ts.map +1 -1
  221. package/lib/gc/gcHelpers.js.map +1 -1
  222. package/lib/gc/gcSummaryStateTracker.d.ts +1 -1
  223. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  224. package/lib/gc/gcSummaryStateTracker.js +1 -1
  225. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  226. package/lib/gc/gcTelemetry.d.ts +1 -1
  227. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  228. package/lib/gc/gcTelemetry.js +1 -1
  229. package/lib/gc/gcTelemetry.js.map +1 -1
  230. package/lib/index.d.ts +2 -2
  231. package/lib/index.d.ts.map +1 -1
  232. package/lib/index.js +2 -2
  233. package/lib/index.js.map +1 -1
  234. package/lib/messageTypes.d.ts +11 -5
  235. package/lib/messageTypes.d.ts.map +1 -1
  236. package/lib/messageTypes.js +4 -0
  237. package/lib/messageTypes.js.map +1 -1
  238. package/lib/opLifecycle/definitions.d.ts +1 -19
  239. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  240. package/lib/opLifecycle/definitions.js.map +1 -1
  241. package/lib/opLifecycle/index.d.ts +3 -3
  242. package/lib/opLifecycle/index.d.ts.map +1 -1
  243. package/lib/opLifecycle/index.js +2 -2
  244. package/lib/opLifecycle/index.js.map +1 -1
  245. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  246. package/lib/opLifecycle/opCompressor.js +2 -3
  247. package/lib/opLifecycle/opCompressor.js.map +1 -1
  248. package/lib/opLifecycle/opDecompressor.d.ts +15 -4
  249. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  250. package/lib/opLifecycle/opDecompressor.js +60 -61
  251. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  252. package/lib/opLifecycle/opGroupingManager.d.ts +2 -1
  253. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  254. package/lib/opLifecycle/opGroupingManager.js +7 -10
  255. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  256. package/lib/opLifecycle/opSplitter.d.ts +11 -3
  257. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  258. package/lib/opLifecycle/opSplitter.js +46 -37
  259. package/lib/opLifecycle/opSplitter.js.map +1 -1
  260. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  261. package/lib/opLifecycle/outbox.js +7 -12
  262. package/lib/opLifecycle/outbox.js.map +1 -1
  263. package/lib/opLifecycle/remoteMessageProcessor.d.ts +8 -0
  264. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  265. package/lib/opLifecycle/remoteMessageProcessor.js +36 -35
  266. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  267. package/lib/packageVersion.d.ts +1 -1
  268. package/lib/packageVersion.js +1 -1
  269. package/lib/packageVersion.js.map +1 -1
  270. package/lib/pendingStateManager.d.ts +1 -1
  271. package/lib/pendingStateManager.d.ts.map +1 -1
  272. package/lib/pendingStateManager.js.map +1 -1
  273. package/lib/scheduleManager.d.ts +1 -1
  274. package/lib/scheduleManager.d.ts.map +1 -1
  275. package/lib/scheduleManager.js +2 -2
  276. package/lib/scheduleManager.js.map +1 -1
  277. package/lib/summary/documentSchema.d.ts +178 -0
  278. package/lib/summary/documentSchema.d.ts.map +1 -0
  279. package/lib/summary/documentSchema.js +341 -0
  280. package/lib/summary/documentSchema.js.map +1 -0
  281. package/lib/summary/index.d.ts +2 -1
  282. package/lib/summary/index.d.ts.map +1 -1
  283. package/lib/summary/index.js +1 -0
  284. package/lib/summary/index.js.map +1 -1
  285. package/lib/summary/orderedClientElection.d.ts +2 -2
  286. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  287. package/lib/summary/orderedClientElection.js +3 -2
  288. package/lib/summary/orderedClientElection.js.map +1 -1
  289. package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -1
  290. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  291. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  292. package/lib/summary/runningSummarizer.d.ts +2 -2
  293. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  294. package/lib/summary/runningSummarizer.js +3 -3
  295. package/lib/summary/runningSummarizer.js.map +1 -1
  296. package/lib/summary/summarizer.d.ts +2 -2
  297. package/lib/summary/summarizer.d.ts.map +1 -1
  298. package/lib/summary/summarizer.js +3 -3
  299. package/lib/summary/summarizer.js.map +1 -1
  300. package/lib/summary/summarizerClientElection.d.ts +2 -2
  301. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  302. package/lib/summary/summarizerClientElection.js.map +1 -1
  303. package/lib/summary/summarizerHeuristics.d.ts +1 -1
  304. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  305. package/lib/summary/summarizerHeuristics.js.map +1 -1
  306. package/lib/summary/summarizerNode/summarizerNode.d.ts +2 -2
  307. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  308. package/lib/summary/summarizerNode/summarizerNode.js +4 -4
  309. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  310. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  311. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  312. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  313. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
  314. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  315. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
  316. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  317. package/lib/summary/summarizerTypes.d.ts +3 -3
  318. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  319. package/lib/summary/summarizerTypes.js.map +1 -1
  320. package/lib/summary/summaryCollection.d.ts +2 -2
  321. package/lib/summary/summaryCollection.d.ts.map +1 -1
  322. package/lib/summary/summaryCollection.js +1 -1
  323. package/lib/summary/summaryCollection.js.map +1 -1
  324. package/lib/summary/summaryFormat.d.ts +5 -16
  325. package/lib/summary/summaryFormat.d.ts.map +1 -1
  326. package/lib/summary/summaryFormat.js +1 -1
  327. package/lib/summary/summaryFormat.js.map +1 -1
  328. package/lib/summary/summaryGenerator.d.ts +2 -2
  329. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  330. package/lib/summary/summaryGenerator.js +3 -3
  331. package/lib/summary/summaryGenerator.js.map +1 -1
  332. package/lib/summary/summaryManager.d.ts +1 -1
  333. package/lib/summary/summaryManager.d.ts.map +1 -1
  334. package/lib/summary/summaryManager.js +2 -2
  335. package/lib/summary/summaryManager.js.map +1 -1
  336. package/lib/test/blobManager.spec.js +3 -3
  337. package/lib/test/blobManager.spec.js.map +1 -1
  338. package/lib/test/containerRuntime.spec.js +6 -4
  339. package/lib/test/containerRuntime.spec.js.map +1 -1
  340. package/lib/test/dataStoreContext.spec.js +4 -4
  341. package/lib/test/dataStoreContext.spec.js.map +1 -1
  342. package/lib/test/dataStoreCreation.spec.js +1 -1
  343. package/lib/test/dataStoreCreation.spec.js.map +1 -1
  344. package/lib/test/dataStoreRegistry.spec.js.map +1 -1
  345. package/lib/test/documentSchema.spec.js +282 -0
  346. package/lib/test/documentSchema.spec.js.map +1 -0
  347. package/lib/test/fuzz/fuzzUtils.js +11 -7
  348. package/lib/test/fuzz/fuzzUtils.js.map +1 -1
  349. package/lib/test/fuzz/summarizer.fuzz.spec.js +9 -7
  350. package/lib/test/fuzz/summarizer.fuzz.spec.js.map +1 -1
  351. package/lib/test/fuzz/summarizerFuzzMocks.js +43 -25
  352. package/lib/test/fuzz/summarizerFuzzMocks.js.map +1 -1
  353. package/lib/test/fuzz/summarizerFuzzSuite.js +7 -4
  354. package/lib/test/fuzz/summarizerFuzzSuite.js.map +1 -1
  355. package/lib/test/gc/garbageCollection.spec.js +5 -5
  356. package/lib/test/gc/garbageCollection.spec.js.map +1 -1
  357. package/lib/test/gc/gcConfigs.spec.js +2 -2
  358. package/lib/test/gc/gcConfigs.spec.js.map +1 -1
  359. package/lib/test/gc/gcHelpers.spec.js.map +1 -1
  360. package/lib/test/gc/gcStats.spec.js +2 -2
  361. package/lib/test/gc/gcStats.spec.js.map +1 -1
  362. package/lib/test/gc/gcSummaryStateTracker.spec.js +1 -1
  363. package/lib/test/gc/gcSummaryStateTracker.spec.js.map +1 -1
  364. package/lib/test/gc/gcTelemetry.spec.js +3 -3
  365. package/lib/test/gc/gcTelemetry.spec.js.map +1 -1
  366. package/lib/test/gc/gcUnreferencedStateTracker.spec.js +1 -1
  367. package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +1 -1
  368. package/lib/test/getPendingBlobs.spec.js +1 -1
  369. package/lib/test/getPendingBlobs.spec.js.map +1 -1
  370. package/lib/test/hardwareStats.spec.js +1 -1
  371. package/lib/test/hardwareStats.spec.js.map +1 -1
  372. package/lib/test/opLifecycle/OpGroupingManager.spec.js +95 -118
  373. package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +1 -1
  374. package/lib/test/opLifecycle/batchManager.spec.js +1 -1
  375. package/lib/test/opLifecycle/batchManager.spec.js.map +1 -1
  376. package/lib/test/opLifecycle/opCompressor.spec.js +0 -1
  377. package/lib/test/opLifecycle/opCompressor.spec.js.map +1 -1
  378. package/lib/test/opLifecycle/opDecompressor.spec.js +60 -55
  379. package/lib/test/opLifecycle/opDecompressor.spec.js.map +1 -1
  380. package/lib/test/opLifecycle/opSplitter.spec.js +56 -41
  381. package/lib/test/opLifecycle/opSplitter.spec.js.map +1 -1
  382. package/lib/test/opLifecycle/outbox.spec.js +118 -10
  383. package/lib/test/opLifecycle/outbox.spec.js.map +1 -1
  384. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +115 -91
  385. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +1 -1
  386. package/lib/test/pendingStateManager.spec.js +1 -1
  387. package/lib/test/pendingStateManager.spec.js.map +1 -1
  388. package/lib/test/scheduleManager.spec.js +1 -1
  389. package/lib/test/scheduleManager.spec.js.map +1 -1
  390. package/lib/test/summarizerNode.spec.js +1 -1
  391. package/lib/test/summarizerNode.spec.js.map +1 -1
  392. package/lib/test/summarizerNodeWithGc.spec.js +1 -1
  393. package/lib/test/summarizerNodeWithGc.spec.js.map +1 -1
  394. package/lib/test/summary/runningSummarizer.spec.js +4 -4
  395. package/lib/test/summary/runningSummarizer.spec.js.map +1 -1
  396. package/lib/test/summary/summarizer.spec.js.map +1 -1
  397. package/lib/test/summary/summarizerClientElection.spec.js +2 -2
  398. package/lib/test/summary/summarizerClientElection.spec.js.map +1 -1
  399. package/lib/test/summary/summarizerHeuristics.spec.js +1 -1
  400. package/lib/test/summary/summarizerHeuristics.spec.js.map +1 -1
  401. package/lib/test/summary/summaryCollection.spec.js +1 -1
  402. package/lib/test/summary/summaryCollection.spec.js.map +1 -1
  403. package/lib/test/summary/summaryManager.spec.js +3 -3
  404. package/lib/test/summary/summaryManager.spec.js.map +1 -1
  405. package/lib/test/throttler.spec.js +1 -1
  406. package/lib/test/throttler.spec.js.map +1 -1
  407. package/lib/test/types/validateContainerRuntimePrevious.generated.js +6 -4
  408. package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +1 -1
  409. package/package.json +35 -21
  410. package/src/batchTracker.ts +3 -3
  411. package/src/blobManager.ts +15 -15
  412. package/src/channelCollection.ts +75 -35
  413. package/src/connectionTelemetry.ts +10 -10
  414. package/src/containerHandleContext.ts +1 -1
  415. package/src/containerRuntime.ts +352 -197
  416. package/src/dataStore.ts +2 -2
  417. package/src/dataStoreContext.ts +19 -19
  418. package/src/dataStoreContexts.ts +2 -2
  419. package/src/dataStoreRegistry.ts +1 -1
  420. package/src/deltaScheduler.ts +1 -1
  421. package/src/gc/garbageCollection.ts +12 -12
  422. package/src/gc/gcConfigs.ts +11 -11
  423. package/src/gc/gcDefinitions.ts +2 -2
  424. package/src/gc/gcHelpers.ts +2 -2
  425. package/src/gc/gcSummaryStateTracker.ts +4 -4
  426. package/src/gc/gcTelemetry.ts +6 -6
  427. package/src/index.ts +8 -1
  428. package/src/messageTypes.ts +18 -5
  429. package/src/opLifecycle/README.md +89 -0
  430. package/src/opLifecycle/definitions.ts +1 -20
  431. package/src/opLifecycle/index.ts +3 -9
  432. package/src/opLifecycle/opCompressor.ts +4 -5
  433. package/src/opLifecycle/opDecompressor.ts +83 -100
  434. package/src/opLifecycle/opGroupingManager.ts +9 -12
  435. package/src/opLifecycle/opSplitter.ts +73 -47
  436. package/src/opLifecycle/outbox.ts +13 -31
  437. package/src/opLifecycle/remoteMessageProcessor.ts +41 -59
  438. package/src/packageVersion.ts +1 -1
  439. package/src/pendingStateManager.ts +2 -2
  440. package/src/scheduleManager.ts +7 -7
  441. package/src/summary/documentSchema.ts +553 -0
  442. package/src/summary/index.ts +10 -1
  443. package/src/summary/orderedClientElection.ts +6 -5
  444. package/src/summary/runWhileConnectedCoordinator.ts +1 -1
  445. package/src/summary/runningSummarizer.ts +19 -19
  446. package/src/summary/summarizer.ts +14 -14
  447. package/src/summary/summarizerClientElection.ts +2 -2
  448. package/src/summary/summarizerHeuristics.ts +2 -2
  449. package/src/summary/summarizerNode/summarizerNode.ts +15 -15
  450. package/src/summary/summarizerNode/summarizerNodeUtils.ts +1 -1
  451. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +4 -4
  452. package/src/summary/summarizerTypes.ts +3 -3
  453. package/src/summary/summaryCollection.ts +3 -3
  454. package/src/summary/summaryFormat.ts +8 -19
  455. package/src/summary/summaryGenerator.ts +10 -10
  456. package/src/summary/summaryManager.ts +4 -4
@@ -3,15 +3,14 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { decompress } from "lz4js";
7
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
- import { assert } from "@fluidframework/core-utils";
9
6
  import { IsoBuffer, Uint8ArrayToString } from "@fluid-internal/client-utils";
10
- import { createChildLogger } from "@fluidframework/telemetry-utils";
11
7
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
+ import { assert } from "@fluidframework/core-utils";
9
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
10
+ import { createChildLogger } from "@fluidframework/telemetry-utils";
11
+ import { decompress } from "lz4js";
12
12
  import { CompressionAlgorithms } from "../containerRuntime.js";
13
13
  import { IBatchMetadata } from "../metadata.js";
14
- import { IMessageProcessingResult } from "./definitions.js";
15
14
 
16
15
  /**
17
16
  * Compression makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
@@ -38,100 +37,7 @@ export class OpDecompressor {
38
37
  this.logger = createChildLogger({ logger, namespace: "OpDecompressor" });
39
38
  }
40
39
 
41
- public processMessage(message: ISequencedDocumentMessage): IMessageProcessingResult {
42
- assert(
43
- message.compression === undefined || message.compression === CompressionAlgorithms.lz4,
44
- 0x511 /* Only lz4 compression is supported */,
45
- );
46
-
47
- if (
48
- (message.metadata as IBatchMetadata | undefined)?.batch === true &&
49
- this.isCompressed(message)
50
- ) {
51
- // Beginning of a compressed batch
52
- assert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);
53
- this.activeBatch = true;
54
-
55
- const contents = IsoBuffer.from(
56
- (message.contents as IPackedContentsContents).packedContents,
57
- "base64",
58
- );
59
- const decompressedMessage = decompress(contents);
60
- const intoString = Uint8ArrayToString(decompressedMessage);
61
- const asObj = JSON.parse(intoString);
62
- this.rootMessageContents = asObj;
63
-
64
- return {
65
- message: newMessage(message, this.rootMessageContents[this.processedCount++]),
66
- state: "Accepted",
67
- };
68
- }
69
-
70
- if (
71
- this.rootMessageContents !== undefined &&
72
- (message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
73
- this.activeBatch
74
- ) {
75
- assert(message.contents === undefined, 0x512 /* Expecting empty message */);
76
-
77
- // Continuation of compressed batch
78
- return {
79
- message: newMessage(message, this.rootMessageContents[this.processedCount++]),
80
- state: "Accepted",
81
- };
82
- }
83
-
84
- if (
85
- this.rootMessageContents !== undefined &&
86
- (message.metadata as IBatchMetadata | undefined)?.batch === false
87
- ) {
88
- // End of compressed batch
89
- const returnMessage = newMessage(
90
- message,
91
- this.rootMessageContents[this.processedCount++],
92
- );
93
-
94
- this.activeBatch = false;
95
- this.rootMessageContents = undefined;
96
- this.processedCount = 0;
97
-
98
- return {
99
- message: returnMessage,
100
- state: "Processed",
101
- };
102
- }
103
-
104
- if (
105
- (message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
106
- this.isCompressed(message)
107
- ) {
108
- // Single compressed message
109
- assert(
110
- this.activeBatch === false,
111
- 0x4ba /* shouldn't receive compressed message in middle of a batch */,
112
- );
113
-
114
- const contents = IsoBuffer.from(
115
- (message.contents as IPackedContentsContents).packedContents,
116
- "base64",
117
- );
118
- const decompressedMessage = decompress(contents);
119
- const intoString = new TextDecoder().decode(decompressedMessage);
120
- const asObj = JSON.parse(intoString);
121
-
122
- return {
123
- message: newMessage(message, asObj[0]),
124
- state: "Processed",
125
- };
126
- }
127
-
128
- return {
129
- message,
130
- state: "Skipped",
131
- };
132
- }
133
-
134
- private isCompressed(message: ISequencedDocumentMessage) {
40
+ public isCompressedMessage(message: ISequencedDocumentMessage): boolean {
135
41
  if (message.compression === CompressionAlgorithms.lz4) {
136
42
  return true;
137
43
  }
@@ -174,6 +80,80 @@ export class OpDecompressor {
174
80
 
175
81
  return false;
176
82
  }
83
+
84
+ public get currentlyUnrolling() {
85
+ return this.activeBatch;
86
+ }
87
+
88
+ /** Is the decompressed and stored batch only comprised of a single message */
89
+ private isSingleMessageBatch = false;
90
+
91
+ /**
92
+ * Decompress the given compressed message and store it to be subsequently unrolled.
93
+ * The stored message will be of type `any[]` where each element represents a message's `contents`
94
+ */
95
+ public decompressAndStore(message: ISequencedDocumentMessage): void {
96
+ assert(
97
+ message.compression === undefined || message.compression === CompressionAlgorithms.lz4,
98
+ 0x511 /* Only lz4 compression is supported */,
99
+ );
100
+ assert(this.isCompressedMessage(message), "provided message should be compressed");
101
+
102
+ assert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);
103
+ this.activeBatch = true;
104
+
105
+ const batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;
106
+ if (batchMetadata === undefined) {
107
+ this.isSingleMessageBatch = true;
108
+ } else {
109
+ assert(batchMetadata === true, "invalid batch metadata");
110
+ }
111
+
112
+ const contents = IsoBuffer.from(
113
+ (message.contents as IPackedContentsContents).packedContents,
114
+ "base64",
115
+ );
116
+ const decompressedMessage = decompress(contents);
117
+ const intoString = Uint8ArrayToString(decompressedMessage);
118
+ const asObj = JSON.parse(intoString);
119
+ this.rootMessageContents = asObj;
120
+ }
121
+
122
+ /**
123
+ * Unroll the next message from the decompressed content provided to {@link decompressAndStore}
124
+ * @returns the unrolled `ISequencedDocumentMessage`
125
+ */
126
+ public unroll(message: ISequencedDocumentMessage): ISequencedDocumentMessage {
127
+ assert(this.currentlyUnrolling, "not currently unrolling");
128
+ assert(this.rootMessageContents !== undefined, "missing rootMessageContents");
129
+ assert(this.rootMessageContents.length > this.processedCount, "no more content to unroll");
130
+
131
+ const batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;
132
+
133
+ if (batchMetadata === false || this.isSingleMessageBatch) {
134
+ // End of compressed batch
135
+ const returnMessage = newMessage(
136
+ message,
137
+ this.rootMessageContents[this.processedCount],
138
+ );
139
+
140
+ this.activeBatch = false;
141
+ this.isSingleMessageBatch = false;
142
+ this.rootMessageContents = undefined;
143
+ this.processedCount = 0;
144
+
145
+ return returnMessage;
146
+ } else if (batchMetadata === true) {
147
+ // Start of compressed batch
148
+ return newMessage(message, this.rootMessageContents[this.processedCount++]);
149
+ }
150
+
151
+ assert(batchMetadata === undefined, "invalid batch metadata");
152
+ assert(message.contents === undefined, 0x512 /* Expecting empty message */);
153
+
154
+ // Continuation of compressed batch
155
+ return newMessage(message, this.rootMessageContents[this.processedCount++]);
156
+ }
177
157
  }
178
158
 
179
159
  // We should not be mutating the input message nor its metadata
@@ -186,5 +166,8 @@ const newMessage = (
186
166
  compression: undefined,
187
167
  // TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.
188
168
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
189
- metadata: { ...(originalMessage.metadata as any) },
169
+ metadata:
170
+ originalMessage.metadata === undefined
171
+ ? undefined
172
+ : { ...(originalMessage.metadata as any) },
190
173
  });
@@ -3,11 +3,10 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
6
7
  import { assert } from "@fluidframework/core-utils";
7
8
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
9
  import { createChildLogger } from "@fluidframework/telemetry-utils";
9
- import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
10
- import { ContainerMessageType } from "../messageTypes.js";
11
10
  import { IBatch } from "./definitions.js";
12
11
 
13
12
  /**
@@ -28,6 +27,10 @@ function isGroupContents(opContents: any): opContents is IGroupedBatchMessageCon
28
27
  return opContents?.type === OpGroupingManager.groupedBatchOp;
29
28
  }
30
29
 
30
+ export function isGroupedBatch(op: ISequencedDocumentMessage): boolean {
31
+ return isGroupContents(op.contents);
32
+ }
33
+
31
34
  export interface OpGroupingManagerConfig {
32
35
  readonly groupedBatchingEnabled: boolean;
33
36
  readonly opCountThreshold: number;
@@ -46,9 +49,7 @@ export class OpGroupingManager {
46
49
  }
47
50
 
48
51
  public groupBatch(batch: IBatch): IBatch {
49
- if (!this.shouldGroup(batch)) {
50
- return batch;
51
- }
52
+ assert(this.shouldGroup(batch), "cannot group the provided batch");
52
53
 
53
54
  if (batch.content.length >= 1000) {
54
55
  this.logger.sendTelemetryEvent({
@@ -84,11 +85,9 @@ export class OpGroupingManager {
84
85
  ...batch,
85
86
  content: [
86
87
  {
87
- localOpMetadata: undefined,
88
88
  metadata: undefined,
89
89
  referenceSequenceNumber: batch.content[0].referenceSequenceNumber,
90
90
  contents: serializedContent,
91
- type: OpGroupingManager.groupedBatchOp as ContainerMessageType,
92
91
  },
93
92
  ],
94
93
  };
@@ -96,13 +95,11 @@ export class OpGroupingManager {
96
95
  }
97
96
 
98
97
  public ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {
99
- if (!isGroupContents(op.contents)) {
100
- return [op];
101
- }
98
+ assert(isGroupContents(op.contents), "can only ungroup a grouped batch");
99
+ const contents: IGroupedBatchMessageContents = op.contents;
102
100
 
103
- const messages = op.contents.contents;
104
101
  let fakeCsn = 1;
105
- return messages.map((subMessage) => ({
102
+ return contents.contents.map((subMessage) => ({
106
103
  ...op,
107
104
  clientSequenceNumber: fakeCsn++,
108
105
  contents: subMessage.contents,
@@ -3,18 +3,31 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { IBatchMessage } from "@fluidframework/container-definitions";
7
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
+ import { assert } from "@fluidframework/core-utils";
9
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
6
10
  import {
7
- createChildLogger,
8
11
  DataCorruptionError,
12
+ createChildLogger,
9
13
  extractSafePropertiesFromMessage,
10
14
  } from "@fluidframework/telemetry-utils";
11
- import { assert } from "@fluidframework/core-utils";
12
- import { IBatchMessage } from "@fluidframework/container-definitions";
13
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
14
- import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
15
15
  import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes.js";
16
16
  import { estimateSocketSize } from "./batchManager.js";
17
- import { BatchMessage, IBatch, IChunkedOp, IMessageProcessingResult } from "./definitions.js";
17
+ import { BatchMessage, IBatch, IChunkedOp } from "./definitions.js";
18
+
19
+ export function isChunkedMessage(message: ISequencedDocumentMessage): boolean {
20
+ return isChunkedContents(message.contents);
21
+ }
22
+
23
+ interface IChunkedContents {
24
+ type: typeof ContainerMessageType.ChunkedOp;
25
+ contents: IChunkedOp;
26
+ }
27
+
28
+ function isChunkedContents(contents: any): contents is IChunkedContents {
29
+ return contents?.type === ContainerMessageType.ChunkedOp;
30
+ }
18
31
 
19
32
  /**
20
33
  * Responsible for creating and reconstructing chunked messages.
@@ -45,44 +58,6 @@ export class OpSplitter {
45
58
  return this.chunkMap;
46
59
  }
47
60
 
48
- public processRemoteMessage(message: ISequencedDocumentMessage): IMessageProcessingResult {
49
- if (message.type !== ContainerMessageType.ChunkedOp) {
50
- return {
51
- message,
52
- state: "Skipped",
53
- };
54
- }
55
-
56
- // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
57
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
58
- const clientId = message.clientId as string;
59
- const chunkedContent = message.contents as IChunkedOp;
60
- this.addChunk(clientId, chunkedContent, message);
61
-
62
- if (chunkedContent.chunkId < chunkedContent.totalChunks) {
63
- // We are processing the op in chunks but haven't reached
64
- // the last chunk yet in order to reconstruct the original op
65
- return {
66
- message,
67
- state: "Accepted",
68
- };
69
- }
70
-
71
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
72
- const serializedContent = this.chunkMap.get(clientId)!.join("");
73
- this.clearPartialChunks(clientId);
74
-
75
- const newMessage = { ...message };
76
- newMessage.contents = serializedContent === "" ? undefined : JSON.parse(serializedContent);
77
- newMessage.type = chunkedContent.originalType;
78
- newMessage.metadata = chunkedContent.originalMetadata;
79
- newMessage.compression = chunkedContent.originalCompression;
80
- return {
81
- message: newMessage,
82
- state: "Processed",
83
- };
84
- }
85
-
86
61
  public clearPartialChunks(clientId: string) {
87
62
  if (this.chunkMap.has(clientId)) {
88
63
  this.chunkMap.delete(clientId);
@@ -203,8 +178,53 @@ export class OpSplitter {
203
178
  referenceSequenceNumber: batch.referenceSequenceNumber,
204
179
  };
205
180
  }
181
+
182
+ public processChunk(message: ISequencedDocumentMessage): ProcessChunkResult {
183
+ assert(isChunkedContents(message.contents), "message not of type ChunkedOp");
184
+ const contents: IChunkedContents = message.contents;
185
+
186
+ // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
187
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
188
+ const clientId = message.clientId as string;
189
+ const chunkedContent = contents.contents;
190
+ this.addChunk(clientId, chunkedContent, message);
191
+
192
+ if (chunkedContent.chunkId < chunkedContent.totalChunks) {
193
+ // We are processing the op in chunks but haven't reached
194
+ // the last chunk yet in order to reconstruct the original op
195
+ return {
196
+ isFinalChunk: false,
197
+ };
198
+ }
199
+
200
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
201
+ const serializedContent = this.chunkMap.get(clientId)!.join("");
202
+ this.clearPartialChunks(clientId);
203
+
204
+ const newMessage = { ...message };
205
+ newMessage.contents = serializedContent === "" ? undefined : JSON.parse(serializedContent);
206
+ // back-compat with 1.x builds
207
+ // This is only required / present for non-compressed, chunked ops
208
+ // For compressed ops, we have op grouping enabled, and type of each op is preserved within compressed content.
209
+ newMessage.type = (chunkedContent as any).originalType;
210
+ newMessage.metadata = chunkedContent.originalMetadata;
211
+ newMessage.compression = chunkedContent.originalCompression;
212
+ return {
213
+ message: newMessage,
214
+ isFinalChunk: true,
215
+ };
216
+ }
206
217
  }
207
218
 
219
+ type ProcessChunkResult =
220
+ | {
221
+ readonly isFinalChunk: false;
222
+ }
223
+ | {
224
+ readonly isFinalChunk: true;
225
+ readonly message: ISequencedDocumentMessage;
226
+ };
227
+
208
228
  const chunkToBatchMessage = (
209
229
  chunk: IChunkedOp,
210
230
  referenceSequenceNumber: number,
@@ -216,9 +236,7 @@ const chunkToBatchMessage = (
216
236
  };
217
237
  return {
218
238
  contents: JSON.stringify(payload),
219
- type: payload.type,
220
239
  metadata,
221
- localOpMetadata: undefined,
222
240
  referenceSequenceNumber,
223
241
  };
224
242
  };
@@ -253,7 +271,6 @@ export const splitOp = (
253
271
  const chunk: IChunkedOp = {
254
272
  chunkId,
255
273
  contents: op.contents.substr(offset, chunkSizeInBytes),
256
- originalType: op.type,
257
274
  totalChunks: chunkCount,
258
275
  };
259
276
 
@@ -263,6 +280,15 @@ export const splitOp = (
263
280
  // last chunk, therefore it is the only one that needs it.
264
281
  chunk.originalMetadata = op.metadata;
265
282
  chunk.originalCompression = op.compression;
283
+
284
+ // back-compat with 1.x builds
285
+ // 2.x builds only do chunking for compressed ops.
286
+ // originalType is no longer used in such cases, as each op preserves its type within compressed payload.
287
+ // But, if 1.x builds see this op, and there is no type on the message, then it will ignore this message silently.
288
+ // This is really bad, as we will crash on later ops and it's very hard to debug these cases.
289
+ // If we put some known type here, then we will crash on it (as 1.x does not understand compression, and thus will not
290
+ // find info on the op like address of the channel to deliver the op)
291
+ (chunk as any).originalType = "component";
266
292
  }
267
293
 
268
294
  chunks.push(chunk);
@@ -3,18 +3,17 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { IBatchMessage, ICriticalContainerError } from "@fluidframework/container-definitions";
7
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
+ import { assert } from "@fluidframework/core-utils";
6
9
  import {
7
- createChildMonitoringContext,
8
10
  GenericError,
9
11
  MonitoringContext,
10
12
  UsageError,
13
+ createChildMonitoringContext,
11
14
  } from "@fluidframework/telemetry-utils";
12
- import { assert } from "@fluidframework/core-utils";
13
- import { IBatchMessage, ICriticalContainerError } from "@fluidframework/container-definitions";
14
- import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
15
15
  import { ICompressionRuntimeOptions } from "../containerRuntime.js";
16
16
  import { IPendingBatchMessage, PendingStateManager } from "../pendingStateManager.js";
17
- import { ContainerMessageType } from "../messageTypes.js";
18
17
  import {
19
18
  BatchManager,
20
19
  BatchSequenceNumbers,
@@ -187,20 +186,12 @@ export class Outbox {
187
186
  }
188
187
 
189
188
  public submit(message: BatchMessage) {
190
- assert(
191
- message.type !== ContainerMessageType.IdAllocation,
192
- 0x8f8 /* Allocation message submitted to mainBatch. */,
193
- );
194
189
  this.maybeFlushPartialBatch();
195
190
 
196
191
  this.addMessageToBatchManager(this.mainBatch, message);
197
192
  }
198
193
 
199
194
  public submitAttach(message: BatchMessage) {
200
- assert(
201
- message.type === ContainerMessageType.Attach,
202
- 0x8f9 /* Non attach message submitted to attachFlowBatch. */,
203
- );
204
195
  this.maybeFlushPartialBatch();
205
196
 
206
197
  if (
@@ -232,10 +223,6 @@ export class Outbox {
232
223
  }
233
224
 
234
225
  public submitBlobAttach(message: BatchMessage) {
235
- assert(
236
- message.type === ContainerMessageType.BlobAttach,
237
- 0x8fa /* Non blobAttach message submitted to blobAttachBatch. */,
238
- );
239
226
  this.maybeFlushPartialBatch();
240
227
 
241
228
  this.addMessageToBatchManager(this.blobAttachBatch, message);
@@ -254,10 +241,6 @@ export class Outbox {
254
241
  }
255
242
 
256
243
  public submitIdAllocation(message: BatchMessage) {
257
- assert(
258
- message.type === ContainerMessageType.IdAllocation,
259
- 0x8fb /* Non allocation message submitted to idAllocationBatch. */,
260
- );
261
244
  this.maybeFlushPartialBatch();
262
245
 
263
246
  if (
@@ -328,10 +311,9 @@ export class Outbox {
328
311
  }
329
312
 
330
313
  const rawBatch = batchManager.popBatch();
331
- if (
332
- rawBatch.hasReentrantOps === true &&
333
- this.params.groupingManager.shouldGroup(rawBatch)
334
- ) {
314
+ const shouldGroup =
315
+ !disableGroupedBatching && this.params.groupingManager.shouldGroup(rawBatch);
316
+ if (rawBatch.hasReentrantOps === true && shouldGroup) {
335
317
  assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
336
318
  // If a batch contains reentrant ops (ops created as a result from processing another op)
337
319
  // it needs to be rebased so that we can ensure consistent reference sequence numbers
@@ -344,7 +326,9 @@ export class Outbox {
344
326
  // If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
345
327
  // Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.
346
328
  if (this.params.shouldSend()) {
347
- const processedBatch = this.compressBatch(rawBatch, disableGroupedBatching);
329
+ const processedBatch = this.compressBatch(
330
+ shouldGroup ? this.params.groupingManager.groupBatch(rawBatch) : rawBatch,
331
+ );
348
332
  this.sendBatch(processedBatch);
349
333
  }
350
334
 
@@ -390,7 +374,7 @@ export class Outbox {
390
374
  return this.params.opReentrancy() && !this.rebasing;
391
375
  }
392
376
 
393
- private compressBatch(batch: IBatch, disableGroupedBatching: boolean): IBatch {
377
+ private compressBatch(batch: IBatch): IBatch {
394
378
  if (
395
379
  batch.content.length === 0 ||
396
380
  this.params.config.compressionOptions === undefined ||
@@ -399,12 +383,10 @@ export class Outbox {
399
383
  this.params.submitBatchFn === undefined
400
384
  ) {
401
385
  // Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
402
- return disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch);
386
+ return batch;
403
387
  }
404
388
 
405
- const compressedBatch = this.params.compressor.compressBatch(
406
- disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch),
407
- );
389
+ const compressedBatch = this.params.compressor.compressBatch(batch);
408
390
 
409
391
  if (this.params.splitter.isBatchChunkingEnabled) {
410
392
  return compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes
@@ -12,8 +12,8 @@ import {
12
12
  type InboundSequencedRecentlyAddedContainerRuntimeMessage,
13
13
  } from "../messageTypes.js";
14
14
  import { OpDecompressor } from "./opDecompressor.js";
15
- import { OpGroupingManager } from "./opGroupingManager.js";
16
- import { OpSplitter } from "./opSplitter.js";
15
+ import { OpGroupingManager, isGroupedBatch } from "./opGroupingManager.js";
16
+ import { OpSplitter, isChunkedMessage } from "./opSplitter.js";
17
17
 
18
18
  /**
19
19
  * Stateful class for processing incoming remote messages as the virtualization measures are unwrapped,
@@ -44,6 +44,14 @@ export class RemoteMessageProcessor {
44
44
  * depends on this object instance.
45
45
  * Note remoteMessageCopy.contents (and other object props) MUST not be modified,
46
46
  * but may be overwritten (as is the case with contents).
47
+ *
48
+ * Incoming messages will always have compression, chunking, and grouped batching happen in a defined order and that order cannot be changed.
49
+ * When processing these messages, the order is:
50
+ * 1. If chunked, process the chunk and only continue if this is a final chunk
51
+ * 2. If compressed, decompress the message and store for further unrolling of the decompressed content
52
+ * 3. If grouped, ungroup the message
53
+ * For more details, see https://github.com/microsoft/FluidFramework/blob/main/packages/runtime/container-runtime/src/opLifecycle/README.md#inbound
54
+ *
47
55
  * @returns the unchunked, decompressed, ungrouped, unpacked SequencedContainerRuntimeMessages encapsulated in the remote message.
48
56
  * For ops that weren't virtualized (e.g. System ops that the ContainerRuntime will ultimately ignore),
49
57
  * a singleton array [remoteMessageCopy] is returned
@@ -51,63 +59,38 @@ export class RemoteMessageProcessor {
51
59
  public process(
52
60
  remoteMessageCopy: ISequencedDocumentMessage,
53
61
  ): InboundSequencedContainerRuntimeMessageOrSystemMessage[] {
54
- const result: InboundSequencedContainerRuntimeMessageOrSystemMessage[] = [];
55
-
56
- ensureContentsDeserialized(remoteMessageCopy);
57
-
58
- // Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)
59
- for (const ungroupedMessage of this.opGroupingManager.ungroupOp(remoteMessageCopy)) {
60
- const message = this.opDecompressor.processMessage(ungroupedMessage).message;
61
-
62
- for (let ungroupedMessage2 of this.opGroupingManager.ungroupOp(message)) {
63
- // unpack and unchunk the ungrouped message in place
64
- unpackRuntimeMessage(ungroupedMessage2);
65
- const chunkProcessingResult =
66
- this.opSplitter.processRemoteMessage(ungroupedMessage2);
67
- ungroupedMessage2 = chunkProcessingResult.message;
68
-
69
- // if the splitter is still rebuilding the original message, there is no need to continue processing
70
- if (chunkProcessingResult.state === "Accepted") {
71
- continue;
72
- }
73
-
74
- // If the message is not chunked there is no need to continue processing
75
- if (chunkProcessingResult.state !== "Processed") {
76
- result.push(
77
- ungroupedMessage2 as InboundSequencedContainerRuntimeMessageOrSystemMessage,
78
- );
79
- continue;
80
- }
81
-
82
- // Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)
83
- for (const ungroupedMessageAfterChunking of this.opGroupingManager.ungroupOp(
84
- ungroupedMessage2,
85
- )) {
86
- const decompressionAfterChunking = this.opDecompressor.processMessage(
87
- ungroupedMessageAfterChunking,
88
- );
89
-
90
- for (const ungroupedMessageAfterChunking2 of this.opGroupingManager.ungroupOp(
91
- decompressionAfterChunking.message,
92
- )) {
93
- if (decompressionAfterChunking.state === "Skipped") {
94
- // After chunking, if the original message was not compressed,
95
- // there is no need to continue processing
96
- result.push(
97
- ungroupedMessageAfterChunking2 as InboundSequencedContainerRuntimeMessageOrSystemMessage,
98
- );
99
- continue;
100
- }
101
-
102
- // The message needs to be unpacked after chunking + decompression
103
- unpack(ungroupedMessageAfterChunking2);
104
- result.push(ungroupedMessageAfterChunking2);
105
- }
106
- }
62
+ let message = remoteMessageCopy;
63
+ ensureContentsDeserialized(message);
64
+
65
+ if (isChunkedMessage(message)) {
66
+ const chunkProcessingResult = this.opSplitter.processChunk(message);
67
+ // Only continue further if current chunk is the final chunk
68
+ if (!chunkProcessingResult.isFinalChunk) {
69
+ return [];
107
70
  }
71
+ // This message will always be compressed
72
+ message = chunkProcessingResult.message;
108
73
  }
109
74
 
110
- return result;
75
+ if (this.opDecompressor.isCompressedMessage(message)) {
76
+ this.opDecompressor.decompressAndStore(message);
77
+ }
78
+
79
+ if (this.opDecompressor.currentlyUnrolling) {
80
+ message = this.opDecompressor.unroll(message);
81
+ // Need to unpack after unrolling if not a groupedBatch
82
+ if (!isGroupedBatch(message)) {
83
+ unpack(message);
84
+ }
85
+ }
86
+
87
+ if (isGroupedBatch(message)) {
88
+ return this.opGroupingManager.ungroupOp(message).map(unpack);
89
+ }
90
+
91
+ // Do a final unpack of runtime messages in case the message was not grouped, compressed, or chunked
92
+ unpackRuntimeMessage(message);
93
+ return [message as InboundSequencedContainerRuntimeMessageOrSystemMessage];
111
94
  }
112
95
  }
113
96
 
@@ -128,9 +111,7 @@ function ensureContentsDeserialized(mutableMessage: ISequencedDocumentMessage):
128
111
  * becomes a InboundSequencedContainerRuntimeMessage by the time the function returns
129
112
  * (but there is no runtime validation of the 'type' or 'compatDetails' values).
130
113
  */
131
- function unpack(
132
- message: ISequencedDocumentMessage,
133
- ): asserts message is InboundSequencedContainerRuntimeMessage {
114
+ function unpack(message: ISequencedDocumentMessage): InboundSequencedContainerRuntimeMessage {
134
115
  // We assume the contents is an InboundContainerRuntimeMessage (the message is "packed")
135
116
  const contents = message.contents as InboundContainerRuntimeMessage;
136
117
 
@@ -143,6 +124,7 @@ function unpack(
143
124
  (messageUnpacked as InboundSequencedRecentlyAddedContainerRuntimeMessage).compatDetails =
144
125
  contents.compatDetails;
145
126
  }
127
+ return messageUnpacked;
146
128
  }
147
129
 
148
130
  /**