@fluidframework/container-runtime 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.224419

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 (703) hide show
  1. package/.eslintrc.js +19 -29
  2. package/.mocharc.js +12 -0
  3. package/CHANGELOG.md +427 -0
  4. package/README.md +69 -0
  5. package/api-extractor-lint.json +4 -0
  6. package/api-extractor.json +2 -2
  7. package/api-report/container-runtime.api.md +863 -0
  8. package/dist/{batchTracker.js → batchTracker.cjs} +9 -8
  9. package/dist/batchTracker.cjs.map +1 -0
  10. package/dist/batchTracker.d.ts +6 -5
  11. package/dist/batchTracker.d.ts.map +1 -1
  12. package/dist/blobManager.cjs +704 -0
  13. package/dist/blobManager.cjs.map +1 -0
  14. package/dist/blobManager.d.ts +135 -39
  15. package/dist/blobManager.d.ts.map +1 -1
  16. package/dist/connectionTelemetry.cjs +230 -0
  17. package/dist/connectionTelemetry.cjs.map +1 -0
  18. package/dist/connectionTelemetry.d.ts +2 -2
  19. package/dist/connectionTelemetry.d.ts.map +1 -1
  20. package/dist/container-runtime-alpha.d.ts +1677 -0
  21. package/dist/container-runtime-beta.d.ts +250 -0
  22. package/dist/container-runtime-public.d.ts +250 -0
  23. package/dist/container-runtime-untrimmed.d.ts +1792 -0
  24. package/dist/{containerHandleContext.js → containerHandleContext.cjs} +4 -2
  25. package/dist/containerHandleContext.cjs.map +1 -0
  26. package/dist/containerHandleContext.d.ts.map +1 -1
  27. package/dist/containerRuntime.cjs +2531 -0
  28. package/dist/containerRuntime.cjs.map +1 -0
  29. package/dist/containerRuntime.d.ts +454 -256
  30. package/dist/containerRuntime.d.ts.map +1 -1
  31. package/dist/{dataStore.js → dataStore.cjs} +54 -45
  32. package/dist/dataStore.cjs.map +1 -0
  33. package/dist/dataStore.d.ts +2 -2
  34. package/dist/dataStore.d.ts.map +1 -1
  35. package/dist/{dataStoreContext.js → dataStoreContext.cjs} +343 -247
  36. package/dist/dataStoreContext.cjs.map +1 -0
  37. package/dist/dataStoreContext.d.ts +73 -41
  38. package/dist/dataStoreContext.d.ts.map +1 -1
  39. package/dist/{dataStoreContexts.js → dataStoreContexts.cjs} +19 -15
  40. package/dist/dataStoreContexts.cjs.map +1 -0
  41. package/dist/dataStoreContexts.d.ts +1 -1
  42. package/dist/dataStoreContexts.d.ts.map +1 -1
  43. package/dist/{dataStoreRegistry.js → dataStoreRegistry.cjs} +9 -4
  44. package/dist/dataStoreRegistry.cjs.map +1 -0
  45. package/dist/dataStoreRegistry.d.ts +3 -0
  46. package/dist/dataStoreRegistry.d.ts.map +1 -1
  47. package/dist/{dataStores.js → dataStores.cjs} +273 -124
  48. package/dist/dataStores.cjs.map +1 -0
  49. package/dist/dataStores.d.ts +53 -23
  50. package/dist/dataStores.d.ts.map +1 -1
  51. package/dist/deltaManagerProxyBase.cjs +77 -0
  52. package/dist/deltaManagerProxyBase.cjs.map +1 -0
  53. package/dist/deltaManagerProxyBase.d.ts +35 -0
  54. package/dist/deltaManagerProxyBase.d.ts.map +1 -0
  55. package/dist/deltaManagerSummarizerProxy.cjs +42 -0
  56. package/dist/deltaManagerSummarizerProxy.cjs.map +1 -0
  57. package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
  58. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
  59. package/dist/{deltaScheduler.js → deltaScheduler.cjs} +25 -18
  60. package/dist/deltaScheduler.cjs.map +1 -0
  61. package/dist/deltaScheduler.d.ts +8 -6
  62. package/dist/deltaScheduler.d.ts.map +1 -1
  63. package/dist/error.cjs +21 -0
  64. package/dist/error.cjs.map +1 -0
  65. package/dist/error.d.ts +14 -0
  66. package/dist/error.d.ts.map +1 -0
  67. package/dist/gc/garbageCollection.cjs +861 -0
  68. package/dist/gc/garbageCollection.cjs.map +1 -0
  69. package/dist/gc/garbageCollection.d.ts +224 -0
  70. package/dist/gc/garbageCollection.d.ts.map +1 -0
  71. package/dist/gc/gcConfigs.cjs +153 -0
  72. package/dist/gc/gcConfigs.cjs.map +1 -0
  73. package/dist/gc/gcConfigs.d.ts +23 -0
  74. package/dist/gc/gcConfigs.d.ts.map +1 -0
  75. package/dist/gc/gcDefinitions.cjs +96 -0
  76. package/dist/gc/gcDefinitions.cjs.map +1 -0
  77. package/dist/gc/gcDefinitions.d.ts +437 -0
  78. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  79. package/dist/gc/gcHelpers.cjs +235 -0
  80. package/dist/gc/gcHelpers.cjs.map +1 -0
  81. package/dist/gc/gcHelpers.d.ts +71 -0
  82. package/dist/gc/gcHelpers.d.ts.map +1 -0
  83. package/dist/gc/gcReferenceGraphAlgorithm.cjs +49 -0
  84. package/dist/gc/gcReferenceGraphAlgorithm.cjs.map +1 -0
  85. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  86. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  87. package/dist/{summarizerTypes.js → gc/gcSummaryDefinitions.cjs} +1 -6
  88. package/dist/gc/gcSummaryDefinitions.cjs.map +1 -0
  89. package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
  90. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
  91. package/dist/gc/gcSummaryStateTracker.cjs +213 -0
  92. package/dist/gc/gcSummaryStateTracker.cjs.map +1 -0
  93. package/dist/gc/gcSummaryStateTracker.d.ts +94 -0
  94. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  95. package/dist/gc/gcTelemetry.cjs +298 -0
  96. package/dist/gc/gcTelemetry.cjs.map +1 -0
  97. package/dist/gc/gcTelemetry.d.ts +92 -0
  98. package/dist/gc/gcTelemetry.d.ts.map +1 -0
  99. package/dist/gc/gcUnreferencedStateTracker.cjs +118 -0
  100. package/dist/gc/gcUnreferencedStateTracker.cjs.map +1 -0
  101. package/dist/gc/gcUnreferencedStateTracker.d.ts +40 -0
  102. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  103. package/dist/gc/index.cjs +44 -0
  104. package/dist/gc/index.cjs.map +1 -0
  105. package/dist/gc/index.d.ts +13 -0
  106. package/dist/gc/index.d.ts.map +1 -0
  107. package/dist/index.cjs +47 -0
  108. package/dist/index.cjs.map +1 -0
  109. package/dist/index.d.ts +19 -8
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/messageTypes.cjs +37 -0
  112. package/dist/messageTypes.cjs.map +1 -0
  113. package/dist/messageTypes.d.ts +142 -0
  114. package/dist/messageTypes.d.ts.map +1 -0
  115. package/dist/metadata.cjs +7 -0
  116. package/dist/metadata.cjs.map +1 -0
  117. package/dist/metadata.d.ts +24 -0
  118. package/dist/metadata.d.ts.map +1 -0
  119. package/dist/opLifecycle/batchManager.cjs +139 -0
  120. package/dist/opLifecycle/batchManager.cjs.map +1 -0
  121. package/dist/opLifecycle/batchManager.d.ts +48 -0
  122. package/dist/opLifecycle/batchManager.d.ts.map +1 -0
  123. package/dist/opLifecycle/definitions.cjs +7 -0
  124. package/dist/opLifecycle/definitions.cjs.map +1 -0
  125. package/dist/opLifecycle/definitions.d.ts +83 -0
  126. package/dist/opLifecycle/definitions.d.ts.map +1 -0
  127. package/dist/opLifecycle/index.cjs +26 -0
  128. package/dist/opLifecycle/index.cjs.map +1 -0
  129. package/dist/opLifecycle/index.d.ts +13 -0
  130. package/dist/opLifecycle/index.d.ts.map +1 -0
  131. package/dist/opLifecycle/opCompressor.cjs +84 -0
  132. package/dist/opLifecycle/opCompressor.cjs.map +1 -0
  133. package/dist/opLifecycle/opCompressor.d.ts +18 -0
  134. package/dist/opLifecycle/opCompressor.d.ts.map +1 -0
  135. package/dist/opLifecycle/opDecompressor.cjs +132 -0
  136. package/dist/opLifecycle/opDecompressor.cjs.map +1 -0
  137. package/dist/opLifecycle/opDecompressor.d.ts +25 -0
  138. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -0
  139. package/dist/opLifecycle/opGroupingManager.cjs +95 -0
  140. package/dist/opLifecycle/opGroupingManager.cjs.map +1 -0
  141. package/dist/opLifecycle/opGroupingManager.d.ts +22 -0
  142. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
  143. package/dist/opLifecycle/opSplitter.cjs +202 -0
  144. package/dist/opLifecycle/opSplitter.cjs.map +1 -0
  145. package/dist/opLifecycle/opSplitter.d.ts +61 -0
  146. package/dist/opLifecycle/opSplitter.d.ts.map +1 -0
  147. package/dist/opLifecycle/outbox.cjs +323 -0
  148. package/dist/opLifecycle/outbox.cjs.map +1 -0
  149. package/dist/opLifecycle/outbox.d.ts +104 -0
  150. package/dist/opLifecycle/outbox.d.ts.map +1 -0
  151. package/dist/opLifecycle/remoteMessageProcessor.cjs +136 -0
  152. package/dist/opLifecycle/remoteMessageProcessor.cjs.map +1 -0
  153. package/dist/opLifecycle/remoteMessageProcessor.d.ts +47 -0
  154. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
  155. package/dist/opProperties.cjs +17 -0
  156. package/dist/opProperties.cjs.map +1 -0
  157. package/dist/opProperties.d.ts +7 -0
  158. package/dist/opProperties.d.ts.map +1 -0
  159. package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
  160. package/dist/packageVersion.cjs.map +1 -0
  161. package/dist/packageVersion.d.ts +1 -1
  162. package/dist/packageVersion.d.ts.map +1 -1
  163. package/dist/pendingStateManager.cjs +282 -0
  164. package/dist/pendingStateManager.cjs.map +1 -0
  165. package/dist/pendingStateManager.d.ts +32 -69
  166. package/dist/pendingStateManager.d.ts.map +1 -1
  167. package/dist/scheduleManager.cjs +258 -0
  168. package/dist/scheduleManager.cjs.map +1 -0
  169. package/dist/scheduleManager.d.ts +31 -0
  170. package/dist/scheduleManager.d.ts.map +1 -0
  171. package/dist/storageServiceWithAttachBlobs.cjs +32 -0
  172. package/dist/storageServiceWithAttachBlobs.cjs.map +1 -0
  173. package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
  174. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
  175. package/dist/summary/index.cjs +51 -0
  176. package/dist/summary/index.cjs.map +1 -0
  177. package/dist/summary/index.d.ts +17 -0
  178. package/dist/summary/index.d.ts.map +1 -0
  179. package/dist/{orderedClientElection.js → summary/orderedClientElection.cjs} +100 -84
  180. package/dist/summary/orderedClientElection.cjs.map +1 -0
  181. package/{lib → dist/summary}/orderedClientElection.d.ts +41 -18
  182. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  183. package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.cjs} +12 -10
  184. package/dist/summary/runWhileConnectedCoordinator.cjs.map +1 -0
  185. package/{lib → dist/summary}/runWhileConnectedCoordinator.d.ts +8 -2
  186. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  187. package/dist/summary/runningSummarizer.cjs +679 -0
  188. package/dist/summary/runningSummarizer.cjs.map +1 -0
  189. package/dist/summary/runningSummarizer.d.ts +128 -0
  190. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  191. package/dist/summary/summarizer.cjs +263 -0
  192. package/dist/summary/summarizer.cjs.map +1 -0
  193. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +18 -33
  194. package/dist/summary/summarizer.d.ts.map +1 -0
  195. package/dist/{summarizerClientElection.js → summary/summarizerClientElection.cjs} +15 -46
  196. package/dist/summary/summarizerClientElection.cjs.map +1 -0
  197. package/{lib → dist/summary}/summarizerClientElection.d.ts +4 -4
  198. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  199. package/dist/summary/summarizerHeuristics.cjs +156 -0
  200. package/dist/summary/summarizerHeuristics.cjs.map +1 -0
  201. package/{lib → dist/summary}/summarizerHeuristics.d.ts +28 -6
  202. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  203. package/dist/summary/summarizerNode/index.cjs +12 -0
  204. package/dist/summary/summarizerNode/index.cjs.map +1 -0
  205. package/dist/summary/summarizerNode/index.d.ts +8 -0
  206. package/dist/summary/summarizerNode/index.d.ts.map +1 -0
  207. package/dist/summary/summarizerNode/summarizerNode.cjs +526 -0
  208. package/dist/summary/summarizerNode/summarizerNode.cjs.map +1 -0
  209. package/dist/summary/summarizerNode/summarizerNode.d.ts +167 -0
  210. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  211. package/dist/summary/summarizerNode/summarizerNodeUtils.cjs +130 -0
  212. package/dist/summary/summarizerNode/summarizerNodeUtils.cjs.map +1 -0
  213. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +121 -0
  214. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  215. package/dist/summary/summarizerNode/summarizerNodeWithGc.cjs +375 -0
  216. package/dist/summary/summarizerNode/summarizerNodeWithGc.cjs.map +1 -0
  217. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +153 -0
  218. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  219. package/dist/summary/summarizerTypes.cjs +7 -0
  220. package/dist/summary/summarizerTypes.cjs.map +1 -0
  221. package/{lib → dist/summary}/summarizerTypes.d.ts +233 -83
  222. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  223. package/dist/{summaryCollection.js → summary/summaryCollection.cjs} +80 -49
  224. package/dist/summary/summaryCollection.cjs.map +1 -0
  225. package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +23 -5
  226. package/dist/summary/summaryCollection.d.ts.map +1 -0
  227. package/dist/{summaryFormat.js → summary/summaryFormat.cjs} +29 -26
  228. package/dist/summary/summaryFormat.cjs.map +1 -0
  229. package/{lib → dist/summary}/summaryFormat.d.ts +25 -30
  230. package/dist/summary/summaryFormat.d.ts.map +1 -0
  231. package/dist/{summaryGenerator.js → summary/summaryGenerator.cjs} +162 -74
  232. package/dist/summary/summaryGenerator.cjs.map +1 -0
  233. package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +53 -11
  234. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  235. package/dist/{summaryManager.js → summary/summaryManager.cjs} +98 -55
  236. package/dist/summary/summaryManager.cjs.map +1 -0
  237. package/{lib → dist/summary}/summaryManager.d.ts +13 -11
  238. package/dist/summary/summaryManager.d.ts.map +1 -0
  239. package/dist/{throttler.js → throttler.cjs} +21 -21
  240. package/dist/throttler.cjs.map +1 -0
  241. package/dist/throttler.d.ts +2 -2
  242. package/dist/throttler.d.ts.map +1 -1
  243. package/dist/tsdoc-metadata.json +11 -0
  244. package/lib/{batchTracker.d.ts → batchTracker.d.mts} +6 -5
  245. package/lib/batchTracker.d.mts.map +1 -0
  246. package/lib/{batchTracker.js → batchTracker.mjs} +9 -8
  247. package/lib/batchTracker.mjs.map +1 -0
  248. package/lib/blobManager.d.mts +191 -0
  249. package/lib/blobManager.d.mts.map +1 -0
  250. package/lib/blobManager.mjs +699 -0
  251. package/lib/blobManager.mjs.map +1 -0
  252. package/lib/{connectionTelemetry.d.ts → connectionTelemetry.d.mts} +2 -2
  253. package/lib/connectionTelemetry.d.mts.map +1 -0
  254. package/lib/connectionTelemetry.mjs +226 -0
  255. package/lib/connectionTelemetry.mjs.map +1 -0
  256. package/lib/container-runtime-alpha.d.mts +1677 -0
  257. package/lib/container-runtime-beta.d.mts +250 -0
  258. package/lib/container-runtime-public.d.mts +250 -0
  259. package/lib/container-runtime-untrimmed.d.mts +1792 -0
  260. package/lib/{containerHandleContext.d.ts → containerHandleContext.d.mts} +1 -1
  261. package/lib/containerHandleContext.d.mts.map +1 -0
  262. package/lib/{containerHandleContext.js → containerHandleContext.mjs} +4 -2
  263. package/lib/containerHandleContext.mjs.map +1 -0
  264. package/lib/containerRuntime.d.mts +809 -0
  265. package/lib/containerRuntime.d.mts.map +1 -0
  266. package/lib/containerRuntime.mjs +2526 -0
  267. package/lib/containerRuntime.mjs.map +1 -0
  268. package/lib/{dataStore.d.ts → dataStore.d.mts} +4 -4
  269. package/lib/dataStore.d.mts.map +1 -0
  270. package/lib/{dataStore.js → dataStore.mjs} +52 -43
  271. package/lib/dataStore.mjs.map +1 -0
  272. package/lib/{dataStoreContext.d.ts → dataStoreContext.d.mts} +74 -42
  273. package/lib/dataStoreContext.d.mts.map +1 -0
  274. package/lib/{dataStoreContext.js → dataStoreContext.mjs} +309 -213
  275. package/lib/dataStoreContext.mjs.map +1 -0
  276. package/lib/{dataStoreContexts.d.ts → dataStoreContexts.d.mts} +2 -2
  277. package/lib/dataStoreContexts.d.mts.map +1 -0
  278. package/lib/{dataStoreContexts.js → dataStoreContexts.mjs} +12 -8
  279. package/lib/dataStoreContexts.mjs.map +1 -0
  280. package/lib/{dataStoreRegistry.d.ts → dataStoreRegistry.d.mts} +3 -0
  281. package/lib/dataStoreRegistry.d.mts.map +1 -0
  282. package/lib/{dataStoreRegistry.js → dataStoreRegistry.mjs} +7 -6
  283. package/lib/dataStoreRegistry.mjs.map +1 -0
  284. package/lib/{dataStores.d.ts → dataStores.d.mts} +56 -26
  285. package/lib/dataStores.d.mts.map +1 -0
  286. package/lib/{dataStores.js → dataStores.mjs} +254 -105
  287. package/lib/dataStores.mjs.map +1 -0
  288. package/lib/deltaManagerProxyBase.d.mts +35 -0
  289. package/lib/deltaManagerProxyBase.d.mts.map +1 -0
  290. package/lib/deltaManagerProxyBase.mjs +73 -0
  291. package/lib/deltaManagerProxyBase.mjs.map +1 -0
  292. package/lib/deltaManagerSummarizerProxy.d.mts +19 -0
  293. package/lib/deltaManagerSummarizerProxy.d.mts.map +1 -0
  294. package/lib/deltaManagerSummarizerProxy.mjs +38 -0
  295. package/lib/deltaManagerSummarizerProxy.mjs.map +1 -0
  296. package/lib/{deltaScheduler.d.ts → deltaScheduler.d.mts} +8 -6
  297. package/lib/deltaScheduler.d.mts.map +1 -0
  298. package/lib/{deltaScheduler.js → deltaScheduler.mjs} +22 -15
  299. package/lib/deltaScheduler.mjs.map +1 -0
  300. package/lib/error.d.mts +14 -0
  301. package/lib/error.d.mts.map +1 -0
  302. package/lib/error.mjs +17 -0
  303. package/lib/error.mjs.map +1 -0
  304. package/lib/gc/garbageCollection.d.mts +224 -0
  305. package/lib/gc/garbageCollection.d.mts.map +1 -0
  306. package/lib/gc/garbageCollection.mjs +857 -0
  307. package/lib/gc/garbageCollection.mjs.map +1 -0
  308. package/lib/gc/gcConfigs.d.mts +23 -0
  309. package/lib/gc/gcConfigs.d.mts.map +1 -0
  310. package/lib/gc/gcConfigs.mjs +149 -0
  311. package/lib/gc/gcConfigs.mjs.map +1 -0
  312. package/lib/gc/gcDefinitions.d.mts +437 -0
  313. package/lib/gc/gcDefinitions.d.mts.map +1 -0
  314. package/lib/gc/gcDefinitions.mjs +93 -0
  315. package/lib/gc/gcDefinitions.mjs.map +1 -0
  316. package/lib/gc/gcHelpers.d.mts +71 -0
  317. package/lib/gc/gcHelpers.d.mts.map +1 -0
  318. package/lib/gc/gcHelpers.mjs +222 -0
  319. package/lib/gc/gcHelpers.mjs.map +1 -0
  320. package/lib/gc/gcReferenceGraphAlgorithm.d.mts +16 -0
  321. package/lib/gc/gcReferenceGraphAlgorithm.d.mts.map +1 -0
  322. package/lib/gc/gcReferenceGraphAlgorithm.mjs +45 -0
  323. package/lib/gc/gcReferenceGraphAlgorithm.mjs.map +1 -0
  324. package/lib/gc/gcSummaryDefinitions.d.mts +52 -0
  325. package/lib/gc/gcSummaryDefinitions.d.mts.map +1 -0
  326. package/lib/gc/gcSummaryDefinitions.mjs +6 -0
  327. package/lib/gc/gcSummaryDefinitions.mjs.map +1 -0
  328. package/lib/gc/gcSummaryStateTracker.d.mts +94 -0
  329. package/lib/gc/gcSummaryStateTracker.d.mts.map +1 -0
  330. package/lib/gc/gcSummaryStateTracker.mjs +209 -0
  331. package/lib/gc/gcSummaryStateTracker.mjs.map +1 -0
  332. package/lib/gc/gcTelemetry.d.mts +92 -0
  333. package/lib/gc/gcTelemetry.d.mts.map +1 -0
  334. package/lib/gc/gcTelemetry.mjs +293 -0
  335. package/lib/gc/gcTelemetry.mjs.map +1 -0
  336. package/lib/gc/gcUnreferencedStateTracker.d.mts +40 -0
  337. package/lib/gc/gcUnreferencedStateTracker.d.mts.map +1 -0
  338. package/lib/gc/gcUnreferencedStateTracker.mjs +114 -0
  339. package/lib/gc/gcUnreferencedStateTracker.mjs.map +1 -0
  340. package/lib/gc/index.d.mts +13 -0
  341. package/lib/gc/index.d.mts.map +1 -0
  342. package/lib/gc/index.mjs +12 -0
  343. package/lib/gc/index.mjs.map +1 -0
  344. package/lib/index.d.mts +25 -0
  345. package/lib/index.d.mts.map +1 -0
  346. package/lib/index.mjs +24 -0
  347. package/lib/index.mjs.map +1 -0
  348. package/lib/messageTypes.d.mts +142 -0
  349. package/lib/messageTypes.d.mts.map +1 -0
  350. package/lib/messageTypes.mjs +34 -0
  351. package/lib/messageTypes.mjs.map +1 -0
  352. package/lib/metadata.d.mts +24 -0
  353. package/lib/metadata.d.mts.map +1 -0
  354. package/lib/metadata.mjs +6 -0
  355. package/lib/metadata.mjs.map +1 -0
  356. package/lib/opLifecycle/batchManager.d.mts +48 -0
  357. package/lib/opLifecycle/batchManager.d.mts.map +1 -0
  358. package/lib/opLifecycle/batchManager.mjs +133 -0
  359. package/lib/opLifecycle/batchManager.mjs.map +1 -0
  360. package/lib/opLifecycle/definitions.d.mts +83 -0
  361. package/lib/opLifecycle/definitions.d.mts.map +1 -0
  362. package/lib/opLifecycle/definitions.mjs +6 -0
  363. package/lib/opLifecycle/definitions.mjs.map +1 -0
  364. package/lib/opLifecycle/index.d.mts +13 -0
  365. package/lib/opLifecycle/index.d.mts.map +1 -0
  366. package/lib/opLifecycle/index.mjs +12 -0
  367. package/lib/opLifecycle/index.mjs.map +1 -0
  368. package/lib/opLifecycle/opCompressor.d.mts +18 -0
  369. package/lib/opLifecycle/opCompressor.d.mts.map +1 -0
  370. package/lib/opLifecycle/opCompressor.mjs +80 -0
  371. package/lib/opLifecycle/opCompressor.mjs.map +1 -0
  372. package/lib/opLifecycle/opDecompressor.d.mts +25 -0
  373. package/lib/opLifecycle/opDecompressor.d.mts.map +1 -0
  374. package/lib/opLifecycle/opDecompressor.mjs +128 -0
  375. package/lib/opLifecycle/opDecompressor.mjs.map +1 -0
  376. package/lib/opLifecycle/opGroupingManager.d.mts +22 -0
  377. package/lib/opLifecycle/opGroupingManager.d.mts.map +1 -0
  378. package/lib/opLifecycle/opGroupingManager.mjs +91 -0
  379. package/lib/opLifecycle/opGroupingManager.mjs.map +1 -0
  380. package/lib/opLifecycle/opSplitter.d.mts +61 -0
  381. package/lib/opLifecycle/opSplitter.d.mts.map +1 -0
  382. package/lib/opLifecycle/opSplitter.mjs +197 -0
  383. package/lib/opLifecycle/opSplitter.mjs.map +1 -0
  384. package/lib/opLifecycle/outbox.d.mts +104 -0
  385. package/lib/opLifecycle/outbox.d.mts.map +1 -0
  386. package/lib/opLifecycle/outbox.mjs +318 -0
  387. package/lib/opLifecycle/outbox.mjs.map +1 -0
  388. package/lib/opLifecycle/remoteMessageProcessor.d.mts +47 -0
  389. package/lib/opLifecycle/remoteMessageProcessor.d.mts.map +1 -0
  390. package/lib/opLifecycle/remoteMessageProcessor.mjs +131 -0
  391. package/lib/opLifecycle/remoteMessageProcessor.mjs.map +1 -0
  392. package/lib/opProperties.d.mts +7 -0
  393. package/lib/opProperties.d.mts.map +1 -0
  394. package/lib/opProperties.mjs +13 -0
  395. package/lib/opProperties.mjs.map +1 -0
  396. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +1 -1
  397. package/lib/{packageVersion.d.ts.map → packageVersion.d.mts.map} +1 -1
  398. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  399. package/lib/packageVersion.mjs.map +1 -0
  400. package/lib/{pendingStateManager.d.ts → pendingStateManager.d.mts} +32 -69
  401. package/lib/pendingStateManager.d.mts.map +1 -0
  402. package/lib/pendingStateManager.mjs +275 -0
  403. package/lib/pendingStateManager.mjs.map +1 -0
  404. package/lib/scheduleManager.d.mts +27 -0
  405. package/lib/scheduleManager.d.mts.map +1 -0
  406. package/lib/scheduleManager.mjs +254 -0
  407. package/lib/scheduleManager.mjs.map +1 -0
  408. package/lib/storageServiceWithAttachBlobs.d.mts +17 -0
  409. package/lib/storageServiceWithAttachBlobs.d.mts.map +1 -0
  410. package/lib/storageServiceWithAttachBlobs.mjs +28 -0
  411. package/lib/storageServiceWithAttachBlobs.mjs.map +1 -0
  412. package/lib/summary/index.d.mts +17 -0
  413. package/lib/summary/index.d.mts.map +1 -0
  414. package/lib/summary/index.mjs +16 -0
  415. package/lib/summary/index.mjs.map +1 -0
  416. package/{dist/orderedClientElection.d.ts → lib/summary/orderedClientElection.d.mts} +41 -22
  417. package/lib/summary/orderedClientElection.d.mts.map +1 -0
  418. package/lib/{orderedClientElection.js → summary/orderedClientElection.mjs} +95 -79
  419. package/lib/summary/orderedClientElection.mjs.map +1 -0
  420. package/{dist/runWhileConnectedCoordinator.d.ts → lib/summary/runWhileConnectedCoordinator.d.mts} +9 -3
  421. package/lib/summary/runWhileConnectedCoordinator.d.mts.map +1 -0
  422. package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.mjs} +12 -10
  423. package/lib/summary/runWhileConnectedCoordinator.mjs.map +1 -0
  424. package/lib/summary/runningSummarizer.d.mts +128 -0
  425. package/lib/summary/runningSummarizer.d.mts.map +1 -0
  426. package/lib/summary/runningSummarizer.mjs +675 -0
  427. package/lib/summary/runningSummarizer.mjs.map +1 -0
  428. package/lib/{summarizer.d.ts → summary/summarizer.d.mts} +20 -35
  429. package/lib/summary/summarizer.d.mts.map +1 -0
  430. package/lib/summary/summarizer.mjs +257 -0
  431. package/lib/summary/summarizer.mjs.map +1 -0
  432. package/{dist/summarizerClientElection.d.ts → lib/summary/summarizerClientElection.d.mts} +6 -6
  433. package/lib/summary/summarizerClientElection.d.mts.map +1 -0
  434. package/lib/{summarizerClientElection.js → summary/summarizerClientElection.mjs} +14 -45
  435. package/lib/summary/summarizerClientElection.mjs.map +1 -0
  436. package/{dist/summarizerHeuristics.d.ts → lib/summary/summarizerHeuristics.d.mts} +29 -7
  437. package/lib/summary/summarizerHeuristics.d.mts.map +1 -0
  438. package/lib/summary/summarizerHeuristics.mjs +151 -0
  439. package/lib/summary/summarizerHeuristics.mjs.map +1 -0
  440. package/lib/summary/summarizerNode/index.d.mts +8 -0
  441. package/lib/summary/summarizerNode/index.d.mts.map +1 -0
  442. package/lib/summary/summarizerNode/index.mjs +7 -0
  443. package/lib/summary/summarizerNode/index.mjs.map +1 -0
  444. package/lib/summary/summarizerNode/summarizerNode.d.mts +167 -0
  445. package/lib/summary/summarizerNode/summarizerNode.d.mts.map +1 -0
  446. package/lib/summary/summarizerNode/summarizerNode.mjs +521 -0
  447. package/lib/summary/summarizerNode/summarizerNode.mjs.map +1 -0
  448. package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts +121 -0
  449. package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts.map +1 -0
  450. package/lib/summary/summarizerNode/summarizerNodeUtils.mjs +123 -0
  451. package/lib/summary/summarizerNode/summarizerNodeUtils.mjs.map +1 -0
  452. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts +153 -0
  453. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts.map +1 -0
  454. package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs +370 -0
  455. package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs.map +1 -0
  456. package/{dist/summarizerTypes.d.ts → lib/summary/summarizerTypes.d.mts} +234 -84
  457. package/lib/summary/summarizerTypes.d.mts.map +1 -0
  458. package/lib/summary/summarizerTypes.mjs +6 -0
  459. package/lib/summary/summarizerTypes.mjs.map +1 -0
  460. package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.mts} +23 -5
  461. package/lib/summary/summaryCollection.d.mts.map +1 -0
  462. package/lib/{summaryCollection.js → summary/summaryCollection.mjs} +76 -45
  463. package/lib/summary/summaryCollection.mjs.map +1 -0
  464. package/{dist/summaryFormat.d.ts → lib/summary/summaryFormat.d.mts} +25 -30
  465. package/lib/summary/summaryFormat.d.mts.map +1 -0
  466. package/lib/{summaryFormat.js → summary/summaryFormat.mjs} +30 -26
  467. package/lib/summary/summaryFormat.mjs.map +1 -0
  468. package/lib/summary/summaryGenerator.d.mts +127 -0
  469. package/lib/summary/summaryGenerator.d.mts.map +1 -0
  470. package/lib/{summaryGenerator.js → summary/summaryGenerator.mjs} +153 -67
  471. package/lib/summary/summaryGenerator.mjs.map +1 -0
  472. package/{dist/summaryManager.d.ts → lib/summary/summaryManager.d.mts} +15 -13
  473. package/lib/summary/summaryManager.d.mts.map +1 -0
  474. package/lib/{summaryManager.js → summary/summaryManager.mjs} +94 -51
  475. package/lib/summary/summaryManager.mjs.map +1 -0
  476. package/lib/{throttler.d.ts → throttler.d.mts} +2 -2
  477. package/lib/throttler.d.mts.map +1 -0
  478. package/lib/{throttler.js → throttler.mjs} +21 -21
  479. package/lib/throttler.mjs.map +1 -0
  480. package/package.json +173 -72
  481. package/prettier.config.cjs +8 -0
  482. package/src/batchTracker.ts +59 -54
  483. package/src/blobManager.ts +937 -294
  484. package/src/connectionTelemetry.ts +342 -252
  485. package/src/containerHandleContext.ts +27 -29
  486. package/src/containerRuntime.ts +3879 -3143
  487. package/src/dataStore.ts +170 -140
  488. package/src/dataStoreContext.ts +1166 -986
  489. package/src/dataStoreContexts.ts +176 -163
  490. package/src/dataStoreRegistry.ts +29 -21
  491. package/src/dataStores.ts +921 -678
  492. package/src/deltaManagerProxyBase.ts +111 -0
  493. package/src/deltaManagerSummarizerProxy.ts +49 -0
  494. package/src/deltaScheduler.ts +161 -156
  495. package/src/error.ts +21 -0
  496. package/src/gc/garbageCollection.md +106 -0
  497. package/src/gc/garbageCollection.ts +1153 -0
  498. package/src/gc/gcConfigs.ts +216 -0
  499. package/src/gc/gcDefinitions.ts +502 -0
  500. package/src/gc/gcHelpers.ts +284 -0
  501. package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
  502. package/src/gc/gcSummaryDefinitions.ts +54 -0
  503. package/src/gc/gcSummaryStateTracker.ts +299 -0
  504. package/src/gc/gcTelemetry.ts +423 -0
  505. package/src/gc/gcUnreferencedStateTracker.ts +153 -0
  506. package/src/gc/index.ts +59 -0
  507. package/src/index.ts +101 -74
  508. package/src/messageTypes.ts +238 -0
  509. package/src/metadata.ts +26 -0
  510. package/src/opLifecycle/README.md +321 -0
  511. package/src/opLifecycle/batchManager.ts +179 -0
  512. package/src/opLifecycle/definitions.ts +89 -0
  513. package/src/opLifecycle/index.ts +19 -0
  514. package/src/opLifecycle/opCompressor.ts +99 -0
  515. package/src/opLifecycle/opDecompressor.ts +190 -0
  516. package/src/opLifecycle/opGroupingManager.ts +133 -0
  517. package/src/opLifecycle/opSplitter.ts +279 -0
  518. package/src/opLifecycle/outbox.ts +471 -0
  519. package/src/opLifecycle/remoteMessageProcessor.ts +175 -0
  520. package/src/opProperties.ts +21 -0
  521. package/src/packageVersion.ts +1 -1
  522. package/src/pendingStateManager.ts +396 -465
  523. package/src/scheduleManager.ts +358 -0
  524. package/src/storageServiceWithAttachBlobs.ts +38 -0
  525. package/src/summary/index.ts +109 -0
  526. package/src/summary/orderedClientElection.ts +571 -0
  527. package/src/summary/runWhileConnectedCoordinator.ts +117 -0
  528. package/src/summary/runningSummarizer.ts +920 -0
  529. package/src/summary/summarizer.ts +352 -0
  530. package/src/summary/summarizerClientElection.ts +140 -0
  531. package/src/summary/summarizerHeuristics.ts +227 -0
  532. package/src/summary/summarizerNode/index.ts +12 -0
  533. package/src/summary/summarizerNode/summarizerNode.ts +725 -0
  534. package/src/summary/summarizerNode/summarizerNodeUtils.ts +206 -0
  535. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +571 -0
  536. package/src/summary/summarizerTypes.ts +631 -0
  537. package/src/summary/summaryCollection.ts +474 -0
  538. package/src/summary/summaryFormat.ts +249 -0
  539. package/src/summary/summaryGenerator.ts +539 -0
  540. package/src/summary/summaryManager.ts +452 -0
  541. package/src/throttler.ts +131 -122
  542. package/tsc-multi.test.json +4 -0
  543. package/tsconfig.json +11 -13
  544. package/dist/batchTracker.js.map +0 -1
  545. package/dist/blobManager.js +0 -249
  546. package/dist/blobManager.js.map +0 -1
  547. package/dist/connectionTelemetry.js +0 -178
  548. package/dist/connectionTelemetry.js.map +0 -1
  549. package/dist/containerHandleContext.js.map +0 -1
  550. package/dist/containerRuntime.js +0 -2174
  551. package/dist/containerRuntime.js.map +0 -1
  552. package/dist/dataStore.js.map +0 -1
  553. package/dist/dataStoreContext.js.map +0 -1
  554. package/dist/dataStoreContexts.js.map +0 -1
  555. package/dist/dataStoreRegistry.js.map +0 -1
  556. package/dist/dataStores.js.map +0 -1
  557. package/dist/deltaScheduler.js.map +0 -1
  558. package/dist/garbageCollection.d.ts +0 -319
  559. package/dist/garbageCollection.d.ts.map +0 -1
  560. package/dist/garbageCollection.js +0 -993
  561. package/dist/garbageCollection.js.map +0 -1
  562. package/dist/index.js +0 -33
  563. package/dist/index.js.map +0 -1
  564. package/dist/opTelemetry.d.ts +0 -22
  565. package/dist/opTelemetry.d.ts.map +0 -1
  566. package/dist/opTelemetry.js +0 -60
  567. package/dist/opTelemetry.js.map +0 -1
  568. package/dist/orderedClientElection.d.ts.map +0 -1
  569. package/dist/orderedClientElection.js.map +0 -1
  570. package/dist/packageVersion.js.map +0 -1
  571. package/dist/pendingStateManager.js +0 -346
  572. package/dist/pendingStateManager.js.map +0 -1
  573. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  574. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  575. package/dist/runningSummarizer.d.ts +0 -93
  576. package/dist/runningSummarizer.d.ts.map +0 -1
  577. package/dist/runningSummarizer.js +0 -384
  578. package/dist/runningSummarizer.js.map +0 -1
  579. package/dist/serializedSnapshotStorage.d.ts +0 -58
  580. package/dist/serializedSnapshotStorage.d.ts.map +0 -1
  581. package/dist/serializedSnapshotStorage.js +0 -108
  582. package/dist/serializedSnapshotStorage.js.map +0 -1
  583. package/dist/summarizer.d.ts.map +0 -1
  584. package/dist/summarizer.js +0 -348
  585. package/dist/summarizer.js.map +0 -1
  586. package/dist/summarizerClientElection.d.ts.map +0 -1
  587. package/dist/summarizerClientElection.js.map +0 -1
  588. package/dist/summarizerHandle.d.ts +0 -12
  589. package/dist/summarizerHandle.d.ts.map +0 -1
  590. package/dist/summarizerHandle.js +0 -22
  591. package/dist/summarizerHandle.js.map +0 -1
  592. package/dist/summarizerHeuristics.d.ts.map +0 -1
  593. package/dist/summarizerHeuristics.js +0 -84
  594. package/dist/summarizerHeuristics.js.map +0 -1
  595. package/dist/summarizerTypes.d.ts.map +0 -1
  596. package/dist/summarizerTypes.js.map +0 -1
  597. package/dist/summaryCollection.d.ts.map +0 -1
  598. package/dist/summaryCollection.js.map +0 -1
  599. package/dist/summaryFormat.d.ts.map +0 -1
  600. package/dist/summaryFormat.js.map +0 -1
  601. package/dist/summaryGenerator.d.ts.map +0 -1
  602. package/dist/summaryGenerator.js.map +0 -1
  603. package/dist/summaryManager.d.ts.map +0 -1
  604. package/dist/summaryManager.js.map +0 -1
  605. package/dist/throttler.js.map +0 -1
  606. package/garbageCollection.md +0 -41
  607. package/lib/batchTracker.d.ts.map +0 -1
  608. package/lib/batchTracker.js.map +0 -1
  609. package/lib/blobManager.d.ts +0 -95
  610. package/lib/blobManager.d.ts.map +0 -1
  611. package/lib/blobManager.js +0 -244
  612. package/lib/blobManager.js.map +0 -1
  613. package/lib/connectionTelemetry.d.ts.map +0 -1
  614. package/lib/connectionTelemetry.js +0 -174
  615. package/lib/connectionTelemetry.js.map +0 -1
  616. package/lib/containerHandleContext.d.ts.map +0 -1
  617. package/lib/containerHandleContext.js.map +0 -1
  618. package/lib/containerRuntime.d.ts +0 -615
  619. package/lib/containerRuntime.d.ts.map +0 -1
  620. package/lib/containerRuntime.js +0 -2166
  621. package/lib/containerRuntime.js.map +0 -1
  622. package/lib/dataStore.d.ts.map +0 -1
  623. package/lib/dataStore.js.map +0 -1
  624. package/lib/dataStoreContext.d.ts.map +0 -1
  625. package/lib/dataStoreContext.js.map +0 -1
  626. package/lib/dataStoreContexts.d.ts.map +0 -1
  627. package/lib/dataStoreContexts.js.map +0 -1
  628. package/lib/dataStoreRegistry.d.ts.map +0 -1
  629. package/lib/dataStoreRegistry.js.map +0 -1
  630. package/lib/dataStores.d.ts.map +0 -1
  631. package/lib/dataStores.js.map +0 -1
  632. package/lib/deltaScheduler.d.ts.map +0 -1
  633. package/lib/deltaScheduler.js.map +0 -1
  634. package/lib/garbageCollection.d.ts +0 -319
  635. package/lib/garbageCollection.d.ts.map +0 -1
  636. package/lib/garbageCollection.js +0 -989
  637. package/lib/garbageCollection.js.map +0 -1
  638. package/lib/index.d.ts +0 -14
  639. package/lib/index.d.ts.map +0 -1
  640. package/lib/index.js +0 -13
  641. package/lib/index.js.map +0 -1
  642. package/lib/opTelemetry.d.ts +0 -22
  643. package/lib/opTelemetry.d.ts.map +0 -1
  644. package/lib/opTelemetry.js +0 -56
  645. package/lib/opTelemetry.js.map +0 -1
  646. package/lib/orderedClientElection.d.ts.map +0 -1
  647. package/lib/orderedClientElection.js.map +0 -1
  648. package/lib/packageVersion.js.map +0 -1
  649. package/lib/pendingStateManager.d.ts.map +0 -1
  650. package/lib/pendingStateManager.js +0 -339
  651. package/lib/pendingStateManager.js.map +0 -1
  652. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  653. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  654. package/lib/runningSummarizer.d.ts +0 -93
  655. package/lib/runningSummarizer.d.ts.map +0 -1
  656. package/lib/runningSummarizer.js +0 -380
  657. package/lib/runningSummarizer.js.map +0 -1
  658. package/lib/serializedSnapshotStorage.d.ts +0 -58
  659. package/lib/serializedSnapshotStorage.d.ts.map +0 -1
  660. package/lib/serializedSnapshotStorage.js +0 -104
  661. package/lib/serializedSnapshotStorage.js.map +0 -1
  662. package/lib/summarizer.d.ts.map +0 -1
  663. package/lib/summarizer.js +0 -342
  664. package/lib/summarizer.js.map +0 -1
  665. package/lib/summarizerClientElection.d.ts.map +0 -1
  666. package/lib/summarizerClientElection.js.map +0 -1
  667. package/lib/summarizerHandle.d.ts +0 -12
  668. package/lib/summarizerHandle.d.ts.map +0 -1
  669. package/lib/summarizerHandle.js +0 -18
  670. package/lib/summarizerHandle.js.map +0 -1
  671. package/lib/summarizerHeuristics.d.ts.map +0 -1
  672. package/lib/summarizerHeuristics.js +0 -79
  673. package/lib/summarizerHeuristics.js.map +0 -1
  674. package/lib/summarizerTypes.d.ts.map +0 -1
  675. package/lib/summarizerTypes.js +0 -9
  676. package/lib/summarizerTypes.js.map +0 -1
  677. package/lib/summaryCollection.d.ts.map +0 -1
  678. package/lib/summaryCollection.js.map +0 -1
  679. package/lib/summaryFormat.d.ts.map +0 -1
  680. package/lib/summaryFormat.js.map +0 -1
  681. package/lib/summaryGenerator.d.ts +0 -85
  682. package/lib/summaryGenerator.d.ts.map +0 -1
  683. package/lib/summaryGenerator.js.map +0 -1
  684. package/lib/summaryManager.d.ts.map +0 -1
  685. package/lib/summaryManager.js.map +0 -1
  686. package/lib/throttler.d.ts.map +0 -1
  687. package/lib/throttler.js.map +0 -1
  688. package/src/garbageCollection.ts +0 -1434
  689. package/src/opTelemetry.ts +0 -71
  690. package/src/orderedClientElection.ts +0 -511
  691. package/src/runWhileConnectedCoordinator.ts +0 -106
  692. package/src/runningSummarizer.ts +0 -550
  693. package/src/serializedSnapshotStorage.ts +0 -146
  694. package/src/summarizer.ts +0 -438
  695. package/src/summarizerClientElection.ts +0 -161
  696. package/src/summarizerHandle.ts +0 -21
  697. package/src/summarizerHeuristics.ts +0 -108
  698. package/src/summarizerTypes.ts +0 -462
  699. package/src/summaryCollection.ts +0 -406
  700. package/src/summaryFormat.ts +0 -239
  701. package/src/summaryGenerator.ts +0 -427
  702. package/src/summaryManager.ts +0 -368
  703. package/tsconfig.esnext.json +0 -7
@@ -0,0 +1,99 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { createChildLogger, UsageError } from "@fluidframework/telemetry-utils";
7
+ import { assert } from "@fluidframework/core-utils";
8
+ import { IsoBuffer } from "@fluid-internal/client-utils";
9
+ import { compress } from "lz4js";
10
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
11
+ import { CompressionAlgorithms } from "../containerRuntime";
12
+ import { estimateSocketSize } from "./batchManager";
13
+ import { IBatch, BatchMessage } from "./definitions";
14
+
15
+ /**
16
+ * Compresses batches of ops. It generates a single compressed op that contains
17
+ * the contents of each op in the batch. It then submits empty ops for each original
18
+ * op to reserve sequence numbers.
19
+ */
20
+ export class OpCompressor {
21
+ private readonly logger;
22
+
23
+ constructor(logger: ITelemetryBaseLogger) {
24
+ this.logger = createChildLogger({ logger, namespace: "OpCompressor" });
25
+ }
26
+
27
+ public compressBatch(batch: IBatch): IBatch {
28
+ assert(
29
+ batch.contentSizeInBytes > 0 && batch.content.length > 0,
30
+ 0x5a4 /* Batch should not be empty */,
31
+ );
32
+
33
+ const compressionStart = Date.now();
34
+ const contentsAsBuffer = new TextEncoder().encode(this.serializeBatch(batch));
35
+ const compressedContents = compress(contentsAsBuffer);
36
+ const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
37
+ const duration = Date.now() - compressionStart;
38
+
39
+ const messages: BatchMessage[] = [];
40
+ messages.push({
41
+ ...batch.content[0],
42
+ contents: JSON.stringify({ packedContents: compressedContent }),
43
+ metadata: batch.content[0].metadata,
44
+ compression: CompressionAlgorithms.lz4,
45
+ });
46
+
47
+ // Add empty placeholder messages to reserve the sequence numbers
48
+ for (const message of batch.content.slice(1)) {
49
+ messages.push({
50
+ type: message.type,
51
+ localOpMetadata: message.localOpMetadata,
52
+ metadata: message.metadata,
53
+ referenceSequenceNumber: message.referenceSequenceNumber,
54
+ });
55
+ }
56
+
57
+ const compressedBatch: IBatch = {
58
+ contentSizeInBytes: compressedContent.length,
59
+ content: messages,
60
+ referenceSequenceNumber: batch.referenceSequenceNumber,
61
+ };
62
+
63
+ if (batch.contentSizeInBytes > 200000) {
64
+ this.logger.sendPerformanceEvent({
65
+ eventName: "CompressedBatch",
66
+ duration,
67
+ sizeBeforeCompression: batch.contentSizeInBytes,
68
+ sizeAfterCompression: compressedBatch.contentSizeInBytes,
69
+ opCount: compressedBatch.content.length,
70
+ socketSize: estimateSocketSize(compressedBatch),
71
+ });
72
+ }
73
+
74
+ return compressedBatch;
75
+ }
76
+
77
+ private serializeBatch(batch: IBatch): string {
78
+ try {
79
+ return `[${batch.content.map((message) => message.contents).join(",")}]`;
80
+ } catch (e: any) {
81
+ if (e.message === "Invalid string length") {
82
+ // This is how JSON.stringify signals that
83
+ // the content size exceeds its capacity
84
+ const error = new UsageError("Payload too large");
85
+ this.logger.sendErrorEvent(
86
+ {
87
+ eventName: "BatchTooLarge",
88
+ size: batch.contentSizeInBytes,
89
+ length: batch.content.length,
90
+ },
91
+ error,
92
+ );
93
+ throw error;
94
+ }
95
+
96
+ throw e;
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,190 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { decompress } from "lz4js";
7
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
+ import { assert } from "@fluidframework/core-utils";
9
+ import { IsoBuffer, Uint8ArrayToString } from "@fluid-internal/client-utils";
10
+ import { createChildLogger } from "@fluidframework/telemetry-utils";
11
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
12
+ import { CompressionAlgorithms } from "../containerRuntime";
13
+ import { IBatchMetadata } from "../metadata";
14
+ import { IMessageProcessingResult } from "./definitions";
15
+
16
+ /**
17
+ * Compression makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
18
+ */
19
+ interface IPackedContentsContents {
20
+ packedContents: string;
21
+ }
22
+
23
+ /**
24
+ * State machine that "unrolls" contents of compressed batches of ops after decompressing them.
25
+ * This class relies on some implicit contracts defined below:
26
+ * 1. A compressed batch will have its first message with batch metadata set to true and compressed set to true
27
+ * 2. Messages in the middle of a compressed batch will have neither batch metadata nor the compression property set
28
+ * 3. The final message of a batch will have batch metadata set to false
29
+ * 4. An individually compressed op will have undefined batch metadata and compression set to true
30
+ */
31
+ export class OpDecompressor {
32
+ private activeBatch = false;
33
+ private rootMessageContents: any | undefined;
34
+ private processedCount = 0;
35
+ private readonly logger;
36
+
37
+ constructor(logger: ITelemetryBaseLogger) {
38
+ this.logger = createChildLogger({ logger, namespace: "OpDecompressor" });
39
+ }
40
+
41
+ public processMessage(message: ISequencedDocumentMessage): IMessageProcessingResult {
42
+ assert(
43
+ message.compression === undefined || message.compression === CompressionAlgorithms.lz4,
44
+ 0x511 /* Only lz4 compression is supported */,
45
+ );
46
+
47
+ if (
48
+ (message.metadata as IBatchMetadata | undefined)?.batch === true &&
49
+ this.isCompressed(message)
50
+ ) {
51
+ // Beginning of a compressed batch
52
+ assert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);
53
+ this.activeBatch = true;
54
+
55
+ const contents = IsoBuffer.from(
56
+ (message.contents as IPackedContentsContents).packedContents,
57
+ "base64",
58
+ );
59
+ const decompressedMessage = decompress(contents);
60
+ const intoString = Uint8ArrayToString(decompressedMessage);
61
+ const asObj = JSON.parse(intoString);
62
+ this.rootMessageContents = asObj;
63
+
64
+ return {
65
+ message: newMessage(message, this.rootMessageContents[this.processedCount++]),
66
+ state: "Accepted",
67
+ };
68
+ }
69
+
70
+ if (
71
+ this.rootMessageContents !== undefined &&
72
+ (message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
73
+ this.activeBatch
74
+ ) {
75
+ assert(message.contents === undefined, 0x512 /* Expecting empty message */);
76
+
77
+ // Continuation of compressed batch
78
+ return {
79
+ message: newMessage(message, this.rootMessageContents[this.processedCount++]),
80
+ state: "Accepted",
81
+ };
82
+ }
83
+
84
+ if (
85
+ this.rootMessageContents !== undefined &&
86
+ (message.metadata as IBatchMetadata | undefined)?.batch === false
87
+ ) {
88
+ // End of compressed batch
89
+ const returnMessage = newMessage(
90
+ message,
91
+ this.rootMessageContents[this.processedCount++],
92
+ );
93
+
94
+ this.activeBatch = false;
95
+ this.rootMessageContents = undefined;
96
+ this.processedCount = 0;
97
+
98
+ return {
99
+ message: returnMessage,
100
+ state: "Processed",
101
+ };
102
+ }
103
+
104
+ if (
105
+ (message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
106
+ this.isCompressed(message)
107
+ ) {
108
+ // Single compressed message
109
+ assert(
110
+ this.activeBatch === false,
111
+ 0x4ba /* shouldn't receive compressed message in middle of a batch */,
112
+ );
113
+
114
+ const contents = IsoBuffer.from(
115
+ (message.contents as IPackedContentsContents).packedContents,
116
+ "base64",
117
+ );
118
+ const decompressedMessage = decompress(contents);
119
+ const intoString = new TextDecoder().decode(decompressedMessage);
120
+ const asObj = JSON.parse(intoString);
121
+
122
+ return {
123
+ message: newMessage(message, asObj[0]),
124
+ state: "Processed",
125
+ };
126
+ }
127
+
128
+ return {
129
+ message,
130
+ state: "Skipped",
131
+ };
132
+ }
133
+
134
+ private isCompressed(message: ISequencedDocumentMessage) {
135
+ if (message.compression === CompressionAlgorithms.lz4) {
136
+ return true;
137
+ }
138
+
139
+ /**
140
+ * Back-compat self healing mechanism for ADO:3538, as loaders from
141
+ * version client_v2.0.0-internal.1.2.0 to client_v2.0.0-internal.2.2.0 do not
142
+ * support adding the proper compression metadata to compressed messages submitted
143
+ * by the runtime. Should be removed after the loader reaches sufficient saturation
144
+ * for a version greater or equal than client_v2.0.0-internal.2.2.0.
145
+ *
146
+ * The condition holds true for compressed messages, regardless of metadata. We are ultimately
147
+ * looking for a message with a single property `packedContents` inside `contents`, of type 'string'
148
+ * with a base64 encoded value.
149
+ */
150
+ try {
151
+ if (
152
+ message.contents !== null &&
153
+ typeof message.contents === "object" &&
154
+ Object.keys(message.contents).length === 1 &&
155
+ typeof (message.contents as { packedContents?: unknown }).packedContents ===
156
+ "string" &&
157
+ (message.contents as IPackedContentsContents).packedContents.length > 0 &&
158
+ IsoBuffer.from(
159
+ (message.contents as IPackedContentsContents).packedContents,
160
+ "base64",
161
+ ).toString("base64") ===
162
+ (message.contents as IPackedContentsContents).packedContents
163
+ ) {
164
+ this.logger.sendTelemetryEvent({
165
+ eventName: "LegacyCompression",
166
+ type: message.type,
167
+ batch: (message.metadata as IBatchMetadata | undefined)?.batch,
168
+ });
169
+ return true;
170
+ }
171
+ } catch (err) {
172
+ return false;
173
+ }
174
+
175
+ return false;
176
+ }
177
+ }
178
+
179
+ // We should not be mutating the input message nor its metadata
180
+ const newMessage = (
181
+ originalMessage: ISequencedDocumentMessage,
182
+ contents: any,
183
+ ): ISequencedDocumentMessage => ({
184
+ ...originalMessage,
185
+ contents,
186
+ compression: undefined,
187
+ // TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.
188
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
189
+ metadata: { ...(originalMessage.metadata as any) },
190
+ });
@@ -0,0 +1,133 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { assert } from "@fluidframework/core-utils";
7
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
+ import { createChildLogger } from "@fluidframework/telemetry-utils";
9
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
10
+ import { ContainerMessageType } from "../messageTypes";
11
+ import { IBatch } from "./definitions";
12
+
13
+ /**
14
+ * Grouping makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
15
+ */
16
+ interface IGroupedBatchMessageContents {
17
+ type: typeof OpGroupingManager.groupedBatchOp;
18
+ contents: IGroupedMessage[];
19
+ }
20
+
21
+ interface IGroupedMessage {
22
+ contents?: unknown;
23
+ metadata?: Record<string, unknown>;
24
+ compression?: string;
25
+ }
26
+
27
+ function isGroupContents(opContents: any): opContents is IGroupedBatchMessageContents {
28
+ return opContents?.type === OpGroupingManager.groupedBatchOp;
29
+ }
30
+
31
+ export interface OpGroupingManagerConfig {
32
+ readonly groupedBatchingEnabled: boolean;
33
+ readonly opCountThreshold: number;
34
+ readonly reentrantBatchGroupingEnabled: boolean;
35
+ }
36
+
37
+ export class OpGroupingManager {
38
+ static readonly groupedBatchOp = "groupedBatch";
39
+ private readonly logger;
40
+
41
+ constructor(
42
+ private readonly config: OpGroupingManagerConfig,
43
+ logger: ITelemetryBaseLogger,
44
+ ) {
45
+ this.logger = createChildLogger({ logger, namespace: "OpGroupingManager" });
46
+ }
47
+
48
+ public groupBatch(batch: IBatch): IBatch {
49
+ if (!this.shouldGroup(batch)) {
50
+ return batch;
51
+ }
52
+
53
+ if (batch.content.length >= 1000) {
54
+ this.logger.sendTelemetryEvent({
55
+ eventName: "GroupLargeBatch",
56
+ length: batch.content.length,
57
+ threshold: this.config.opCountThreshold,
58
+ reentrant: batch.hasReentrantOps,
59
+ referenceSequenceNumber: batch.content[0].referenceSequenceNumber,
60
+ });
61
+ }
62
+
63
+ for (const message of batch.content) {
64
+ if (message.metadata) {
65
+ const keys = Object.keys(message.metadata);
66
+ assert(keys.length < 2, 0x5dd /* cannot group ops with metadata */);
67
+ assert(
68
+ keys.length === 0 || keys[0] === "batch",
69
+ 0x5de /* unexpected op metadata */,
70
+ );
71
+ }
72
+ }
73
+
74
+ const serializedContent = JSON.stringify({
75
+ type: OpGroupingManager.groupedBatchOp,
76
+ contents: batch.content.map<IGroupedMessage>((message) => ({
77
+ contents: message.contents === undefined ? undefined : JSON.parse(message.contents),
78
+ metadata: message.metadata,
79
+ compression: message.compression,
80
+ })),
81
+ });
82
+
83
+ const groupedBatch: IBatch = {
84
+ ...batch,
85
+ content: [
86
+ {
87
+ localOpMetadata: undefined,
88
+ metadata: undefined,
89
+ referenceSequenceNumber: batch.content[0].referenceSequenceNumber,
90
+ contents: serializedContent,
91
+ type: OpGroupingManager.groupedBatchOp as ContainerMessageType,
92
+ },
93
+ ],
94
+ };
95
+ return groupedBatch;
96
+ }
97
+
98
+ public ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {
99
+ let fakeCsn = 1;
100
+ if (!isGroupContents(op.contents)) {
101
+ // Align the worlds of what clientSequenceNumber represents when grouped batching is enabled
102
+ if (this.config.groupedBatchingEnabled) {
103
+ return [
104
+ {
105
+ ...op,
106
+ clientSequenceNumber: fakeCsn,
107
+ },
108
+ ];
109
+ }
110
+ return [op];
111
+ }
112
+
113
+ const messages = op.contents.contents;
114
+ return messages.map((subMessage) => ({
115
+ ...op,
116
+ clientSequenceNumber: fakeCsn++,
117
+ contents: subMessage.contents,
118
+ metadata: subMessage.metadata,
119
+ compression: subMessage.compression,
120
+ }));
121
+ }
122
+
123
+ public shouldGroup(batch: IBatch): boolean {
124
+ return (
125
+ // Grouped batching must be enabled
126
+ this.config.groupedBatchingEnabled &&
127
+ // The number of ops in the batch must surpass the configured threshold
128
+ batch.content.length >= this.config.opCountThreshold &&
129
+ // Support for reentrant batches must be explicitly enabled
130
+ (this.config.reentrantBatchGroupingEnabled || batch.hasReentrantOps !== true)
131
+ );
132
+ }
133
+ }
@@ -0,0 +1,279 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ createChildLogger,
8
+ DataCorruptionError,
9
+ extractSafePropertiesFromMessage,
10
+ } from "@fluidframework/telemetry-utils";
11
+ import { assert } from "@fluidframework/core-utils";
12
+ import { IBatchMessage } from "@fluidframework/container-definitions";
13
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
14
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
15
+ import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes";
16
+ import { estimateSocketSize } from "./batchManager";
17
+ import { BatchMessage, IBatch, IChunkedOp, IMessageProcessingResult } from "./definitions";
18
+
19
+ /**
20
+ * Responsible for creating and reconstructing chunked messages.
21
+ */
22
+ export class OpSplitter {
23
+ // Local copy of incomplete received chunks.
24
+ private readonly chunkMap: Map<string, string[]>;
25
+ private readonly logger;
26
+
27
+ constructor(
28
+ chunks: [string, string[]][],
29
+ private readonly submitBatchFn:
30
+ | ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)
31
+ | undefined,
32
+ public readonly chunkSizeInBytes: number,
33
+ private readonly maxBatchSizeInBytes: number,
34
+ logger: ITelemetryBaseLogger,
35
+ ) {
36
+ this.chunkMap = new Map<string, string[]>(chunks);
37
+ this.logger = createChildLogger({ logger, namespace: "OpSplitter" });
38
+ }
39
+
40
+ public get isBatchChunkingEnabled(): boolean {
41
+ return this.chunkSizeInBytes < Number.POSITIVE_INFINITY && this.submitBatchFn !== undefined;
42
+ }
43
+
44
+ public get chunks(): ReadonlyMap<string, string[]> {
45
+ return this.chunkMap;
46
+ }
47
+
48
+ public processRemoteMessage(message: ISequencedDocumentMessage): IMessageProcessingResult {
49
+ if (message.type !== ContainerMessageType.ChunkedOp) {
50
+ return {
51
+ message,
52
+ state: "Skipped",
53
+ };
54
+ }
55
+
56
+ // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
57
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
58
+ const clientId = message.clientId as string;
59
+ const chunkedContent = message.contents as IChunkedOp;
60
+ this.addChunk(clientId, chunkedContent, message);
61
+
62
+ if (chunkedContent.chunkId < chunkedContent.totalChunks) {
63
+ // We are processing the op in chunks but haven't reached
64
+ // the last chunk yet in order to reconstruct the original op
65
+ return {
66
+ message,
67
+ state: "Accepted",
68
+ };
69
+ }
70
+
71
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
72
+ const serializedContent = this.chunkMap.get(clientId)!.join("");
73
+ this.clearPartialChunks(clientId);
74
+
75
+ const newMessage = { ...message };
76
+ newMessage.contents = serializedContent === "" ? undefined : JSON.parse(serializedContent);
77
+ newMessage.type = chunkedContent.originalType;
78
+ newMessage.metadata = chunkedContent.originalMetadata;
79
+ newMessage.compression = chunkedContent.originalCompression;
80
+ return {
81
+ message: newMessage,
82
+ state: "Processed",
83
+ };
84
+ }
85
+
86
+ public clearPartialChunks(clientId: string) {
87
+ if (this.chunkMap.has(clientId)) {
88
+ this.chunkMap.delete(clientId);
89
+ }
90
+ }
91
+
92
+ private addChunk(
93
+ clientId: string,
94
+ chunkedContent: IChunkedOp,
95
+ originalMessage: ISequencedDocumentMessage,
96
+ ) {
97
+ let map = this.chunkMap.get(clientId);
98
+ if (map === undefined) {
99
+ map = [];
100
+ this.chunkMap.set(clientId, map);
101
+ }
102
+
103
+ if (chunkedContent.chunkId !== map.length + 1) {
104
+ // We are expecting the chunks to be processed sequentially, in the same order as they are sent.
105
+ // Therefore, the chunkId of the incoming op needs to match the length of the array (1-based indexing)
106
+ // holding the existing chunks for that particular clientId.
107
+ throw new DataCorruptionError("Chunk Id mismatch", {
108
+ ...extractSafePropertiesFromMessage(originalMessage),
109
+ chunkMapLength: map.length,
110
+ chunkId: chunkedContent.chunkId,
111
+ totalChunks: chunkedContent.totalChunks,
112
+ });
113
+ }
114
+
115
+ map.push(chunkedContent.contents);
116
+ }
117
+
118
+ /**
119
+ * Splits the first op of a compressed batch in chunks, sends the chunks separately and
120
+ * returns a new batch composed of the last chunk and the rest of the ops in the original batch.
121
+ *
122
+ * A compressed batch is formed by one large op at the first position, followed by a series of placeholder ops
123
+ * which are used in order to reserve the sequence numbers for when the first op gets unrolled into the original
124
+ * uncompressed ops at ingestion in the runtime.
125
+ *
126
+ * If the first op is too large, it can be chunked (split into smaller op) which can be sent individually over the wire
127
+ * and accumulate at ingestion, until the last op in the chunk is processed, when the original op is unrolled.
128
+ *
129
+ * This method will send the first N - 1 chunks separately and use the last chunk as the first message in the result batch
130
+ * and then appends the original placeholder ops. This will ensure that the batch semantics of the original (non-compressed) batch
131
+ * are preserved, as the original chunked op will be unrolled by the runtime when the first message in the batch is processed
132
+ * (as it is the last chunk).
133
+ *
134
+ * To illustrate, if the input is `[largeOp, emptyOp, emptyOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
135
+ * `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4, emptyOp, emptyOp]` will be returned.
136
+ *
137
+ * @param batch - the compressed batch which needs to be processed
138
+ * @returns A new adjusted batch which can be sent over the wire
139
+ */
140
+ public splitFirstBatchMessage(batch: IBatch): IBatch {
141
+ assert(this.isBatchChunkingEnabled, 0x513 /* Chunking needs to be enabled */);
142
+ assert(
143
+ batch.contentSizeInBytes > 0 && batch.content.length > 0,
144
+ 0x514 /* Batch needs to be non-empty */,
145
+ );
146
+ assert(
147
+ batch.referenceSequenceNumber !== undefined,
148
+ 0x58a /* Batch must have a reference sequence number if non-empty */,
149
+ );
150
+ assert(this.chunkSizeInBytes !== 0, 0x515 /* Chunk size needs to be non-zero */);
151
+ assert(
152
+ this.chunkSizeInBytes < this.maxBatchSizeInBytes,
153
+ 0x516 /* Chunk size needs to be smaller than the max batch size */,
154
+ );
155
+
156
+ const firstMessage = batch.content[0]; // we expect this to be the large compressed op, which needs to be split
157
+ assert(
158
+ (firstMessage.contents?.length ?? 0) >= this.chunkSizeInBytes,
159
+ 0x518 /* First message in the batch needs to be chunkable */,
160
+ );
161
+
162
+ const restOfMessages = batch.content.slice(1); // we expect these to be empty ops, created to reserve sequence numbers
163
+ const socketSize = estimateSocketSize(batch);
164
+ const chunks = splitOp(
165
+ firstMessage,
166
+ this.chunkSizeInBytes,
167
+ // If we estimate that the socket batch size will exceed the batch limit
168
+ // we will inject an empty op to minimize the risk of the payload failing due to
169
+ // the overhead from the trailing empty ops in the batch.
170
+ socketSize >= this.maxBatchSizeInBytes,
171
+ );
172
+
173
+ assert(this.submitBatchFn !== undefined, 0x519 /* We don't support old loaders */);
174
+ // Send the first N-1 chunks immediately
175
+ for (const chunk of chunks.slice(0, -1)) {
176
+ this.submitBatchFn(
177
+ [chunkToBatchMessage(chunk, batch.referenceSequenceNumber)],
178
+ batch.referenceSequenceNumber,
179
+ );
180
+ }
181
+
182
+ // The last chunk will be part of the new batch and needs to
183
+ // preserve the batch metadata of the original batch
184
+ const lastChunk = chunkToBatchMessage(
185
+ chunks[chunks.length - 1],
186
+ batch.referenceSequenceNumber,
187
+ { batch: firstMessage.metadata?.batch },
188
+ );
189
+
190
+ this.logger.sendPerformanceEvent({
191
+ // Used to be "Chunked compressed batch"
192
+ eventName: "CompressedChunkedBatch",
193
+ length: batch.content.length,
194
+ sizeInBytes: batch.contentSizeInBytes,
195
+ chunks: chunks.length,
196
+ chunkSizeInBytes: this.chunkSizeInBytes,
197
+ socketSize,
198
+ });
199
+
200
+ return {
201
+ content: [lastChunk, ...restOfMessages],
202
+ contentSizeInBytes: lastChunk.contents?.length ?? 0,
203
+ referenceSequenceNumber: batch.referenceSequenceNumber,
204
+ };
205
+ }
206
+ }
207
+
208
+ const chunkToBatchMessage = (
209
+ chunk: IChunkedOp,
210
+ referenceSequenceNumber: number,
211
+ metadata: Record<string, unknown> | undefined = undefined,
212
+ ): BatchMessage => {
213
+ const payload: ContainerRuntimeChunkedOpMessage = {
214
+ type: ContainerMessageType.ChunkedOp,
215
+ contents: chunk,
216
+ };
217
+ return {
218
+ contents: JSON.stringify(payload),
219
+ type: payload.type,
220
+ metadata,
221
+ localOpMetadata: undefined,
222
+ referenceSequenceNumber,
223
+ };
224
+ };
225
+
226
+ /**
227
+ * Splits an op into smaller ops (chunks), based on the size of the op and the `chunkSizeInBytes` parameter.
228
+ *
229
+ * The last op of the result will be bundled with empty ops in the same batch. There is a risk of the batch payload
230
+ * exceeding the 1MB limit due to the overhead from the empty ops. If the last op is large, the risk is even higher.
231
+ * To minimize the odds, an extra empty op can be added to the result using the `extraOp` parameter.
232
+ *
233
+ * @param op - the op to be split
234
+ * @param chunkSizeInBytes - how large should the chunks be
235
+ * @param extraOp - should an extra empty op be added to the result
236
+ * @returns an array of chunked ops
237
+ */
238
+ export const splitOp = (
239
+ op: BatchMessage,
240
+ chunkSizeInBytes: number,
241
+ extraOp: boolean = false,
242
+ ): IChunkedOp[] => {
243
+ const chunks: IChunkedOp[] = [];
244
+ assert(
245
+ op.contents !== undefined && op.contents !== null,
246
+ 0x51a /* We should have something to chunk */,
247
+ );
248
+
249
+ const contentLength = op.contents.length;
250
+ const chunkCount = Math.floor((contentLength - 1) / chunkSizeInBytes) + 1 + (extraOp ? 1 : 0);
251
+ let offset = 0;
252
+ for (let chunkId = 1; chunkId <= chunkCount; chunkId++) {
253
+ const chunk: IChunkedOp = {
254
+ chunkId,
255
+ contents: op.contents.substr(offset, chunkSizeInBytes),
256
+ originalType: op.type,
257
+ totalChunks: chunkCount,
258
+ };
259
+
260
+ if (chunkId === chunkCount) {
261
+ // We don't need to port these to all the chunks,
262
+ // as we rebuild the original op when we process the
263
+ // last chunk, therefore it is the only one that needs it.
264
+ chunk.originalMetadata = op.metadata;
265
+ chunk.originalCompression = op.compression;
266
+ }
267
+
268
+ chunks.push(chunk);
269
+ offset += chunkSizeInBytes;
270
+ assert(
271
+ chunkId >= chunkCount - 1 || offset <= contentLength,
272
+ 0x58b /* Content offset within bounds */,
273
+ );
274
+ }
275
+
276
+ assert(offset >= contentLength, 0x58c /* Content offset equal or larger than content length */);
277
+ assert(chunks.length === chunkCount, 0x5a5 /* Expected number of chunks */);
278
+ return chunks;
279
+ };