@fluidframework/container-runtime 2.0.0-rc.4.0.6 → 2.0.0-rc.5.0.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 (424) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  3. package/api-extractor/api-extractor-lint-legacy.cjs.json +5 -0
  4. package/api-extractor/api-extractor-lint-legacy.esm.json +5 -0
  5. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  6. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  7. package/api-extractor.json +1 -1
  8. package/api-report/{container-runtime.api.md → container-runtime.alpha.api.md} +33 -516
  9. package/api-report/container-runtime.beta.api.md +73 -0
  10. package/api-report/container-runtime.public.api.md +73 -0
  11. package/biome.jsonc +4 -0
  12. package/container-runtime.test-files.tar +0 -0
  13. package/dist/batchTracker.d.ts.map +1 -1
  14. package/dist/batchTracker.js.map +1 -1
  15. package/dist/blobManager.d.ts +3 -20
  16. package/dist/blobManager.d.ts.map +1 -1
  17. package/dist/blobManager.js +1 -35
  18. package/dist/blobManager.js.map +1 -1
  19. package/dist/channelCollection.d.ts +21 -12
  20. package/dist/channelCollection.d.ts.map +1 -1
  21. package/dist/channelCollection.js +113 -110
  22. package/dist/channelCollection.js.map +1 -1
  23. package/dist/connectionTelemetry.d.ts +1 -1
  24. package/dist/connectionTelemetry.d.ts.map +1 -1
  25. package/dist/connectionTelemetry.js +14 -14
  26. package/dist/connectionTelemetry.js.map +1 -1
  27. package/dist/containerHandleContext.d.ts +2 -1
  28. package/dist/containerHandleContext.d.ts.map +1 -1
  29. package/dist/containerHandleContext.js.map +1 -1
  30. package/dist/containerRuntime.d.ts +17 -34
  31. package/dist/containerRuntime.d.ts.map +1 -1
  32. package/dist/containerRuntime.js +109 -145
  33. package/dist/containerRuntime.js.map +1 -1
  34. package/dist/dataStore.d.ts.map +1 -1
  35. package/dist/dataStore.js.map +1 -1
  36. package/dist/dataStoreContext.d.ts +30 -44
  37. package/dist/dataStoreContext.d.ts.map +1 -1
  38. package/dist/dataStoreContext.js +26 -40
  39. package/dist/dataStoreContext.js.map +1 -1
  40. package/dist/dataStoreContexts.d.ts.map +1 -1
  41. package/dist/dataStoreContexts.js.map +1 -1
  42. package/dist/dataStoreRegistry.js.map +1 -1
  43. package/dist/deltaManagerProxies.d.ts +4 -3
  44. package/dist/deltaManagerProxies.d.ts.map +1 -1
  45. package/dist/deltaManagerProxies.js.map +1 -1
  46. package/dist/deltaScheduler.d.ts +1 -1
  47. package/dist/deltaScheduler.d.ts.map +1 -1
  48. package/dist/deltaScheduler.js +1 -3
  49. package/dist/deltaScheduler.js.map +1 -1
  50. package/dist/gc/garbageCollection.d.ts +5 -5
  51. package/dist/gc/garbageCollection.d.ts.map +1 -1
  52. package/dist/gc/garbageCollection.js +29 -30
  53. package/dist/gc/garbageCollection.js.map +1 -1
  54. package/dist/gc/gcConfigs.d.ts.map +1 -1
  55. package/dist/gc/gcConfigs.js +12 -31
  56. package/dist/gc/gcConfigs.js.map +1 -1
  57. package/dist/gc/gcDefinitions.d.ts +10 -38
  58. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  59. package/dist/gc/gcDefinitions.js +1 -5
  60. package/dist/gc/gcDefinitions.js.map +1 -1
  61. package/dist/gc/gcHelpers.d.ts +2 -3
  62. package/dist/gc/gcHelpers.d.ts.map +1 -1
  63. package/dist/gc/gcHelpers.js.map +1 -1
  64. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  65. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  66. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
  67. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  68. package/dist/gc/gcSummaryStateTracker.d.ts +2 -35
  69. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  70. package/dist/gc/gcSummaryStateTracker.js +9 -62
  71. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  72. package/dist/gc/gcTelemetry.d.ts +2 -2
  73. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  74. package/dist/gc/gcTelemetry.js +3 -9
  75. package/dist/gc/gcTelemetry.js.map +1 -1
  76. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  77. package/dist/gc/index.d.ts +1 -1
  78. package/dist/gc/index.d.ts.map +1 -1
  79. package/dist/gc/index.js +1 -3
  80. package/dist/gc/index.js.map +1 -1
  81. package/dist/index.d.ts +2 -2
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js.map +1 -1
  84. package/dist/legacy.d.ts +1 -1
  85. package/dist/messageTypes.d.ts +6 -22
  86. package/dist/messageTypes.d.ts.map +1 -1
  87. package/dist/messageTypes.js.map +1 -1
  88. package/dist/opLifecycle/batchManager.js.map +1 -1
  89. package/dist/opLifecycle/definitions.d.ts +2 -2
  90. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  91. package/dist/opLifecycle/definitions.js.map +1 -1
  92. package/dist/opLifecycle/index.d.ts +1 -1
  93. package/dist/opLifecycle/index.d.ts.map +1 -1
  94. package/dist/opLifecycle/index.js.map +1 -1
  95. package/dist/opLifecycle/opCompressor.d.ts +11 -1
  96. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  97. package/dist/opLifecycle/opCompressor.js +13 -2
  98. package/dist/opLifecycle/opCompressor.js.map +1 -1
  99. package/dist/opLifecycle/opDecompressor.d.ts +1 -1
  100. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  101. package/dist/opLifecycle/opDecompressor.js +1 -2
  102. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  103. package/dist/opLifecycle/opGroupingManager.d.ts +10 -3
  104. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  105. package/dist/opLifecycle/opGroupingManager.js +7 -0
  106. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  107. package/dist/opLifecycle/opSplitter.d.ts +4 -2
  108. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  109. package/dist/opLifecycle/opSplitter.js +13 -8
  110. package/dist/opLifecycle/opSplitter.js.map +1 -1
  111. package/dist/opLifecycle/outbox.d.ts +10 -0
  112. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  113. package/dist/opLifecycle/outbox.js +13 -18
  114. package/dist/opLifecycle/outbox.js.map +1 -1
  115. package/dist/opLifecycle/remoteMessageProcessor.d.ts +1 -1
  116. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  117. package/dist/opLifecycle/remoteMessageProcessor.js +2 -2
  118. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  119. package/dist/opProperties.d.ts +1 -1
  120. package/dist/opProperties.d.ts.map +1 -1
  121. package/dist/opProperties.js.map +1 -1
  122. package/dist/packageVersion.d.ts +1 -1
  123. package/dist/packageVersion.js +1 -1
  124. package/dist/packageVersion.js.map +1 -1
  125. package/dist/pendingStateManager.d.ts.map +1 -1
  126. package/dist/pendingStateManager.js +15 -5
  127. package/dist/pendingStateManager.js.map +1 -1
  128. package/dist/scheduleManager.d.ts +1 -1
  129. package/dist/scheduleManager.d.ts.map +1 -1
  130. package/dist/scheduleManager.js.map +1 -1
  131. package/dist/storageServiceWithAttachBlobs.js.map +1 -1
  132. package/dist/summary/documentSchema.d.ts.map +1 -1
  133. package/dist/summary/documentSchema.js +2 -3
  134. package/dist/summary/documentSchema.js.map +1 -1
  135. package/dist/summary/index.d.ts +2 -2
  136. package/dist/summary/index.d.ts.map +1 -1
  137. package/dist/summary/index.js.map +1 -1
  138. package/dist/summary/orderedClientElection.d.ts +4 -2
  139. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  140. package/dist/summary/orderedClientElection.js +35 -13
  141. package/dist/summary/orderedClientElection.js.map +1 -1
  142. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  143. package/dist/summary/runningSummarizer.d.ts +1 -6
  144. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  145. package/dist/summary/runningSummarizer.js +23 -110
  146. package/dist/summary/runningSummarizer.js.map +1 -1
  147. package/dist/summary/summarizer.d.ts +1 -1
  148. package/dist/summary/summarizer.d.ts.map +1 -1
  149. package/dist/summary/summarizer.js +4 -1
  150. package/dist/summary/summarizer.js.map +1 -1
  151. package/dist/summary/summarizerClientElection.d.ts +1 -1
  152. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  153. package/dist/summary/summarizerClientElection.js +2 -2
  154. package/dist/summary/summarizerClientElection.js.map +1 -1
  155. package/dist/summary/summarizerHeuristics.js.map +1 -1
  156. package/dist/summary/summarizerNode/summarizerNode.d.ts +2 -3
  157. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  158. package/dist/summary/summarizerNode/summarizerNode.js +16 -16
  159. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  160. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
  161. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  162. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  163. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -3
  164. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  165. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +5 -2
  166. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  167. package/dist/summary/summarizerTypes.d.ts +17 -29
  168. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  169. package/dist/summary/summarizerTypes.js.map +1 -1
  170. package/dist/summary/summaryCollection.d.ts +1 -1
  171. package/dist/summary/summaryCollection.d.ts.map +1 -1
  172. package/dist/summary/summaryCollection.js +11 -11
  173. package/dist/summary/summaryCollection.js.map +1 -1
  174. package/dist/summary/summaryFormat.d.ts +2 -3
  175. package/dist/summary/summaryFormat.d.ts.map +1 -1
  176. package/dist/summary/summaryFormat.js +2 -2
  177. package/dist/summary/summaryFormat.js.map +1 -1
  178. package/dist/summary/summaryGenerator.d.ts +7 -8
  179. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  180. package/dist/summary/summaryGenerator.js +27 -24
  181. package/dist/summary/summaryGenerator.js.map +1 -1
  182. package/dist/summary/summaryManager.d.ts.map +1 -1
  183. package/dist/summary/summaryManager.js +1 -2
  184. package/dist/summary/summaryManager.js.map +1 -1
  185. package/dist/throttler.d.ts.map +1 -1
  186. package/dist/throttler.js +3 -1
  187. package/dist/throttler.js.map +1 -1
  188. package/lib/batchTracker.d.ts.map +1 -1
  189. package/lib/batchTracker.js +1 -1
  190. package/lib/batchTracker.js.map +1 -1
  191. package/lib/blobManager.d.ts +3 -20
  192. package/lib/blobManager.d.ts.map +1 -1
  193. package/lib/blobManager.js +2 -36
  194. package/lib/blobManager.js.map +1 -1
  195. package/lib/channelCollection.d.ts +21 -12
  196. package/lib/channelCollection.d.ts.map +1 -1
  197. package/lib/channelCollection.js +114 -112
  198. package/lib/channelCollection.js.map +1 -1
  199. package/lib/connectionTelemetry.d.ts +1 -1
  200. package/lib/connectionTelemetry.d.ts.map +1 -1
  201. package/lib/connectionTelemetry.js +2 -2
  202. package/lib/connectionTelemetry.js.map +1 -1
  203. package/lib/containerHandleContext.d.ts +2 -1
  204. package/lib/containerHandleContext.d.ts.map +1 -1
  205. package/lib/containerHandleContext.js.map +1 -1
  206. package/lib/containerRuntime.d.ts +17 -34
  207. package/lib/containerRuntime.d.ts.map +1 -1
  208. package/lib/containerRuntime.js +106 -142
  209. package/lib/containerRuntime.js.map +1 -1
  210. package/lib/dataStore.d.ts.map +1 -1
  211. package/lib/dataStore.js.map +1 -1
  212. package/lib/dataStoreContext.d.ts +30 -44
  213. package/lib/dataStoreContext.d.ts.map +1 -1
  214. package/lib/dataStoreContext.js +29 -43
  215. package/lib/dataStoreContext.js.map +1 -1
  216. package/lib/dataStoreContexts.d.ts.map +1 -1
  217. package/lib/dataStoreContexts.js +1 -1
  218. package/lib/dataStoreContexts.js.map +1 -1
  219. package/lib/dataStoreRegistry.js.map +1 -1
  220. package/lib/deltaManagerProxies.d.ts +4 -3
  221. package/lib/deltaManagerProxies.d.ts.map +1 -1
  222. package/lib/deltaManagerProxies.js.map +1 -1
  223. package/lib/deltaScheduler.d.ts +1 -1
  224. package/lib/deltaScheduler.d.ts.map +1 -1
  225. package/lib/deltaScheduler.js +1 -3
  226. package/lib/deltaScheduler.js.map +1 -1
  227. package/lib/gc/garbageCollection.d.ts +5 -5
  228. package/lib/gc/garbageCollection.d.ts.map +1 -1
  229. package/lib/gc/garbageCollection.js +30 -31
  230. package/lib/gc/garbageCollection.js.map +1 -1
  231. package/lib/gc/gcConfigs.d.ts.map +1 -1
  232. package/lib/gc/gcConfigs.js +13 -32
  233. package/lib/gc/gcConfigs.js.map +1 -1
  234. package/lib/gc/gcDefinitions.d.ts +10 -38
  235. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  236. package/lib/gc/gcDefinitions.js +0 -4
  237. package/lib/gc/gcDefinitions.js.map +1 -1
  238. package/lib/gc/gcHelpers.d.ts +2 -3
  239. package/lib/gc/gcHelpers.d.ts.map +1 -1
  240. package/lib/gc/gcHelpers.js.map +1 -1
  241. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  242. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  243. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
  244. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  245. package/lib/gc/gcSummaryStateTracker.d.ts +2 -35
  246. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  247. package/lib/gc/gcSummaryStateTracker.js +4 -57
  248. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  249. package/lib/gc/gcTelemetry.d.ts +2 -2
  250. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  251. package/lib/gc/gcTelemetry.js +3 -9
  252. package/lib/gc/gcTelemetry.js.map +1 -1
  253. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  254. package/lib/gc/index.d.ts +1 -1
  255. package/lib/gc/index.d.ts.map +1 -1
  256. package/lib/gc/index.js +1 -1
  257. package/lib/gc/index.js.map +1 -1
  258. package/lib/index.d.ts +2 -2
  259. package/lib/index.d.ts.map +1 -1
  260. package/lib/index.js.map +1 -1
  261. package/lib/legacy.d.ts +1 -1
  262. package/lib/messageTypes.d.ts +6 -22
  263. package/lib/messageTypes.d.ts.map +1 -1
  264. package/lib/messageTypes.js.map +1 -1
  265. package/lib/opLifecycle/batchManager.js.map +1 -1
  266. package/lib/opLifecycle/definitions.d.ts +2 -2
  267. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  268. package/lib/opLifecycle/definitions.js.map +1 -1
  269. package/lib/opLifecycle/index.d.ts +1 -1
  270. package/lib/opLifecycle/index.d.ts.map +1 -1
  271. package/lib/opLifecycle/index.js +1 -1
  272. package/lib/opLifecycle/index.js.map +1 -1
  273. package/lib/opLifecycle/opCompressor.d.ts +11 -1
  274. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  275. package/lib/opLifecycle/opCompressor.js +13 -2
  276. package/lib/opLifecycle/opCompressor.js.map +1 -1
  277. package/lib/opLifecycle/opDecompressor.d.ts +1 -1
  278. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  279. package/lib/opLifecycle/opDecompressor.js +1 -2
  280. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  281. package/lib/opLifecycle/opGroupingManager.d.ts +10 -3
  282. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  283. package/lib/opLifecycle/opGroupingManager.js +7 -0
  284. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  285. package/lib/opLifecycle/opSplitter.d.ts +4 -2
  286. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  287. package/lib/opLifecycle/opSplitter.js +13 -8
  288. package/lib/opLifecycle/opSplitter.js.map +1 -1
  289. package/lib/opLifecycle/outbox.d.ts +10 -0
  290. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  291. package/lib/opLifecycle/outbox.js +13 -18
  292. package/lib/opLifecycle/outbox.js.map +1 -1
  293. package/lib/opLifecycle/remoteMessageProcessor.d.ts +1 -1
  294. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  295. package/lib/opLifecycle/remoteMessageProcessor.js +1 -1
  296. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  297. package/lib/opProperties.d.ts +1 -1
  298. package/lib/opProperties.d.ts.map +1 -1
  299. package/lib/opProperties.js.map +1 -1
  300. package/lib/packageVersion.d.ts +1 -1
  301. package/lib/packageVersion.js +1 -1
  302. package/lib/packageVersion.js.map +1 -1
  303. package/lib/pendingStateManager.d.ts.map +1 -1
  304. package/lib/pendingStateManager.js +15 -5
  305. package/lib/pendingStateManager.js.map +1 -1
  306. package/lib/scheduleManager.d.ts +1 -1
  307. package/lib/scheduleManager.d.ts.map +1 -1
  308. package/lib/scheduleManager.js.map +1 -1
  309. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  310. package/lib/summary/documentSchema.d.ts.map +1 -1
  311. package/lib/summary/documentSchema.js +2 -3
  312. package/lib/summary/documentSchema.js.map +1 -1
  313. package/lib/summary/index.d.ts +2 -2
  314. package/lib/summary/index.d.ts.map +1 -1
  315. package/lib/summary/index.js +1 -1
  316. package/lib/summary/index.js.map +1 -1
  317. package/lib/summary/orderedClientElection.d.ts +4 -2
  318. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  319. package/lib/summary/orderedClientElection.js +35 -13
  320. package/lib/summary/orderedClientElection.js.map +1 -1
  321. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  322. package/lib/summary/runningSummarizer.d.ts +1 -6
  323. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  324. package/lib/summary/runningSummarizer.js +22 -109
  325. package/lib/summary/runningSummarizer.js.map +1 -1
  326. package/lib/summary/summarizer.d.ts +1 -1
  327. package/lib/summary/summarizer.d.ts.map +1 -1
  328. package/lib/summary/summarizer.js +4 -1
  329. package/lib/summary/summarizer.js.map +1 -1
  330. package/lib/summary/summarizerClientElection.d.ts +1 -1
  331. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  332. package/lib/summary/summarizerClientElection.js +1 -1
  333. package/lib/summary/summarizerClientElection.js.map +1 -1
  334. package/lib/summary/summarizerHeuristics.js.map +1 -1
  335. package/lib/summary/summarizerNode/summarizerNode.d.ts +2 -3
  336. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  337. package/lib/summary/summarizerNode/summarizerNode.js +14 -14
  338. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  339. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
  340. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  341. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  342. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -3
  343. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  344. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +5 -2
  345. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  346. package/lib/summary/summarizerTypes.d.ts +17 -29
  347. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  348. package/lib/summary/summarizerTypes.js.map +1 -1
  349. package/lib/summary/summaryCollection.d.ts +1 -1
  350. package/lib/summary/summaryCollection.d.ts.map +1 -1
  351. package/lib/summary/summaryCollection.js +3 -3
  352. package/lib/summary/summaryCollection.js.map +1 -1
  353. package/lib/summary/summaryFormat.d.ts +2 -3
  354. package/lib/summary/summaryFormat.d.ts.map +1 -1
  355. package/lib/summary/summaryFormat.js +2 -2
  356. package/lib/summary/summaryFormat.js.map +1 -1
  357. package/lib/summary/summaryGenerator.d.ts +7 -8
  358. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  359. package/lib/summary/summaryGenerator.js +26 -23
  360. package/lib/summary/summaryGenerator.js.map +1 -1
  361. package/lib/summary/summaryManager.d.ts.map +1 -1
  362. package/lib/summary/summaryManager.js +1 -2
  363. package/lib/summary/summaryManager.js.map +1 -1
  364. package/lib/throttler.d.ts.map +1 -1
  365. package/lib/throttler.js +3 -1
  366. package/lib/throttler.js.map +1 -1
  367. package/lib/tsdoc-metadata.json +1 -1
  368. package/package.json +92 -28
  369. package/src/batchTracker.ts +5 -2
  370. package/src/blobManager.ts +21 -61
  371. package/src/channelCollection.ts +179 -186
  372. package/src/connectionTelemetry.ts +18 -12
  373. package/src/containerHandleContext.ts +2 -1
  374. package/src/containerRuntime.ts +166 -214
  375. package/src/dataStore.ts +2 -1
  376. package/src/dataStoreContext.ts +79 -98
  377. package/src/dataStoreContexts.ts +7 -2
  378. package/src/deltaManagerProxies.ts +15 -6
  379. package/src/deltaScheduler.ts +5 -4
  380. package/src/gc/garbageCollection.md +0 -8
  381. package/src/gc/garbageCollection.ts +66 -57
  382. package/src/gc/gcConfigs.ts +15 -37
  383. package/src/gc/gcDefinitions.ts +20 -39
  384. package/src/gc/gcHelpers.ts +8 -4
  385. package/src/gc/gcSummaryDefinitions.ts +1 -1
  386. package/src/gc/gcSummaryStateTracker.ts +11 -74
  387. package/src/gc/gcTelemetry.ts +4 -11
  388. package/src/gc/index.ts +0 -2
  389. package/src/index.ts +1 -2
  390. package/src/messageTypes.ts +8 -24
  391. package/src/opLifecycle/README.md +120 -160
  392. package/src/opLifecycle/definitions.ts +2 -2
  393. package/src/opLifecycle/index.ts +5 -1
  394. package/src/opLifecycle/opCompressor.ts +13 -2
  395. package/src/opLifecycle/opDecompressor.ts +3 -7
  396. package/src/opLifecycle/opGroupingManager.ts +12 -8
  397. package/src/opLifecycle/opSplitter.ts +22 -11
  398. package/src/opLifecycle/outbox.ts +14 -32
  399. package/src/opLifecycle/remoteMessageProcessor.ts +4 -1
  400. package/src/opProperties.ts +2 -2
  401. package/src/packageVersion.ts +1 -1
  402. package/src/pendingStateManager.ts +20 -7
  403. package/src/scheduleManager.ts +4 -1
  404. package/src/summary/documentSchema.ts +4 -7
  405. package/src/summary/images/appTree.png +0 -0
  406. package/src/summary/images/protocolAndAppTree.png +0 -0
  407. package/src/summary/images/summaryTree.png +0 -0
  408. package/src/summary/index.ts +5 -2
  409. package/src/summary/orderedClientElection.ts +100 -22
  410. package/src/summary/runningSummarizer.ts +54 -124
  411. package/src/summary/summarizer.ts +5 -2
  412. package/src/summary/summarizerClientElection.ts +4 -2
  413. package/src/summary/summarizerNode/summarizerNode.ts +23 -30
  414. package/src/summary/summarizerNode/summarizerNodeUtils.ts +9 -3
  415. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +11 -11
  416. package/src/summary/summarizerTypes.ts +32 -33
  417. package/src/summary/summaryCollection.ts +6 -3
  418. package/src/summary/summaryFormat.ts +18 -10
  419. package/src/summary/summaryFormats.md +160 -0
  420. package/src/summary/summaryGenerator.ts +47 -30
  421. package/src/summary/summaryManager.ts +6 -9
  422. package/src/throttler.ts +3 -1
  423. package/tsconfig.json +2 -0
  424. package/tsdoc.json +4 -0
@@ -2,8 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
5
6
  import type { IdCreationRange } from "@fluidframework/id-compressor/internal";
6
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
7
7
  import { IAttachMessage, IEnvelope, InboundAttachMessage } from "@fluidframework/runtime-definitions/internal";
8
8
  import { IDataStoreAliasMessage } from "./dataStore.js";
9
9
  import { GarbageCollectionMessage } from "./gc/index.js";
@@ -38,6 +38,7 @@ export declare enum ContainerMessageType {
38
38
  /**
39
39
  * How should an older client handle an unrecognized remote op type?
40
40
  *
41
+ * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
41
42
  * @internal
42
43
  */
43
44
  export type CompatModeBehavior =
@@ -48,6 +49,7 @@ export type CompatModeBehavior =
48
49
  /**
49
50
  * All the info an older client would need to know how to handle an unrecognized remote op type
50
51
  *
52
+ * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
51
53
  * @internal
52
54
  */
53
55
  export interface IContainerRuntimeMessageCompatDetails {
@@ -61,7 +63,7 @@ export interface IContainerRuntimeMessageCompatDetails {
61
63
  * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
62
64
  * This way stringified values can be compared.
63
65
  */
64
- interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> extends Partial<RecentlyAddedContainerRuntimeMessageDetails> {
66
+ interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {
65
67
  /** Type of the op, within the ContainerRuntime's domain */
66
68
  type: TType;
67
69
  /** Domain-specific contents, interpreted according to the type */
@@ -69,6 +71,7 @@ interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TCont
69
71
  }
70
72
  /**
71
73
  * Additional details expected for any recently added message.
74
+ * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
72
75
  * @internal
73
76
  */
74
77
  export interface RecentlyAddedContainerRuntimeMessageDetails {
@@ -83,7 +86,7 @@ export type ContainerRuntimeBlobAttachMessage = TypedContainerRuntimeMessage<Con
83
86
  export type ContainerRuntimeRejoinMessage = TypedContainerRuntimeMessage<ContainerMessageType.Rejoin, undefined>;
84
87
  export type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<ContainerMessageType.Alias, IDataStoreAliasMessage>;
85
88
  export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<ContainerMessageType.IdAllocation, IdCreationRange>;
86
- export type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<ContainerMessageType.GC, GarbageCollectionMessage>;
89
+ export type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<ContainerMessageType.GC, GarbageCollectionMessage> & Partial<RecentlyAddedContainerRuntimeMessageDetails>;
87
90
  export type ContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage<ContainerMessageType.DocumentSchemaChange, IDocumentSchemaChangeMessage>;
88
91
  /**
89
92
  * Represents an unrecognized TypedContainerRuntimeMessage, e.g. a message from a future version of the container runtime.
@@ -128,24 +131,5 @@ export type InboundSequencedContainerRuntimeMessageOrSystemMessage = InboundSequ
128
131
  * It exists solely to to provide access to those details.
129
132
  */
130
133
  export type InboundSequencedRecentlyAddedContainerRuntimeMessage = ISequencedDocumentMessage & Partial<RecentlyAddedContainerRuntimeMessageDetails>;
131
- /**
132
- * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime
133
- *
134
- * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
135
- * This way stringified values can be compared.
136
- *
137
- * @deprecated this is an internal type which should not be used outside of the package.
138
- * Internally, it is superseded by `TypedContainerRuntimeMessage`.
139
- *
140
- * @internal
141
- */
142
- export interface ContainerRuntimeMessage {
143
- /** Type of the op, within the ContainerRuntime's domain */
144
- type: ContainerMessageType;
145
- /** Domain-specific contents, interpreted according to the type */
146
- contents: any;
147
- /** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */
148
- compatDetails?: IContainerRuntimeMessageCompatDetails;
149
- }
150
134
  export {};
151
135
  //# sourceMappingURL=messageTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messageTypes.d.ts","sourceRoot":"","sources":["../src/messageTypes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messageTypes.d.ts","sourceRoot":"","sources":["../src/messageTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EACN,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAElE;;GAEG;AACH,oBAAY,oBAAoB;IAE/B,gBAAgB,cAAc;IAG9B,MAAM,WAAW;IAGjB,SAAS,cAAc;IAGvB,UAAU,eAAe;IAGzB,MAAM,WAAW;IAGjB,KAAK,UAAU;IAEf;;;;OAIG;IACH,YAAY,iBAAiB;IAE7B;;OAEG;IACH,oBAAoB,WAAW;IAE/B;;;OAGG;IACH,EAAE,OAAO;CACT;AAED;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB;AAC7B,qEAAqE;AACnE,QAAQ;AACV,8DAA8D;GAC5D,eAAe,CAAC;AAEnB;;;;;GAKG;AACH,MAAM,WAAW,qCAAqC;IACrD,wEAAwE;IACxE,QAAQ,EAAE,kBAAkB,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,UAAU,4BAA4B,CAAC,KAAK,SAAS,oBAAoB,EAAE,SAAS;IACnF,2DAA2D;IAC3D,IAAI,EAAE,KAAK,CAAC;IACZ,kEAAkE;IAClE,QAAQ,EAAE,SAAS,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,2CAA2C;IAC3D,wGAAwG;IACxG,aAAa,EAAE,qCAAqC,CAAC;CACrD;AAED,MAAM,MAAM,kCAAkC,GAAG,4BAA4B,CAC5E,oBAAoB,CAAC,gBAAgB,EACrC,SAAS,CACT,CAAC;AACF,MAAM,MAAM,oCAAoC,GAAG,4BAA4B,CAC9E,oBAAoB,CAAC,MAAM,EAC3B,oBAAoB,CACpB,CAAC;AACF,MAAM,MAAM,qCAAqC,GAAG,4BAA4B,CAC/E,oBAAoB,CAAC,MAAM,EAC3B,cAAc,CACd,CAAC;AACF,MAAM,MAAM,gCAAgC,GAAG,4BAA4B,CAC1E,oBAAoB,CAAC,SAAS,EAC9B,UAAU,CACV,CAAC;AACF,MAAM,MAAM,iCAAiC,GAAG,4BAA4B,CAC3E,oBAAoB,CAAC,UAAU,EAC/B,SAAS,CACT,CAAC;AACF,MAAM,MAAM,6BAA6B,GAAG,4BAA4B,CACvE,oBAAoB,CAAC,MAAM,EAC3B,SAAS,CACT,CAAC;AACF,MAAM,MAAM,4BAA4B,GAAG,4BAA4B,CACtE,oBAAoB,CAAC,KAAK,EAC1B,sBAAsB,CACtB,CAAC;AACF,MAAM,MAAM,mCAAmC,GAAG,4BAA4B,CAC7E,oBAAoB,CAAC,YAAY,EACjC,eAAe,CACf,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,4BAA4B,CACnE,oBAAoB,CAAC,EAAE,EACvB,wBAAwB,CACxB,GAEA,OAAO,CAAC,2CAA2C,CAAC,CAAC;AACtD,MAAM,MAAM,qCAAqC,GAAG,4BAA4B,CAC/E,oBAAoB,CAAC,oBAAoB,EACzC,4BAA4B,CAC5B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,8BAChB,SAAQ,OAAO,CAAC,2CAA2C,CAAC;IAC5D;;;OAGG;IACH,IAAI,EAAE,wDAAwD,CAAC;IAE/D,uEAAuE;IACvE,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,8BAA8B,GACvC,kCAAkC,GAClC,oCAAoC,GACpC,gCAAgC,GAChC,iCAAiC,GACjC,6BAA6B,GAC7B,4BAA4B,GAC5B,mCAAmC,GACnC,yBAAyB,GAEzB,8BAA8B,GAC9B,qCAAqC,CAAC;AAEzC;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GACrC,kCAAkC,GAClC,qCAAqC,GACrC,iCAAiC,GACjC,6BAA6B,GAC7B,4BAA4B,GAC5B,mCAAmC,GACnC,yBAAyB,GAEzB,8BAA8B,GAC9B,qCAAqC,CAAC;AAEzC,0GAA0G;AAC1G,MAAM,MAAM,+BAA+B,GACxC,kCAAkC,GAClC,qCAAqC,GACrC,gCAAgC,GAChC,iCAAiC,GACjC,6BAA6B,GAC7B,4BAA4B,GAC5B,mCAAmC,GACnC,yBAAyB,GACzB,qCAAqC,CAAC;AAEzC;;;GAGG;AACH,MAAM,MAAM,uCAAuC,GAAG,IAAI,CACzD,yBAAyB,EACzB,MAAM,GAAG,UAAU,CACnB,GACA,8BAA8B,CAAC;AAEhC;;;;GAIG;AACH,KAAK,0CAA0C,GAAG,IAAI,CACrD,yBAAyB,EACzB,MAAM,GAAG,UAAU,CACnB,GAAG;IAAE,IAAI,EAAE,0CAA0C,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5E,MAAM,MAAM,sDAAsD,GAC/D,uCAAuC,GACvC,0CAA0C,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,oDAAoD,GAAG,yBAAyB,GAC3F,OAAO,CAAC,2CAA2C,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"messageTypes.js","sourceRoot":"","sources":["../src/messageTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;GAEG;AACH,MAAM,CAAN,IAAY,oBAoCX;AApCD,WAAY,oBAAoB;IAC/B,iCAAiC;IACjC,sDAA8B,CAAA;IAE9B,sBAAsB;IACtB,yCAAiB,CAAA;IAEjB,qBAAqB;IACrB,+CAAuB,CAAA;IAEvB,yFAAyF;IACzF,iDAAyB,CAAA;IAEzB,oDAAoD;IACpD,yCAAiB,CAAA;IAEjB,sCAAsC;IACtC,uCAAe,CAAA;IAEf;;;;OAIG;IACH,qDAA6B,CAAA;IAE7B;;OAEG;IACH,uDAA+B,CAAA;IAE/B;;;OAGG;IACH,iCAAS,CAAA;AACV,CAAC,EApCW,oBAAoB,KAApB,oBAAoB,QAoC/B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IdCreationRange } from \"@fluidframework/id-compressor/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIAttachMessage,\n\tIEnvelope,\n\tInboundAttachMessage,\n} from \"@fluidframework/runtime-definitions/internal\";\n\nimport { IDataStoreAliasMessage } from \"./dataStore.js\";\nimport { GarbageCollectionMessage } from \"./gc/index.js\";\nimport { IChunkedOp } from \"./opLifecycle/index.js\";\nimport { IDocumentSchemaChangeMessage } from \"./summary/index.js\";\n\n/**\n * @alpha\n */\nexport enum ContainerMessageType {\n\t// An op to be delivered to store\n\tFluidDataStoreOp = \"component\",\n\n\t// Creates a new store\n\tAttach = \"attach\",\n\n\t// Chunked operation.\n\tChunkedOp = \"chunkedOp\",\n\n\t// Signifies that a blob has been attached and should not be garbage collected by storage\n\tBlobAttach = \"blobAttach\",\n\n\t// Ties our new clientId to our old one on reconnect\n\tRejoin = \"rejoin\",\n\n\t// Sets the alias of a root data store\n\tAlias = \"alias\",\n\n\t/**\n\t * An op containing an IdRange of Ids allocated using the runtime's IdCompressor since\n\t * the last allocation op was sent.\n\t * See the [IdCompressor README](./id-compressor/README.md) for more details.\n\t */\n\tIdAllocation = \"idAllocation\",\n\n\t/**\n\t * An op that changes document schema\n\t */\n\tDocumentSchemaChange = \"schema\",\n\n\t/**\n\t * Garbage collection specific op. This is sent by the summarizer client when GC runs. It's used to synchronize GC\n\t * state across all clients.\n\t */\n\tGC = \"GC\",\n}\n\n/**\n * How should an older client handle an unrecognized remote op type?\n *\n * @internal\n */\nexport type CompatModeBehavior =\n\t/** Ignore the op. It won't be persisted if this client summarizes */\n\t| \"Ignore\"\n\t/** Fail processing immediately. (The container will close) */\n\t| \"FailToProcess\";\n\n/**\n * All the info an older client would need to know how to handle an unrecognized remote op type\n *\n * @internal\n */\nexport interface IContainerRuntimeMessageCompatDetails {\n\t/** How should an older client handle an unrecognized remote op type? */\n\tbehavior: CompatModeBehavior;\n}\n\n/**\n * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime.\n * Message type are differentiated via a `type` string and contain different contents depending on their type.\n *\n * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.\n * This way stringified values can be compared.\n */\ninterface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents>\n\textends Partial<RecentlyAddedContainerRuntimeMessageDetails> {\n\t/** Type of the op, within the ContainerRuntime's domain */\n\ttype: TType;\n\t/** Domain-specific contents, interpreted according to the type */\n\tcontents: TContents;\n}\n\n/**\n * Additional details expected for any recently added message.\n * @internal\n */\nexport interface RecentlyAddedContainerRuntimeMessageDetails {\n\t/** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */\n\tcompatDetails: IContainerRuntimeMessageCompatDetails;\n}\n\nexport type ContainerRuntimeDataStoreOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.FluidDataStoreOp,\n\tIEnvelope\n>;\nexport type InboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tInboundAttachMessage\n>;\nexport type OutboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tIAttachMessage\n>;\nexport type ContainerRuntimeChunkedOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.ChunkedOp,\n\tIChunkedOp\n>;\nexport type ContainerRuntimeBlobAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.BlobAttach,\n\tundefined\n>;\nexport type ContainerRuntimeRejoinMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Rejoin,\n\tundefined\n>;\nexport type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Alias,\n\tIDataStoreAliasMessage\n>;\nexport type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.IdAllocation,\n\tIdCreationRange\n>;\nexport type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.GC,\n\tGarbageCollectionMessage\n>;\nexport type ContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.DocumentSchemaChange,\n\tIDocumentSchemaChangeMessage\n>;\n\n/**\n * Represents an unrecognized TypedContainerRuntimeMessage, e.g. a message from a future version of the container runtime.\n * @internal\n */\nexport interface UnknownContainerRuntimeMessage\n\textends Partial<RecentlyAddedContainerRuntimeMessageDetails> {\n\t/** Invalid type of the op, within the ContainerRuntime's domain. This value should never exist at runtime.\n\t * This is useful for type narrowing but should never be used as an actual message type at runtime.\n\t * Actual value will not be \"__unknown...\", but the type `Exclude<string, ContainerMessageType>` is not supported.\n\t */\n\ttype: \"__unknown_container_message_type__never_use_as_value__\";\n\n\t/** Domain-specific contents, but not decipherable by an unknown op. */\n\tcontents: unknown;\n}\n\n/**\n * A {@link TypedContainerRuntimeMessage} that is received from the server and will be processed by the container runtime.\n */\nexport type InboundContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| InboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeChunkedOpMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t// Inbound messages may include unknown types from other clients, so we include that as a special case here\n\t| UnknownContainerRuntimeMessage\n\t| ContainerRuntimeDocumentSchemaMessage;\n\n/**\n * A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime but is not yet being sent to the server.\n * These are messages generated by the local runtime, before the outbox's op virtualization step.\n */\nexport type LocalContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| OutboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t// In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type\n\t| UnknownContainerRuntimeMessage\n\t| ContainerRuntimeDocumentSchemaMessage;\n\n/** A {@link TypedContainerRuntimeMessage} that is being sent to the server from the container runtime. */\nexport type OutboundContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| OutboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeChunkedOpMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t| ContainerRuntimeDocumentSchemaMessage;\n\n/**\n * An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc\n * promoted up to the outer object\n */\nexport type InboundSequencedContainerRuntimeMessage = Omit<\n\tISequencedDocumentMessage,\n\t\"type\" | \"contents\"\n> &\n\tInboundContainerRuntimeMessage;\n\n/** Essentially ISequencedDocumentMessage except that `type` is not `string` to enable narrowing\n * as `Exclude<string, InboundContainerRuntimeMessage['type']>` is not supported.\n * There should never be a runtime value of \"__not_a_...\".\n * Currently additionally replaces `contents` type until protocol-definitions update is taken with `unknown` instead of `any`.\n */\ntype InboundSequencedNonContainerRuntimeMessage = Omit<\n\tISequencedDocumentMessage,\n\t\"type\" | \"contents\"\n> & { type: \"__not_a_container_runtime_message_type__\"; contents: unknown };\n\nexport type InboundSequencedContainerRuntimeMessageOrSystemMessage =\n\t| InboundSequencedContainerRuntimeMessage\n\t| InboundSequencedNonContainerRuntimeMessage;\n\n/** A [loose] InboundSequencedContainerRuntimeMessage that is recent and may contain compat details.\n * It exists solely to to provide access to those details.\n */\nexport type InboundSequencedRecentlyAddedContainerRuntimeMessage = ISequencedDocumentMessage &\n\tPartial<RecentlyAddedContainerRuntimeMessageDetails>;\n\n/**\n * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime\n *\n * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.\n * This way stringified values can be compared.\n *\n * @deprecated this is an internal type which should not be used outside of the package.\n * Internally, it is superseded by `TypedContainerRuntimeMessage`.\n *\n * @internal\n */\nexport interface ContainerRuntimeMessage {\n\t/** Type of the op, within the ContainerRuntime's domain */\n\ttype: ContainerMessageType;\n\t/** Domain-specific contents, interpreted according to the type */\n\tcontents: any;\n\t/** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */\n\tcompatDetails?: IContainerRuntimeMessageCompatDetails;\n}\n"]}
1
+ {"version":3,"file":"messageTypes.js","sourceRoot":"","sources":["../src/messageTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;GAEG;AACH,MAAM,CAAN,IAAY,oBAoCX;AApCD,WAAY,oBAAoB;IAC/B,iCAAiC;IACjC,sDAA8B,CAAA;IAE9B,sBAAsB;IACtB,yCAAiB,CAAA;IAEjB,qBAAqB;IACrB,+CAAuB,CAAA;IAEvB,yFAAyF;IACzF,iDAAyB,CAAA;IAEzB,oDAAoD;IACpD,yCAAiB,CAAA;IAEjB,sCAAsC;IACtC,uCAAe,CAAA;IAEf;;;;OAIG;IACH,qDAA6B,CAAA;IAE7B;;OAEG;IACH,uDAA+B,CAAA;IAE/B;;;OAGG;IACH,iCAAS,CAAA;AACV,CAAC,EApCW,oBAAoB,KAApB,oBAAoB,QAoC/B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IdCreationRange } from \"@fluidframework/id-compressor/internal\";\nimport {\n\tIAttachMessage,\n\tIEnvelope,\n\tInboundAttachMessage,\n} from \"@fluidframework/runtime-definitions/internal\";\n\nimport { IDataStoreAliasMessage } from \"./dataStore.js\";\nimport { GarbageCollectionMessage } from \"./gc/index.js\";\nimport { IChunkedOp } from \"./opLifecycle/index.js\";\nimport { IDocumentSchemaChangeMessage } from \"./summary/index.js\";\n\n/**\n * @alpha\n */\nexport enum ContainerMessageType {\n\t// An op to be delivered to store\n\tFluidDataStoreOp = \"component\",\n\n\t// Creates a new store\n\tAttach = \"attach\",\n\n\t// Chunked operation.\n\tChunkedOp = \"chunkedOp\",\n\n\t// Signifies that a blob has been attached and should not be garbage collected by storage\n\tBlobAttach = \"blobAttach\",\n\n\t// Ties our new clientId to our old one on reconnect\n\tRejoin = \"rejoin\",\n\n\t// Sets the alias of a root data store\n\tAlias = \"alias\",\n\n\t/**\n\t * An op containing an IdRange of Ids allocated using the runtime's IdCompressor since\n\t * the last allocation op was sent.\n\t * See the [IdCompressor README](./id-compressor/README.md) for more details.\n\t */\n\tIdAllocation = \"idAllocation\",\n\n\t/**\n\t * An op that changes document schema\n\t */\n\tDocumentSchemaChange = \"schema\",\n\n\t/**\n\t * Garbage collection specific op. This is sent by the summarizer client when GC runs. It's used to synchronize GC\n\t * state across all clients.\n\t */\n\tGC = \"GC\",\n}\n\n/**\n * How should an older client handle an unrecognized remote op type?\n *\n * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.\n * @internal\n */\nexport type CompatModeBehavior =\n\t/** Ignore the op. It won't be persisted if this client summarizes */\n\t| \"Ignore\"\n\t/** Fail processing immediately. (The container will close) */\n\t| \"FailToProcess\";\n\n/**\n * All the info an older client would need to know how to handle an unrecognized remote op type\n *\n * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.\n * @internal\n */\nexport interface IContainerRuntimeMessageCompatDetails {\n\t/** How should an older client handle an unrecognized remote op type? */\n\tbehavior: CompatModeBehavior;\n}\n\n/**\n * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime.\n * Message type are differentiated via a `type` string and contain different contents depending on their type.\n *\n * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.\n * This way stringified values can be compared.\n */\ninterface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {\n\t/** Type of the op, within the ContainerRuntime's domain */\n\ttype: TType;\n\t/** Domain-specific contents, interpreted according to the type */\n\tcontents: TContents;\n}\n\n/**\n * Additional details expected for any recently added message.\n * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.\n * @internal\n */\nexport interface RecentlyAddedContainerRuntimeMessageDetails {\n\t/** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */\n\tcompatDetails: IContainerRuntimeMessageCompatDetails;\n}\n\nexport type ContainerRuntimeDataStoreOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.FluidDataStoreOp,\n\tIEnvelope\n>;\nexport type InboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tInboundAttachMessage\n>;\nexport type OutboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tIAttachMessage\n>;\nexport type ContainerRuntimeChunkedOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.ChunkedOp,\n\tIChunkedOp\n>;\nexport type ContainerRuntimeBlobAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.BlobAttach,\n\tundefined\n>;\nexport type ContainerRuntimeRejoinMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Rejoin,\n\tundefined\n>;\nexport type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Alias,\n\tIDataStoreAliasMessage\n>;\nexport type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.IdAllocation,\n\tIdCreationRange\n>;\nexport type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.GC,\n\tGarbageCollectionMessage\n> &\n\t// While deprecating: GC messages may still contain compat details for now\n\tPartial<RecentlyAddedContainerRuntimeMessageDetails>;\nexport type ContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.DocumentSchemaChange,\n\tIDocumentSchemaChangeMessage\n>;\n\n/**\n * Represents an unrecognized TypedContainerRuntimeMessage, e.g. a message from a future version of the container runtime.\n * @internal\n */\nexport interface UnknownContainerRuntimeMessage\n\textends Partial<RecentlyAddedContainerRuntimeMessageDetails> {\n\t/** Invalid type of the op, within the ContainerRuntime's domain. This value should never exist at runtime.\n\t * This is useful for type narrowing but should never be used as an actual message type at runtime.\n\t * Actual value will not be \"__unknown...\", but the type `Exclude<string, ContainerMessageType>` is not supported.\n\t */\n\ttype: \"__unknown_container_message_type__never_use_as_value__\";\n\n\t/** Domain-specific contents, but not decipherable by an unknown op. */\n\tcontents: unknown;\n}\n\n/**\n * A {@link TypedContainerRuntimeMessage} that is received from the server and will be processed by the container runtime.\n */\nexport type InboundContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| InboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeChunkedOpMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t// Inbound messages may include unknown types from other clients, so we include that as a special case here\n\t| UnknownContainerRuntimeMessage\n\t| ContainerRuntimeDocumentSchemaMessage;\n\n/**\n * A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime but is not yet being sent to the server.\n * These are messages generated by the local runtime, before the outbox's op virtualization step.\n */\nexport type LocalContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| OutboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t// In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type\n\t| UnknownContainerRuntimeMessage\n\t| ContainerRuntimeDocumentSchemaMessage;\n\n/** A {@link TypedContainerRuntimeMessage} that is being sent to the server from the container runtime. */\nexport type OutboundContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| OutboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeChunkedOpMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t| ContainerRuntimeDocumentSchemaMessage;\n\n/**\n * An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc\n * promoted up to the outer object\n */\nexport type InboundSequencedContainerRuntimeMessage = Omit<\n\tISequencedDocumentMessage,\n\t\"type\" | \"contents\"\n> &\n\tInboundContainerRuntimeMessage;\n\n/** Essentially ISequencedDocumentMessage except that `type` is not `string` to enable narrowing\n * as `Exclude<string, InboundContainerRuntimeMessage['type']>` is not supported.\n * There should never be a runtime value of \"__not_a_...\".\n * Currently additionally replaces `contents` type until protocol-definitions update is taken with `unknown` instead of `any`.\n */\ntype InboundSequencedNonContainerRuntimeMessage = Omit<\n\tISequencedDocumentMessage,\n\t\"type\" | \"contents\"\n> & { type: \"__not_a_container_runtime_message_type__\"; contents: unknown };\n\nexport type InboundSequencedContainerRuntimeMessageOrSystemMessage =\n\t| InboundSequencedContainerRuntimeMessage\n\t| InboundSequencedNonContainerRuntimeMessage;\n\n/** A [loose] InboundSequencedContainerRuntimeMessage that is recent and may contain compat details.\n * It exists solely to to provide access to those details.\n */\nexport type InboundSequencedRecentlyAddedContainerRuntimeMessage = ISequencedDocumentMessage &\n\tPartial<RecentlyAddedContainerRuntimeMessageDetails>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"batchManager.js","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ICompressionRuntimeOptions } from \"../containerRuntime.js\";\n\nimport { BatchMessage, IBatch, IBatchCheckpoint } from \"./definitions.js\";\n\nexport interface IBatchManagerOptions {\n\treadonly hardLimit: number;\n\treadonly compressionOptions?: ICompressionRuntimeOptions;\n\n\t/**\n\t * If true, the outbox is allowed to rebase the batch during flushing.\n\t */\n\treadonly canRebase: boolean;\n}\n\nexport interface BatchSequenceNumbers {\n\treferenceSequenceNumber?: number;\n\tclientSequenceNumber?: number;\n}\n\n/**\n * Estimated size of the stringification overhead for an op accumulated\n * from runtime to loader to the service.\n */\nconst opOverhead = 200;\n\n/**\n * Helper class that manages partial batch & rollback.\n */\nexport class BatchManager {\n\tprivate pendingBatch: BatchMessage[] = [];\n\tprivate batchContentSize = 0;\n\tprivate hasReentrantOps = false;\n\n\tpublic get length() {\n\t\treturn this.pendingBatch.length;\n\t}\n\tpublic get contentSizeInBytes() {\n\t\treturn this.batchContentSize;\n\t}\n\n\tpublic get sequenceNumbers(): BatchSequenceNumbers {\n\t\treturn {\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\tclientSequenceNumber: this.clientSequenceNumber,\n\t\t};\n\t}\n\n\tprivate get referenceSequenceNumber(): number | undefined {\n\t\treturn this.pendingBatch.length === 0\n\t\t\t? undefined\n\t\t\t: this.pendingBatch[this.pendingBatch.length - 1].referenceSequenceNumber;\n\t}\n\n\tprivate clientSequenceNumber: number | undefined;\n\n\tconstructor(public readonly options: IBatchManagerOptions) {}\n\n\tpublic push(\n\t\tmessage: BatchMessage,\n\t\treentrant: boolean,\n\t\tcurrentClientSequenceNumber?: number,\n\t): boolean {\n\t\tconst contentSize = this.batchContentSize + (message.contents?.length ?? 0);\n\t\tconst opCount = this.pendingBatch.length;\n\t\tthis.hasReentrantOps = this.hasReentrantOps || reentrant;\n\n\t\t// Attempt to estimate batch size, aka socket message size.\n\t\t// Each op has pretty large envelope, estimating to be 200 bytes.\n\t\t// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.\n\t\t// Not taking it into account, as compression work should help there - compressed payload will be\n\t\t// initially stored as base64, and that requires only 2 extra escape characters.\n\t\tconst socketMessageSize = contentSize + opOverhead * opCount;\n\n\t\tif (socketMessageSize >= this.options.hardLimit) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.pendingBatch.length === 0) {\n\t\t\tthis.clientSequenceNumber = currentClientSequenceNumber;\n\t\t}\n\n\t\tthis.batchContentSize = contentSize;\n\t\tthis.pendingBatch.push(message);\n\t\treturn true;\n\t}\n\n\tpublic get empty() {\n\t\treturn this.pendingBatch.length === 0;\n\t}\n\n\tpublic popBatch(): IBatch {\n\t\tconst batch: IBatch = {\n\t\t\tcontent: this.pendingBatch,\n\t\t\tcontentSizeInBytes: this.batchContentSize,\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\thasReentrantOps: this.hasReentrantOps,\n\t\t};\n\n\t\tthis.pendingBatch = [];\n\t\tthis.batchContentSize = 0;\n\t\tthis.clientSequenceNumber = undefined;\n\t\tthis.hasReentrantOps = false;\n\n\t\treturn addBatchMetadata(batch);\n\t}\n\n\t/**\n\t * Capture the pending state at this point\n\t */\n\tpublic checkpoint(): IBatchCheckpoint {\n\t\tconst startPoint = this.pendingBatch.length;\n\t\treturn {\n\t\t\trollback: (process: (message: BatchMessage) => void) => {\n\t\t\t\tfor (let i = this.pendingBatch.length; i > startPoint; ) {\n\t\t\t\t\ti--;\n\t\t\t\t\tconst message = this.pendingBatch[i];\n\t\t\t\t\tthis.batchContentSize -= message.contents?.length ?? 0;\n\t\t\t\t\tprocess(message);\n\t\t\t\t}\n\n\t\t\t\tthis.pendingBatch.length = startPoint;\n\t\t\t},\n\t\t};\n\t}\n}\n\nconst addBatchMetadata = (batch: IBatch): IBatch => {\n\tif (batch.content.length > 1) {\n\t\tbatch.content[0].metadata = {\n\t\t\t...batch.content[0].metadata,\n\t\t\tbatch: true,\n\t\t};\n\t\tbatch.content[batch.content.length - 1].metadata = {\n\t\t\t...batch.content[batch.content.length - 1].metadata,\n\t\t\tbatch: false,\n\t\t};\n\t}\n\n\treturn batch;\n};\n\n/**\n * Estimates the real size in bytes on the socket for a given batch. It assumes that\n * the envelope size (and the size of an empty op) is 200 bytes, taking into account\n * extra overhead from stringification.\n *\n * @param batch - the batch to inspect\n * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire\n */\nexport const estimateSocketSize = (batch: IBatch): number => {\n\treturn batch.contentSizeInBytes + opOverhead * batch.content.length;\n};\n\nexport const sequenceNumbersMatch = (\n\tseqNums: BatchSequenceNumbers,\n\totherSeqNums: BatchSequenceNumbers,\n): boolean => {\n\treturn (\n\t\t(seqNums.referenceSequenceNumber === undefined ||\n\t\t\totherSeqNums.referenceSequenceNumber === undefined ||\n\t\t\tseqNums.referenceSequenceNumber === otherSeqNums.referenceSequenceNumber) &&\n\t\t(seqNums.clientSequenceNumber === undefined ||\n\t\t\totherSeqNums.clientSequenceNumber === undefined ||\n\t\t\tseqNums.clientSequenceNumber === otherSeqNums.clientSequenceNumber)\n\t);\n};\n"]}
1
+ {"version":3,"file":"batchManager.js","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ICompressionRuntimeOptions } from \"../containerRuntime.js\";\n\nimport { BatchMessage, IBatch, IBatchCheckpoint } from \"./definitions.js\";\n\nexport interface IBatchManagerOptions {\n\treadonly hardLimit: number;\n\treadonly compressionOptions?: ICompressionRuntimeOptions;\n\n\t/**\n\t * If true, the outbox is allowed to rebase the batch during flushing.\n\t */\n\treadonly canRebase: boolean;\n}\n\nexport interface BatchSequenceNumbers {\n\treferenceSequenceNumber?: number;\n\tclientSequenceNumber?: number;\n}\n\n/**\n * Estimated size of the stringification overhead for an op accumulated\n * from runtime to loader to the service.\n */\nconst opOverhead = 200;\n\n/**\n * Helper class that manages partial batch & rollback.\n */\nexport class BatchManager {\n\tprivate pendingBatch: BatchMessage[] = [];\n\tprivate batchContentSize = 0;\n\tprivate hasReentrantOps = false;\n\n\tpublic get length() {\n\t\treturn this.pendingBatch.length;\n\t}\n\tpublic get contentSizeInBytes() {\n\t\treturn this.batchContentSize;\n\t}\n\n\tpublic get sequenceNumbers(): BatchSequenceNumbers {\n\t\treturn {\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\tclientSequenceNumber: this.clientSequenceNumber,\n\t\t};\n\t}\n\n\tprivate get referenceSequenceNumber(): number | undefined {\n\t\treturn this.pendingBatch.length === 0\n\t\t\t? undefined\n\t\t\t: this.pendingBatch[this.pendingBatch.length - 1].referenceSequenceNumber;\n\t}\n\n\tprivate clientSequenceNumber: number | undefined;\n\n\tconstructor(public readonly options: IBatchManagerOptions) {}\n\n\tpublic push(\n\t\tmessage: BatchMessage,\n\t\treentrant: boolean,\n\t\tcurrentClientSequenceNumber?: number,\n\t): boolean {\n\t\tconst contentSize = this.batchContentSize + (message.contents?.length ?? 0);\n\t\tconst opCount = this.pendingBatch.length;\n\t\tthis.hasReentrantOps = this.hasReentrantOps || reentrant;\n\n\t\t// Attempt to estimate batch size, aka socket message size.\n\t\t// Each op has pretty large envelope, estimating to be 200 bytes.\n\t\t// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.\n\t\t// Not taking it into account, as compression work should help there - compressed payload will be\n\t\t// initially stored as base64, and that requires only 2 extra escape characters.\n\t\tconst socketMessageSize = contentSize + opOverhead * opCount;\n\n\t\tif (socketMessageSize >= this.options.hardLimit) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.pendingBatch.length === 0) {\n\t\t\tthis.clientSequenceNumber = currentClientSequenceNumber;\n\t\t}\n\n\t\tthis.batchContentSize = contentSize;\n\t\tthis.pendingBatch.push(message);\n\t\treturn true;\n\t}\n\n\tpublic get empty() {\n\t\treturn this.pendingBatch.length === 0;\n\t}\n\n\tpublic popBatch(): IBatch {\n\t\tconst batch: IBatch = {\n\t\t\tcontent: this.pendingBatch,\n\t\t\tcontentSizeInBytes: this.batchContentSize,\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\thasReentrantOps: this.hasReentrantOps,\n\t\t};\n\n\t\tthis.pendingBatch = [];\n\t\tthis.batchContentSize = 0;\n\t\tthis.clientSequenceNumber = undefined;\n\t\tthis.hasReentrantOps = false;\n\n\t\treturn addBatchMetadata(batch);\n\t}\n\n\t/**\n\t * Capture the pending state at this point\n\t */\n\tpublic checkpoint(): IBatchCheckpoint {\n\t\tconst startPoint = this.pendingBatch.length;\n\t\treturn {\n\t\t\trollback: (process: (message: BatchMessage) => void) => {\n\t\t\t\tfor (let i = this.pendingBatch.length; i > startPoint; ) {\n\t\t\t\t\ti--;\n\t\t\t\t\tconst message = this.pendingBatch[i];\n\t\t\t\t\tthis.batchContentSize -= message.contents?.length ?? 0;\n\t\t\t\t\tprocess(message);\n\t\t\t\t}\n\n\t\t\t\tthis.pendingBatch.length = startPoint;\n\t\t\t},\n\t\t};\n\t}\n}\n\nconst addBatchMetadata = (batch: IBatch): IBatch => {\n\tif (batch.content.length > 1) {\n\t\tbatch.content[0].metadata = {\n\t\t\t...batch.content[0].metadata,\n\t\t\tbatch: true,\n\t\t};\n\t\tbatch.content[batch.content.length - 1].metadata = {\n\t\t\t...batch.content[batch.content.length - 1].metadata,\n\t\t\tbatch: false,\n\t\t};\n\t}\n\n\treturn batch;\n};\n\n/**\n * Estimates the real size in bytes on the socket for a given batch. It assumes that\n * the envelope size (and the size of an empty op) is 200 bytes, taking into account\n * extra overhead from stringification.\n *\n * @param batch - the batch to inspect\n * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire\n */\nexport const estimateSocketSize = (batch: IBatch): number => {\n\treturn batch.contentSizeInBytes + opOverhead * batch.content.length;\n};\n\nexport const sequenceNumbersMatch = (\n\tseqNums: BatchSequenceNumbers,\n\totherSeqNums: BatchSequenceNumbers,\n): boolean => {\n\treturn (\n\t\t(seqNums.referenceSequenceNumber === undefined ||\n\t\t\totherSeqNums.referenceSequenceNumber === undefined ||\n\t\t\tseqNums.referenceSequenceNumber === otherSeqNums.referenceSequenceNumber) &&\n\t\t(seqNums.clientSequenceNumber === undefined ||\n\t\t\totherSeqNums.clientSequenceNumber === undefined ||\n\t\t\tseqNums.clientSequenceNumber === otherSeqNums.clientSequenceNumber)\n\t);\n};\n"]}
@@ -15,7 +15,7 @@ export type BatchMessage = IBatchMessage & {
15
15
  /**
16
16
  * Batch interface used internally by the runtime.
17
17
  */
18
- export interface IBatch {
18
+ export interface IBatch<TMessages extends BatchMessage[] = BatchMessage[]> {
19
19
  /**
20
20
  * Sum of the in-memory content sizes of all messages in the batch.
21
21
  * If the batch is compressed, this number reflects the post-compression size.
@@ -24,7 +24,7 @@ export interface IBatch {
24
24
  /**
25
25
  * All the messages in the batch
26
26
  */
27
- readonly content: BatchMessage[];
27
+ readonly content: TMessages;
28
28
  /**
29
29
  * The reference sequence number for the batch
30
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAE/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,MAAM;IACtB;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;IACjC;;OAEG;IACH,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrD;;;;;;;;;OASG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,KAAK,IAAI,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAE/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,SAAS,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE;IACxE;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrD;;;;;;;;;OASG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,KAAK,IAAI,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IBatchMessage } from \"@fluidframework/container-definitions/internal\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\n\n/**\n * Batch message type used internally by the runtime\n */\nexport type BatchMessage = IBatchMessage & {\n\tlocalOpMetadata?: unknown;\n\treferenceSequenceNumber: number;\n\tcompression?: CompressionAlgorithms;\n};\n\n/**\n * Batch interface used internally by the runtime.\n */\nexport interface IBatch {\n\t/**\n\t * Sum of the in-memory content sizes of all messages in the batch.\n\t * If the batch is compressed, this number reflects the post-compression size.\n\t */\n\treadonly contentSizeInBytes: number;\n\t/**\n\t * All the messages in the batch\n\t */\n\treadonly content: BatchMessage[];\n\t/**\n\t * The reference sequence number for the batch\n\t */\n\treadonly referenceSequenceNumber: number | undefined;\n\t/**\n\t * Wether or not the batch contains at least one op which was produced as the result\n\t * of processing another op. This means that the batch must be rebased before\n\t * submitted, to ensure that all ops have the same reference sequence numbers and a\n\t * consistent view of the data model. This happens when the op is created within a\n\t * 'changed' event handler of a DDS and will have a different reference sequence number\n\t * than the rest of the ops in the batch, meaning that it has a different view of the\n\t * state of the data model, therefore all ops must be resubmitted and rebased to the current\n\t * reference sequence number to be in agreement about the data model state.\n\t */\n\treadonly hasReentrantOps?: boolean;\n}\n\nexport interface IBatchCheckpoint {\n\trollback: (action: (message: BatchMessage) => void) => void;\n}\n\n/**\n * @internal\n */\nexport interface IChunkedOp {\n\tchunkId: number;\n\ttotalChunks: number;\n\tcontents: string;\n\toriginalMetadata?: Record<string, unknown>;\n\toriginalCompression?: string;\n}\n\n/**\n * The state of remote message processing:\n * `Processed` - the message can be considered processed\n * `Skipped` - the message was ignored by the processor\n * `Accepted` - the message was processed partially. Eventually, a message\n * will make the processor return `Processed`.\n */\nexport type ProcessingState = \"Processed\" | \"Skipped\" | \"Accepted\";\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IBatchMessage } from \"@fluidframework/container-definitions/internal\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\n\n/**\n * Batch message type used internally by the runtime\n */\nexport type BatchMessage = IBatchMessage & {\n\tlocalOpMetadata?: unknown;\n\treferenceSequenceNumber: number;\n\tcompression?: CompressionAlgorithms;\n};\n\n/**\n * Batch interface used internally by the runtime.\n */\nexport interface IBatch<TMessages extends BatchMessage[] = BatchMessage[]> {\n\t/**\n\t * Sum of the in-memory content sizes of all messages in the batch.\n\t * If the batch is compressed, this number reflects the post-compression size.\n\t */\n\treadonly contentSizeInBytes: number;\n\t/**\n\t * All the messages in the batch\n\t */\n\treadonly content: TMessages;\n\t/**\n\t * The reference sequence number for the batch\n\t */\n\treadonly referenceSequenceNumber: number | undefined;\n\t/**\n\t * Wether or not the batch contains at least one op which was produced as the result\n\t * of processing another op. This means that the batch must be rebased before\n\t * submitted, to ensure that all ops have the same reference sequence numbers and a\n\t * consistent view of the data model. This happens when the op is created within a\n\t * 'changed' event handler of a DDS and will have a different reference sequence number\n\t * than the rest of the ops in the batch, meaning that it has a different view of the\n\t * state of the data model, therefore all ops must be resubmitted and rebased to the current\n\t * reference sequence number to be in agreement about the data model state.\n\t */\n\treadonly hasReentrantOps?: boolean;\n}\n\nexport interface IBatchCheckpoint {\n\trollback: (action: (message: BatchMessage) => void) => void;\n}\n\n/**\n * @internal\n */\nexport interface IChunkedOp {\n\tchunkId: number;\n\ttotalChunks: number;\n\tcontents: string;\n\toriginalMetadata?: Record<string, unknown>;\n\toriginalCompression?: string;\n}\n\n/**\n * The state of remote message processing:\n * `Processed` - the message can be considered processed\n * `Skipped` - the message was ignored by the processor\n * `Accepted` - the message was processed partially. Eventually, a message\n * will make the processor return `Processed`.\n */\nexport type ProcessingState = \"Processed\" | \"Skipped\" | \"Accepted\";\n"]}
@@ -9,5 +9,5 @@ export { OpCompressor } from "./opCompressor.js";
9
9
  export { OpDecompressor } from "./opDecompressor.js";
10
10
  export { OpSplitter, splitOp, isChunkedMessage } from "./opSplitter.js";
11
11
  export { RemoteMessageProcessor, unpackRuntimeMessage } from "./remoteMessageProcessor.js";
12
- export { OpGroupingManager, OpGroupingManagerConfig, isGroupedBatch } from "./opGroupingManager.js";
12
+ export { OpGroupingManager, OpGroupingManagerConfig, isGroupedBatch, } from "./opGroupingManager.js";
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACN,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,GACd,MAAM,wBAAwB,CAAC"}
@@ -8,5 +8,5 @@ export { OpCompressor } from "./opCompressor.js";
8
8
  export { OpDecompressor } from "./opDecompressor.js";
9
9
  export { OpSplitter, splitOp, isChunkedMessage } from "./opSplitter.js";
10
10
  export { RemoteMessageProcessor, unpackRuntimeMessage } from "./remoteMessageProcessor.js";
11
- export { OpGroupingManager, isGroupedBatch } from "./opGroupingManager.js";
11
+ export { OpGroupingManager, isGroupedBatch, } from "./opGroupingManager.js";
12
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAwB,MAAM,mBAAmB,CAAC;AAE3F,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAA2B,cAAc,EAAE,MAAM,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { BatchManager, estimateSocketSize, BatchSequenceNumbers } from \"./batchManager.js\";\nexport { BatchMessage, IBatch, IBatchCheckpoint, IChunkedOp } from \"./definitions.js\";\nexport { Outbox, getLongStack } from \"./outbox.js\";\nexport { OpCompressor } from \"./opCompressor.js\";\nexport { OpDecompressor } from \"./opDecompressor.js\";\nexport { OpSplitter, splitOp, isChunkedMessage } from \"./opSplitter.js\";\nexport { RemoteMessageProcessor, unpackRuntimeMessage } from \"./remoteMessageProcessor.js\";\nexport { OpGroupingManager, OpGroupingManagerConfig, isGroupedBatch } from \"./opGroupingManager.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAwB,MAAM,mBAAmB,CAAC;AAE3F,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACN,iBAAiB,EAEjB,cAAc,GACd,MAAM,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { BatchManager, estimateSocketSize, BatchSequenceNumbers } from \"./batchManager.js\";\nexport { BatchMessage, IBatch, IBatchCheckpoint, IChunkedOp } from \"./definitions.js\";\nexport { Outbox, getLongStack } from \"./outbox.js\";\nexport { OpCompressor } from \"./opCompressor.js\";\nexport { OpDecompressor } from \"./opDecompressor.js\";\nexport { OpSplitter, splitOp, isChunkedMessage } from \"./opSplitter.js\";\nexport { RemoteMessageProcessor, unpackRuntimeMessage } from \"./remoteMessageProcessor.js\";\nexport {\n\tOpGroupingManager,\n\tOpGroupingManagerConfig,\n\tisGroupedBatch,\n} from \"./opGroupingManager.js\";\n"]}
@@ -12,7 +12,17 @@ import { IBatch } from "./definitions.js";
12
12
  export declare class OpCompressor {
13
13
  private readonly logger;
14
14
  constructor(logger: ITelemetryBaseLogger);
15
+ /**
16
+ * Combines the contents of the batch into a single JSON string and compresses it, putting
17
+ * the resulting string as the first message of the batch. The rest of the messages are
18
+ * empty placeholders to reserve sequence numbers.
19
+ * @param batch - The batch to compress
20
+ * @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
21
+ */
15
22
  compressBatch(batch: IBatch): IBatch;
16
- private serializeBatch;
23
+ /**
24
+ * Combine the batch's content strings into a single JSON string (a serialized array)
25
+ */
26
+ private serializeBatchContents;
17
27
  }
18
28
  //# sourceMappingURL=opCompressor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opCompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAQvE,OAAO,EAAgB,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;GAIG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAEZ,MAAM,EAAE,oBAAoB;IAIjC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAiD3C,OAAO,CAAC,cAAc;CAsBtB"}
1
+ {"version":3,"file":"opCompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAQvE,OAAO,EAAgB,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;GAIG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAEZ,MAAM,EAAE,oBAAoB;IAIxC;;;;;;OAMG;IACI,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAiD3C;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAuB9B"}
@@ -17,10 +17,17 @@ export class OpCompressor {
17
17
  constructor(logger) {
18
18
  this.logger = createChildLogger({ logger, namespace: "OpCompressor" });
19
19
  }
20
+ /**
21
+ * Combines the contents of the batch into a single JSON string and compresses it, putting
22
+ * the resulting string as the first message of the batch. The rest of the messages are
23
+ * empty placeholders to reserve sequence numbers.
24
+ * @param batch - The batch to compress
25
+ * @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
26
+ */
20
27
  compressBatch(batch) {
21
28
  assert(batch.contentSizeInBytes > 0 && batch.content.length > 0, 0x5a4 /* Batch should not be empty */);
22
29
  const compressionStart = Date.now();
23
- const contentsAsBuffer = new TextEncoder().encode(this.serializeBatch(batch));
30
+ const contentsAsBuffer = new TextEncoder().encode(this.serializeBatchContents(batch));
24
31
  const compressedContents = compress(contentsAsBuffer);
25
32
  const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
26
33
  const duration = Date.now() - compressionStart;
@@ -56,8 +63,12 @@ export class OpCompressor {
56
63
  }
57
64
  return compressedBatch;
58
65
  }
59
- serializeBatch(batch) {
66
+ /**
67
+ * Combine the batch's content strings into a single JSON string (a serialized array)
68
+ */
69
+ serializeBatchContents(batch) {
60
70
  try {
71
+ // Yields a valid JSON array, since each message.contents is already serialized to JSON
61
72
  return `[${batch.content.map((message) => message.contents).join(",")}]`;
62
73
  }
63
74
  catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"opCompressor.js","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IsoBuffer } from \"@fluid-internal/client-utils\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { UsageError, createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { compress } from \"lz4js\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\n\nimport { estimateSocketSize } from \"./batchManager.js\";\nimport { BatchMessage, IBatch } from \"./definitions.js\";\n\n/**\n * Compresses batches of ops. It generates a single compressed op that contains\n * the contents of each op in the batch. It then submits empty ops for each original\n * op to reserve sequence numbers.\n */\nexport class OpCompressor {\n\tprivate readonly logger;\n\n\tconstructor(logger: ITelemetryBaseLogger) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"OpCompressor\" });\n\t}\n\n\tpublic compressBatch(batch: IBatch): IBatch {\n\t\tassert(\n\t\t\tbatch.contentSizeInBytes > 0 && batch.content.length > 0,\n\t\t\t0x5a4 /* Batch should not be empty */,\n\t\t);\n\n\t\tconst compressionStart = Date.now();\n\t\tconst contentsAsBuffer = new TextEncoder().encode(this.serializeBatch(batch));\n\t\tconst compressedContents = compress(contentsAsBuffer);\n\t\tconst compressedContent = IsoBuffer.from(compressedContents).toString(\"base64\");\n\t\tconst duration = Date.now() - compressionStart;\n\n\t\tconst messages: BatchMessage[] = [];\n\t\tmessages.push({\n\t\t\t...batch.content[0],\n\t\t\tcontents: JSON.stringify({ packedContents: compressedContent }),\n\t\t\tmetadata: batch.content[0].metadata,\n\t\t\tcompression: CompressionAlgorithms.lz4,\n\t\t});\n\n\t\t// Add empty placeholder messages to reserve the sequence numbers\n\t\tfor (const message of batch.content.slice(1)) {\n\t\t\tmessages.push({\n\t\t\t\tlocalOpMetadata: message.localOpMetadata,\n\t\t\t\tmetadata: message.metadata,\n\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t});\n\t\t}\n\n\t\tconst compressedBatch: IBatch = {\n\t\t\tcontentSizeInBytes: compressedContent.length,\n\t\t\tcontent: messages,\n\t\t\treferenceSequenceNumber: batch.referenceSequenceNumber,\n\t\t};\n\n\t\tif (batch.contentSizeInBytes > 200000) {\n\t\t\tthis.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"CompressedBatch\",\n\t\t\t\tduration,\n\t\t\t\tsizeBeforeCompression: batch.contentSizeInBytes,\n\t\t\t\tsizeAfterCompression: compressedBatch.contentSizeInBytes,\n\t\t\t\topCount: compressedBatch.content.length,\n\t\t\t\tsocketSize: estimateSocketSize(compressedBatch),\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\tprivate serializeBatch(batch: IBatch): string {\n\t\ttry {\n\t\t\treturn `[${batch.content.map((message) => message.contents).join(\",\")}]`;\n\t\t} catch (e: any) {\n\t\t\tif (e.message === \"Invalid string length\") {\n\t\t\t\t// This is how JSON.stringify signals that\n\t\t\t\t// the content size exceeds its capacity\n\t\t\t\tconst error = new UsageError(\"Payload too large\");\n\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"BatchTooLarge\",\n\t\t\t\t\t\tsize: batch.contentSizeInBytes,\n\t\t\t\t\t\tlength: batch.content.length,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tthrow e;\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"opCompressor.js","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IsoBuffer } from \"@fluid-internal/client-utils\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { UsageError, createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { compress } from \"lz4js\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\n\nimport { estimateSocketSize } from \"./batchManager.js\";\nimport { BatchMessage, IBatch } from \"./definitions.js\";\n\n/**\n * Compresses batches of ops. It generates a single compressed op that contains\n * the contents of each op in the batch. It then submits empty ops for each original\n * op to reserve sequence numbers.\n */\nexport class OpCompressor {\n\tprivate readonly logger;\n\n\tconstructor(logger: ITelemetryBaseLogger) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"OpCompressor\" });\n\t}\n\n\t/**\n\t * Combines the contents of the batch into a single JSON string and compresses it, putting\n\t * the resulting string as the first message of the batch. The rest of the messages are\n\t * empty placeholders to reserve sequence numbers.\n\t * @param batch - The batch to compress\n\t * @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders\n\t */\n\tpublic compressBatch(batch: IBatch): IBatch {\n\t\tassert(\n\t\t\tbatch.contentSizeInBytes > 0 && batch.content.length > 0,\n\t\t\t0x5a4 /* Batch should not be empty */,\n\t\t);\n\n\t\tconst compressionStart = Date.now();\n\t\tconst contentsAsBuffer = new TextEncoder().encode(this.serializeBatchContents(batch));\n\t\tconst compressedContents = compress(contentsAsBuffer);\n\t\tconst compressedContent = IsoBuffer.from(compressedContents).toString(\"base64\");\n\t\tconst duration = Date.now() - compressionStart;\n\n\t\tconst messages: BatchMessage[] = [];\n\t\tmessages.push({\n\t\t\t...batch.content[0],\n\t\t\tcontents: JSON.stringify({ packedContents: compressedContent }),\n\t\t\tmetadata: batch.content[0].metadata,\n\t\t\tcompression: CompressionAlgorithms.lz4,\n\t\t});\n\n\t\t// Add empty placeholder messages to reserve the sequence numbers\n\t\tfor (const message of batch.content.slice(1)) {\n\t\t\tmessages.push({\n\t\t\t\tlocalOpMetadata: message.localOpMetadata,\n\t\t\t\tmetadata: message.metadata,\n\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t});\n\t\t}\n\n\t\tconst compressedBatch: IBatch = {\n\t\t\tcontentSizeInBytes: compressedContent.length,\n\t\t\tcontent: messages,\n\t\t\treferenceSequenceNumber: batch.referenceSequenceNumber,\n\t\t};\n\n\t\tif (batch.contentSizeInBytes > 200000) {\n\t\t\tthis.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"CompressedBatch\",\n\t\t\t\tduration,\n\t\t\t\tsizeBeforeCompression: batch.contentSizeInBytes,\n\t\t\t\tsizeAfterCompression: compressedBatch.contentSizeInBytes,\n\t\t\t\topCount: compressedBatch.content.length,\n\t\t\t\tsocketSize: estimateSocketSize(compressedBatch),\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\t/**\n\t * Combine the batch's content strings into a single JSON string (a serialized array)\n\t */\n\tprivate serializeBatchContents(batch: IBatch): string {\n\t\ttry {\n\t\t\t// Yields a valid JSON array, since each message.contents is already serialized to JSON\n\t\t\treturn `[${batch.content.map((message) => message.contents).join(\",\")}]`;\n\t\t} catch (e: any) {\n\t\t\tif (e.message === \"Invalid string length\") {\n\t\t\t\t// This is how JSON.stringify signals that\n\t\t\t\t// the content size exceeds its capacity\n\t\t\t\tconst error = new UsageError(\"Payload too large\");\n\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"BatchTooLarge\",\n\t\t\t\t\t\tsize: batch.contentSizeInBytes,\n\t\t\t\t\t\tlength: batch.content.length,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tthrow e;\n\t\t}\n\t}\n}\n"]}
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
6
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
6
+ import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
7
7
  /**
8
8
  * State machine that "unrolls" contents of compressed batches of ops after decompressing them.
9
9
  * This class relies on some implicit contracts defined below:
@@ -1 +1 @@
1
- {"version":3,"file":"opDecompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opDecompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAcjF;;;;;;;GAOG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAEZ,MAAM,EAAE,oBAAoB;IAIjC,mBAAmB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO;IA4CvE,IAAW,kBAAkB,YAE5B;IAED,8EAA8E;IAC9E,OAAO,CAAC,oBAAoB,CAAS;IAErC;;;OAGG;IACI,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI;IA8BnE;;;OAGG;IACI,MAAM,CAAC,OAAO,EAAE,yBAAyB,GAAG,yBAAyB;CAkC5E"}
1
+ {"version":3,"file":"opDecompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opDecompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAcxF;;;;;;;GAOG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAEZ,MAAM,EAAE,oBAAoB;IAIjC,mBAAmB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO;IA2CvE,IAAW,kBAAkB,YAE5B;IAED,8EAA8E;IAC9E,OAAO,CAAC,oBAAoB,CAAS;IAErC;;;OAGG;IACI,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI;IA8BnE;;;OAGG;IACI,MAAM,CAAC,OAAO,EAAE,yBAAyB,GAAG,yBAAyB;CA+B5E"}
@@ -45,8 +45,7 @@ export class OpDecompressor {
45
45
  typeof message.contents.packedContents ===
46
46
  "string" &&
47
47
  message.contents.packedContents.length > 0 &&
48
- IsoBuffer.from(message.contents.packedContents, "base64").toString("base64") ===
49
- message.contents.packedContents) {
48
+ IsoBuffer.from(message.contents.packedContents, "base64").toString("base64") === message.contents.packedContents) {
50
49
  this.logger.sendTelemetryEvent({
51
50
  eventName: "LegacyCompression",
52
51
  type: message.type,
@@ -1 +1 @@
1
- {"version":3,"file":"opDecompressor.js","sourceRoot":"","sources":["../../src/opLifecycle/opDecompressor.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IsoBuffer, Uint8ArrayToString } from \"@fluid-internal/client-utils\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { decompress } from \"lz4js\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\nimport { IBatchMetadata } from \"../metadata.js\";\n\n/**\n * Compression makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.\n */\ninterface IPackedContentsContents {\n\tpackedContents: string;\n}\n\n/**\n * State machine that \"unrolls\" contents of compressed batches of ops after decompressing them.\n * This class relies on some implicit contracts defined below:\n * 1. A compressed batch will have its first message with batch metadata set to true and compressed set to true\n * 2. Messages in the middle of a compressed batch will have neither batch metadata nor the compression property set\n * 3. The final message of a batch will have batch metadata set to false\n * 4. An individually compressed op will have undefined batch metadata and compression set to true\n */\nexport class OpDecompressor {\n\tprivate activeBatch = false;\n\tprivate rootMessageContents: any | undefined;\n\tprivate processedCount = 0;\n\tprivate readonly logger;\n\n\tconstructor(logger: ITelemetryBaseLogger) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"OpDecompressor\" });\n\t}\n\n\tpublic isCompressedMessage(message: ISequencedDocumentMessage): boolean {\n\t\tif (message.compression === CompressionAlgorithms.lz4) {\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Back-compat self healing mechanism for ADO:3538, as loaders from\n\t\t * version client_v2.0.0-internal.1.2.0 to client_v2.0.0-internal.2.2.0 do not\n\t\t * support adding the proper compression metadata to compressed messages submitted\n\t\t * by the runtime. Should be removed after the loader reaches sufficient saturation\n\t\t * for a version greater or equal than client_v2.0.0-internal.2.2.0.\n\t\t *\n\t\t * The condition holds true for compressed messages, regardless of metadata. We are ultimately\n\t\t * looking for a message with a single property `packedContents` inside `contents`, of type 'string'\n\t\t * with a base64 encoded value.\n\t\t */\n\t\ttry {\n\t\t\tif (\n\t\t\t\tmessage.contents !== null &&\n\t\t\t\ttypeof message.contents === \"object\" &&\n\t\t\t\tObject.keys(message.contents).length === 1 &&\n\t\t\t\ttypeof (message.contents as { packedContents?: unknown }).packedContents ===\n\t\t\t\t\t\"string\" &&\n\t\t\t\t(message.contents as IPackedContentsContents).packedContents.length > 0 &&\n\t\t\t\tIsoBuffer.from(\n\t\t\t\t\t(message.contents as IPackedContentsContents).packedContents,\n\t\t\t\t\t\"base64\",\n\t\t\t\t).toString(\"base64\") ===\n\t\t\t\t\t(message.contents as IPackedContentsContents).packedContents\n\t\t\t) {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"LegacyCompression\",\n\t\t\t\t\ttype: message.type,\n\t\t\t\t\tbatch: (message.metadata as IBatchMetadata | undefined)?.batch,\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tpublic get currentlyUnrolling() {\n\t\treturn this.activeBatch;\n\t}\n\n\t/** Is the decompressed and stored batch only comprised of a single message */\n\tprivate isSingleMessageBatch = false;\n\n\t/**\n\t * Decompress the given compressed message and store it to be subsequently unrolled.\n\t * The stored message will be of type `any[]` where each element represents a message's `contents`\n\t */\n\tpublic decompressAndStore(message: ISequencedDocumentMessage): void {\n\t\tassert(\n\t\t\tmessage.compression === undefined || message.compression === CompressionAlgorithms.lz4,\n\t\t\t0x511 /* Only lz4 compression is supported */,\n\t\t);\n\t\tassert(\n\t\t\tthis.isCompressedMessage(message),\n\t\t\t0x940 /* provided message should be compressed */,\n\t\t);\n\n\t\tassert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);\n\t\tthis.activeBatch = true;\n\n\t\tconst batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;\n\t\tif (batchMetadata === undefined) {\n\t\t\tthis.isSingleMessageBatch = true;\n\t\t} else {\n\t\t\tassert(batchMetadata === true, 0x941 /* invalid batch metadata */);\n\t\t}\n\n\t\tconst contents = IsoBuffer.from(\n\t\t\t(message.contents as IPackedContentsContents).packedContents,\n\t\t\t\"base64\",\n\t\t);\n\t\tconst decompressedMessage = decompress(contents);\n\t\tconst intoString = Uint8ArrayToString(decompressedMessage);\n\t\tconst asObj = JSON.parse(intoString);\n\t\tthis.rootMessageContents = asObj;\n\t}\n\n\t/**\n\t * Unroll the next message from the decompressed content provided to {@link decompressAndStore}\n\t * @returns the unrolled `ISequencedDocumentMessage`\n\t */\n\tpublic unroll(message: ISequencedDocumentMessage): ISequencedDocumentMessage {\n\t\tassert(this.currentlyUnrolling, 0x942 /* not currently unrolling */);\n\t\tassert(this.rootMessageContents !== undefined, 0x943 /* missing rootMessageContents */);\n\t\tassert(\n\t\t\tthis.rootMessageContents.length > this.processedCount,\n\t\t\t0x944 /* no more content to unroll */,\n\t\t);\n\n\t\tconst batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;\n\n\t\tif (batchMetadata === false || this.isSingleMessageBatch) {\n\t\t\t// End of compressed batch\n\t\t\tconst returnMessage = newMessage(\n\t\t\t\tmessage,\n\t\t\t\tthis.rootMessageContents[this.processedCount],\n\t\t\t);\n\n\t\t\tthis.activeBatch = false;\n\t\t\tthis.isSingleMessageBatch = false;\n\t\t\tthis.rootMessageContents = undefined;\n\t\t\tthis.processedCount = 0;\n\n\t\t\treturn returnMessage;\n\t\t} else if (batchMetadata === true) {\n\t\t\t// Start of compressed batch\n\t\t\treturn newMessage(message, this.rootMessageContents[this.processedCount++]);\n\t\t}\n\n\t\tassert(batchMetadata === undefined, 0x945 /* invalid batch metadata */);\n\t\tassert(message.contents === undefined, 0x512 /* Expecting empty message */);\n\n\t\t// Continuation of compressed batch\n\t\treturn newMessage(message, this.rootMessageContents[this.processedCount++]);\n\t}\n}\n\n// We should not be mutating the input message nor its metadata\nconst newMessage = (\n\toriginalMessage: ISequencedDocumentMessage,\n\tcontents: any,\n): ISequencedDocumentMessage => ({\n\t...originalMessage,\n\tcontents,\n\tcompression: undefined,\n\t// TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\tmetadata:\n\t\toriginalMessage.metadata === undefined\n\t\t\t? undefined\n\t\t\t: { ...(originalMessage.metadata as any) },\n});\n"]}
1
+ {"version":3,"file":"opDecompressor.js","sourceRoot":"","sources":["../../src/opLifecycle/opDecompressor.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IsoBuffer, Uint8ArrayToString } from \"@fluid-internal/client-utils\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { decompress } from \"lz4js\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\nimport { IBatchMetadata } from \"../metadata.js\";\n\n/**\n * Compression makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.\n */\ninterface IPackedContentsContents {\n\tpackedContents: string;\n}\n\n/**\n * State machine that \"unrolls\" contents of compressed batches of ops after decompressing them.\n * This class relies on some implicit contracts defined below:\n * 1. A compressed batch will have its first message with batch metadata set to true and compressed set to true\n * 2. Messages in the middle of a compressed batch will have neither batch metadata nor the compression property set\n * 3. The final message of a batch will have batch metadata set to false\n * 4. An individually compressed op will have undefined batch metadata and compression set to true\n */\nexport class OpDecompressor {\n\tprivate activeBatch = false;\n\tprivate rootMessageContents: any | undefined;\n\tprivate processedCount = 0;\n\tprivate readonly logger;\n\n\tconstructor(logger: ITelemetryBaseLogger) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"OpDecompressor\" });\n\t}\n\n\tpublic isCompressedMessage(message: ISequencedDocumentMessage): boolean {\n\t\tif (message.compression === CompressionAlgorithms.lz4) {\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * Back-compat self healing mechanism for ADO:3538, as loaders from\n\t\t * version client_v2.0.0-internal.1.2.0 to client_v2.0.0-internal.2.2.0 do not\n\t\t * support adding the proper compression metadata to compressed messages submitted\n\t\t * by the runtime. Should be removed after the loader reaches sufficient saturation\n\t\t * for a version greater or equal than client_v2.0.0-internal.2.2.0.\n\t\t *\n\t\t * The condition holds true for compressed messages, regardless of metadata. We are ultimately\n\t\t * looking for a message with a single property `packedContents` inside `contents`, of type 'string'\n\t\t * with a base64 encoded value.\n\t\t */\n\t\ttry {\n\t\t\tif (\n\t\t\t\tmessage.contents !== null &&\n\t\t\t\ttypeof message.contents === \"object\" &&\n\t\t\t\tObject.keys(message.contents).length === 1 &&\n\t\t\t\ttypeof (message.contents as { packedContents?: unknown }).packedContents ===\n\t\t\t\t\t\"string\" &&\n\t\t\t\t(message.contents as IPackedContentsContents).packedContents.length > 0 &&\n\t\t\t\tIsoBuffer.from(\n\t\t\t\t\t(message.contents as IPackedContentsContents).packedContents,\n\t\t\t\t\t\"base64\",\n\t\t\t\t).toString(\"base64\") === (message.contents as IPackedContentsContents).packedContents\n\t\t\t) {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"LegacyCompression\",\n\t\t\t\t\ttype: message.type,\n\t\t\t\t\tbatch: (message.metadata as IBatchMetadata | undefined)?.batch,\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tpublic get currentlyUnrolling() {\n\t\treturn this.activeBatch;\n\t}\n\n\t/** Is the decompressed and stored batch only comprised of a single message */\n\tprivate isSingleMessageBatch = false;\n\n\t/**\n\t * Decompress the given compressed message and store it to be subsequently unrolled.\n\t * The stored message will be of type `any[]` where each element represents a message's `contents`\n\t */\n\tpublic decompressAndStore(message: ISequencedDocumentMessage): void {\n\t\tassert(\n\t\t\tmessage.compression === undefined || message.compression === CompressionAlgorithms.lz4,\n\t\t\t0x511 /* Only lz4 compression is supported */,\n\t\t);\n\t\tassert(\n\t\t\tthis.isCompressedMessage(message),\n\t\t\t0x940 /* provided message should be compressed */,\n\t\t);\n\n\t\tassert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);\n\t\tthis.activeBatch = true;\n\n\t\tconst batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;\n\t\tif (batchMetadata === undefined) {\n\t\t\tthis.isSingleMessageBatch = true;\n\t\t} else {\n\t\t\tassert(batchMetadata === true, 0x941 /* invalid batch metadata */);\n\t\t}\n\n\t\tconst contents = IsoBuffer.from(\n\t\t\t(message.contents as IPackedContentsContents).packedContents,\n\t\t\t\"base64\",\n\t\t);\n\t\tconst decompressedMessage = decompress(contents);\n\t\tconst intoString = Uint8ArrayToString(decompressedMessage);\n\t\tconst asObj = JSON.parse(intoString);\n\t\tthis.rootMessageContents = asObj;\n\t}\n\n\t/**\n\t * Unroll the next message from the decompressed content provided to {@link decompressAndStore}\n\t * @returns the unrolled `ISequencedDocumentMessage`\n\t */\n\tpublic unroll(message: ISequencedDocumentMessage): ISequencedDocumentMessage {\n\t\tassert(this.currentlyUnrolling, 0x942 /* not currently unrolling */);\n\t\tassert(this.rootMessageContents !== undefined, 0x943 /* missing rootMessageContents */);\n\t\tassert(\n\t\t\tthis.rootMessageContents.length > this.processedCount,\n\t\t\t0x944 /* no more content to unroll */,\n\t\t);\n\n\t\tconst batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;\n\n\t\tif (batchMetadata === false || this.isSingleMessageBatch) {\n\t\t\t// End of compressed batch\n\t\t\tconst returnMessage = newMessage(message, this.rootMessageContents[this.processedCount]);\n\n\t\t\tthis.activeBatch = false;\n\t\t\tthis.isSingleMessageBatch = false;\n\t\t\tthis.rootMessageContents = undefined;\n\t\t\tthis.processedCount = 0;\n\n\t\t\treturn returnMessage;\n\t\t} else if (batchMetadata === true) {\n\t\t\t// Start of compressed batch\n\t\t\treturn newMessage(message, this.rootMessageContents[this.processedCount++]);\n\t\t}\n\n\t\tassert(batchMetadata === undefined, 0x945 /* invalid batch metadata */);\n\t\tassert(message.contents === undefined, 0x512 /* Expecting empty message */);\n\n\t\t// Continuation of compressed batch\n\t\treturn newMessage(message, this.rootMessageContents[this.processedCount++]);\n\t}\n}\n\n// We should not be mutating the input message nor its metadata\nconst newMessage = (\n\toriginalMessage: ISequencedDocumentMessage,\n\tcontents: any,\n): ISequencedDocumentMessage => ({\n\t...originalMessage,\n\tcontents,\n\tcompression: undefined,\n\t// TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\tmetadata:\n\t\toriginalMessage.metadata === undefined\n\t\t\t? undefined\n\t\t\t: { ...(originalMessage.metadata as any) },\n});\n"]}
@@ -3,8 +3,8 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
6
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
7
- import { IBatch } from "./definitions.js";
6
+ import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
7
+ import { IBatch, type BatchMessage } from "./definitions.js";
8
8
  export declare function isGroupedBatch(op: ISequencedDocumentMessage): boolean;
9
9
  export interface OpGroupingManagerConfig {
10
10
  readonly groupedBatchingEnabled: boolean;
@@ -16,7 +16,14 @@ export declare class OpGroupingManager {
16
16
  static readonly groupedBatchOp = "groupedBatch";
17
17
  private readonly logger;
18
18
  constructor(config: OpGroupingManagerConfig, logger: ITelemetryBaseLogger);
19
- groupBatch(batch: IBatch): IBatch;
19
+ /**
20
+ * Converts the given batch into a "grouped batch" - a batch with a single message of type "groupedBatch",
21
+ * with contents being an array of the original batch's messages.
22
+ *
23
+ * @remarks - Remember that a BatchMessage has its content JSON serialized, so the incoming batch message contents
24
+ * must be parsed first, and then the type and contents mentioned above are hidden in that JSON serialization.
25
+ */
26
+ groupBatch(batch: IBatch): IBatch<[BatchMessage]>;
20
27
  ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[];
21
28
  shouldGroup(batch: IBatch): boolean;
22
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"opGroupingManager.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opGroupingManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAGjF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAoB1C,wBAAgB,cAAc,CAAC,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAErE;AAED,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,6BAA6B,EAAE,OAAO,CAAC;CAChD;AAED,qBAAa,iBAAiB;IAK5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJxB,MAAM,CAAC,QAAQ,CAAC,cAAc,kBAAkB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAGN,MAAM,EAAE,uBAAuB,EAChD,MAAM,EAAE,oBAAoB;IAKtB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IA8CjC,SAAS,CAAC,EAAE,EAAE,yBAAyB,GAAG,yBAAyB,EAAE;IAcrE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAU1C"}
1
+ {"version":3,"file":"opGroupingManager.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opGroupingManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAGxF,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAoB7D,wBAAgB,cAAc,CAAC,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAErE;AAED,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,6BAA6B,EAAE,OAAO,CAAC;CAChD;AAED,qBAAa,iBAAiB;IAK5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJxB,MAAM,CAAC,QAAQ,CAAC,cAAc,kBAAkB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAGN,MAAM,EAAE,uBAAuB,EAChD,MAAM,EAAE,oBAAoB;IAK7B;;;;;;OAMG;IACI,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IA2CjD,SAAS,CAAC,EAAE,EAAE,yBAAyB,GAAG,yBAAyB,EAAE;IAcrE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAU1C"}
@@ -15,6 +15,13 @@ export class OpGroupingManager {
15
15
  this.config = config;
16
16
  this.logger = createChildLogger({ logger, namespace: "OpGroupingManager" });
17
17
  }
18
+ /**
19
+ * Converts the given batch into a "grouped batch" - a batch with a single message of type "groupedBatch",
20
+ * with contents being an array of the original batch's messages.
21
+ *
22
+ * @remarks - Remember that a BatchMessage has its content JSON serialized, so the incoming batch message contents
23
+ * must be parsed first, and then the type and contents mentioned above are hidden in that JSON serialization.
24
+ */
18
25
  groupBatch(batch) {
19
26
  assert(this.shouldGroup(batch), 0x946 /* cannot group the provided batch */);
20
27
  if (batch.content.length >= 1000) {
@@ -1 +1 @@
1
- {"version":3,"file":"opGroupingManager.js","sourceRoot":"","sources":["../../src/opLifecycle/opGroupingManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { IBatch } from \"./definitions.js\";\n\n/**\n * Grouping makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.\n */\ninterface IGroupedBatchMessageContents {\n\ttype: typeof OpGroupingManager.groupedBatchOp;\n\tcontents: IGroupedMessage[];\n}\n\ninterface IGroupedMessage {\n\tcontents?: unknown;\n\tmetadata?: Record<string, unknown>;\n\tcompression?: string;\n}\n\nfunction isGroupContents(opContents: any): opContents is IGroupedBatchMessageContents {\n\treturn opContents?.type === OpGroupingManager.groupedBatchOp;\n}\n\nexport function isGroupedBatch(op: ISequencedDocumentMessage): boolean {\n\treturn isGroupContents(op.contents);\n}\n\nexport interface OpGroupingManagerConfig {\n\treadonly groupedBatchingEnabled: boolean;\n\treadonly opCountThreshold: number;\n\treadonly reentrantBatchGroupingEnabled: boolean;\n}\n\nexport class OpGroupingManager {\n\tstatic readonly groupedBatchOp = \"groupedBatch\";\n\tprivate readonly logger;\n\n\tconstructor(\n\t\tprivate readonly config: OpGroupingManagerConfig,\n\t\tlogger: ITelemetryBaseLogger,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"OpGroupingManager\" });\n\t}\n\n\tpublic groupBatch(batch: IBatch): IBatch {\n\t\tassert(this.shouldGroup(batch), 0x946 /* cannot group the provided batch */);\n\n\t\tif (batch.content.length >= 1000) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"GroupLargeBatch\",\n\t\t\t\tlength: batch.content.length,\n\t\t\t\tthreshold: this.config.opCountThreshold,\n\t\t\t\treentrant: batch.hasReentrantOps,\n\t\t\t\treferenceSequenceNumber: batch.content[0].referenceSequenceNumber,\n\t\t\t});\n\t\t}\n\n\t\tfor (const message of batch.content) {\n\t\t\tif (message.metadata) {\n\t\t\t\tconst keys = Object.keys(message.metadata);\n\t\t\t\tassert(keys.length < 2, 0x5dd /* cannot group ops with metadata */);\n\t\t\t\tassert(\n\t\t\t\t\tkeys.length === 0 || keys[0] === \"batch\",\n\t\t\t\t\t0x5de /* unexpected op metadata */,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst serializedContent = JSON.stringify({\n\t\t\ttype: OpGroupingManager.groupedBatchOp,\n\t\t\tcontents: batch.content.map<IGroupedMessage>((message) => ({\n\t\t\t\tcontents: message.contents === undefined ? undefined : JSON.parse(message.contents),\n\t\t\t\tmetadata: message.metadata,\n\t\t\t\tcompression: message.compression,\n\t\t\t})),\n\t\t});\n\n\t\tconst groupedBatch: IBatch = {\n\t\t\t...batch,\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\tmetadata: undefined,\n\t\t\t\t\treferenceSequenceNumber: batch.content[0].referenceSequenceNumber,\n\t\t\t\t\tcontents: serializedContent,\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t\treturn groupedBatch;\n\t}\n\n\tpublic ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {\n\t\tassert(isGroupContents(op.contents), 0x947 /* can only ungroup a grouped batch */);\n\t\tconst contents: IGroupedBatchMessageContents = op.contents;\n\n\t\tlet fakeCsn = 1;\n\t\treturn contents.contents.map((subMessage) => ({\n\t\t\t...op,\n\t\t\tclientSequenceNumber: fakeCsn++,\n\t\t\tcontents: subMessage.contents,\n\t\t\tmetadata: subMessage.metadata,\n\t\t\tcompression: subMessage.compression,\n\t\t}));\n\t}\n\n\tpublic shouldGroup(batch: IBatch): boolean {\n\t\treturn (\n\t\t\t// Grouped batching must be enabled\n\t\t\tthis.config.groupedBatchingEnabled &&\n\t\t\t// The number of ops in the batch must surpass the configured threshold\n\t\t\tbatch.content.length >= this.config.opCountThreshold &&\n\t\t\t// Support for reentrant batches must be explicitly enabled\n\t\t\t(this.config.reentrantBatchGroupingEnabled || batch.hasReentrantOps !== true)\n\t\t);\n\t}\n}\n"]}
1
+ {"version":3,"file":"opGroupingManager.js","sourceRoot":"","sources":["../../src/opLifecycle/opGroupingManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { IBatch, type BatchMessage } from \"./definitions.js\";\n\n/**\n * Grouping makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.\n */\ninterface IGroupedBatchMessageContents {\n\ttype: typeof OpGroupingManager.groupedBatchOp;\n\tcontents: IGroupedMessage[];\n}\n\ninterface IGroupedMessage {\n\tcontents?: unknown;\n\tmetadata?: Record<string, unknown>;\n\tcompression?: string;\n}\n\nfunction isGroupContents(opContents: any): opContents is IGroupedBatchMessageContents {\n\treturn opContents?.type === OpGroupingManager.groupedBatchOp;\n}\n\nexport function isGroupedBatch(op: ISequencedDocumentMessage): boolean {\n\treturn isGroupContents(op.contents);\n}\n\nexport interface OpGroupingManagerConfig {\n\treadonly groupedBatchingEnabled: boolean;\n\treadonly opCountThreshold: number;\n\treadonly reentrantBatchGroupingEnabled: boolean;\n}\n\nexport class OpGroupingManager {\n\tstatic readonly groupedBatchOp = \"groupedBatch\";\n\tprivate readonly logger;\n\n\tconstructor(\n\t\tprivate readonly config: OpGroupingManagerConfig,\n\t\tlogger: ITelemetryBaseLogger,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"OpGroupingManager\" });\n\t}\n\n\t/**\n\t * Converts the given batch into a \"grouped batch\" - a batch with a single message of type \"groupedBatch\",\n\t * with contents being an array of the original batch's messages.\n\t *\n\t * @remarks - Remember that a BatchMessage has its content JSON serialized, so the incoming batch message contents\n\t * must be parsed first, and then the type and contents mentioned above are hidden in that JSON serialization.\n\t */\n\tpublic groupBatch(batch: IBatch): IBatch<[BatchMessage]> {\n\t\tassert(this.shouldGroup(batch), 0x946 /* cannot group the provided batch */);\n\n\t\tif (batch.content.length >= 1000) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"GroupLargeBatch\",\n\t\t\t\tlength: batch.content.length,\n\t\t\t\tthreshold: this.config.opCountThreshold,\n\t\t\t\treentrant: batch.hasReentrantOps,\n\t\t\t\treferenceSequenceNumber: batch.content[0].referenceSequenceNumber,\n\t\t\t});\n\t\t}\n\n\t\tfor (const message of batch.content) {\n\t\t\tif (message.metadata) {\n\t\t\t\tconst keys = Object.keys(message.metadata);\n\t\t\t\tassert(keys.length < 2, 0x5dd /* cannot group ops with metadata */);\n\t\t\t\tassert(keys.length === 0 || keys[0] === \"batch\", 0x5de /* unexpected op metadata */);\n\t\t\t}\n\t\t}\n\n\t\tconst serializedContent = JSON.stringify({\n\t\t\ttype: OpGroupingManager.groupedBatchOp,\n\t\t\tcontents: batch.content.map<IGroupedMessage>((message) => ({\n\t\t\t\tcontents: message.contents === undefined ? undefined : JSON.parse(message.contents),\n\t\t\t\tmetadata: message.metadata,\n\t\t\t\tcompression: message.compression,\n\t\t\t})),\n\t\t});\n\n\t\tconst groupedBatch: IBatch<[BatchMessage]> = {\n\t\t\t...batch,\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\tmetadata: undefined,\n\t\t\t\t\treferenceSequenceNumber: batch.content[0].referenceSequenceNumber,\n\t\t\t\t\tcontents: serializedContent,\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t\treturn groupedBatch;\n\t}\n\n\tpublic ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {\n\t\tassert(isGroupContents(op.contents), 0x947 /* can only ungroup a grouped batch */);\n\t\tconst contents: IGroupedBatchMessageContents = op.contents;\n\n\t\tlet fakeCsn = 1;\n\t\treturn contents.contents.map((subMessage) => ({\n\t\t\t...op,\n\t\t\tclientSequenceNumber: fakeCsn++,\n\t\t\tcontents: subMessage.contents,\n\t\t\tmetadata: subMessage.metadata,\n\t\t\tcompression: subMessage.compression,\n\t\t}));\n\t}\n\n\tpublic shouldGroup(batch: IBatch): boolean {\n\t\treturn (\n\t\t\t// Grouped batching must be enabled\n\t\t\tthis.config.groupedBatchingEnabled &&\n\t\t\t// The number of ops in the batch must surpass the configured threshold\n\t\t\tbatch.content.length >= this.config.opCountThreshold &&\n\t\t\t// Support for reentrant batches must be explicitly enabled\n\t\t\t(this.config.reentrantBatchGroupingEnabled || batch.hasReentrantOps !== true)\n\t\t);\n\t}\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { IBatchMessage } from "@fluidframework/container-definitions/internal";
6
6
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
7
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
7
+ import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
8
8
  import { BatchMessage, IBatch, IChunkedOp } from "./definitions.js";
9
9
  export declare function isChunkedMessage(message: ISequencedDocumentMessage): boolean;
10
10
  /**
@@ -40,8 +40,10 @@ export declare class OpSplitter {
40
40
  * To illustrate, if the input is `[largeOp, emptyOp, emptyOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
41
41
  * `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4, emptyOp, emptyOp]` will be returned.
42
42
  *
43
+ * @remarks - A side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
44
+ *
43
45
  * @param batch - the compressed batch which needs to be processed
44
- * @returns A new adjusted batch which can be sent over the wire
46
+ * @returns A new adjusted batch (last chunk + empty placeholders) which can be sent over the wire
45
47
  */
46
48
  splitFirstBatchMessage(batch: IBatch): IBatch;
47
49
  processChunk(message: ISequencedDocumentMessage): ProcessChunkResult;
@@ -1 +1 @@
1
- {"version":3,"file":"opSplitter.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opSplitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAUjF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEpE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAE5E;AAWD;;GAEG;AACH,qBAAa,UAAU;IAOrB,OAAO,CAAC,QAAQ,CAAC,aAAa;aAGd,gBAAgB,EAAE,MAAM;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IATrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAGvB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,EACX,aAAa,EAC3B,CAAC,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,uBAAuB,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GACtE,SAAS,EACI,gBAAgB,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC5C,MAAM,EAAE,oBAAoB;IAM7B,IAAW,sBAAsB,IAAI,OAAO,CAE3C;IAED,IAAW,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEjD;IAEM,kBAAkB,CAAC,QAAQ,EAAE,MAAM;IAM1C,OAAO,CAAC,QAAQ;IA0BhB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAmE7C,YAAY,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB;CAmC3E;AAED,KAAK,kBAAkB,GACpB;IACA,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC;CAC5B,GACD;IACA,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;CAC3C,CAAC;AAkBL;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,OACf,YAAY,oBACE,MAAM,YACf,OAAO,KACd,UAAU,EA6CZ,CAAC"}
1
+ {"version":3,"file":"opSplitter.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opSplitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAUxF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEpE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAE5E;AAWD;;GAEG;AACH,qBAAa,UAAU;IAOrB,OAAO,CAAC,QAAQ,CAAC,aAAa;aAGd,gBAAgB,EAAE,MAAM;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IATrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAGvB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,EACX,aAAa,EAC3B,CAAC,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,uBAAuB,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GACtE,SAAS,EACI,gBAAgB,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC5C,MAAM,EAAE,oBAAoB;IAM7B,IAAW,sBAAsB,IAAI,OAAO,CAI3C;IAED,IAAW,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEjD;IAEM,kBAAkB,CAAC,QAAQ,EAAE,MAAM;IAM1C,OAAO,CAAC,QAAQ;IA0BhB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACI,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAmE7C,YAAY,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB;CAsC3E;AAED,KAAK,kBAAkB,GACpB;IACA,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC;CAC5B,GACD;IACA,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;CAC3C,CAAC;AAkBL;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,OACf,YAAY,oBACE,MAAM,YACf,OAAO,KACd,UAAU,EAiDZ,CAAC"}