@fluidframework/container-runtime 2.31.1 → 2.33.0-333010

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 (301) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/container-runtime.test-files.tar +0 -0
  3. package/dist/channelCollection.d.ts +0 -14
  4. package/dist/channelCollection.d.ts.map +1 -1
  5. package/dist/channelCollection.js +10 -25
  6. package/dist/channelCollection.js.map +1 -1
  7. package/dist/containerRuntime.d.ts +16 -9
  8. package/dist/containerRuntime.d.ts.map +1 -1
  9. package/dist/containerRuntime.js +137 -103
  10. package/dist/containerRuntime.js.map +1 -1
  11. package/dist/dataStoreContext.d.ts +1 -5
  12. package/dist/dataStoreContext.d.ts.map +1 -1
  13. package/dist/dataStoreContext.js +0 -8
  14. package/dist/dataStoreContext.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -2
  18. package/dist/index.js.map +1 -1
  19. package/dist/messageTypes.d.ts +3 -7
  20. package/dist/messageTypes.d.ts.map +1 -1
  21. package/dist/messageTypes.js.map +1 -1
  22. package/dist/opLifecycle/batchManager.d.ts +3 -15
  23. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  24. package/dist/opLifecycle/batchManager.js +3 -40
  25. package/dist/opLifecycle/batchManager.js.map +1 -1
  26. package/dist/opLifecycle/definitions.d.ts +42 -6
  27. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  28. package/dist/opLifecycle/definitions.js.map +1 -1
  29. package/dist/opLifecycle/index.d.ts +5 -4
  30. package/dist/opLifecycle/index.d.ts.map +1 -1
  31. package/dist/opLifecycle/index.js +6 -4
  32. package/dist/opLifecycle/index.js.map +1 -1
  33. package/dist/opLifecycle/opCompressor.d.ts +10 -11
  34. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  35. package/dist/opLifecycle/opCompressor.js +21 -20
  36. package/dist/opLifecycle/opCompressor.js.map +1 -1
  37. package/dist/opLifecycle/opGroupingManager.d.ts +9 -5
  38. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  39. package/dist/opLifecycle/opGroupingManager.js +18 -22
  40. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  41. package/dist/opLifecycle/opSerialization.d.ts +20 -0
  42. package/dist/opLifecycle/opSerialization.d.ts.map +1 -0
  43. package/dist/opLifecycle/opSerialization.js +40 -0
  44. package/dist/opLifecycle/opSerialization.js.map +1 -0
  45. package/dist/opLifecycle/opSplitter.d.ts +12 -13
  46. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  47. package/dist/opLifecycle/opSplitter.js +15 -15
  48. package/dist/opLifecycle/opSplitter.js.map +1 -1
  49. package/dist/opLifecycle/outbox.d.ts +35 -18
  50. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  51. package/dist/opLifecycle/outbox.js +111 -72
  52. package/dist/opLifecycle/outbox.js.map +1 -1
  53. package/dist/opLifecycle/remoteMessageProcessor.d.ts +0 -7
  54. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  55. package/dist/opLifecycle/remoteMessageProcessor.js +1 -15
  56. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  57. package/dist/packageVersion.d.ts +1 -1
  58. package/dist/packageVersion.d.ts.map +1 -1
  59. package/dist/packageVersion.js +1 -1
  60. package/dist/packageVersion.js.map +1 -1
  61. package/dist/pendingStateManager.d.ts +2 -2
  62. package/dist/pendingStateManager.d.ts.map +1 -1
  63. package/dist/pendingStateManager.js +1 -1
  64. package/dist/pendingStateManager.js.map +1 -1
  65. package/dist/runtimeLayerCompatState.d.ts.map +1 -1
  66. package/dist/runtimeLayerCompatState.js +6 -5
  67. package/dist/runtimeLayerCompatState.js.map +1 -1
  68. package/dist/summary/index.d.ts +5 -8
  69. package/dist/summary/index.d.ts.map +1 -1
  70. package/dist/summary/index.js +20 -21
  71. package/dist/summary/index.js.map +1 -1
  72. package/dist/summary/orderedClientElection.js +9 -9
  73. package/dist/summary/orderedClientElection.js.map +1 -1
  74. package/dist/summary/summarizerClientElection.d.ts +0 -1
  75. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  76. package/dist/summary/summarizerClientElection.js +3 -3
  77. package/dist/summary/summarizerClientElection.js.map +1 -1
  78. package/dist/summary/summarizerTypes.d.ts +3 -75
  79. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  80. package/dist/summary/summarizerTypes.js +2 -0
  81. package/dist/summary/summarizerTypes.js.map +1 -1
  82. package/{lib/summary/summaryGenerator.d.ts → dist/summary/summarizerUtils.d.ts} +12 -43
  83. package/dist/summary/summarizerUtils.d.ts.map +1 -0
  84. package/dist/summary/summarizerUtils.js +71 -0
  85. package/dist/summary/summarizerUtils.js.map +1 -0
  86. package/dist/summary/summaryDelayLoadedModule/index.d.ts +10 -0
  87. package/dist/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
  88. package/dist/summary/summaryDelayLoadedModule/index.js +20 -0
  89. package/dist/summary/summaryDelayLoadedModule/index.js.map +1 -0
  90. package/dist/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
  91. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
  92. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
  93. package/dist/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
  94. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
  95. package/dist/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +17 -24
  96. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
  97. package/dist/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
  98. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
  99. package/dist/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +13 -3
  100. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
  101. package/{lib/summary → dist/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
  102. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
  103. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
  104. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
  105. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
  106. package/dist/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +14 -99
  107. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
  108. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
  109. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
  110. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +44 -0
  111. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
  112. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
  113. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
  114. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js +7 -0
  115. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
  116. package/dist/summary/summaryHelpers.d.ts +1 -1
  117. package/dist/summary/summaryHelpers.d.ts.map +1 -1
  118. package/dist/summary/summaryHelpers.js +2 -2
  119. package/dist/summary/summaryHelpers.js.map +1 -1
  120. package/dist/summary/summaryManager.d.ts +4 -3
  121. package/dist/summary/summaryManager.d.ts.map +1 -1
  122. package/dist/summary/summaryManager.js +2 -2
  123. package/dist/summary/summaryManager.js.map +1 -1
  124. package/lib/channelCollection.d.ts +0 -14
  125. package/lib/channelCollection.d.ts.map +1 -1
  126. package/lib/channelCollection.js +6 -21
  127. package/lib/channelCollection.js.map +1 -1
  128. package/lib/containerRuntime.d.ts +16 -9
  129. package/lib/containerRuntime.d.ts.map +1 -1
  130. package/lib/containerRuntime.js +140 -106
  131. package/lib/containerRuntime.js.map +1 -1
  132. package/lib/dataStoreContext.d.ts +1 -5
  133. package/lib/dataStoreContext.d.ts.map +1 -1
  134. package/lib/dataStoreContext.js +0 -8
  135. package/lib/dataStoreContext.js.map +1 -1
  136. package/lib/index.d.ts +1 -1
  137. package/lib/index.d.ts.map +1 -1
  138. package/lib/index.js +1 -1
  139. package/lib/index.js.map +1 -1
  140. package/lib/messageTypes.d.ts +3 -7
  141. package/lib/messageTypes.d.ts.map +1 -1
  142. package/lib/messageTypes.js.map +1 -1
  143. package/lib/opLifecycle/batchManager.d.ts +3 -15
  144. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  145. package/lib/opLifecycle/batchManager.js +2 -38
  146. package/lib/opLifecycle/batchManager.js.map +1 -1
  147. package/lib/opLifecycle/definitions.d.ts +42 -6
  148. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  149. package/lib/opLifecycle/definitions.js.map +1 -1
  150. package/lib/opLifecycle/index.d.ts +5 -4
  151. package/lib/opLifecycle/index.d.ts.map +1 -1
  152. package/lib/opLifecycle/index.js +4 -3
  153. package/lib/opLifecycle/index.js.map +1 -1
  154. package/lib/opLifecycle/opCompressor.d.ts +10 -11
  155. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  156. package/lib/opLifecycle/opCompressor.js +21 -20
  157. package/lib/opLifecycle/opCompressor.js.map +1 -1
  158. package/lib/opLifecycle/opGroupingManager.d.ts +9 -5
  159. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  160. package/lib/opLifecycle/opGroupingManager.js +18 -22
  161. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  162. package/lib/opLifecycle/opSerialization.d.ts +20 -0
  163. package/lib/opLifecycle/opSerialization.d.ts.map +1 -0
  164. package/lib/opLifecycle/opSerialization.js +35 -0
  165. package/lib/opLifecycle/opSerialization.js.map +1 -0
  166. package/lib/opLifecycle/opSplitter.d.ts +12 -13
  167. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  168. package/lib/opLifecycle/opSplitter.js +14 -14
  169. package/lib/opLifecycle/opSplitter.js.map +1 -1
  170. package/lib/opLifecycle/outbox.d.ts +35 -18
  171. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  172. package/lib/opLifecycle/outbox.js +109 -71
  173. package/lib/opLifecycle/outbox.js.map +1 -1
  174. package/lib/opLifecycle/remoteMessageProcessor.d.ts +0 -7
  175. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  176. package/lib/opLifecycle/remoteMessageProcessor.js +0 -13
  177. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  178. package/lib/packageVersion.d.ts +1 -1
  179. package/lib/packageVersion.d.ts.map +1 -1
  180. package/lib/packageVersion.js +1 -1
  181. package/lib/packageVersion.js.map +1 -1
  182. package/lib/pendingStateManager.d.ts +2 -2
  183. package/lib/pendingStateManager.d.ts.map +1 -1
  184. package/lib/pendingStateManager.js +1 -1
  185. package/lib/pendingStateManager.js.map +1 -1
  186. package/lib/runtimeLayerCompatState.d.ts.map +1 -1
  187. package/lib/runtimeLayerCompatState.js +3 -2
  188. package/lib/runtimeLayerCompatState.js.map +1 -1
  189. package/lib/summary/index.d.ts +5 -8
  190. package/lib/summary/index.d.ts.map +1 -1
  191. package/lib/summary/index.js +5 -7
  192. package/lib/summary/index.js.map +1 -1
  193. package/lib/summary/orderedClientElection.js +1 -1
  194. package/lib/summary/orderedClientElection.js.map +1 -1
  195. package/lib/summary/summarizerClientElection.d.ts +0 -1
  196. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  197. package/lib/summary/summarizerClientElection.js +1 -1
  198. package/lib/summary/summarizerClientElection.js.map +1 -1
  199. package/lib/summary/summarizerTypes.d.ts +3 -75
  200. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  201. package/lib/summary/summarizerTypes.js +1 -1
  202. package/lib/summary/summarizerTypes.js.map +1 -1
  203. package/{dist/summary/summaryGenerator.d.ts → lib/summary/summarizerUtils.d.ts} +12 -43
  204. package/lib/summary/summarizerUtils.d.ts.map +1 -0
  205. package/lib/summary/summarizerUtils.js +64 -0
  206. package/lib/summary/summarizerUtils.js.map +1 -0
  207. package/lib/summary/summaryDelayLoadedModule/index.d.ts +10 -0
  208. package/lib/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
  209. package/lib/summary/summaryDelayLoadedModule/index.js +9 -0
  210. package/lib/summary/summaryDelayLoadedModule/index.js.map +1 -0
  211. package/lib/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
  212. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
  213. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
  214. package/lib/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
  215. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
  216. package/lib/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +5 -12
  217. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
  218. package/lib/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
  219. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
  220. package/lib/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +11 -1
  221. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
  222. package/{dist/summary → lib/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
  223. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
  224. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
  225. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
  226. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
  227. package/lib/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +4 -85
  228. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
  229. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
  230. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
  231. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +40 -0
  232. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
  233. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
  234. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
  235. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js +6 -0
  236. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
  237. package/lib/summary/summaryHelpers.d.ts +1 -1
  238. package/lib/summary/summaryHelpers.d.ts.map +1 -1
  239. package/lib/summary/summaryHelpers.js +1 -1
  240. package/lib/summary/summaryHelpers.js.map +1 -1
  241. package/lib/summary/summaryManager.d.ts +4 -3
  242. package/lib/summary/summaryManager.d.ts.map +1 -1
  243. package/lib/summary/summaryManager.js +2 -2
  244. package/lib/summary/summaryManager.js.map +1 -1
  245. package/package.json +20 -19
  246. package/src/channelCollection.ts +5 -20
  247. package/src/containerRuntime.ts +220 -178
  248. package/src/dataStoreContext.ts +0 -11
  249. package/src/index.ts +0 -1
  250. package/src/messageTypes.ts +5 -19
  251. package/src/opLifecycle/batchManager.ts +12 -51
  252. package/src/opLifecycle/definitions.ts +49 -6
  253. package/src/opLifecycle/index.ts +19 -4
  254. package/src/opLifecycle/opCompressor.ts +26 -25
  255. package/src/opLifecycle/opGroupingManager.ts +27 -26
  256. package/src/opLifecycle/opSerialization.ts +46 -0
  257. package/src/opLifecycle/opSplitter.ts +21 -17
  258. package/src/opLifecycle/outbox.ts +168 -99
  259. package/src/opLifecycle/remoteMessageProcessor.ts +0 -17
  260. package/src/packageVersion.ts +1 -1
  261. package/src/pendingStateManager.ts +3 -3
  262. package/src/runtimeLayerCompatState.ts +3 -2
  263. package/src/summary/index.ts +35 -31
  264. package/src/summary/orderedClientElection.ts +1 -1
  265. package/src/summary/summarizerClientElection.ts +1 -2
  266. package/src/summary/summarizerTypes.ts +7 -91
  267. package/src/summary/summarizerUtils.ts +132 -0
  268. package/src/summary/summaryDelayLoadedModule/index.ts +28 -0
  269. package/src/summary/{runWhileConnectedCoordinator.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.ts} +1 -1
  270. package/src/summary/{runningSummarizer.ts → summaryDelayLoadedModule/runningSummarizer.ts} +13 -28
  271. package/src/summary/{summarizer.ts → summaryDelayLoadedModule/summarizer.ts} +19 -8
  272. package/src/summary/{summarizerHeuristics.ts → summaryDelayLoadedModule/summarizerHeuristics.ts} +3 -3
  273. package/src/summary/{summaryGenerator.ts → summaryDelayLoadedModule/summaryGenerator.ts} +13 -179
  274. package/src/summary/summaryDelayLoadedModule/summaryResultBuilder.ts +70 -0
  275. package/src/summary/summaryDelayLoadedModule/summaryResultTypes.ts +100 -0
  276. package/src/summary/summaryHelpers.ts +6 -6
  277. package/src/summary/summaryManager.ts +8 -6
  278. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
  279. package/dist/summary/runWhileConnectedCoordinator.js.map +0 -1
  280. package/dist/summary/runningSummarizer.d.ts.map +0 -1
  281. package/dist/summary/runningSummarizer.js.map +0 -1
  282. package/dist/summary/summarizer.d.ts.map +0 -1
  283. package/dist/summary/summarizer.js.map +0 -1
  284. package/dist/summary/summarizerHeuristics.d.ts.map +0 -1
  285. package/dist/summary/summarizerHeuristics.js.map +0 -1
  286. package/dist/summary/summaryGenerator.d.ts.map +0 -1
  287. package/dist/summary/summaryGenerator.js.map +0 -1
  288. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
  289. package/lib/summary/runWhileConnectedCoordinator.js.map +0 -1
  290. package/lib/summary/runningSummarizer.d.ts.map +0 -1
  291. package/lib/summary/runningSummarizer.js.map +0 -1
  292. package/lib/summary/summarizer.d.ts.map +0 -1
  293. package/lib/summary/summarizer.js.map +0 -1
  294. package/lib/summary/summarizerHeuristics.d.ts.map +0 -1
  295. package/lib/summary/summarizerHeuristics.js.map +0 -1
  296. package/lib/summary/summaryGenerator.d.ts.map +0 -1
  297. package/lib/summary/summaryGenerator.js.map +0 -1
  298. /package/dist/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
  299. /package/dist/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
  300. /package/lib/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
  301. /package/lib/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
@@ -16,8 +16,12 @@ import {
16
16
 
17
17
  import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes.js";
18
18
 
19
- import { estimateSocketSize } from "./batchManager.js";
20
- import { BatchMessage, IBatch, IChunkedOp } from "./definitions.js";
19
+ import {
20
+ IChunkedOp,
21
+ type OutboundBatchMessage,
22
+ type OutboundSingletonBatch,
23
+ } from "./definitions.js";
24
+ import { estimateSocketSize } from "./outbox.js";
21
25
 
22
26
  export function isChunkedMessage(message: ISequencedDocumentMessage): boolean {
23
27
  return isChunkedContents(message.contents);
@@ -96,8 +100,8 @@ export class OpSplitter {
96
100
  }
97
101
 
98
102
  /**
99
- * Splits the first op of a compressed batch in chunks, sends the chunks separately and
100
- * returns a new batch composed of the last chunk and the rest of the ops in the original batch.
103
+ * Takes a singleton batch, and splits the interior message into chunks, sending the chunks separately and
104
+ * returning a new singleton batch containing the last chunk.
101
105
  *
102
106
  * A compressed batch is formed by one large op at the first position.
103
107
  *
@@ -108,21 +112,20 @@ export class OpSplitter {
108
112
  * This will ensure that the batch semantics of the original (non-compressed) batch are preserved, as the original chunked op
109
113
  * will be unrolled by the runtime when the first message in the batch is processed (as it is the last chunk).
110
114
  *
111
- * To handle legacy compressed batches with empty placeholders this method can attach the empty placeholder ops at the end
112
- * of the result batch, ensuring that the batch semantics are preserved.
113
- *
114
115
  * To illustrate the current functionality, if the input is `[largeOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
115
116
  * `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4]` will be returned.
116
117
  *
117
- * With the legacy code, if the input is `[largeOp, emptyOp, emptyOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
118
- * `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4, emptyOp, emptyOp]` will be returned.
119
- *
120
118
  * @remarks - A side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
121
119
  *
122
- * @param batch - the compressed batch which needs to be processed
123
- * @returns A batch with the last chunk of the original message
120
+ * @privateRemarks
121
+ * This maintains support for splitting a compressed batch with multiple messages (empty placeholders after the first),
122
+ * but this is only used for Unit Tests so the typing has been updated to preclude that.
123
+ * That code should be moved out of this function into a test helper.
124
+ *
125
+ * @param batch - the compressed batch which needs to be split into chunks before being sent over the wire
126
+ * @returns A batch with the last chunk in place of the original complete compressed content
124
127
  */
125
- public splitFirstBatchMessage(batch: IBatch): IBatch {
128
+ public splitSingletonBatchMessage(batch: OutboundSingletonBatch): OutboundSingletonBatch {
126
129
  assert(this.isBatchChunkingEnabled, 0x513 /* Chunking needs to be enabled */);
127
130
  assert(
128
131
  batch.contentSizeInBytes > 0 && batch.messages.length > 0,
@@ -138,13 +141,14 @@ export class OpSplitter {
138
141
  0x516 /* Chunk size needs to be smaller than the max batch size */,
139
142
  );
140
143
 
141
- const firstMessage = batch.messages[0]; // we expect this to be the large compressed op, which needs to be split
144
+ // first message is the large compressed op to split, and we expect restOfMessages to be empty
145
+ // (but we keep it here to support a legacy test case, wherein it contains empty placeholder messages)
146
+ const [firstMessage, ...restOfMessages] = batch.messages;
142
147
  assert(
143
148
  (firstMessage.contents?.length ?? 0) >= this.chunkSizeInBytes,
144
149
  0x518 /* First message in the batch needs to be chunkable */,
145
150
  );
146
151
 
147
- const restOfMessages = batch.messages.slice(1); // we expect these to be empty ops, created to reserve sequence numbers
148
152
  const socketSize = estimateSocketSize(batch);
149
153
  const chunks = splitOp(
150
154
  firstMessage,
@@ -243,7 +247,7 @@ const chunkToBatchMessage = (
243
247
  chunk: IChunkedOp,
244
248
  referenceSequenceNumber: number,
245
249
  metadata: Record<string, unknown> | undefined = undefined,
246
- ): BatchMessage => {
250
+ ): OutboundBatchMessage => {
247
251
  const payload: ContainerRuntimeChunkedOpMessage = {
248
252
  type: ContainerMessageType.ChunkedOp,
249
253
  contents: chunk,
@@ -268,7 +272,7 @@ const chunkToBatchMessage = (
268
272
  * @returns an array of chunked ops
269
273
  */
270
274
  export const splitOp = (
271
- op: BatchMessage,
275
+ op: OutboundBatchMessage,
272
276
  chunkSizeInBytes: number,
273
277
  extraOp: boolean = false,
274
278
  ): IChunkedOp[] => {
@@ -3,35 +3,40 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ICriticalContainerError } from "@fluidframework/container-definitions";
7
6
  import { IBatchMessage } from "@fluidframework/container-definitions/internal";
8
- import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
7
+ import {
8
+ ITelemetryBaseLogger,
9
+ type ITelemetryBaseProperties,
10
+ } from "@fluidframework/core-interfaces";
9
11
  import { assert, Lazy } from "@fluidframework/core-utils/internal";
10
12
  import {
11
13
  DataProcessingError,
12
- GenericError,
13
14
  UsageError,
14
15
  createChildLogger,
16
+ type IFluidErrorBase,
15
17
  type ITelemetryLoggerExt,
16
18
  } from "@fluidframework/telemetry-utils/internal";
17
19
 
18
20
  import { ICompressionRuntimeOptions } from "../containerRuntime.js";
19
- import { OutboundContainerRuntimeMessage } from "../messageTypes.js";
20
21
  import { PendingMessageResubmitData, PendingStateManager } from "../pendingStateManager.js";
21
22
 
22
23
  import {
23
24
  BatchManager,
24
25
  BatchSequenceNumbers,
25
- estimateSocketSize,
26
26
  sequenceNumbersMatch,
27
27
  type BatchId,
28
28
  } from "./batchManager.js";
29
- import { BatchMessage, IBatch, IBatchCheckpoint } from "./definitions.js";
29
+ import {
30
+ LocalBatchMessage,
31
+ IBatchCheckpoint,
32
+ type OutboundBatchMessage,
33
+ type OutboundSingletonBatch,
34
+ type LocalBatch,
35
+ type OutboundBatch,
36
+ } from "./definitions.js";
30
37
  import { OpCompressor } from "./opCompressor.js";
31
38
  import { OpGroupingManager } from "./opGroupingManager.js";
32
39
  import { OpSplitter } from "./opSplitter.js";
33
- // eslint-disable-next-line unused-imports/no-unused-imports -- Used by "@link" comment annotation below
34
- import { ensureContentsDeserialized } from "./remoteMessageProcessor.js";
35
40
 
36
41
  export interface IOutboxConfig {
37
42
  readonly compressionOptions: ICompressionRuntimeOptions;
@@ -53,7 +58,7 @@ export interface IOutboxParameters {
53
58
  readonly submitBatchFn:
54
59
  | ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)
55
60
  | undefined;
56
- readonly legacySendBatchFn: (batch: IBatch) => number;
61
+ readonly legacySendBatchFn: (batch: OutboundBatch) => number;
57
62
  readonly config: IOutboxConfig;
58
63
  readonly compressor: OpCompressor;
59
64
  readonly splitter: OpSplitter;
@@ -62,15 +67,6 @@ export interface IOutboxParameters {
62
67
  readonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;
63
68
  readonly reSubmit: (message: PendingMessageResubmitData) => void;
64
69
  readonly opReentrancy: () => boolean;
65
- readonly closeContainer: (error?: ICriticalContainerError) => void;
66
- }
67
-
68
- /**
69
- * Before submitting an op to the Outbox, its contents must be serialized using this function.
70
- * @remarks - The deserialization on process happens via the function {@link ensureContentsDeserialized}.
71
- */
72
- export function serializeOpContents(contents: OutboundContainerRuntimeMessage): string {
73
- return JSON.stringify(contents);
74
70
  }
75
71
 
76
72
  /**
@@ -112,6 +108,55 @@ export function getLongStack<T>(action: () => T, length: number = 50): T {
112
108
  }
113
109
  }
114
110
 
111
+ /**
112
+ * Convert from local batch to outbound batch, including computing contentSizeInBytes.
113
+ */
114
+ export function localBatchToOutboundBatch(localBatch: LocalBatch): OutboundBatch {
115
+ // Shallow copy each message as we switch types
116
+ const outboundMessages = localBatch.messages.map<OutboundBatchMessage>(
117
+ ({ serializedOp, ...message }) => ({
118
+ contents: serializedOp,
119
+ ...message,
120
+ }),
121
+ );
122
+ const contentSizeInBytes = outboundMessages.reduce(
123
+ (acc, message) => acc + (message.contents?.length ?? 0),
124
+ 0,
125
+ );
126
+
127
+ // Shallow copy the local batch, updating the messages to be outbound messages and adding contentSizeInBytes
128
+ const outboundBatch: OutboundBatch = {
129
+ ...localBatch,
130
+ messages: outboundMessages,
131
+ contentSizeInBytes,
132
+ };
133
+
134
+ return outboundBatch;
135
+ }
136
+
137
+ /**
138
+ * Estimated size of the stringification overhead for an op accumulated
139
+ * from runtime to loader to the service.
140
+ */
141
+ const opOverhead = 200;
142
+
143
+ /**
144
+ * Estimates the real size in bytes on the socket for a given batch. It assumes that
145
+ * the envelope size (and the size of an empty op) is 200 bytes, taking into account
146
+ * extra overhead from stringification.
147
+ *
148
+ * @remarks
149
+ * Also content will be stringified, and that adds a lot of overhead due to a lot of escape characters.
150
+ * Not taking it into account, as compression work should help there - compressed payload will be
151
+ * initially stored as base64, and that requires only 2 extra escape characters.
152
+ *
153
+ * @param batch - the batch to inspect
154
+ * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
155
+ */
156
+ export const estimateSocketSize = (batch: OutboundBatch): number => {
157
+ return batch.contentSizeInBytes + opOverhead * batch.messages.length;
158
+ };
159
+
115
160
  /**
116
161
  * The Outbox collects messages submitted by the ContainerRuntime into a batch,
117
162
  * and then flushes the batch when requested.
@@ -139,18 +184,9 @@ export class Outbox {
139
184
  constructor(private readonly params: IOutboxParameters) {
140
185
  this.logger = createChildLogger({ logger: params.logger, namespace: "Outbox" });
141
186
 
142
- const isCompressionEnabled =
143
- this.params.config.compressionOptions.minimumBatchSizeInBytes !==
144
- Number.POSITIVE_INFINITY;
145
- // We need to allow infinite size batches if we enable compression
146
- const hardLimit = isCompressionEnabled
147
- ? Number.POSITIVE_INFINITY
148
- : this.params.config.maxBatchSizeInBytes;
149
-
150
- this.mainBatch = new BatchManager({ hardLimit, canRebase: true });
151
- this.blobAttachBatch = new BatchManager({ hardLimit, canRebase: true });
187
+ this.mainBatch = new BatchManager({ canRebase: true });
188
+ this.blobAttachBatch = new BatchManager({ canRebase: true });
152
189
  this.idAllocationBatch = new BatchManager({
153
- hardLimit,
154
190
  canRebase: false,
155
191
  ignoreBatchId: true,
156
192
  });
@@ -258,53 +294,48 @@ export class Outbox {
258
294
  throw errorWrapper.value;
259
295
  }
260
296
 
261
- public submit(message: BatchMessage): void {
297
+ public submit(message: LocalBatchMessage): void {
262
298
  this.maybeFlushPartialBatch();
263
299
 
264
300
  this.addMessageToBatchManager(this.mainBatch, message);
265
301
  }
266
302
 
267
- public submitBlobAttach(message: BatchMessage): void {
303
+ public submitBlobAttach(message: LocalBatchMessage): void {
268
304
  this.maybeFlushPartialBatch();
269
305
 
270
306
  this.addMessageToBatchManager(this.blobAttachBatch, message);
271
307
  }
272
308
 
273
- public submitIdAllocation(message: BatchMessage): void {
309
+ public submitIdAllocation(message: LocalBatchMessage): void {
274
310
  this.maybeFlushPartialBatch();
275
311
 
276
312
  this.addMessageToBatchManager(this.idAllocationBatch, message);
277
313
  }
278
314
 
279
- private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage): void {
280
- if (
281
- !batchManager.push(
282
- message,
283
- this.isContextReentrant(),
284
- this.params.getCurrentSequenceNumbers().clientSequenceNumber,
285
- )
286
- ) {
287
- throw new GenericError("BatchTooLarge", /* error */ undefined, {
288
- opSize: message.contents?.length ?? 0,
289
- batchSize: batchManager.contentSizeInBytes,
290
- count: batchManager.length,
291
- limit: batchManager.options.hardLimit,
292
- });
293
- }
315
+ private addMessageToBatchManager(
316
+ batchManager: BatchManager,
317
+ message: LocalBatchMessage,
318
+ ): void {
319
+ batchManager.push(
320
+ message,
321
+ this.isContextReentrant(),
322
+ this.params.getCurrentSequenceNumbers().clientSequenceNumber,
323
+ );
294
324
  }
295
325
 
296
326
  /**
297
327
  * Flush all the batches to the ordering service.
298
328
  * This method is expected to be called at the end of a batch.
329
+ *
330
+ * @throws If called from a reentrant context, or if the batch being flushed is too large.
299
331
  * @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
300
332
  * with the given Batch ID, which must be preserved
301
333
  */
302
334
  public flush(resubmittingBatchId?: BatchId): void {
303
- if (this.isContextReentrant()) {
304
- const error = new UsageError("Flushing is not supported inside DDS event handlers");
305
- this.params.closeContainer(error);
306
- throw error;
307
- }
335
+ assert(
336
+ !this.isContextReentrant(),
337
+ 0xb7b /* Flushing must not happen while incoming changes are being processed */,
338
+ );
308
339
 
309
340
  this.flushAll(resubmittingBatchId);
310
341
  }
@@ -346,16 +377,19 @@ export class Outbox {
346
377
  referenceSequenceNumber !== undefined,
347
378
  0xa01 /* reference sequence number should be defined */,
348
379
  );
349
- const emptyGroupedBatch = this.params.groupingManager.createEmptyGroupedBatch(
350
- resubmittingBatchId,
351
- referenceSequenceNumber,
352
- );
380
+ const { outboundBatch, placeholderMessage } =
381
+ this.params.groupingManager.createEmptyGroupedBatch(
382
+ resubmittingBatchId,
383
+ referenceSequenceNumber,
384
+ );
353
385
  let clientSequenceNumber: number | undefined;
354
386
  if (this.params.shouldSend()) {
355
- clientSequenceNumber = this.sendBatch(emptyGroupedBatch);
387
+ clientSequenceNumber = this.sendBatch(outboundBatch);
356
388
  }
389
+
390
+ // Push the empty batch placeholder to the PendingStateManager
357
391
  this.params.pendingStateManager.onFlushBatch(
358
- emptyGroupedBatch.messages, // This is the single empty Grouped Batch message
392
+ [{ ...placeholderMessage, serializedOp: "", contents: undefined }], // placeholder message - serializedOp will never be used
359
393
  clientSequenceNumber,
360
394
  );
361
395
  return;
@@ -371,9 +405,16 @@ export class Outbox {
371
405
  }
372
406
 
373
407
  const rawBatch = batchManager.popBatch(resubmittingBatchId);
374
- const shouldGroup =
375
- !disableGroupedBatching && this.params.groupingManager.shouldGroup(rawBatch);
376
- if (batchManager.options.canRebase && rawBatch.hasReentrantOps === true && shouldGroup) {
408
+ const groupingEnabled =
409
+ !disableGroupedBatching && this.params.groupingManager.groupedBatchingEnabled();
410
+ if (
411
+ batchManager.options.canRebase &&
412
+ rawBatch.hasReentrantOps === true &&
413
+ // NOTE: This is too restrictive. We should rebase for any reentrant op, not just if it's going to be a grouped batch
414
+ // However there is some test that is depending on this behavior so we haven't removed these conditions yet. See AB#33427
415
+ groupingEnabled &&
416
+ rawBatch.messages.length > 1
417
+ ) {
377
418
  assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
378
419
  // If a batch contains reentrant ops (ops created as a result from processing another op)
379
420
  // it needs to be rebased so that we can ensure consistent reference sequence numbers
@@ -387,12 +428,9 @@ export class Outbox {
387
428
  // If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
388
429
  // Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.
389
430
  if (this.params.shouldSend()) {
390
- const processedBatch = disableGroupedBatching
391
- ? rawBatch
392
- : this.compressAndChunkBatch(
393
- shouldGroup ? this.params.groupingManager.groupBatch(rawBatch) : rawBatch,
394
- );
395
- clientSequenceNumber = this.sendBatch(processedBatch);
431
+ const virtualizedBatch = this.virtualizeBatch(rawBatch, groupingEnabled);
432
+
433
+ clientSequenceNumber = this.sendBatch(virtualizedBatch);
396
434
  assert(
397
435
  clientSequenceNumber === undefined || clientSequenceNumber >= 0,
398
436
  0x9d2 /* unexpected negative clientSequenceNumber (empty batch should yield undefined) */,
@@ -412,15 +450,14 @@ export class Outbox {
412
450
  *
413
451
  * @param rawBatch - the batch to be rebased
414
452
  */
415
- private rebase(rawBatch: IBatch, batchManager: BatchManager): void {
453
+ private rebase(rawBatch: LocalBatch, batchManager: BatchManager): void {
416
454
  assert(!this.rebasing, 0x6fb /* Reentrancy */);
417
455
  assert(batchManager.options.canRebase, 0x9a7 /* BatchManager does not support rebase */);
418
456
 
419
457
  this.rebasing = true;
420
458
  for (const message of rawBatch.messages) {
421
459
  this.params.reSubmit({
422
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
423
- content: message.contents!,
460
+ content: message.serializedOp,
424
461
  localOpMetadata: message.localOpMetadata,
425
462
  opMetadata: message.metadata,
426
463
  });
@@ -447,44 +484,56 @@ export class Outbox {
447
484
  }
448
485
 
449
486
  /**
450
- * As necessary and enabled, compresses and chunks the given batch.
487
+ * As necessary and enabled, groups / compresses / chunks the given batch.
451
488
  *
452
489
  * @remarks - If chunking happens, a side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
453
490
  *
454
- * @param batch - Raw or Grouped batch to consider for compression/chunking
455
- * @returns Either (A) the original batch, (B) a compressed batch (same length as original)
456
- * or (C) a batch containing the last chunk.
491
+ * @param localBatch - Local Batch to be virtualized - i.e. transformed into an Outbound Batch
492
+ * @param groupingEnabled - If true, Grouped batching is enabled.
493
+ * @returns One of the following:
494
+ * - (A) The original batch (Based on what's enabled)
495
+ * - (B) A grouped batch (it's a singleton batch)
496
+ * - (C) A compressed singleton batch
497
+ * - (D) A singleton batch containing the last chunk.
457
498
  */
458
- private compressAndChunkBatch(batch: IBatch): IBatch {
499
+ private virtualizeBatch(localBatch: LocalBatch, groupingEnabled: boolean): OutboundBatch {
500
+ // Shallow copy the local batch, updating the messages to be outbound messages
501
+ const originalBatch = localBatchToOutboundBatch(localBatch);
502
+
503
+ const originalOrGroupedBatch = groupingEnabled
504
+ ? this.params.groupingManager.groupBatch(originalBatch)
505
+ : originalBatch;
506
+
507
+ if (originalOrGroupedBatch.messages.length !== 1) {
508
+ // Compression requires a single message, so return early otherwise.
509
+ return originalOrGroupedBatch;
510
+ }
511
+
512
+ // Regardless of whether we grouped or not, we now have a batch with a single message.
513
+ // Now proceed to compress/chunk it if necessary.
514
+ const singletonBatch = originalOrGroupedBatch as OutboundSingletonBatch;
515
+
459
516
  if (
460
- batch.messages.length === 0 ||
461
- this.params.config.compressionOptions === undefined ||
462
517
  this.params.config.compressionOptions.minimumBatchSizeInBytes >
463
- batch.contentSizeInBytes ||
464
- this.params.submitBatchFn === undefined ||
465
- !this.params.groupingManager.groupedBatchingEnabled()
518
+ singletonBatch.contentSizeInBytes ||
519
+ this.params.submitBatchFn === undefined
466
520
  ) {
467
- // Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
468
- return batch;
521
+ // Nothing to do if compression is disabled, unnecessary or unsupported.
522
+ return singletonBatch;
469
523
  }
470
524
 
471
- const compressedBatch = this.params.compressor.compressBatch(batch);
525
+ const compressedBatch = this.params.compressor.compressBatch(singletonBatch);
472
526
 
473
527
  if (this.params.splitter.isBatchChunkingEnabled) {
474
528
  return compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes
475
529
  ? compressedBatch
476
- : this.params.splitter.splitFirstBatchMessage(compressedBatch);
530
+ : this.params.splitter.splitSingletonBatchMessage(compressedBatch);
477
531
  }
478
532
 
533
+ // We want to distinguish this "BatchTooLarge" case from the generic "BatchTooLarge" case in sendBatch
479
534
  if (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {
480
- throw new GenericError("BatchTooLarge", /* error */ undefined, {
481
- batchSize: batch.contentSizeInBytes,
482
- compressedBatchSize: compressedBatch.contentSizeInBytes,
483
- count: compressedBatch.messages.length,
484
- limit: this.params.config.maxBatchSizeInBytes,
485
- chunkingEnabled: this.params.splitter.isBatchChunkingEnabled,
486
- compressionOptions: JSON.stringify(this.params.config.compressionOptions),
487
- socketSize: estimateSocketSize(batch),
535
+ throw this.makeBatchTooLargeError(compressedBatch, "CompressionInsufficient", {
536
+ uncompressedSizeInBytes: singletonBatch.contentSizeInBytes,
488
537
  });
489
538
  }
490
539
 
@@ -497,7 +546,7 @@ export class Outbox {
497
546
  * @param batch - batch to be sent
498
547
  * @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent
499
548
  */
500
- private sendBatch(batch: IBatch): number | undefined {
549
+ private sendBatch(batch: OutboundBatch): number | undefined {
501
550
  const length = batch.messages.length;
502
551
  if (length === 0) {
503
552
  return undefined; // Nothing submitted
@@ -505,12 +554,7 @@ export class Outbox {
505
554
 
506
555
  const socketSize = estimateSocketSize(batch);
507
556
  if (socketSize >= this.params.config.maxBatchSizeInBytes) {
508
- this.logger.sendPerformanceEvent({
509
- eventName: "LargeBatch",
510
- length: batch.messages.length,
511
- sizeInBytes: batch.contentSizeInBytes,
512
- socketSize,
513
- });
557
+ throw this.makeBatchTooLargeError(batch, "CannotSend");
514
558
  }
515
559
 
516
560
  let clientSequenceNumber: number;
@@ -542,6 +586,31 @@ export class Outbox {
542
586
  return clientSequenceNumber;
543
587
  }
544
588
 
589
+ private makeBatchTooLargeError(
590
+ batch: OutboundBatch,
591
+ codepath: string,
592
+ moreDetails?: ITelemetryBaseProperties,
593
+ ): IFluidErrorBase {
594
+ return DataProcessingError.create(
595
+ "BatchTooLarge",
596
+ codepath,
597
+ /* sequencedMessage */ undefined,
598
+ {
599
+ errorDetails: {
600
+ opCount: batch.messages.length,
601
+ contentSizeInBytes: batch.contentSizeInBytes,
602
+ socketSize: estimateSocketSize(batch),
603
+ maxBatchSizeInBytes: this.params.config.maxBatchSizeInBytes,
604
+ groupedBatchingEnabled: this.params.groupingManager.groupedBatchingEnabled(),
605
+ compressionOptions: JSON.stringify(this.params.config.compressionOptions),
606
+ chunkingEnabled: this.params.splitter.isBatchChunkingEnabled,
607
+ chunkSizeInBytes: this.params.splitter.chunkSizeInBytes,
608
+ ...moreDetails,
609
+ },
610
+ },
611
+ );
612
+ }
613
+
545
614
  /**
546
615
  * Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
547
616
  */
@@ -19,9 +19,6 @@ import { asBatchMetadata } from "../metadata.js";
19
19
  import { OpDecompressor } from "./opDecompressor.js";
20
20
  import { OpGroupingManager, isGroupedBatch } from "./opGroupingManager.js";
21
21
  import { OpSplitter, isChunkedMessage } from "./opSplitter.js";
22
- // eslint-disable-next-line unused-imports/no-unused-imports -- Used by "@link" comment annotation below
23
- import { serializeOpContents } from "./outbox.js";
24
-
25
22
  /**
26
23
  * Info about the batch we learn when we process the first message
27
24
  */
@@ -247,20 +244,6 @@ export class RemoteMessageProcessor {
247
244
  }
248
245
  }
249
246
 
250
- /**
251
- * Takes an incoming runtime message JSON.parse's its contents in place, if needed (old Loader does this for us).
252
- * Only to be used for runtine messages.
253
- * @remarks - Serialization during submit happens via {@link serializeOpContents}
254
- * @param mutableMessage - op message received
255
- */
256
- export function ensureContentsDeserialized(mutableMessage: ISequencedDocumentMessage): void {
257
- // This should become unconditional once Loader LTS reaches 2.4 or later.
258
- // There will be a long time of needing both cases, until LTS advances to that point.
259
- if (typeof mutableMessage.contents === "string" && mutableMessage.contents !== "") {
260
- mutableMessage.contents = JSON.parse(mutableMessage.contents);
261
- }
262
- }
263
-
264
247
  /**
265
248
  * For a given message, it moves the nested InboundContainerRuntimeMessage props one level up.
266
249
  *
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.31.1";
9
+ export const pkgVersion = "2.33.0-333010";
@@ -23,7 +23,7 @@ import {
23
23
  import { asBatchMetadata, asEmptyBatchLocalOpMetadata } from "./metadata.js";
24
24
  import {
25
25
  BatchId,
26
- BatchMessage,
26
+ LocalBatchMessage,
27
27
  getEffectiveBatchId,
28
28
  BatchStartInfo,
29
29
  InboundMessageResult,
@@ -305,7 +305,7 @@ export class PendingStateManager implements IDisposable {
305
305
  * @param ignoreBatchId - Whether to ignore the batchId in the batchStartInfo
306
306
  */
307
307
  public onFlushBatch(
308
- batch: BatchMessage[],
308
+ batch: LocalBatchMessage[],
309
309
  clientSequenceNumber: number | undefined,
310
310
  ignoreBatchId?: boolean,
311
311
  ): void {
@@ -325,7 +325,7 @@ export class PendingStateManager implements IDisposable {
325
325
 
326
326
  for (const message of batch) {
327
327
  const {
328
- contents: content = "",
328
+ serializedOp: content,
329
329
  referenceSequenceNumber,
330
330
  localOpMetadata,
331
331
  metadata: opMetadata,
@@ -9,6 +9,7 @@ import {
9
9
  type ILayerCompatSupportRequirements,
10
10
  } from "@fluid-internal/client-utils";
11
11
  import type { ICriticalContainerError } from "@fluidframework/container-definitions";
12
+ import { encodeHandlesInContainerRuntime } from "@fluidframework/runtime-definitions/internal";
12
13
  import { UsageError } from "@fluidframework/telemetry-utils/internal";
13
14
 
14
15
  import { pkgVersion } from "./packageVersion.js";
@@ -63,9 +64,9 @@ export const loaderSupportRequirements: ILayerCompatSupportRequirements = {
63
64
  export const runtimeCompatDetailsForDataStore: ILayerCompatDetails = {
64
65
  ...runtimeCoreCompatDetails,
65
66
  /**
66
- * The features supported by the Runtime layer across the Runtime / Loader boundary.
67
+ * The features supported by the Runtime layer across the Runtime / DataStore boundary.
67
68
  */
68
- supportedFeatures: new Set<string>(),
69
+ supportedFeatures: new Set<string>([encodeHandlesInContainerRuntime]),
69
70
  };
70
71
 
71
72
  /**