@fluidframework/container-runtime 2.31.1 → 2.32.0

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 (299) 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 +4 -4
  23. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  24. package/dist/opLifecycle/batchManager.js +4 -4
  25. package/dist/opLifecycle/batchManager.js.map +1 -1
  26. package/dist/opLifecycle/definitions.d.ts +40 -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 +4 -3
  30. package/dist/opLifecycle/index.d.ts.map +1 -1
  31. package/dist/opLifecycle/index.js +4 -3
  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 +19 -18
  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 +13 -13
  48. package/dist/opLifecycle/opSplitter.js.map +1 -1
  49. package/dist/opLifecycle/outbox.d.ts +16 -18
  50. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  51. package/dist/opLifecycle/outbox.js +57 -43
  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.js +1 -1
  59. package/dist/packageVersion.js.map +1 -1
  60. package/dist/pendingStateManager.d.ts +2 -2
  61. package/dist/pendingStateManager.d.ts.map +1 -1
  62. package/dist/pendingStateManager.js +1 -1
  63. package/dist/pendingStateManager.js.map +1 -1
  64. package/dist/runtimeLayerCompatState.d.ts.map +1 -1
  65. package/dist/runtimeLayerCompatState.js +6 -5
  66. package/dist/runtimeLayerCompatState.js.map +1 -1
  67. package/dist/summary/index.d.ts +5 -8
  68. package/dist/summary/index.d.ts.map +1 -1
  69. package/dist/summary/index.js +20 -21
  70. package/dist/summary/index.js.map +1 -1
  71. package/dist/summary/orderedClientElection.js +9 -9
  72. package/dist/summary/orderedClientElection.js.map +1 -1
  73. package/dist/summary/summarizerClientElection.d.ts +0 -1
  74. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  75. package/dist/summary/summarizerClientElection.js +3 -3
  76. package/dist/summary/summarizerClientElection.js.map +1 -1
  77. package/dist/summary/summarizerTypes.d.ts +3 -75
  78. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  79. package/dist/summary/summarizerTypes.js +2 -0
  80. package/dist/summary/summarizerTypes.js.map +1 -1
  81. package/{lib/summary/summaryGenerator.d.ts → dist/summary/summarizerUtils.d.ts} +12 -43
  82. package/dist/summary/summarizerUtils.d.ts.map +1 -0
  83. package/dist/summary/summarizerUtils.js +71 -0
  84. package/dist/summary/summarizerUtils.js.map +1 -0
  85. package/dist/summary/summaryDelayLoadedModule/index.d.ts +10 -0
  86. package/dist/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
  87. package/dist/summary/summaryDelayLoadedModule/index.js +20 -0
  88. package/dist/summary/summaryDelayLoadedModule/index.js.map +1 -0
  89. package/dist/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
  90. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
  91. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
  92. package/dist/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
  93. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
  94. package/dist/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +17 -24
  95. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
  96. package/dist/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
  97. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
  98. package/dist/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +13 -3
  99. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
  100. package/{lib/summary → dist/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
  101. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
  102. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
  103. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
  104. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
  105. package/dist/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +14 -99
  106. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
  107. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
  108. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
  109. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +44 -0
  110. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
  111. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
  112. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
  113. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js +7 -0
  114. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
  115. package/dist/summary/summaryHelpers.d.ts +1 -1
  116. package/dist/summary/summaryHelpers.d.ts.map +1 -1
  117. package/dist/summary/summaryHelpers.js +2 -2
  118. package/dist/summary/summaryHelpers.js.map +1 -1
  119. package/dist/summary/summaryManager.d.ts +4 -3
  120. package/dist/summary/summaryManager.d.ts.map +1 -1
  121. package/dist/summary/summaryManager.js +2 -2
  122. package/dist/summary/summaryManager.js.map +1 -1
  123. package/lib/channelCollection.d.ts +0 -14
  124. package/lib/channelCollection.d.ts.map +1 -1
  125. package/lib/channelCollection.js +6 -21
  126. package/lib/channelCollection.js.map +1 -1
  127. package/lib/containerRuntime.d.ts +16 -9
  128. package/lib/containerRuntime.d.ts.map +1 -1
  129. package/lib/containerRuntime.js +140 -106
  130. package/lib/containerRuntime.js.map +1 -1
  131. package/lib/dataStoreContext.d.ts +1 -5
  132. package/lib/dataStoreContext.d.ts.map +1 -1
  133. package/lib/dataStoreContext.js +0 -8
  134. package/lib/dataStoreContext.js.map +1 -1
  135. package/lib/index.d.ts +1 -1
  136. package/lib/index.d.ts.map +1 -1
  137. package/lib/index.js +1 -1
  138. package/lib/index.js.map +1 -1
  139. package/lib/messageTypes.d.ts +3 -7
  140. package/lib/messageTypes.d.ts.map +1 -1
  141. package/lib/messageTypes.js.map +1 -1
  142. package/lib/opLifecycle/batchManager.d.ts +4 -4
  143. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  144. package/lib/opLifecycle/batchManager.js +4 -4
  145. package/lib/opLifecycle/batchManager.js.map +1 -1
  146. package/lib/opLifecycle/definitions.d.ts +40 -6
  147. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  148. package/lib/opLifecycle/definitions.js.map +1 -1
  149. package/lib/opLifecycle/index.d.ts +4 -3
  150. package/lib/opLifecycle/index.d.ts.map +1 -1
  151. package/lib/opLifecycle/index.js +3 -2
  152. package/lib/opLifecycle/index.js.map +1 -1
  153. package/lib/opLifecycle/opCompressor.d.ts +10 -11
  154. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  155. package/lib/opLifecycle/opCompressor.js +20 -19
  156. package/lib/opLifecycle/opCompressor.js.map +1 -1
  157. package/lib/opLifecycle/opGroupingManager.d.ts +9 -5
  158. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  159. package/lib/opLifecycle/opGroupingManager.js +18 -22
  160. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  161. package/lib/opLifecycle/opSerialization.d.ts +20 -0
  162. package/lib/opLifecycle/opSerialization.d.ts.map +1 -0
  163. package/lib/opLifecycle/opSerialization.js +35 -0
  164. package/lib/opLifecycle/opSerialization.js.map +1 -0
  165. package/lib/opLifecycle/opSplitter.d.ts +12 -13
  166. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  167. package/lib/opLifecycle/opSplitter.js +13 -13
  168. package/lib/opLifecycle/opSplitter.js.map +1 -1
  169. package/lib/opLifecycle/outbox.d.ts +16 -18
  170. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  171. package/lib/opLifecycle/outbox.js +56 -41
  172. package/lib/opLifecycle/outbox.js.map +1 -1
  173. package/lib/opLifecycle/remoteMessageProcessor.d.ts +0 -7
  174. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  175. package/lib/opLifecycle/remoteMessageProcessor.js +0 -13
  176. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  177. package/lib/packageVersion.d.ts +1 -1
  178. package/lib/packageVersion.js +1 -1
  179. package/lib/packageVersion.js.map +1 -1
  180. package/lib/pendingStateManager.d.ts +2 -2
  181. package/lib/pendingStateManager.d.ts.map +1 -1
  182. package/lib/pendingStateManager.js +1 -1
  183. package/lib/pendingStateManager.js.map +1 -1
  184. package/lib/runtimeLayerCompatState.d.ts.map +1 -1
  185. package/lib/runtimeLayerCompatState.js +3 -2
  186. package/lib/runtimeLayerCompatState.js.map +1 -1
  187. package/lib/summary/index.d.ts +5 -8
  188. package/lib/summary/index.d.ts.map +1 -1
  189. package/lib/summary/index.js +5 -7
  190. package/lib/summary/index.js.map +1 -1
  191. package/lib/summary/orderedClientElection.js +1 -1
  192. package/lib/summary/orderedClientElection.js.map +1 -1
  193. package/lib/summary/summarizerClientElection.d.ts +0 -1
  194. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  195. package/lib/summary/summarizerClientElection.js +1 -1
  196. package/lib/summary/summarizerClientElection.js.map +1 -1
  197. package/lib/summary/summarizerTypes.d.ts +3 -75
  198. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  199. package/lib/summary/summarizerTypes.js +1 -1
  200. package/lib/summary/summarizerTypes.js.map +1 -1
  201. package/{dist/summary/summaryGenerator.d.ts → lib/summary/summarizerUtils.d.ts} +12 -43
  202. package/lib/summary/summarizerUtils.d.ts.map +1 -0
  203. package/lib/summary/summarizerUtils.js +64 -0
  204. package/lib/summary/summarizerUtils.js.map +1 -0
  205. package/lib/summary/summaryDelayLoadedModule/index.d.ts +10 -0
  206. package/lib/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
  207. package/lib/summary/summaryDelayLoadedModule/index.js +9 -0
  208. package/lib/summary/summaryDelayLoadedModule/index.js.map +1 -0
  209. package/lib/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
  210. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
  211. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
  212. package/lib/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
  213. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
  214. package/lib/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +5 -12
  215. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
  216. package/lib/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
  217. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
  218. package/lib/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +11 -1
  219. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
  220. package/{dist/summary → lib/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
  221. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
  222. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
  223. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
  224. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
  225. package/lib/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +4 -85
  226. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
  227. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
  228. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
  229. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +40 -0
  230. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
  231. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
  232. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
  233. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js +6 -0
  234. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
  235. package/lib/summary/summaryHelpers.d.ts +1 -1
  236. package/lib/summary/summaryHelpers.d.ts.map +1 -1
  237. package/lib/summary/summaryHelpers.js +1 -1
  238. package/lib/summary/summaryHelpers.js.map +1 -1
  239. package/lib/summary/summaryManager.d.ts +4 -3
  240. package/lib/summary/summaryManager.d.ts.map +1 -1
  241. package/lib/summary/summaryManager.js +2 -2
  242. package/lib/summary/summaryManager.js.map +1 -1
  243. package/package.json +20 -19
  244. package/src/channelCollection.ts +5 -20
  245. package/src/containerRuntime.ts +220 -178
  246. package/src/dataStoreContext.ts +0 -11
  247. package/src/index.ts +0 -1
  248. package/src/messageTypes.ts +5 -19
  249. package/src/opLifecycle/batchManager.ts +19 -12
  250. package/src/opLifecycle/definitions.ts +45 -6
  251. package/src/opLifecycle/index.ts +14 -3
  252. package/src/opLifecycle/opCompressor.ts +25 -24
  253. package/src/opLifecycle/opGroupingManager.ts +27 -26
  254. package/src/opLifecycle/opSerialization.ts +46 -0
  255. package/src/opLifecycle/opSplitter.ts +20 -16
  256. package/src/opLifecycle/outbox.ts +101 -66
  257. package/src/opLifecycle/remoteMessageProcessor.ts +0 -17
  258. package/src/packageVersion.ts +1 -1
  259. package/src/pendingStateManager.ts +3 -3
  260. package/src/runtimeLayerCompatState.ts +3 -2
  261. package/src/summary/index.ts +35 -31
  262. package/src/summary/orderedClientElection.ts +1 -1
  263. package/src/summary/summarizerClientElection.ts +1 -2
  264. package/src/summary/summarizerTypes.ts +7 -91
  265. package/src/summary/summarizerUtils.ts +132 -0
  266. package/src/summary/summaryDelayLoadedModule/index.ts +28 -0
  267. package/src/summary/{runWhileConnectedCoordinator.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.ts} +1 -1
  268. package/src/summary/{runningSummarizer.ts → summaryDelayLoadedModule/runningSummarizer.ts} +13 -28
  269. package/src/summary/{summarizer.ts → summaryDelayLoadedModule/summarizer.ts} +19 -8
  270. package/src/summary/{summarizerHeuristics.ts → summaryDelayLoadedModule/summarizerHeuristics.ts} +3 -3
  271. package/src/summary/{summaryGenerator.ts → summaryDelayLoadedModule/summaryGenerator.ts} +13 -179
  272. package/src/summary/summaryDelayLoadedModule/summaryResultBuilder.ts +70 -0
  273. package/src/summary/summaryDelayLoadedModule/summaryResultTypes.ts +100 -0
  274. package/src/summary/summaryHelpers.ts +6 -6
  275. package/src/summary/summaryManager.ts +8 -6
  276. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
  277. package/dist/summary/runWhileConnectedCoordinator.js.map +0 -1
  278. package/dist/summary/runningSummarizer.d.ts.map +0 -1
  279. package/dist/summary/runningSummarizer.js.map +0 -1
  280. package/dist/summary/summarizer.d.ts.map +0 -1
  281. package/dist/summary/summarizer.js.map +0 -1
  282. package/dist/summary/summarizerHeuristics.d.ts.map +0 -1
  283. package/dist/summary/summarizerHeuristics.js.map +0 -1
  284. package/dist/summary/summaryGenerator.d.ts.map +0 -1
  285. package/dist/summary/summaryGenerator.js.map +0 -1
  286. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
  287. package/lib/summary/runWhileConnectedCoordinator.js.map +0 -1
  288. package/lib/summary/runningSummarizer.d.ts.map +0 -1
  289. package/lib/summary/runningSummarizer.js.map +0 -1
  290. package/lib/summary/summarizer.d.ts.map +0 -1
  291. package/lib/summary/summarizer.js.map +0 -1
  292. package/lib/summary/summarizerHeuristics.d.ts.map +0 -1
  293. package/lib/summary/summarizerHeuristics.js.map +0 -1
  294. package/lib/summary/summaryGenerator.d.ts.map +0 -1
  295. package/lib/summary/summaryGenerator.js.map +0 -1
  296. /package/dist/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
  297. /package/dist/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
  298. /package/lib/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
  299. /package/lib/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
@@ -9,8 +9,6 @@ import { IDeltaManager } from "@fluidframework/container-definitions/internal";
9
9
  import {
10
10
  FluidObject,
11
11
  IDisposable,
12
- IRequest,
13
- IResponse,
14
12
  ITelemetryBaseProperties,
15
13
  type IEvent,
16
14
  } from "@fluidframework/core-interfaces";
@@ -796,15 +794,6 @@ export abstract class FluidDataStoreContext
796
794
  this.parentContext.addedGCOutboundRoute(fromPath, toPath, messageTimestampMs);
797
795
  }
798
796
 
799
- // eslint-disable-next-line jsdoc/require-description
800
- /**
801
- * @deprecated 0.18.Should call request on the runtime directly
802
- */
803
- public async request(request: IRequest): Promise<IResponse> {
804
- const runtime = await this.realize();
805
- return runtime.request(request);
806
- }
807
-
808
797
  public submitMessage(type: string, content: unknown, localOpMetadata: unknown): void {
809
798
  this.verifyNotClosed("submitMessage");
810
799
  assert(!!this.channel, 0x146 /* "Channel must exist when submitting message" */);
package/src/index.ts CHANGED
@@ -27,7 +27,6 @@ export { IBlobManagerLoadInfo } from "./blobManager/index.js";
27
27
  export { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
28
28
  export {
29
29
  detectOutboundReferences,
30
- RuntimeHeaders,
31
30
  ChannelCollectionFactory,
32
31
  AllowTombstoneRequestHeaderKey,
33
32
  } from "./channelCollection.js";
@@ -147,12 +147,12 @@ export type InboundContainerRuntimeMessage =
147
147
  | ContainerRuntimeAliasMessage
148
148
  | ContainerRuntimeIdAllocationMessage
149
149
  | ContainerRuntimeGCMessage
150
+ | ContainerRuntimeDocumentSchemaMessage
150
151
  // Inbound messages may include unknown types from other clients, so we include that as a special case here
151
- | UnknownContainerRuntimeMessage
152
- | ContainerRuntimeDocumentSchemaMessage;
152
+ | UnknownContainerRuntimeMessage;
153
153
 
154
154
  /**
155
- * A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime but is not yet being sent to the server.
155
+ * A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime, eventually to be sent to the ordering service.
156
156
  * These are messages generated by the local runtime, before the outbox's op virtualization step.
157
157
  */
158
158
  export type LocalContainerRuntimeMessage =
@@ -163,23 +163,9 @@ export type LocalContainerRuntimeMessage =
163
163
  | ContainerRuntimeAliasMessage
164
164
  | ContainerRuntimeIdAllocationMessage
165
165
  | ContainerRuntimeGCMessage
166
+ | ContainerRuntimeDocumentSchemaMessage
166
167
  // In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type
167
- | UnknownContainerRuntimeMessage
168
- | ContainerRuntimeDocumentSchemaMessage;
169
-
170
- /**
171
- * A {@link TypedContainerRuntimeMessage} that is being sent to the server from the container runtime.
172
- */
173
- export type OutboundContainerRuntimeMessage =
174
- | ContainerRuntimeDataStoreOpMessage
175
- | OutboundContainerRuntimeAttachMessage
176
- | ContainerRuntimeChunkedOpMessage
177
- | ContainerRuntimeBlobAttachMessage
178
- | ContainerRuntimeRejoinMessage
179
- | ContainerRuntimeAliasMessage
180
- | ContainerRuntimeIdAllocationMessage
181
- | ContainerRuntimeGCMessage
182
- | ContainerRuntimeDocumentSchemaMessage;
168
+ | UnknownContainerRuntimeMessage;
183
169
 
184
170
  /**
185
171
  * An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc
@@ -14,7 +14,12 @@ import { ICompressionRuntimeOptions } from "../containerRuntime.js";
14
14
  import { asBatchMetadata, type IBatchMetadata } from "../metadata.js";
15
15
  import type { IPendingMessage } from "../pendingStateManager.js";
16
16
 
17
- import { BatchMessage, IBatch, IBatchCheckpoint } from "./definitions.js";
17
+ import {
18
+ LocalBatchMessage,
19
+ IBatchCheckpoint,
20
+ type LocalBatch,
21
+ type OutboundBatch,
22
+ } from "./definitions.js";
18
23
  import type { BatchStartInfo } from "./remoteMessageProcessor.js";
19
24
 
20
25
  export interface IBatchManagerOptions {
@@ -83,7 +88,7 @@ const opOverhead = 200;
83
88
  * Helper class that manages partial batch & rollback.
84
89
  */
85
90
  export class BatchManager {
86
- private pendingBatch: BatchMessage[] = [];
91
+ private pendingBatch: LocalBatchMessage[] = [];
87
92
  private batchContentSize = 0;
88
93
  private hasReentrantOps = false;
89
94
 
@@ -117,11 +122,11 @@ export class BatchManager {
117
122
  constructor(public readonly options: IBatchManagerOptions) {}
118
123
 
119
124
  public push(
120
- message: BatchMessage,
125
+ message: LocalBatchMessage,
121
126
  reentrant: boolean,
122
127
  currentClientSequenceNumber?: number,
123
128
  ): boolean {
124
- const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
129
+ const contentSize = this.batchContentSize + (message.serializedOp?.length ?? 0);
125
130
  const opCount = this.pendingBatch.length;
126
131
  this.hasReentrantOps = this.hasReentrantOps || reentrant;
127
132
 
@@ -152,8 +157,8 @@ export class BatchManager {
152
157
  /**
153
158
  * Gets the pending batch and clears state for the next batch.
154
159
  */
155
- public popBatch(batchId?: BatchId): IBatch {
156
- const batch: IBatch = {
160
+ public popBatch(batchId?: BatchId): LocalBatch {
161
+ const batch: LocalBatch = {
157
162
  messages: this.pendingBatch,
158
163
  contentSizeInBytes: this.batchContentSize,
159
164
  referenceSequenceNumber: this.referenceSequenceNumber,
@@ -175,19 +180,21 @@ export class BatchManager {
175
180
  const startSequenceNumber = this.clientSequenceNumber;
176
181
  const startPoint = this.pendingBatch.length;
177
182
  return {
178
- rollback: (process: (message: BatchMessage) => void) => {
183
+ rollback: (process: (message: LocalBatchMessage) => void) => {
179
184
  this.clientSequenceNumber = startSequenceNumber;
180
185
  const rollbackOpsLifo = this.pendingBatch.splice(startPoint).reverse();
181
186
  for (const message of rollbackOpsLifo) {
182
- this.batchContentSize -= message.contents?.length ?? 0;
187
+ this.batchContentSize -= message.serializedOp?.length ?? 0;
183
188
  process(message);
184
189
  }
185
190
  const count = this.pendingBatch.length - startPoint;
186
191
  if (count !== 0) {
187
- throw new LoggingError("Ops generated durning rollback", {
192
+ throw new LoggingError("Ops generated during rollback", {
188
193
  count,
189
194
  ...tagData(TelemetryDataTag.UserData, {
190
- ops: JSON.stringify(this.pendingBatch.slice(startPoint).map((b) => b.contents)),
195
+ ops: JSON.stringify(
196
+ this.pendingBatch.slice(startPoint).map((b) => b.serializedOp),
197
+ ),
191
198
  }),
192
199
  });
193
200
  }
@@ -196,7 +203,7 @@ export class BatchManager {
196
203
  }
197
204
  }
198
205
 
199
- const addBatchMetadata = (batch: IBatch, batchId?: BatchId): IBatch => {
206
+ const addBatchMetadata = (batch: LocalBatch, batchId?: BatchId): LocalBatch => {
200
207
  const batchEnd = batch.messages.length - 1;
201
208
 
202
209
  const firstMsg = batch.messages[0];
@@ -234,7 +241,7 @@ const addBatchMetadata = (batch: IBatch, batchId?: BatchId): IBatch => {
234
241
  * @param batch - the batch to inspect
235
242
  * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
236
243
  */
237
- export const estimateSocketSize = (batch: IBatch): number => {
244
+ export const estimateSocketSize = (batch: OutboundBatch): number => {
238
245
  return batch.contentSizeInBytes + opOverhead * batch.messages.length;
239
246
  };
240
247
 
@@ -3,23 +3,62 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IBatchMessage } from "@fluidframework/container-definitions/internal";
6
+ import type { IBatchMessage } from "@fluidframework/container-definitions/internal";
7
7
 
8
8
  import { CompressionAlgorithms } from "../containerRuntime.js";
9
9
 
10
10
  /**
11
- * Batch message type used internally by the runtime
11
+ * Local Batch message, before it is virtualized and sent to the ordering service
12
12
  */
13
- export type BatchMessage = IBatchMessage & {
13
+ export interface LocalBatchMessage {
14
+ serializedOp: string;
15
+ metadata?: Record<string, unknown>;
14
16
  localOpMetadata?: unknown;
15
17
  referenceSequenceNumber: number;
16
18
  compression?: CompressionAlgorithms;
19
+
20
+ /**
21
+ * @deprecated Use serializedOp
22
+ */
23
+ contents?: never; // To ensure we don't leave this one when converting from OutboundBatchMessage
24
+ }
25
+
26
+ /**
27
+ * Virtualized Batch message, on its way out the door to the ordering service
28
+ */
29
+ export type OutboundBatchMessage = IBatchMessage & {
30
+ localOpMetadata?: unknown;
31
+ referenceSequenceNumber: number;
32
+ compression?: CompressionAlgorithms;
33
+
34
+ /**
35
+ * @deprecated Use contents
36
+ */
37
+ serializedOp?: never; // To ensure we don't leave this one when converting from LocalBatchMessage
17
38
  };
18
39
 
19
40
  /**
20
- * Batch interface used internally by the runtime.
41
+ * A batch of messages we have accumulated locally, but haven't sent to the ordering service yet.
42
+ */
43
+ export type LocalBatch = IBatch<LocalBatchMessage[]>;
44
+
45
+ /**
46
+ * A batch of messages that has been virtualized as needed (grouped, compressed, chunked)
47
+ * and is ready to be sent to the ordering service.
48
+ */
49
+ export type OutboundBatch = IBatch<OutboundBatchMessage[]>;
50
+
51
+ /**
52
+ * An {@link OutboundBatch} with exactly one message
53
+ * This type is helpful as Grouping yields this kind of batch, and Compression only operates on this type of batch.
54
+ */
55
+ export type OutboundSingletonBatch = IBatch<[OutboundBatchMessage]>;
56
+
57
+ /**
58
+ * Base batch interface used internally by the runtime.
59
+ * See {@link LocalBatch} and {@link OutboundBatch} for the concrete types.
21
60
  */
22
- export interface IBatch<TMessages extends BatchMessage[] = BatchMessage[]> {
61
+ interface IBatch<TMessages extends LocalBatchMessage[] | OutboundBatchMessage[]> {
23
62
  /**
24
63
  * Sum of the in-memory content sizes of all messages in the batch.
25
64
  * If the batch is compressed, this number reflects the post-compression size.
@@ -47,7 +86,7 @@ export interface IBatch<TMessages extends BatchMessage[] = BatchMessage[]> {
47
86
  }
48
87
 
49
88
  export interface IBatchCheckpoint {
50
- rollback: (action: (message: BatchMessage) => void) => void;
89
+ rollback: (action: (message: LocalBatchMessage) => void) => void;
51
90
  }
52
91
 
53
92
  /**
@@ -12,14 +12,25 @@ export {
12
12
  generateBatchId,
13
13
  IBatchManagerOptions,
14
14
  } from "./batchManager.js";
15
- export { BatchMessage, IBatch, IBatchCheckpoint, IChunkedOp } from "./definitions.js";
15
+ export {
16
+ LocalBatch,
17
+ LocalBatchMessage,
18
+ OutboundBatch,
19
+ OutboundBatchMessage,
20
+ OutboundSingletonBatch,
21
+ IBatchCheckpoint,
22
+ IChunkedOp,
23
+ } from "./definitions.js";
16
24
  export { DuplicateBatchDetector } from "./duplicateBatchDetector.js";
17
- export { Outbox, getLongStack, serializeOpContents } from "./outbox.js";
25
+ export {
26
+ serializeOp,
27
+ ensureContentsDeserialized,
28
+ } from "./opSerialization.js";
29
+ export { Outbox, getLongStack } from "./outbox.js";
18
30
  export { OpCompressor } from "./opCompressor.js";
19
31
  export { OpDecompressor } from "./opDecompressor.js";
20
32
  export { OpSplitter, splitOp, isChunkedMessage } from "./opSplitter.js";
21
33
  export {
22
- ensureContentsDeserialized,
23
34
  InboundMessageResult,
24
35
  BatchStartInfo,
25
36
  RemoteMessageProcessor,
@@ -7,7 +7,7 @@ import { IsoBuffer } from "@fluid-internal/client-utils";
7
7
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
9
  import {
10
- UsageError,
10
+ DataProcessingError,
11
11
  createChildLogger,
12
12
  type ITelemetryLoggerExt,
13
13
  } from "@fluidframework/telemetry-utils/internal";
@@ -16,12 +16,13 @@ import { compress } from "lz4js";
16
16
  import { CompressionAlgorithms } from "../containerRuntime.js";
17
17
 
18
18
  import { estimateSocketSize } from "./batchManager.js";
19
- import { BatchMessage, IBatch } from "./definitions.js";
19
+ import { type OutboundBatchMessage, type OutboundSingletonBatch } from "./definitions.js";
20
20
 
21
21
  /**
22
- * Compresses batches of ops. It generates a single compressed op that contains
23
- * the contents of each op in the batch. It then submits empty ops for each original
24
- * op to reserve sequence numbers.
22
+ * Compresses batches of ops.
23
+ *
24
+ * @remarks Only single-message batches are supported
25
+ * Use opGroupingManager to group a batch into a singleton batch suitable for compression.
25
26
  */
26
27
  export class OpCompressor {
27
28
  private readonly logger: ITelemetryLoggerExt;
@@ -31,14 +32,12 @@ export class OpCompressor {
31
32
  }
32
33
 
33
34
  /**
34
- * Combines the contents of the batch into a single JSON string and compresses it, putting
35
- * the resulting string as the first message of the batch. The rest of the messages are
36
- * empty placeholders to reserve sequence numbers.
37
- * This should only take a single message batch and compress it.
38
- * @param batch - The batch to compress
39
- * @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
35
+ * Combines the contents of the singleton batch into a single JSON string and compresses it, putting
36
+ * the resulting string as the message contents in place of the original uncompressed payload.
37
+ * @param batch - The batch to compress. Must have only 1 message
38
+ * @returns A singleton batch containing a single compressed message
40
39
  */
41
- public compressBatch(batch: IBatch): IBatch<[BatchMessage]> {
40
+ public compressBatch(batch: OutboundSingletonBatch): OutboundSingletonBatch {
42
41
  assert(
43
42
  batch.contentSizeInBytes > 0 && batch.messages.length === 1,
44
43
  0x5a4 /* Batch should not be empty and should contain a single message */,
@@ -50,7 +49,7 @@ export class OpCompressor {
50
49
  const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
51
50
  const duration = Date.now() - compressionStart;
52
51
 
53
- const messages: [BatchMessage] = [
52
+ const messages: [OutboundBatchMessage] = [
54
53
  {
55
54
  ...batch.messages[0],
56
55
  contents: JSON.stringify({ packedContents: compressedContent }),
@@ -59,7 +58,7 @@ export class OpCompressor {
59
58
  },
60
59
  ];
61
60
 
62
- const compressedBatch = {
61
+ const compressedBatch: OutboundSingletonBatch = {
63
62
  contentSizeInBytes: compressedContent.length,
64
63
  messages,
65
64
  referenceSequenceNumber: batch.referenceSequenceNumber,
@@ -82,27 +81,29 @@ export class OpCompressor {
82
81
  /**
83
82
  * Combine the batch's content strings into a single JSON string (a serialized array)
84
83
  */
85
- private serializeBatchContents(batch: IBatch): string {
84
+ private serializeBatchContents(batch: OutboundSingletonBatch): string {
85
+ const [message, ...none] = batch.messages;
86
+ assert(none.length === 0, 0xb78 /* Batch should only contain a single message */);
86
87
  try {
87
- // Yields a valid JSON array, since each message.contents is already serialized to JSON
88
- return `[${batch.messages.map(({ contents }) => contents).join(",")}]`;
89
- } catch (newError: unknown) {
90
- if ((newError as Partial<Error>).message === "Invalid string length") {
91
- // This is how JSON.stringify signals that
88
+ // This is expressed as a JSON array, for legacy reasons
89
+ return `[${message.contents}]`;
90
+ } catch (error: unknown) {
91
+ if ((error as Partial<Error>).message === "Invalid string length") {
92
+ // This is how string interpolation signals that
92
93
  // the content size exceeds its capacity
93
- const error = new UsageError("Payload too large");
94
+ const dpe = DataProcessingError.create("Payload too large", "OpCompressor");
94
95
  this.logger.sendErrorEvent(
95
96
  {
96
97
  eventName: "BatchTooLarge",
97
98
  size: batch.contentSizeInBytes,
98
99
  length: batch.messages.length,
99
100
  },
100
- error,
101
+ dpe,
101
102
  );
102
- throw error;
103
+ throw dpe;
103
104
  }
104
105
 
105
- throw newError;
106
+ throw error;
106
107
  }
107
108
  }
108
109
  }
@@ -11,7 +11,11 @@ import {
11
11
  type ITelemetryLoggerExt,
12
12
  } from "@fluidframework/telemetry-utils/internal";
13
13
 
14
- import { IBatch, type BatchMessage } from "./definitions.js";
14
+ import {
15
+ type OutboundBatch,
16
+ type OutboundBatchMessage,
17
+ type OutboundSingletonBatch,
18
+ } from "./definitions.js";
15
19
 
16
20
  /**
17
21
  * Grouping makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
@@ -58,44 +62,51 @@ export class OpGroupingManager {
58
62
  * This is needed as a placeholder if a batch becomes empty on resubmit, but we are tracking batch IDs.
59
63
  * @param resubmittingBatchId - batch ID of the resubmitting batch
60
64
  * @param referenceSequenceNumber - reference sequence number
61
- * @returns - IBatch containing a single empty Grouped Batch op
65
+ * @returns - The outbound batch as well as the interior placeholder message
62
66
  */
63
67
  public createEmptyGroupedBatch(
64
68
  resubmittingBatchId: string,
65
69
  referenceSequenceNumber: number,
66
- ): IBatch<[BatchMessage]> {
70
+ ): { outboundBatch: OutboundSingletonBatch; placeholderMessage: OutboundBatchMessage } {
67
71
  assert(
68
72
  this.config.groupedBatchingEnabled,
69
73
  0xa00 /* cannot create empty grouped batch when grouped batching is disabled */,
70
74
  );
71
- const serializedContent = JSON.stringify({
75
+ const serializedOp = JSON.stringify({
72
76
  type: OpGroupingManager.groupedBatchOp,
73
77
  contents: [],
74
78
  });
75
79
 
76
- return {
80
+ const placeholderMessage: OutboundBatchMessage = {
81
+ metadata: { batchId: resubmittingBatchId },
82
+ localOpMetadata: { emptyBatch: true },
83
+ referenceSequenceNumber,
84
+ contents: serializedOp,
85
+ };
86
+ const outboundBatch: OutboundSingletonBatch = {
77
87
  contentSizeInBytes: 0,
78
- messages: [
79
- {
80
- metadata: { batchId: resubmittingBatchId },
81
- localOpMetadata: { emptyBatch: true },
82
- referenceSequenceNumber,
83
- contents: serializedContent,
84
- },
85
- ],
88
+ messages: [placeholderMessage],
86
89
  referenceSequenceNumber,
87
90
  };
91
+ return { outboundBatch, placeholderMessage };
88
92
  }
89
93
 
90
94
  /**
91
95
  * Converts the given batch into a "grouped batch" - a batch with a single message of type "groupedBatch",
92
96
  * with contents being an array of the original batch's messages.
93
97
  *
98
+ * If the batch already has only 1 message, it is returned as-is.
99
+ *
94
100
  * @remarks - Remember that a BatchMessage has its content JSON serialized, so the incoming batch message contents
95
101
  * must be parsed first, and then the type and contents mentioned above are hidden in that JSON serialization.
96
102
  */
97
- public groupBatch(batch: IBatch): IBatch<[BatchMessage]> {
98
- assert(this.shouldGroup(batch), 0x946 /* cannot group the provided batch */);
103
+ public groupBatch(batch: OutboundBatch): OutboundSingletonBatch {
104
+ assert(this.groupedBatchingEnabled(), 0xb79 /* grouping disabled! */);
105
+ assert(batch.messages.length > 0, 0xb7a /* Unexpected attempt to group an empty batch */);
106
+
107
+ if (batch.messages.length === 1) {
108
+ return batch as OutboundSingletonBatch;
109
+ }
99
110
 
100
111
  if (batch.messages.length >= 1000) {
101
112
  this.logger.sendTelemetryEvent({
@@ -126,7 +137,7 @@ export class OpGroupingManager {
126
137
  })),
127
138
  });
128
139
 
129
- const groupedBatch: IBatch<[BatchMessage]> = {
140
+ const groupedBatch: OutboundSingletonBatch = {
130
141
  ...batch,
131
142
  messages: [
132
143
  {
@@ -153,16 +164,6 @@ export class OpGroupingManager {
153
164
  }));
154
165
  }
155
166
 
156
- public shouldGroup(batch: IBatch): boolean {
157
- return (
158
- // Grouped batching must be enabled
159
- this.config.groupedBatchingEnabled &&
160
- // The number of ops in the batch must be 2 or more
161
- // or be empty (to allow for empty batches to be grouped)
162
- batch.messages.length !== 1
163
- // Support for reentrant batches will be on by default
164
- );
165
- }
166
167
  public groupedBatchingEnabled(): boolean {
167
168
  return this.config.groupedBatchingEnabled;
168
169
  }
@@ -0,0 +1,46 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
7
+ import {
8
+ encodeHandleForSerialization,
9
+ isFluidHandle,
10
+ toFluidHandleInternal,
11
+ } from "@fluidframework/runtime-utils/internal";
12
+
13
+ import type { LocalContainerRuntimeMessage } from "../messageTypes.js";
14
+
15
+ /**
16
+ * Takes an incoming runtime message (outer type "op"), JSON.parses the message's contents in place,
17
+ * if needed (old Loader does this for us).
18
+ * Only to be used for runtime messages. The contents here would be the virtualized payload for a batch of ops.
19
+ * @remarks - Serialization during submit happens via {@link serializeOp}
20
+ * @param mutableMessage - op message received
21
+ */
22
+ export function ensureContentsDeserialized(mutableMessage: ISequencedDocumentMessage): void {
23
+ // This should become unconditional once Loader LTS reaches 2.4 or later.
24
+ // There will be a long time of needing both cases, until LTS advances to that point.
25
+ if (typeof mutableMessage.contents === "string" && mutableMessage.contents !== "") {
26
+ mutableMessage.contents = JSON.parse(mutableMessage.contents);
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Before submitting an op to the Outbox, its contents must be serialized using this function.
32
+ * @remarks - The deserialization on process happens via the function {@link ensureContentsDeserialized}.
33
+ */
34
+ export function serializeOp(op: LocalContainerRuntimeMessage): string {
35
+ return JSON.stringify(
36
+ op,
37
+ // replacer:
38
+ (key, value: unknown) => {
39
+ // If 'value' is an IFluidHandle return its encoded form.
40
+ if (isFluidHandle(value)) {
41
+ return encodeHandleForSerialization(toFluidHandleInternal(value));
42
+ }
43
+ return value;
44
+ },
45
+ );
46
+ }
@@ -17,7 +17,11 @@ import {
17
17
  import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes.js";
18
18
 
19
19
  import { estimateSocketSize } from "./batchManager.js";
20
- import { BatchMessage, IBatch, IChunkedOp } from "./definitions.js";
20
+ import {
21
+ IChunkedOp,
22
+ type OutboundBatchMessage,
23
+ type OutboundSingletonBatch,
24
+ } from "./definitions.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[] => {