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

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 (705) 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-esm.json +4 -0
  6. package/api-extractor-lint.json +4 -0
  7. package/api-extractor.json +2 -2
  8. package/api-report/container-runtime.api.md +863 -0
  9. package/dist/{batchTracker.js → batchTracker.cjs} +9 -8
  10. package/dist/batchTracker.cjs.map +1 -0
  11. package/dist/batchTracker.d.ts +6 -5
  12. package/dist/batchTracker.d.ts.map +1 -1
  13. package/dist/blobManager.cjs +709 -0
  14. package/dist/blobManager.cjs.map +1 -0
  15. package/dist/blobManager.d.ts +140 -39
  16. package/dist/blobManager.d.ts.map +1 -1
  17. package/dist/connectionTelemetry.cjs +230 -0
  18. package/dist/connectionTelemetry.cjs.map +1 -0
  19. package/dist/connectionTelemetry.d.ts +2 -2
  20. package/dist/connectionTelemetry.d.ts.map +1 -1
  21. package/dist/container-runtime-alpha.d.ts +1690 -0
  22. package/dist/container-runtime-beta.d.ts +250 -0
  23. package/dist/container-runtime-public.d.ts +250 -0
  24. package/dist/container-runtime-untrimmed.d.ts +1805 -0
  25. package/dist/{containerHandleContext.js → containerHandleContext.cjs} +4 -2
  26. package/dist/containerHandleContext.cjs.map +1 -0
  27. package/dist/containerHandleContext.d.ts.map +1 -1
  28. package/dist/containerRuntime.cjs +2535 -0
  29. package/dist/containerRuntime.cjs.map +1 -0
  30. package/dist/containerRuntime.d.ts +458 -256
  31. package/dist/containerRuntime.d.ts.map +1 -1
  32. package/dist/{dataStore.js → dataStore.cjs} +54 -45
  33. package/dist/dataStore.cjs.map +1 -0
  34. package/dist/dataStore.d.ts +2 -2
  35. package/dist/dataStore.d.ts.map +1 -1
  36. package/dist/{dataStoreContext.js → dataStoreContext.cjs} +343 -247
  37. package/dist/dataStoreContext.cjs.map +1 -0
  38. package/dist/dataStoreContext.d.ts +73 -41
  39. package/dist/dataStoreContext.d.ts.map +1 -1
  40. package/dist/{dataStoreContexts.js → dataStoreContexts.cjs} +19 -15
  41. package/dist/dataStoreContexts.cjs.map +1 -0
  42. package/dist/dataStoreContexts.d.ts +1 -1
  43. package/dist/dataStoreContexts.d.ts.map +1 -1
  44. package/dist/{dataStoreRegistry.js → dataStoreRegistry.cjs} +9 -4
  45. package/dist/dataStoreRegistry.cjs.map +1 -0
  46. package/dist/dataStoreRegistry.d.ts +3 -0
  47. package/dist/dataStoreRegistry.d.ts.map +1 -1
  48. package/dist/{dataStores.js → dataStores.cjs} +276 -124
  49. package/dist/dataStores.cjs.map +1 -0
  50. package/dist/dataStores.d.ts +56 -23
  51. package/dist/dataStores.d.ts.map +1 -1
  52. package/dist/deltaManagerProxyBase.cjs +77 -0
  53. package/dist/deltaManagerProxyBase.cjs.map +1 -0
  54. package/dist/deltaManagerProxyBase.d.ts +35 -0
  55. package/dist/deltaManagerProxyBase.d.ts.map +1 -0
  56. package/dist/deltaManagerSummarizerProxy.cjs +42 -0
  57. package/dist/deltaManagerSummarizerProxy.cjs.map +1 -0
  58. package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
  59. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
  60. package/dist/{deltaScheduler.js → deltaScheduler.cjs} +25 -18
  61. package/dist/deltaScheduler.cjs.map +1 -0
  62. package/dist/deltaScheduler.d.ts +8 -6
  63. package/dist/deltaScheduler.d.ts.map +1 -1
  64. package/dist/error.cjs +21 -0
  65. package/dist/error.cjs.map +1 -0
  66. package/dist/error.d.ts +14 -0
  67. package/dist/error.d.ts.map +1 -0
  68. package/dist/gc/garbageCollection.cjs +865 -0
  69. package/dist/gc/garbageCollection.cjs.map +1 -0
  70. package/dist/gc/garbageCollection.d.ts +224 -0
  71. package/dist/gc/garbageCollection.d.ts.map +1 -0
  72. package/dist/gc/gcConfigs.cjs +160 -0
  73. package/dist/gc/gcConfigs.cjs.map +1 -0
  74. package/dist/gc/gcConfigs.d.ts +23 -0
  75. package/dist/gc/gcConfigs.d.ts.map +1 -0
  76. package/dist/gc/gcDefinitions.cjs +96 -0
  77. package/dist/gc/gcDefinitions.cjs.map +1 -0
  78. package/dist/gc/gcDefinitions.d.ts +458 -0
  79. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  80. package/dist/gc/gcHelpers.cjs +235 -0
  81. package/dist/gc/gcHelpers.cjs.map +1 -0
  82. package/dist/gc/gcHelpers.d.ts +71 -0
  83. package/dist/gc/gcHelpers.d.ts.map +1 -0
  84. package/dist/gc/gcReferenceGraphAlgorithm.cjs +49 -0
  85. package/dist/gc/gcReferenceGraphAlgorithm.cjs.map +1 -0
  86. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  87. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  88. package/dist/{summarizerTypes.js → gc/gcSummaryDefinitions.cjs} +1 -6
  89. package/dist/gc/gcSummaryDefinitions.cjs.map +1 -0
  90. package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
  91. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
  92. package/dist/gc/gcSummaryStateTracker.cjs +213 -0
  93. package/dist/gc/gcSummaryStateTracker.cjs.map +1 -0
  94. package/dist/gc/gcSummaryStateTracker.d.ts +94 -0
  95. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  96. package/dist/gc/gcTelemetry.cjs +307 -0
  97. package/dist/gc/gcTelemetry.cjs.map +1 -0
  98. package/dist/gc/gcTelemetry.d.ts +99 -0
  99. package/dist/gc/gcTelemetry.d.ts.map +1 -0
  100. package/dist/gc/gcUnreferencedStateTracker.cjs +118 -0
  101. package/dist/gc/gcUnreferencedStateTracker.cjs.map +1 -0
  102. package/dist/gc/gcUnreferencedStateTracker.d.ts +40 -0
  103. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  104. package/dist/gc/index.cjs +44 -0
  105. package/dist/gc/index.cjs.map +1 -0
  106. package/dist/gc/index.d.ts +13 -0
  107. package/dist/gc/index.d.ts.map +1 -0
  108. package/dist/index.cjs +47 -0
  109. package/dist/index.cjs.map +1 -0
  110. package/dist/index.d.ts +19 -8
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/messageTypes.cjs +37 -0
  113. package/dist/messageTypes.cjs.map +1 -0
  114. package/dist/messageTypes.d.ts +142 -0
  115. package/dist/messageTypes.d.ts.map +1 -0
  116. package/dist/metadata.cjs +7 -0
  117. package/dist/metadata.cjs.map +1 -0
  118. package/dist/metadata.d.ts +24 -0
  119. package/dist/metadata.d.ts.map +1 -0
  120. package/dist/opLifecycle/batchManager.cjs +139 -0
  121. package/dist/opLifecycle/batchManager.cjs.map +1 -0
  122. package/dist/opLifecycle/batchManager.d.ts +48 -0
  123. package/dist/opLifecycle/batchManager.d.ts.map +1 -0
  124. package/dist/opLifecycle/definitions.cjs +7 -0
  125. package/dist/opLifecycle/definitions.cjs.map +1 -0
  126. package/dist/opLifecycle/definitions.d.ts +83 -0
  127. package/dist/opLifecycle/definitions.d.ts.map +1 -0
  128. package/dist/opLifecycle/index.cjs +26 -0
  129. package/dist/opLifecycle/index.cjs.map +1 -0
  130. package/dist/opLifecycle/index.d.ts +13 -0
  131. package/dist/opLifecycle/index.d.ts.map +1 -0
  132. package/dist/opLifecycle/opCompressor.cjs +84 -0
  133. package/dist/opLifecycle/opCompressor.cjs.map +1 -0
  134. package/dist/opLifecycle/opCompressor.d.ts +18 -0
  135. package/dist/opLifecycle/opCompressor.d.ts.map +1 -0
  136. package/dist/opLifecycle/opDecompressor.cjs +132 -0
  137. package/dist/opLifecycle/opDecompressor.cjs.map +1 -0
  138. package/dist/opLifecycle/opDecompressor.d.ts +25 -0
  139. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -0
  140. package/dist/opLifecycle/opGroupingManager.cjs +95 -0
  141. package/dist/opLifecycle/opGroupingManager.cjs.map +1 -0
  142. package/dist/opLifecycle/opGroupingManager.d.ts +22 -0
  143. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
  144. package/dist/opLifecycle/opSplitter.cjs +202 -0
  145. package/dist/opLifecycle/opSplitter.cjs.map +1 -0
  146. package/dist/opLifecycle/opSplitter.d.ts +61 -0
  147. package/dist/opLifecycle/opSplitter.d.ts.map +1 -0
  148. package/dist/opLifecycle/outbox.cjs +326 -0
  149. package/dist/opLifecycle/outbox.cjs.map +1 -0
  150. package/dist/opLifecycle/outbox.d.ts +104 -0
  151. package/dist/opLifecycle/outbox.d.ts.map +1 -0
  152. package/dist/opLifecycle/remoteMessageProcessor.cjs +136 -0
  153. package/dist/opLifecycle/remoteMessageProcessor.cjs.map +1 -0
  154. package/dist/opLifecycle/remoteMessageProcessor.d.ts +47 -0
  155. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
  156. package/dist/opProperties.cjs +17 -0
  157. package/dist/opProperties.cjs.map +1 -0
  158. package/dist/opProperties.d.ts +7 -0
  159. package/dist/opProperties.d.ts.map +1 -0
  160. package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
  161. package/dist/packageVersion.cjs.map +1 -0
  162. package/dist/packageVersion.d.ts +1 -1
  163. package/dist/packageVersion.d.ts.map +1 -1
  164. package/dist/pendingStateManager.cjs +282 -0
  165. package/dist/pendingStateManager.cjs.map +1 -0
  166. package/dist/pendingStateManager.d.ts +32 -69
  167. package/dist/pendingStateManager.d.ts.map +1 -1
  168. package/dist/scheduleManager.cjs +258 -0
  169. package/dist/scheduleManager.cjs.map +1 -0
  170. package/dist/scheduleManager.d.ts +31 -0
  171. package/dist/scheduleManager.d.ts.map +1 -0
  172. package/dist/storageServiceWithAttachBlobs.cjs +32 -0
  173. package/dist/storageServiceWithAttachBlobs.cjs.map +1 -0
  174. package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
  175. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
  176. package/dist/summary/index.cjs +51 -0
  177. package/dist/summary/index.cjs.map +1 -0
  178. package/dist/summary/index.d.ts +17 -0
  179. package/dist/summary/index.d.ts.map +1 -0
  180. package/dist/{orderedClientElection.js → summary/orderedClientElection.cjs} +100 -84
  181. package/dist/summary/orderedClientElection.cjs.map +1 -0
  182. package/{lib → dist/summary}/orderedClientElection.d.ts +41 -18
  183. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  184. package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.cjs} +12 -10
  185. package/dist/summary/runWhileConnectedCoordinator.cjs.map +1 -0
  186. package/{lib → dist/summary}/runWhileConnectedCoordinator.d.ts +8 -2
  187. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  188. package/dist/summary/runningSummarizer.cjs +679 -0
  189. package/dist/summary/runningSummarizer.cjs.map +1 -0
  190. package/dist/summary/runningSummarizer.d.ts +128 -0
  191. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  192. package/dist/summary/summarizer.cjs +263 -0
  193. package/dist/summary/summarizer.cjs.map +1 -0
  194. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +18 -33
  195. package/dist/summary/summarizer.d.ts.map +1 -0
  196. package/dist/{summarizerClientElection.js → summary/summarizerClientElection.cjs} +15 -46
  197. package/dist/summary/summarizerClientElection.cjs.map +1 -0
  198. package/{lib → dist/summary}/summarizerClientElection.d.ts +4 -4
  199. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  200. package/dist/summary/summarizerHeuristics.cjs +156 -0
  201. package/dist/summary/summarizerHeuristics.cjs.map +1 -0
  202. package/{lib → dist/summary}/summarizerHeuristics.d.ts +28 -6
  203. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  204. package/dist/summary/summarizerNode/index.cjs +12 -0
  205. package/dist/summary/summarizerNode/index.cjs.map +1 -0
  206. package/dist/summary/summarizerNode/index.d.ts +8 -0
  207. package/dist/summary/summarizerNode/index.d.ts.map +1 -0
  208. package/dist/summary/summarizerNode/summarizerNode.cjs +526 -0
  209. package/dist/summary/summarizerNode/summarizerNode.cjs.map +1 -0
  210. package/dist/summary/summarizerNode/summarizerNode.d.ts +167 -0
  211. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  212. package/dist/summary/summarizerNode/summarizerNodeUtils.cjs +130 -0
  213. package/dist/summary/summarizerNode/summarizerNodeUtils.cjs.map +1 -0
  214. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +121 -0
  215. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  216. package/dist/summary/summarizerNode/summarizerNodeWithGc.cjs +375 -0
  217. package/dist/summary/summarizerNode/summarizerNodeWithGc.cjs.map +1 -0
  218. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +153 -0
  219. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  220. package/dist/summary/summarizerTypes.cjs +7 -0
  221. package/dist/summary/summarizerTypes.cjs.map +1 -0
  222. package/{lib → dist/summary}/summarizerTypes.d.ts +233 -83
  223. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  224. package/dist/{summaryCollection.js → summary/summaryCollection.cjs} +80 -49
  225. package/dist/summary/summaryCollection.cjs.map +1 -0
  226. package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +23 -5
  227. package/dist/summary/summaryCollection.d.ts.map +1 -0
  228. package/dist/{summaryFormat.js → summary/summaryFormat.cjs} +29 -26
  229. package/dist/summary/summaryFormat.cjs.map +1 -0
  230. package/{lib → dist/summary}/summaryFormat.d.ts +25 -30
  231. package/dist/summary/summaryFormat.d.ts.map +1 -0
  232. package/dist/{summaryGenerator.js → summary/summaryGenerator.cjs} +162 -74
  233. package/dist/summary/summaryGenerator.cjs.map +1 -0
  234. package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +53 -11
  235. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  236. package/dist/{summaryManager.js → summary/summaryManager.cjs} +98 -55
  237. package/dist/summary/summaryManager.cjs.map +1 -0
  238. package/{lib → dist/summary}/summaryManager.d.ts +13 -11
  239. package/dist/summary/summaryManager.d.ts.map +1 -0
  240. package/dist/{throttler.js → throttler.cjs} +21 -21
  241. package/dist/throttler.cjs.map +1 -0
  242. package/dist/throttler.d.ts +2 -2
  243. package/dist/throttler.d.ts.map +1 -1
  244. package/dist/tsdoc-metadata.json +11 -0
  245. package/lib/{batchTracker.d.ts → batchTracker.d.mts} +7 -6
  246. package/lib/batchTracker.d.mts.map +1 -0
  247. package/lib/{batchTracker.js → batchTracker.mjs} +9 -8
  248. package/lib/batchTracker.mjs.map +1 -0
  249. package/lib/blobManager.d.mts +196 -0
  250. package/lib/blobManager.d.mts.map +1 -0
  251. package/lib/blobManager.mjs +704 -0
  252. package/lib/blobManager.mjs.map +1 -0
  253. package/lib/{connectionTelemetry.d.ts → connectionTelemetry.d.mts} +3 -3
  254. package/lib/connectionTelemetry.d.mts.map +1 -0
  255. package/lib/connectionTelemetry.mjs +226 -0
  256. package/lib/connectionTelemetry.mjs.map +1 -0
  257. package/lib/container-runtime-alpha.d.mts +1690 -0
  258. package/lib/container-runtime-beta.d.mts +250 -0
  259. package/lib/container-runtime-public.d.mts +250 -0
  260. package/lib/container-runtime-untrimmed.d.mts +1805 -0
  261. package/lib/{containerHandleContext.d.ts → containerHandleContext.d.mts} +2 -2
  262. package/lib/containerHandleContext.d.mts.map +1 -0
  263. package/lib/{containerHandleContext.js → containerHandleContext.mjs} +4 -2
  264. package/lib/containerHandleContext.mjs.map +1 -0
  265. package/lib/containerRuntime.d.mts +813 -0
  266. package/lib/containerRuntime.d.mts.map +1 -0
  267. package/lib/containerRuntime.mjs +2530 -0
  268. package/lib/containerRuntime.mjs.map +1 -0
  269. package/lib/{dataStore.d.ts → dataStore.d.mts} +5 -5
  270. package/lib/dataStore.d.mts.map +1 -0
  271. package/lib/{dataStore.js → dataStore.mjs} +52 -43
  272. package/lib/dataStore.mjs.map +1 -0
  273. package/lib/{dataStoreContext.d.ts → dataStoreContext.d.mts} +75 -43
  274. package/lib/dataStoreContext.d.mts.map +1 -0
  275. package/lib/{dataStoreContext.js → dataStoreContext.mjs} +309 -213
  276. package/lib/dataStoreContext.mjs.map +1 -0
  277. package/lib/{dataStoreContexts.d.ts → dataStoreContexts.d.mts} +3 -3
  278. package/lib/dataStoreContexts.d.mts.map +1 -0
  279. package/lib/{dataStoreContexts.js → dataStoreContexts.mjs} +12 -8
  280. package/lib/dataStoreContexts.mjs.map +1 -0
  281. package/lib/{dataStoreRegistry.d.ts → dataStoreRegistry.d.mts} +4 -1
  282. package/lib/dataStoreRegistry.d.mts.map +1 -0
  283. package/lib/{dataStoreRegistry.js → dataStoreRegistry.mjs} +7 -6
  284. package/lib/dataStoreRegistry.mjs.map +1 -0
  285. package/lib/{dataStores.d.ts → dataStores.d.mts} +60 -27
  286. package/lib/dataStores.d.mts.map +1 -0
  287. package/lib/{dataStores.js → dataStores.mjs} +257 -105
  288. package/lib/dataStores.mjs.map +1 -0
  289. package/lib/deltaManagerProxyBase.d.mts +35 -0
  290. package/lib/deltaManagerProxyBase.d.mts.map +1 -0
  291. package/lib/deltaManagerProxyBase.mjs +73 -0
  292. package/lib/deltaManagerProxyBase.mjs.map +1 -0
  293. package/lib/deltaManagerSummarizerProxy.d.mts +19 -0
  294. package/lib/deltaManagerSummarizerProxy.d.mts.map +1 -0
  295. package/lib/deltaManagerSummarizerProxy.mjs +38 -0
  296. package/lib/deltaManagerSummarizerProxy.mjs.map +1 -0
  297. package/lib/{deltaScheduler.d.ts → deltaScheduler.d.mts} +9 -7
  298. package/lib/deltaScheduler.d.mts.map +1 -0
  299. package/lib/{deltaScheduler.js → deltaScheduler.mjs} +22 -15
  300. package/lib/deltaScheduler.mjs.map +1 -0
  301. package/lib/error.d.mts +14 -0
  302. package/lib/error.d.mts.map +1 -0
  303. package/lib/error.mjs +17 -0
  304. package/lib/error.mjs.map +1 -0
  305. package/lib/gc/garbageCollection.d.mts +224 -0
  306. package/lib/gc/garbageCollection.d.mts.map +1 -0
  307. package/lib/gc/garbageCollection.mjs +861 -0
  308. package/lib/gc/garbageCollection.mjs.map +1 -0
  309. package/lib/gc/gcConfigs.d.mts +23 -0
  310. package/lib/gc/gcConfigs.d.mts.map +1 -0
  311. package/lib/gc/gcConfigs.mjs +156 -0
  312. package/lib/gc/gcConfigs.mjs.map +1 -0
  313. package/lib/gc/gcDefinitions.d.mts +458 -0
  314. package/lib/gc/gcDefinitions.d.mts.map +1 -0
  315. package/lib/gc/gcDefinitions.mjs +93 -0
  316. package/lib/gc/gcDefinitions.mjs.map +1 -0
  317. package/lib/gc/gcHelpers.d.mts +71 -0
  318. package/lib/gc/gcHelpers.d.mts.map +1 -0
  319. package/lib/gc/gcHelpers.mjs +222 -0
  320. package/lib/gc/gcHelpers.mjs.map +1 -0
  321. package/lib/gc/gcReferenceGraphAlgorithm.d.mts +16 -0
  322. package/lib/gc/gcReferenceGraphAlgorithm.d.mts.map +1 -0
  323. package/lib/gc/gcReferenceGraphAlgorithm.mjs +45 -0
  324. package/lib/gc/gcReferenceGraphAlgorithm.mjs.map +1 -0
  325. package/lib/gc/gcSummaryDefinitions.d.mts +52 -0
  326. package/lib/gc/gcSummaryDefinitions.d.mts.map +1 -0
  327. package/lib/gc/gcSummaryDefinitions.mjs +6 -0
  328. package/lib/gc/gcSummaryDefinitions.mjs.map +1 -0
  329. package/lib/gc/gcSummaryStateTracker.d.mts +94 -0
  330. package/lib/gc/gcSummaryStateTracker.d.mts.map +1 -0
  331. package/lib/gc/gcSummaryStateTracker.mjs +209 -0
  332. package/lib/gc/gcSummaryStateTracker.mjs.map +1 -0
  333. package/lib/gc/gcTelemetry.d.mts +99 -0
  334. package/lib/gc/gcTelemetry.d.mts.map +1 -0
  335. package/lib/gc/gcTelemetry.mjs +302 -0
  336. package/lib/gc/gcTelemetry.mjs.map +1 -0
  337. package/lib/gc/gcUnreferencedStateTracker.d.mts +40 -0
  338. package/lib/gc/gcUnreferencedStateTracker.d.mts.map +1 -0
  339. package/lib/gc/gcUnreferencedStateTracker.mjs +114 -0
  340. package/lib/gc/gcUnreferencedStateTracker.mjs.map +1 -0
  341. package/lib/gc/index.d.mts +13 -0
  342. package/lib/gc/index.d.mts.map +1 -0
  343. package/lib/gc/index.mjs +12 -0
  344. package/lib/gc/index.mjs.map +1 -0
  345. package/lib/index.d.mts +25 -0
  346. package/lib/index.d.mts.map +1 -0
  347. package/lib/index.mjs +24 -0
  348. package/lib/index.mjs.map +1 -0
  349. package/lib/messageTypes.d.mts +142 -0
  350. package/lib/messageTypes.d.mts.map +1 -0
  351. package/lib/messageTypes.mjs +34 -0
  352. package/lib/messageTypes.mjs.map +1 -0
  353. package/lib/metadata.d.mts +24 -0
  354. package/lib/metadata.d.mts.map +1 -0
  355. package/lib/metadata.mjs +6 -0
  356. package/lib/metadata.mjs.map +1 -0
  357. package/lib/opLifecycle/batchManager.d.mts +48 -0
  358. package/lib/opLifecycle/batchManager.d.mts.map +1 -0
  359. package/lib/opLifecycle/batchManager.mjs +133 -0
  360. package/lib/opLifecycle/batchManager.mjs.map +1 -0
  361. package/lib/opLifecycle/definitions.d.mts +83 -0
  362. package/lib/opLifecycle/definitions.d.mts.map +1 -0
  363. package/lib/opLifecycle/definitions.mjs +6 -0
  364. package/lib/opLifecycle/definitions.mjs.map +1 -0
  365. package/lib/opLifecycle/index.d.mts +13 -0
  366. package/lib/opLifecycle/index.d.mts.map +1 -0
  367. package/lib/opLifecycle/index.mjs +12 -0
  368. package/lib/opLifecycle/index.mjs.map +1 -0
  369. package/lib/opLifecycle/opCompressor.d.mts +18 -0
  370. package/lib/opLifecycle/opCompressor.d.mts.map +1 -0
  371. package/lib/opLifecycle/opCompressor.mjs +80 -0
  372. package/lib/opLifecycle/opCompressor.mjs.map +1 -0
  373. package/lib/opLifecycle/opDecompressor.d.mts +25 -0
  374. package/lib/opLifecycle/opDecompressor.d.mts.map +1 -0
  375. package/lib/opLifecycle/opDecompressor.mjs +128 -0
  376. package/lib/opLifecycle/opDecompressor.mjs.map +1 -0
  377. package/lib/opLifecycle/opGroupingManager.d.mts +22 -0
  378. package/lib/opLifecycle/opGroupingManager.d.mts.map +1 -0
  379. package/lib/opLifecycle/opGroupingManager.mjs +91 -0
  380. package/lib/opLifecycle/opGroupingManager.mjs.map +1 -0
  381. package/lib/opLifecycle/opSplitter.d.mts +61 -0
  382. package/lib/opLifecycle/opSplitter.d.mts.map +1 -0
  383. package/lib/opLifecycle/opSplitter.mjs +197 -0
  384. package/lib/opLifecycle/opSplitter.mjs.map +1 -0
  385. package/lib/opLifecycle/outbox.d.mts +104 -0
  386. package/lib/opLifecycle/outbox.d.mts.map +1 -0
  387. package/lib/opLifecycle/outbox.mjs +321 -0
  388. package/lib/opLifecycle/outbox.mjs.map +1 -0
  389. package/lib/opLifecycle/remoteMessageProcessor.d.mts +47 -0
  390. package/lib/opLifecycle/remoteMessageProcessor.d.mts.map +1 -0
  391. package/lib/opLifecycle/remoteMessageProcessor.mjs +131 -0
  392. package/lib/opLifecycle/remoteMessageProcessor.mjs.map +1 -0
  393. package/lib/opProperties.d.mts +7 -0
  394. package/lib/opProperties.d.mts.map +1 -0
  395. package/lib/opProperties.mjs +13 -0
  396. package/lib/opProperties.mjs.map +1 -0
  397. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +2 -2
  398. package/lib/packageVersion.d.mts.map +1 -0
  399. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  400. package/lib/packageVersion.mjs.map +1 -0
  401. package/lib/{pendingStateManager.d.ts → pendingStateManager.d.mts} +33 -70
  402. package/lib/pendingStateManager.d.mts.map +1 -0
  403. package/lib/pendingStateManager.mjs +275 -0
  404. package/lib/pendingStateManager.mjs.map +1 -0
  405. package/lib/scheduleManager.d.mts +27 -0
  406. package/lib/scheduleManager.d.mts.map +1 -0
  407. package/lib/scheduleManager.mjs +254 -0
  408. package/lib/scheduleManager.mjs.map +1 -0
  409. package/lib/storageServiceWithAttachBlobs.d.mts +17 -0
  410. package/lib/storageServiceWithAttachBlobs.d.mts.map +1 -0
  411. package/lib/storageServiceWithAttachBlobs.mjs +28 -0
  412. package/lib/storageServiceWithAttachBlobs.mjs.map +1 -0
  413. package/lib/summary/index.d.mts +17 -0
  414. package/lib/summary/index.d.mts.map +1 -0
  415. package/lib/summary/index.mjs +16 -0
  416. package/lib/summary/index.mjs.map +1 -0
  417. package/{dist/orderedClientElection.d.ts → lib/summary/orderedClientElection.d.mts} +42 -23
  418. package/lib/summary/orderedClientElection.d.mts.map +1 -0
  419. package/lib/{orderedClientElection.js → summary/orderedClientElection.mjs} +95 -79
  420. package/lib/summary/orderedClientElection.mjs.map +1 -0
  421. package/{dist/runWhileConnectedCoordinator.d.ts → lib/summary/runWhileConnectedCoordinator.d.mts} +10 -4
  422. package/lib/summary/runWhileConnectedCoordinator.d.mts.map +1 -0
  423. package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.mjs} +12 -10
  424. package/lib/summary/runWhileConnectedCoordinator.mjs.map +1 -0
  425. package/lib/summary/runningSummarizer.d.mts +128 -0
  426. package/lib/summary/runningSummarizer.d.mts.map +1 -0
  427. package/lib/summary/runningSummarizer.mjs +675 -0
  428. package/lib/summary/runningSummarizer.mjs.map +1 -0
  429. package/lib/{summarizer.d.ts → summary/summarizer.d.mts} +21 -36
  430. package/lib/summary/summarizer.d.mts.map +1 -0
  431. package/lib/summary/summarizer.mjs +257 -0
  432. package/lib/summary/summarizer.mjs.map +1 -0
  433. package/{dist/summarizerClientElection.d.ts → lib/summary/summarizerClientElection.d.mts} +7 -7
  434. package/lib/summary/summarizerClientElection.d.mts.map +1 -0
  435. package/lib/{summarizerClientElection.js → summary/summarizerClientElection.mjs} +14 -45
  436. package/lib/summary/summarizerClientElection.mjs.map +1 -0
  437. package/{dist/summarizerHeuristics.d.ts → lib/summary/summarizerHeuristics.d.mts} +30 -8
  438. package/lib/summary/summarizerHeuristics.d.mts.map +1 -0
  439. package/lib/summary/summarizerHeuristics.mjs +151 -0
  440. package/lib/summary/summarizerHeuristics.mjs.map +1 -0
  441. package/lib/summary/summarizerNode/index.d.mts +8 -0
  442. package/lib/summary/summarizerNode/index.d.mts.map +1 -0
  443. package/lib/summary/summarizerNode/index.mjs +7 -0
  444. package/lib/summary/summarizerNode/index.mjs.map +1 -0
  445. package/lib/summary/summarizerNode/summarizerNode.d.mts +167 -0
  446. package/lib/summary/summarizerNode/summarizerNode.d.mts.map +1 -0
  447. package/lib/summary/summarizerNode/summarizerNode.mjs +521 -0
  448. package/lib/summary/summarizerNode/summarizerNode.mjs.map +1 -0
  449. package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts +121 -0
  450. package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts.map +1 -0
  451. package/lib/summary/summarizerNode/summarizerNodeUtils.mjs +123 -0
  452. package/lib/summary/summarizerNode/summarizerNodeUtils.mjs.map +1 -0
  453. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts +153 -0
  454. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts.map +1 -0
  455. package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs +370 -0
  456. package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs.map +1 -0
  457. package/{dist/summarizerTypes.d.ts → lib/summary/summarizerTypes.d.mts} +235 -85
  458. package/lib/summary/summarizerTypes.d.mts.map +1 -0
  459. package/lib/summary/summarizerTypes.mjs +6 -0
  460. package/lib/summary/summarizerTypes.mjs.map +1 -0
  461. package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.mts} +24 -6
  462. package/lib/summary/summaryCollection.d.mts.map +1 -0
  463. package/lib/{summaryCollection.js → summary/summaryCollection.mjs} +76 -45
  464. package/lib/summary/summaryCollection.mjs.map +1 -0
  465. package/{dist/summaryFormat.d.ts → lib/summary/summaryFormat.d.mts} +26 -31
  466. package/lib/summary/summaryFormat.d.mts.map +1 -0
  467. package/lib/{summaryFormat.js → summary/summaryFormat.mjs} +30 -26
  468. package/lib/summary/summaryFormat.mjs.map +1 -0
  469. package/lib/summary/summaryGenerator.d.mts +127 -0
  470. package/lib/summary/summaryGenerator.d.mts.map +1 -0
  471. package/lib/{summaryGenerator.js → summary/summaryGenerator.mjs} +153 -67
  472. package/lib/summary/summaryGenerator.mjs.map +1 -0
  473. package/{dist/summaryManager.d.ts → lib/summary/summaryManager.d.mts} +16 -14
  474. package/lib/summary/summaryManager.d.mts.map +1 -0
  475. package/lib/{summaryManager.js → summary/summaryManager.mjs} +94 -51
  476. package/lib/summary/summaryManager.mjs.map +1 -0
  477. package/lib/{throttler.d.ts → throttler.d.mts} +3 -3
  478. package/lib/throttler.d.mts.map +1 -0
  479. package/lib/{throttler.js → throttler.mjs} +21 -21
  480. package/lib/throttler.mjs.map +1 -0
  481. package/package.json +199 -71
  482. package/prettier.config.cjs +8 -0
  483. package/src/batchTracker.ts +59 -54
  484. package/src/blobManager.ts +942 -294
  485. package/src/connectionTelemetry.ts +342 -252
  486. package/src/containerHandleContext.ts +27 -29
  487. package/src/containerRuntime.ts +3883 -3143
  488. package/src/dataStore.ts +170 -140
  489. package/src/dataStoreContext.ts +1166 -986
  490. package/src/dataStoreContexts.ts +176 -163
  491. package/src/dataStoreRegistry.ts +29 -21
  492. package/src/dataStores.ts +924 -678
  493. package/src/deltaManagerProxyBase.ts +111 -0
  494. package/src/deltaManagerSummarizerProxy.ts +49 -0
  495. package/src/deltaScheduler.ts +161 -156
  496. package/src/error.ts +21 -0
  497. package/src/gc/garbageCollection.md +106 -0
  498. package/src/gc/garbageCollection.ts +1157 -0
  499. package/src/gc/gcConfigs.ts +224 -0
  500. package/src/gc/gcDefinitions.ts +524 -0
  501. package/src/gc/gcHelpers.ts +284 -0
  502. package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
  503. package/src/gc/gcSummaryDefinitions.ts +54 -0
  504. package/src/gc/gcSummaryStateTracker.ts +299 -0
  505. package/src/gc/gcTelemetry.ts +433 -0
  506. package/src/gc/gcUnreferencedStateTracker.ts +153 -0
  507. package/src/gc/index.ts +60 -0
  508. package/src/index.ts +101 -74
  509. package/src/messageTypes.ts +238 -0
  510. package/src/metadata.ts +26 -0
  511. package/src/opLifecycle/README.md +321 -0
  512. package/src/opLifecycle/batchManager.ts +179 -0
  513. package/src/opLifecycle/definitions.ts +89 -0
  514. package/src/opLifecycle/index.ts +19 -0
  515. package/src/opLifecycle/opCompressor.ts +99 -0
  516. package/src/opLifecycle/opDecompressor.ts +190 -0
  517. package/src/opLifecycle/opGroupingManager.ts +133 -0
  518. package/src/opLifecycle/opSplitter.ts +279 -0
  519. package/src/opLifecycle/outbox.ts +474 -0
  520. package/src/opLifecycle/remoteMessageProcessor.ts +175 -0
  521. package/src/opProperties.ts +21 -0
  522. package/src/packageVersion.ts +1 -1
  523. package/src/pendingStateManager.ts +396 -465
  524. package/src/scheduleManager.ts +358 -0
  525. package/src/storageServiceWithAttachBlobs.ts +38 -0
  526. package/src/summary/index.ts +109 -0
  527. package/src/summary/orderedClientElection.ts +571 -0
  528. package/src/summary/runWhileConnectedCoordinator.ts +117 -0
  529. package/src/summary/runningSummarizer.ts +920 -0
  530. package/src/summary/summarizer.ts +352 -0
  531. package/src/summary/summarizerClientElection.ts +140 -0
  532. package/src/summary/summarizerHeuristics.ts +227 -0
  533. package/src/summary/summarizerNode/index.ts +12 -0
  534. package/src/summary/summarizerNode/summarizerNode.ts +725 -0
  535. package/src/summary/summarizerNode/summarizerNodeUtils.ts +206 -0
  536. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +571 -0
  537. package/src/summary/summarizerTypes.ts +631 -0
  538. package/src/summary/summaryCollection.ts +474 -0
  539. package/src/summary/summaryFormat.ts +249 -0
  540. package/src/summary/summaryGenerator.ts +539 -0
  541. package/src/summary/summaryManager.ts +452 -0
  542. package/src/throttler.ts +131 -122
  543. package/tsc-multi.test.json +4 -0
  544. package/tsconfig.json +11 -13
  545. package/dist/batchTracker.js.map +0 -1
  546. package/dist/blobManager.js +0 -249
  547. package/dist/blobManager.js.map +0 -1
  548. package/dist/connectionTelemetry.js +0 -178
  549. package/dist/connectionTelemetry.js.map +0 -1
  550. package/dist/containerHandleContext.js.map +0 -1
  551. package/dist/containerRuntime.js +0 -2174
  552. package/dist/containerRuntime.js.map +0 -1
  553. package/dist/dataStore.js.map +0 -1
  554. package/dist/dataStoreContext.js.map +0 -1
  555. package/dist/dataStoreContexts.js.map +0 -1
  556. package/dist/dataStoreRegistry.js.map +0 -1
  557. package/dist/dataStores.js.map +0 -1
  558. package/dist/deltaScheduler.js.map +0 -1
  559. package/dist/garbageCollection.d.ts +0 -319
  560. package/dist/garbageCollection.d.ts.map +0 -1
  561. package/dist/garbageCollection.js +0 -993
  562. package/dist/garbageCollection.js.map +0 -1
  563. package/dist/index.js +0 -33
  564. package/dist/index.js.map +0 -1
  565. package/dist/opTelemetry.d.ts +0 -22
  566. package/dist/opTelemetry.d.ts.map +0 -1
  567. package/dist/opTelemetry.js +0 -60
  568. package/dist/opTelemetry.js.map +0 -1
  569. package/dist/orderedClientElection.d.ts.map +0 -1
  570. package/dist/orderedClientElection.js.map +0 -1
  571. package/dist/packageVersion.js.map +0 -1
  572. package/dist/pendingStateManager.js +0 -346
  573. package/dist/pendingStateManager.js.map +0 -1
  574. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  575. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  576. package/dist/runningSummarizer.d.ts +0 -93
  577. package/dist/runningSummarizer.d.ts.map +0 -1
  578. package/dist/runningSummarizer.js +0 -384
  579. package/dist/runningSummarizer.js.map +0 -1
  580. package/dist/serializedSnapshotStorage.d.ts +0 -58
  581. package/dist/serializedSnapshotStorage.d.ts.map +0 -1
  582. package/dist/serializedSnapshotStorage.js +0 -108
  583. package/dist/serializedSnapshotStorage.js.map +0 -1
  584. package/dist/summarizer.d.ts.map +0 -1
  585. package/dist/summarizer.js +0 -348
  586. package/dist/summarizer.js.map +0 -1
  587. package/dist/summarizerClientElection.d.ts.map +0 -1
  588. package/dist/summarizerClientElection.js.map +0 -1
  589. package/dist/summarizerHandle.d.ts +0 -12
  590. package/dist/summarizerHandle.d.ts.map +0 -1
  591. package/dist/summarizerHandle.js +0 -22
  592. package/dist/summarizerHandle.js.map +0 -1
  593. package/dist/summarizerHeuristics.d.ts.map +0 -1
  594. package/dist/summarizerHeuristics.js +0 -84
  595. package/dist/summarizerHeuristics.js.map +0 -1
  596. package/dist/summarizerTypes.d.ts.map +0 -1
  597. package/dist/summarizerTypes.js.map +0 -1
  598. package/dist/summaryCollection.d.ts.map +0 -1
  599. package/dist/summaryCollection.js.map +0 -1
  600. package/dist/summaryFormat.d.ts.map +0 -1
  601. package/dist/summaryFormat.js.map +0 -1
  602. package/dist/summaryGenerator.d.ts.map +0 -1
  603. package/dist/summaryGenerator.js.map +0 -1
  604. package/dist/summaryManager.d.ts.map +0 -1
  605. package/dist/summaryManager.js.map +0 -1
  606. package/dist/throttler.js.map +0 -1
  607. package/garbageCollection.md +0 -41
  608. package/lib/batchTracker.d.ts.map +0 -1
  609. package/lib/batchTracker.js.map +0 -1
  610. package/lib/blobManager.d.ts +0 -95
  611. package/lib/blobManager.d.ts.map +0 -1
  612. package/lib/blobManager.js +0 -244
  613. package/lib/blobManager.js.map +0 -1
  614. package/lib/connectionTelemetry.d.ts.map +0 -1
  615. package/lib/connectionTelemetry.js +0 -174
  616. package/lib/connectionTelemetry.js.map +0 -1
  617. package/lib/containerHandleContext.d.ts.map +0 -1
  618. package/lib/containerHandleContext.js.map +0 -1
  619. package/lib/containerRuntime.d.ts +0 -615
  620. package/lib/containerRuntime.d.ts.map +0 -1
  621. package/lib/containerRuntime.js +0 -2166
  622. package/lib/containerRuntime.js.map +0 -1
  623. package/lib/dataStore.d.ts.map +0 -1
  624. package/lib/dataStore.js.map +0 -1
  625. package/lib/dataStoreContext.d.ts.map +0 -1
  626. package/lib/dataStoreContext.js.map +0 -1
  627. package/lib/dataStoreContexts.d.ts.map +0 -1
  628. package/lib/dataStoreContexts.js.map +0 -1
  629. package/lib/dataStoreRegistry.d.ts.map +0 -1
  630. package/lib/dataStoreRegistry.js.map +0 -1
  631. package/lib/dataStores.d.ts.map +0 -1
  632. package/lib/dataStores.js.map +0 -1
  633. package/lib/deltaScheduler.d.ts.map +0 -1
  634. package/lib/deltaScheduler.js.map +0 -1
  635. package/lib/garbageCollection.d.ts +0 -319
  636. package/lib/garbageCollection.d.ts.map +0 -1
  637. package/lib/garbageCollection.js +0 -989
  638. package/lib/garbageCollection.js.map +0 -1
  639. package/lib/index.d.ts +0 -14
  640. package/lib/index.d.ts.map +0 -1
  641. package/lib/index.js +0 -13
  642. package/lib/index.js.map +0 -1
  643. package/lib/opTelemetry.d.ts +0 -22
  644. package/lib/opTelemetry.d.ts.map +0 -1
  645. package/lib/opTelemetry.js +0 -56
  646. package/lib/opTelemetry.js.map +0 -1
  647. package/lib/orderedClientElection.d.ts.map +0 -1
  648. package/lib/orderedClientElection.js.map +0 -1
  649. package/lib/packageVersion.d.ts.map +0 -1
  650. package/lib/packageVersion.js.map +0 -1
  651. package/lib/pendingStateManager.d.ts.map +0 -1
  652. package/lib/pendingStateManager.js +0 -339
  653. package/lib/pendingStateManager.js.map +0 -1
  654. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  655. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  656. package/lib/runningSummarizer.d.ts +0 -93
  657. package/lib/runningSummarizer.d.ts.map +0 -1
  658. package/lib/runningSummarizer.js +0 -380
  659. package/lib/runningSummarizer.js.map +0 -1
  660. package/lib/serializedSnapshotStorage.d.ts +0 -58
  661. package/lib/serializedSnapshotStorage.d.ts.map +0 -1
  662. package/lib/serializedSnapshotStorage.js +0 -104
  663. package/lib/serializedSnapshotStorage.js.map +0 -1
  664. package/lib/summarizer.d.ts.map +0 -1
  665. package/lib/summarizer.js +0 -342
  666. package/lib/summarizer.js.map +0 -1
  667. package/lib/summarizerClientElection.d.ts.map +0 -1
  668. package/lib/summarizerClientElection.js.map +0 -1
  669. package/lib/summarizerHandle.d.ts +0 -12
  670. package/lib/summarizerHandle.d.ts.map +0 -1
  671. package/lib/summarizerHandle.js +0 -18
  672. package/lib/summarizerHandle.js.map +0 -1
  673. package/lib/summarizerHeuristics.d.ts.map +0 -1
  674. package/lib/summarizerHeuristics.js +0 -79
  675. package/lib/summarizerHeuristics.js.map +0 -1
  676. package/lib/summarizerTypes.d.ts.map +0 -1
  677. package/lib/summarizerTypes.js +0 -9
  678. package/lib/summarizerTypes.js.map +0 -1
  679. package/lib/summaryCollection.d.ts.map +0 -1
  680. package/lib/summaryCollection.js.map +0 -1
  681. package/lib/summaryFormat.d.ts.map +0 -1
  682. package/lib/summaryFormat.js.map +0 -1
  683. package/lib/summaryGenerator.d.ts +0 -85
  684. package/lib/summaryGenerator.d.ts.map +0 -1
  685. package/lib/summaryGenerator.js.map +0 -1
  686. package/lib/summaryManager.d.ts.map +0 -1
  687. package/lib/summaryManager.js.map +0 -1
  688. package/lib/throttler.d.ts.map +0 -1
  689. package/lib/throttler.js.map +0 -1
  690. package/src/garbageCollection.ts +0 -1434
  691. package/src/opTelemetry.ts +0 -71
  692. package/src/orderedClientElection.ts +0 -511
  693. package/src/runWhileConnectedCoordinator.ts +0 -106
  694. package/src/runningSummarizer.ts +0 -550
  695. package/src/serializedSnapshotStorage.ts +0 -146
  696. package/src/summarizer.ts +0 -438
  697. package/src/summarizerClientElection.ts +0 -161
  698. package/src/summarizerHandle.ts +0 -21
  699. package/src/summarizerHeuristics.ts +0 -108
  700. package/src/summarizerTypes.ts +0 -462
  701. package/src/summaryCollection.ts +0 -406
  702. package/src/summaryFormat.ts +0 -239
  703. package/src/summaryGenerator.ts +0 -427
  704. package/src/summaryManager.ts +0 -368
  705. package/tsconfig.esnext.json +0 -7
@@ -3,495 +3,426 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IDisposable } from "@fluidframework/common-definitions";
7
- import { assert, Lazy } from "@fluidframework/common-utils";
8
- import { ICriticalContainerError } from "@fluidframework/container-definitions";
9
- import { DataProcessingError } from "@fluidframework/container-utils";
10
- import {
11
- ISequencedDocumentMessage,
12
- } from "@fluidframework/protocol-definitions";
13
- import { FlushMode } from "@fluidframework/runtime-definitions";
14
- import { wrapError } from "@fluidframework/telemetry-utils";
15
6
  import Deque from "double-ended-queue";
16
- import { ContainerMessageType } from "./containerRuntime";
7
+
8
+ import { IDisposable } from "@fluidframework/core-interfaces";
9
+ import { assert, Lazy } from "@fluidframework/core-utils";
10
+ import { ICriticalContainerError } from "@fluidframework/container-definitions";
11
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
12
+ import { DataProcessingError, ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
13
+
14
+ import { InboundSequencedContainerRuntimeMessage } from "./messageTypes";
15
+ import { pkgVersion } from "./packageVersion";
16
+ import { IBatchMetadata } from "./metadata";
17
17
 
18
18
  /**
19
19
  * This represents a message that has been submitted and is added to the pending queue when `submit` is called on the
20
20
  * ContainerRuntime. This message has either not been ack'd by the server or has not been submitted to the server yet.
21
21
  */
22
22
  export interface IPendingMessage {
23
- type: "message";
24
- messageType: ContainerMessageType;
25
- clientSequenceNumber: number;
26
- referenceSequenceNumber: number;
27
- content: any;
28
- localOpMetadata: unknown;
29
- opMetadata: Record<string, unknown> | undefined;
23
+ type: "message";
24
+ referenceSequenceNumber: number;
25
+ content: string;
26
+ localOpMetadata: unknown;
27
+ opMetadata: Record<string, unknown> | undefined;
30
28
  }
31
29
 
32
- /**
33
- * This represents a FlushMode update and is added to the pending queue when `setFlushMode` is called on the
34
- * ContainerRuntime and the FlushMode changes.
35
- */
36
- export interface IPendingFlushMode {
37
- type: "flushMode";
38
- flushMode: FlushMode;
30
+ export interface IPendingLocalState {
31
+ /**
32
+ * list of pending states, including ops and batch information
33
+ */
34
+ pendingStates: IPendingMessage[];
39
35
  }
40
36
 
41
- /**
42
- * This represents an explicit flush call and is added to the pending queue when flush is called on the ContainerRuntime
43
- * to flush pending messages.
44
- */
45
- export interface IPendingFlush {
46
- type: "flush";
37
+ export interface IPendingBatchMessage {
38
+ content: string;
39
+ localOpMetadata: unknown;
40
+ opMetadata: Record<string, unknown> | undefined;
47
41
  }
48
42
 
49
- export type IPendingState = IPendingMessage | IPendingFlushMode | IPendingFlush;
50
-
51
- export interface IPendingLocalState {
52
- /**
53
- * list of pending states, including ops and batch information
54
- */
55
- pendingStates: IPendingState[];
43
+ export interface IRuntimeStateHandler {
44
+ connected(): boolean;
45
+ clientId(): string | undefined;
46
+ close(error?: ICriticalContainerError): void;
47
+ applyStashedOp(content: string): Promise<unknown>;
48
+ reSubmit(message: IPendingBatchMessage): void;
49
+ reSubmitBatch(batch: IPendingBatchMessage[]): void;
50
+ isActiveConnection: () => boolean;
56
51
  }
57
52
 
58
- export interface IRuntimeStateHandler{
59
- connected(): boolean;
60
- clientId(): string | undefined;
61
- flushMode(): FlushMode;
62
- setFlushMode(mode: FlushMode): void;
63
- close(error?: ICriticalContainerError): void;
64
- applyStashedOp: (type: ContainerMessageType, content: ISequencedDocumentMessage) => Promise<unknown>;
65
- flush(): void;
66
- reSubmit(
67
- type: ContainerMessageType,
68
- content: any,
69
- localOpMetadata: unknown,
70
- opMetadata: Record<string, unknown> | undefined): void;
71
- rollback(
72
- type: ContainerMessageType,
73
- content: any,
74
- localOpMetadata: unknown): void;
53
+ /** Union of keys of T */
54
+ type KeysOfUnion<T extends object> = T extends T ? keyof T : never;
55
+ /** *Partial* type all possible combinations of properties and values of union T.
56
+ * This loosens typing allowing access to all possible properties without
57
+ * narrowing.
58
+ */
59
+ type AnyComboFromUnion<T extends object> = { [P in KeysOfUnion<T>]?: T[P] };
60
+
61
+ function buildPendingMessageContent(
62
+ // AnyComboFromUnion is needed need to gain access to compatDetails that
63
+ // is only defined for some cases.
64
+ message: AnyComboFromUnion<InboundSequencedContainerRuntimeMessage>,
65
+ ): string {
66
+ // IMPORTANT: Order matters here, this must match the order of the properties used
67
+ // when submitting the message.
68
+ const { type, contents, compatDetails } = message;
69
+ // Any properties that are not defined, won't be emitted by stringify.
70
+ return JSON.stringify({ type, contents, compatDetails });
75
71
  }
76
72
 
77
73
  /**
78
74
  * PendingStateManager is responsible for maintaining the messages that have not been sent or have not yet been
79
75
  * acknowledged by the server. It also maintains the batch information for both automatically and manually flushed
80
76
  * batches along with the messages.
81
- * When the Container reconnects, it replays the pending states, which includes setting the FlushMode, manual flushing
77
+ * When the Container reconnects, it replays the pending states, which includes manual flushing
82
78
  * of messages and triggering resubmission of unacked ops.
83
79
  *
84
80
  * It verifies that all the ops are acked, are received in the right order and batch information is correct.
85
81
  */
86
82
  export class PendingStateManager implements IDisposable {
87
- private readonly pendingStates = new Deque<IPendingState>();
88
- private readonly initialStates: Deque<IPendingState>;
89
- private readonly disposeOnce = new Lazy<void>(() => {
90
- this.initialStates.clear();
91
- this.pendingStates.clear();
92
- });
93
-
94
- // Maintains the count of messages that are currently unacked.
95
- private _pendingMessagesCount: number = 0;
96
- public get pendingMessagesCount(): number {
97
- return this._pendingMessagesCount;
98
- }
99
-
100
- // Indicates whether we are processing a batch.
101
- private isProcessingBatch: boolean = false;
102
-
103
- // This stores the first message in the batch that we are processing. This is used to verify that we get
104
- // the correct batch metadata.
105
- private pendingBatchBeginMessage: ISequencedDocumentMessage | undefined;
106
-
107
- /**
108
- * This tracks the flush mode for the next message in the pending state queue. When replaying messages, we need to
109
- * first set the flush mode to this value and then send ops. It is important to do this info because the flush
110
- * mode could have been updated.
111
- */
112
- private flushModeForNextMessage: FlushMode;
113
-
114
- private clientId: string | undefined;
115
-
116
- /**
117
- * Called to check if there are any pending messages in the pending state queue.
118
- * @returns A boolean indicating whether there are messages or not.
119
- */
120
- public hasPendingMessages(): boolean {
121
- return this._pendingMessagesCount !== 0 || !this.initialStates.isEmpty();
122
- }
123
-
124
- public getLocalState(): IPendingLocalState | undefined {
125
- assert(this.initialStates.isEmpty(), 0x2e9 /* "Must call getLocalState() after applying initial states" */);
126
- if (this.hasPendingMessages()) {
127
- return {
128
- pendingStates: this.pendingStates.toArray().map(
129
- // delete localOpMetadata since it may not be serializable
130
- // and will be regenerated by applyStashedOp()
131
- (state) => state.type === "message" ? { ...state, localOpMetadata: undefined } : state),
132
- };
133
- }
134
- }
135
-
136
- constructor(
137
- private readonly stateHandler: IRuntimeStateHandler,
138
- initialFlushMode: FlushMode,
139
- initialLocalState: IPendingLocalState | undefined,
140
- ) {
141
- this.initialStates = new Deque<IPendingState>(initialLocalState?.pendingStates ?? []);
142
-
143
- this.flushModeForNextMessage = initialFlushMode;
144
- this.onFlushModeUpdated(initialFlushMode);
145
- }
146
-
147
- public get disposed() { return this.disposeOnce.evaluated; }
148
- public readonly dispose = () => this.disposeOnce.value;
149
-
150
- /**
151
- * Called when a message is submitted locally. Adds the message and the associated details to the pending state
152
- * queue.
153
- * @param type - The container message type.
154
- * @param clientSequenceNumber - The clientSequenceNumber associated with the message.
155
- * @param content - The message content.
156
- * @param localOpMetadata - The local metadata associated with the message.
157
- */
158
- public onSubmitMessage(
159
- type: ContainerMessageType,
160
- clientSequenceNumber: number,
161
- referenceSequenceNumber: number,
162
- content: any,
163
- localOpMetadata: unknown,
164
- opMetadata: Record<string, unknown> | undefined,
165
- ) {
166
- const pendingMessage: IPendingMessage = {
167
- type: "message",
168
- messageType: type,
169
- clientSequenceNumber,
170
- referenceSequenceNumber,
171
- content,
172
- localOpMetadata,
173
- opMetadata,
174
- };
175
-
176
- this.pendingStates.push(pendingMessage);
177
-
178
- this._pendingMessagesCount++;
179
- }
180
-
181
- /**
182
- * Called when the FlushMode is updated. Adds the FlushMode to the pending state queue.
183
- * @param flushMode - The flushMode that was updated.
184
- */
185
- public onFlushModeUpdated(flushMode: FlushMode) {
186
- this.pendingStates.push({ type: "flushMode", flushMode });
187
- }
188
-
189
- /**
190
- * Called when flush() is called on the ContainerRuntime to manually flush messages.
191
- */
192
- public onFlush() {
193
- // If the FlushMode is Immediate, we don't need to track an explicit flush call because every message is
194
- // automatically flushed. So, flush is a no-op.
195
- if (this.stateHandler.flushMode() === FlushMode.Immediate) {
196
- return;
197
- }
198
-
199
- // If the previous state is not a message, flush is a no-op.
200
- const previousState = this.pendingStates.peekBack();
201
- if (previousState?.type !== "message") {
202
- return;
203
- }
204
-
205
- // An explicit flush is interesting and is tracked only if there are messages sent in TurnBased mode.
206
- this.pendingStates.push({ type: "flush" });
207
- }
208
-
209
- /**
210
- * Applies stashed ops at their reference sequence number so they are ready to be ACKed or resubmitted
211
- * @param seqNum - Sequence number at which to apply ops. Will apply all ops if seqNum is undefined.
212
- */
213
- public async applyStashedOpsAt(seqNum?: number) {
214
- // apply stashed ops at sequence number
215
- while (!this.initialStates.isEmpty()) {
216
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
217
- const nextState = this.initialStates.peekFront()!;
218
- if (nextState.type === "message") {
219
- if (seqNum !== undefined) {
220
- if (nextState.referenceSequenceNumber > seqNum) {
221
- break; // nothing left to do at this sequence number
222
- } else if (nextState.referenceSequenceNumber < seqNum) {
223
- throw new Error("loaded from snapshot too recent to apply stashed ops");
224
- }
225
- }
226
-
227
- // applyStashedOp will cause the DDS to behave as if it has sent the op but not actually send it
228
- const localOpMetadata =
229
- await this.stateHandler.applyStashedOp(nextState.messageType, nextState.content);
230
- nextState.localOpMetadata = localOpMetadata;
231
- }
232
-
233
- // then we push onto pendingStates which will cause PendingStateManager to resubmit when we connect
234
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
235
- this.pendingStates.push(this.initialStates.shift()!);
236
- }
237
- }
238
-
239
- /**
240
- * Processes a local message once its ack'd by the server. It verifies that there was no data corruption and that
241
- * the batch information was preserved for batch messages.
242
- * @param message - The message that got ack'd and needs to be processed.
243
- */
244
- public processPendingLocalMessage(message: ISequencedDocumentMessage): unknown {
245
- // Pre-processing part - This may be the start of a batch.
246
- this.maybeProcessBatchBegin(message);
247
-
248
- // Get the next state from the pending queue and verify that it is of type "message".
249
- const pendingState = this.peekNextPendingState();
250
- assert(pendingState.type === "message", 0x169 /* "No pending message found for this remote message" */);
251
- this.pendingStates.shift();
252
-
253
- // Processing part - Verify that there has been no data corruption.
254
- // The clientSequenceNumber of the incoming message must match that of the pending message.
255
- if (pendingState.clientSequenceNumber !== message.clientSequenceNumber) {
256
- // Close the container because this could indicate data corruption.
257
- const error = DataProcessingError.create(
258
- "pending local message clientSequenceNumber mismatch",
259
- "unexpectedAckReceived",
260
- message,
261
- { expectedClientSequenceNumber: pendingState.clientSequenceNumber },
262
- );
263
-
264
- this.stateHandler.close(error);
265
- return;
266
- }
267
-
268
- this._pendingMessagesCount--;
269
-
270
- // Post-processing part - If we are processing a batch then this could be the last message in the batch.
271
- this.maybeProcessBatchEnd(message);
272
-
273
- return pendingState.localOpMetadata;
274
- }
275
-
276
- /**
277
- * This message could be the first message in batch. If so, set batch state marking the beginning of a batch.
278
- * @param message - The message that is being processed.
279
- */
280
- private maybeProcessBatchBegin(message: ISequencedDocumentMessage) {
281
- // Tracks the last FlushMode that was set before this message was sent.
282
- let pendingFlushMode: FlushMode | undefined;
283
- // Tracks whether a flush was called before this message was sent.
284
- let pendingFlush: boolean = false;
285
-
286
- /**
287
- * We are checking if the next message is the start of a batch. It can happen in the following scenarios:
288
- * 1. The FlushMode was set to TurnBased before this message was sent.
289
- * 2. The FlushMode was already TurnBased and a flush was called before this message was sent. This essentially
290
- * means that the flush marked the end of a previous batch and beginning of a new batch.
291
- *
292
- * Keep reading pending states from the queue until we encounter a message. It's possible that the FlushMode was
293
- * updated a bunch of times without sending any messages.
294
- */
295
- let nextPendingState = this.peekNextPendingState();
296
- while (nextPendingState.type !== "message") {
297
- if (nextPendingState.type === "flushMode") {
298
- pendingFlushMode = nextPendingState.flushMode;
299
- }
300
- if (nextPendingState.type === "flush") {
301
- pendingFlush = true;
302
- }
303
- this.pendingStates.shift();
304
- nextPendingState = this.peekNextPendingState();
305
- }
306
-
307
- if (pendingFlushMode !== undefined) {
308
- this.flushModeForNextMessage = pendingFlushMode;
309
- }
310
-
311
- // If the FlushMode was set to Immediate before this message was sent, this message won't be a batch message
312
- // because in Immediate mode, every message is flushed individually.
313
- if (pendingFlushMode === FlushMode.Immediate) {
314
- return;
315
- }
316
-
317
- /**
318
- * This message is the first in a batch if before it was sent either the FlushMode was set to TurnBased or there
319
- * was an explicit flush call. Note that a flush call is tracked only in TurnBased mode and it indicates the end
320
- * of one batch and beginning of another.
321
- */
322
- if (pendingFlushMode === FlushMode.TurnBased || pendingFlush) {
323
- // We should not already be processing a batch and there should be no pending batch begin message.
324
- assert(!this.isProcessingBatch && this.pendingBatchBeginMessage === undefined,
325
- 0x16b /* "The pending batch state indicates we are already processing a batch" */);
326
-
327
- // Set the pending batch state indicating we have started processing a batch.
328
- this.pendingBatchBeginMessage = message;
329
- this.isProcessingBatch = true;
330
- }
331
- }
332
-
333
- /**
334
- * This message could be the last message in batch. If so, clear batch state since the batch is complete.
335
- * @param message - The message that is being processed.
336
- */
337
- private maybeProcessBatchEnd(message: ISequencedDocumentMessage) {
338
- if (!this.isProcessingBatch) {
339
- return;
340
- }
341
-
342
- const nextPendingState = this.peekNextPendingState();
343
- if (nextPendingState.type === "message") {
344
- return;
345
- }
346
-
347
- /**
348
- * We are in the middle of processing a batch. The batch ends when we see an explicit flush. We should never see
349
- * a FlushMode before flush. This is true because we track batches only when FlushMode is TurnBased and in this
350
- * mode, a batch ends either by calling flush or by changing the mode to Immediate which also triggers a flush.
351
- */
352
- assert(
353
- nextPendingState.type !== "flushMode",
354
- 0x2bd /* "We should not see a pending FlushMode until we see a flush when processing a batch" */,
355
- );
356
-
357
- // There should be a pending batch begin message.
358
- assert(this.pendingBatchBeginMessage !== undefined, 0x16d /* "There is no pending batch begin message" */);
359
-
360
- // Get the batch begin metadata from the first message in the batch.
361
- const batchBeginMetadata = this.pendingBatchBeginMessage.metadata?.batch;
362
-
363
- // There could be just a single message in the batch. If so, it should not have any batch metadata. If there
364
- // are multiple messages in the batch, verify that we got the correct batch begin and end metadata.
365
- if (this.pendingBatchBeginMessage === message) {
366
- assert(batchBeginMetadata === undefined,
367
- 0x16e /* "Batch with single message should not have batch metadata" */);
368
- } else {
369
- // Get the batch metadata from the last message in the batch.
370
- const batchEndMetadata = message.metadata?.batch;
371
- assert(batchBeginMetadata === true, 0x16f /* "Did not receive batch begin metadata" */);
372
- assert(batchEndMetadata === false, 0x170 /* "Did not receive batch end metadata" */);
373
- }
374
-
375
- // Clear the pending batch state now that we have processed the entire batch.
376
- this.pendingBatchBeginMessage = undefined;
377
- this.isProcessingBatch = false;
378
- }
379
-
380
- /**
381
- * Capture the pending state at this point
382
- */
383
- public checkpoint() {
384
- const checkpointHead = this.pendingStates.peekBack();
385
- return {
386
- rollback: () => {
387
- try {
388
- while (this.pendingStates.peekBack() !== checkpointHead) {
389
- this.rollbackNextPendingState();
390
- }
391
- } catch (err) {
392
- const error = wrapError(err, (message) => {
393
- return DataProcessingError.create(
394
- `RollbackError: ${message}`,
395
- "checkpointRollback",
396
- undefined) as DataProcessingError;
397
- });
398
- this.stateHandler.close(error);
399
- throw error;
400
- }
401
- },
402
- };
403
- }
404
-
405
- /**
406
- * Returns the next pending state from the pending state queue.
407
- */
408
- private peekNextPendingState(): IPendingState {
409
- const nextPendingState = this.pendingStates.peekFront();
410
- assert(!!nextPendingState, 0x171 /* "No pending state found for the remote message" */);
411
- return nextPendingState;
412
- }
413
-
414
- /**
415
- * Undo the last pending state
416
- */
417
- private rollbackNextPendingState() {
418
- const pendingStatesCount = this.pendingStates.length;
419
- if (pendingStatesCount === 0) {
420
- return;
421
- }
422
-
423
- this._pendingMessagesCount--;
424
-
425
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
426
- const pendingState = this.pendingStates.pop()!;
427
- switch (pendingState.type) {
428
- case "message":
429
- this.stateHandler.rollback(
430
- pendingState.messageType,
431
- pendingState.content,
432
- pendingState.localOpMetadata);
433
- break;
434
- default:
435
- throw new Error(`Can't rollback state ${pendingState.type}`);
436
- }
437
- }
438
-
439
- /**
440
- * Called when the Container's connection state changes. If the Container gets connected, it replays all the pending
441
- * states in its queue. This includes setting the FlushMode and triggering resubmission of unacked ops.
442
- */
443
- public replayPendingStates() {
444
- assert(this.stateHandler.connected(), 0x172 /* "The connection state is not consistent with the runtime" */);
445
-
446
- // This assert suggests we are about to send same ops twice, which will result in data loss.
447
- assert(this.clientId !== this.stateHandler.clientId(),
448
- 0x173 /* "replayPendingStates called twice for same clientId!" */);
449
- this.clientId = this.stateHandler.clientId();
450
-
451
- assert(this.initialStates.isEmpty(), 0x174 /* "initial states should be empty before replaying pending" */);
452
-
453
- let pendingStatesCount = this.pendingStates.length;
454
- if (pendingStatesCount === 0) {
455
- return;
456
- }
457
-
458
- // Reset the pending message count because all these messages will be removed from the queue.
459
- this._pendingMessagesCount = 0;
460
-
461
- // Save the current FlushMode so that we can revert it back after replaying the states.
462
- const savedFlushMode = this.stateHandler.flushMode();
463
-
464
- // Set the flush mode for the next message. This step is important because the flush mode may have been changed
465
- // after the next pending message was sent.
466
- this.stateHandler.setFlushMode(this.flushModeForNextMessage);
467
-
468
- // Process exactly `pendingStatesCount` items in the queue as it represents the number of states that were
469
- // pending when we connected. This is important because the `reSubmitFn` might add more items in the queue
470
- // which must not be replayed.
471
- while (pendingStatesCount > 0) {
472
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
473
- const pendingState = this.pendingStates.shift()!;
474
- switch (pendingState.type) {
475
- case "message":
476
- this.stateHandler.reSubmit(
477
- pendingState.messageType,
478
- pendingState.content,
479
- pendingState.localOpMetadata,
480
- pendingState.opMetadata);
481
- break;
482
- case "flushMode":
483
- this.stateHandler.setFlushMode(pendingState.flushMode);
484
- break;
485
- case "flush":
486
- this.stateHandler.flush();
487
- break;
488
- default:
489
- break;
490
- }
491
- pendingStatesCount--;
492
- }
493
-
494
- // Revert the FlushMode.
495
- this.stateHandler.setFlushMode(savedFlushMode);
496
- }
83
+ private readonly pendingMessages = new Deque<IPendingMessage>();
84
+ private readonly initialMessages = new Deque<IPendingMessage>();
85
+
86
+ /**
87
+ * Sequenced local ops that are saved when stashing since pending ops may depend on them
88
+ */
89
+ private savedOps: IPendingMessage[] = [];
90
+
91
+ private readonly disposeOnce = new Lazy<void>(() => {
92
+ this.initialMessages.clear();
93
+ this.pendingMessages.clear();
94
+ });
95
+
96
+ // Indicates whether we are processing a batch.
97
+ private isProcessingBatch: boolean = false;
98
+
99
+ // This stores the first message in the batch that we are processing. This is used to verify that we get
100
+ // the correct batch metadata.
101
+ private pendingBatchBeginMessage: ISequencedDocumentMessage | undefined;
102
+
103
+ private clientId: string | undefined;
104
+
105
+ /**
106
+ * The pending messages count. Includes `pendingMessages` and `initialMessages` to keep in sync with
107
+ * 'hasPendingMessages'.
108
+ */
109
+ public get pendingMessagesCount(): number {
110
+ return this.pendingMessages.length + this.initialMessages.length;
111
+ }
112
+
113
+ /**
114
+ * Called to check if there are any pending messages in the pending message queue.
115
+ * @returns A boolean indicating whether there are messages or not.
116
+ */
117
+ public hasPendingMessages(): boolean {
118
+ return this.pendingMessagesCount !== 0;
119
+ }
120
+
121
+ public getLocalState(): IPendingLocalState | undefined {
122
+ assert(
123
+ this.initialMessages.isEmpty(),
124
+ 0x2e9 /* "Must call getLocalState() after applying initial states" */,
125
+ );
126
+ if (!this.pendingMessages.isEmpty()) {
127
+ return {
128
+ pendingStates: [...this.savedOps, ...this.pendingMessages.toArray()].map(
129
+ (message) => {
130
+ // delete localOpMetadata since it may not be serializable
131
+ // and will be regenerated by applyStashedOp()
132
+ return { ...message, localOpMetadata: undefined };
133
+ },
134
+ ),
135
+ };
136
+ }
137
+ }
138
+
139
+ constructor(
140
+ private readonly stateHandler: IRuntimeStateHandler,
141
+ initialLocalState: IPendingLocalState | undefined,
142
+ private readonly logger: ITelemetryLoggerExt | undefined,
143
+ ) {
144
+ if (initialLocalState?.pendingStates) {
145
+ this.initialMessages.push(...initialLocalState.pendingStates);
146
+ }
147
+ }
148
+
149
+ public get disposed() {
150
+ return this.disposeOnce.evaluated;
151
+ }
152
+ public readonly dispose = () => this.disposeOnce.value;
153
+
154
+ /**
155
+ * Called when a message is submitted locally. Adds the message and the associated details to the pending state
156
+ * queue.
157
+ * @param type - The container message type.
158
+ * @param content - The message content.
159
+ * @param localOpMetadata - The local metadata associated with the message.
160
+ */
161
+ public onSubmitMessage(
162
+ content: string,
163
+ referenceSequenceNumber: number,
164
+ localOpMetadata: unknown,
165
+ opMetadata: Record<string, unknown> | undefined,
166
+ ) {
167
+ const pendingMessage: IPendingMessage = {
168
+ type: "message",
169
+ referenceSequenceNumber,
170
+ content,
171
+ localOpMetadata,
172
+ opMetadata,
173
+ };
174
+
175
+ this.pendingMessages.push(pendingMessage);
176
+ }
177
+
178
+ /**
179
+ * Applies stashed ops at their reference sequence number so they are ready to be ACKed or resubmitted
180
+ * @param seqNum - Sequence number at which to apply ops. Will apply all ops if seqNum is undefined.
181
+ */
182
+ public async applyStashedOpsAt(seqNum?: number) {
183
+ // apply stashed ops at sequence number
184
+ while (!this.initialMessages.isEmpty()) {
185
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
186
+ const nextMessage = this.initialMessages.peekFront()!;
187
+ if (seqNum !== undefined) {
188
+ if (nextMessage.referenceSequenceNumber > seqNum) {
189
+ break; // nothing left to do at this sequence number
190
+ }
191
+ if (nextMessage.referenceSequenceNumber < seqNum) {
192
+ throw new Error("loaded from snapshot too recent to apply stashed ops");
193
+ }
194
+ }
195
+
196
+ try {
197
+ // applyStashedOp will cause the DDS to behave as if it has sent the op but not actually send it
198
+ const localOpMetadata = await this.stateHandler.applyStashedOp(nextMessage.content);
199
+ nextMessage.localOpMetadata = localOpMetadata;
200
+ } catch (error) {
201
+ throw DataProcessingError.wrapIfUnrecognized(error, "applyStashedOp", nextMessage);
202
+ }
203
+
204
+ // then we push onto pendingMessages which will cause PendingStateManager to resubmit when we connect
205
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
206
+ this.pendingMessages.push(this.initialMessages.shift()!);
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Processes a local message once its ack'd by the server. It verifies that there was no data corruption and that
212
+ * the batch information was preserved for batch messages.
213
+ * @param message - The message that got ack'd and needs to be processed.
214
+ */
215
+ public processPendingLocalMessage(message: InboundSequencedContainerRuntimeMessage): unknown {
216
+ // Pre-processing part - This may be the start of a batch.
217
+ this.maybeProcessBatchBegin(message);
218
+
219
+ // Get the next message from the pending queue. Verify a message exists.
220
+ const pendingMessage = this.pendingMessages.peekFront();
221
+ assert(
222
+ pendingMessage !== undefined,
223
+ 0x169 /* "No pending message found for this remote message" */,
224
+ );
225
+ this.savedOps.push(pendingMessage);
226
+
227
+ this.pendingMessages.shift();
228
+
229
+ const messageContent = buildPendingMessageContent(message);
230
+
231
+ // Stringified content should match
232
+ if (pendingMessage.content !== messageContent) {
233
+ this.stateHandler.close(
234
+ DataProcessingError.create(
235
+ "pending local message content mismatch",
236
+ "unexpectedAckReceived",
237
+ message,
238
+ {
239
+ expectedMessageType: JSON.parse(pendingMessage.content).type,
240
+ },
241
+ ),
242
+ );
243
+ return;
244
+ }
245
+
246
+ // Post-processing part - If we are processing a batch then this could be the last message in the batch.
247
+ this.maybeProcessBatchEnd(message);
248
+
249
+ return pendingMessage.localOpMetadata;
250
+ }
251
+
252
+ /**
253
+ * This message could be the first message in batch. If so, set batch state marking the beginning of a batch.
254
+ * @param message - The message that is being processed.
255
+ */
256
+ private maybeProcessBatchBegin(message: ISequencedDocumentMessage) {
257
+ // This message is the first in a batch if the "batch" property on the metadata is set to true
258
+ if ((message.metadata as IBatchMetadata | undefined)?.batch) {
259
+ // We should not already be processing a batch and there should be no pending batch begin message.
260
+ assert(
261
+ !this.isProcessingBatch && this.pendingBatchBeginMessage === undefined,
262
+ 0x16b /* "The pending batch state indicates we are already processing a batch" */,
263
+ );
264
+
265
+ // Set the pending batch state indicating we have started processing a batch.
266
+ this.pendingBatchBeginMessage = message;
267
+ this.isProcessingBatch = true;
268
+ }
269
+ }
270
+
271
+ /**
272
+ * This message could be the last message in batch. If so, clear batch state since the batch is complete.
273
+ * @param message - The message that is being processed.
274
+ */
275
+ private maybeProcessBatchEnd(message: ISequencedDocumentMessage) {
276
+ if (!this.isProcessingBatch) {
277
+ return;
278
+ }
279
+
280
+ // There should be a pending batch begin message.
281
+ assert(
282
+ this.pendingBatchBeginMessage !== undefined,
283
+ 0x16d /* "There is no pending batch begin message" */,
284
+ );
285
+
286
+ const batchEndMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;
287
+ if (this.pendingMessages.isEmpty() || batchEndMetadata === false) {
288
+ // Get the batch begin metadata from the first message in the batch.
289
+ const batchBeginMetadata = (
290
+ this.pendingBatchBeginMessage.metadata as IBatchMetadata | undefined
291
+ )?.batch;
292
+
293
+ // There could be just a single message in the batch. If so, it should not have any batch metadata. If there
294
+ // are multiple messages in the batch, verify that we got the correct batch begin and end metadata.
295
+ if (this.pendingBatchBeginMessage === message) {
296
+ assert(
297
+ batchBeginMetadata === undefined,
298
+ 0x16e /* "Batch with single message should not have batch metadata" */,
299
+ );
300
+ } else {
301
+ if (batchBeginMetadata !== true || batchEndMetadata !== false) {
302
+ this.stateHandler.close(
303
+ DataProcessingError.create(
304
+ "Pending batch inconsistency", // Formerly known as asserts 0x16f and 0x170
305
+ "processPendingLocalMessage",
306
+ message,
307
+ {
308
+ runtimeVersion: pkgVersion,
309
+ batchClientId:
310
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
311
+ this.pendingBatchBeginMessage.clientId === null
312
+ ? "null"
313
+ : this.pendingBatchBeginMessage.clientId,
314
+ clientId: this.stateHandler.clientId(),
315
+ hasBatchStart: batchBeginMetadata === true,
316
+ hasBatchEnd: batchEndMetadata === false,
317
+ messageType: message.type,
318
+ pendingMessagesCount: this.pendingMessagesCount,
319
+ },
320
+ ),
321
+ );
322
+ }
323
+ }
324
+
325
+ // Clear the pending batch state now that we have processed the entire batch.
326
+ this.pendingBatchBeginMessage = undefined;
327
+ this.isProcessingBatch = false;
328
+ }
329
+ }
330
+
331
+ /**
332
+ * Called when the Container's connection state changes. If the Container gets connected, it replays all the pending
333
+ * states in its queue. This includes triggering resubmission of unacked ops.
334
+ * ! Note: successfully resubmitting an op that has been successfully sequenced is not possible due to checks in the ConnectionStateHandler (Loader layer)
335
+ */
336
+ public replayPendingStates() {
337
+ assert(
338
+ this.stateHandler.connected(),
339
+ 0x172 /* "The connection state is not consistent with the runtime" */,
340
+ );
341
+
342
+ // This assert suggests we are about to send same ops twice, which will result in data loss.
343
+ assert(
344
+ this.clientId !== this.stateHandler.clientId(),
345
+ 0x173 /* "replayPendingStates called twice for same clientId!" */,
346
+ );
347
+ this.clientId = this.stateHandler.clientId();
348
+
349
+ assert(
350
+ this.initialMessages.isEmpty(),
351
+ 0x174 /* "initial states should be empty before replaying pending" */,
352
+ );
353
+
354
+ const initialPendingMessagesCount = this.pendingMessages.length;
355
+ let remainingPendingMessagesCount = this.pendingMessages.length;
356
+
357
+ // Process exactly `pendingMessagesCount` items in the queue as it represents the number of messages that were
358
+ // pending when we connected. This is important because the `reSubmitFn` might add more items in the queue
359
+ // which must not be replayed.
360
+ while (remainingPendingMessagesCount > 0) {
361
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
362
+ let pendingMessage = this.pendingMessages.shift()!;
363
+ remainingPendingMessagesCount--;
364
+ assert(
365
+ pendingMessage.opMetadata?.batch !== false,
366
+ 0x41b /* We cannot process batches in chunks */,
367
+ );
368
+
369
+ /**
370
+ * We want to ensure grouped messages get processed in a batch.
371
+ * Note: It is not possible for the PendingStateManager to receive a partially acked batch. It will
372
+ * either receive the whole batch ack or nothing at all.
373
+ */
374
+ if (pendingMessage.opMetadata?.batch) {
375
+ assert(
376
+ remainingPendingMessagesCount > 0,
377
+ 0x554 /* Last pending message cannot be a batch begin */,
378
+ );
379
+
380
+ const batch: IPendingBatchMessage[] = [];
381
+
382
+ // check is >= because batch end may be last pending message
383
+ while (remainingPendingMessagesCount >= 0) {
384
+ batch.push({
385
+ content: pendingMessage.content,
386
+ localOpMetadata: pendingMessage.localOpMetadata,
387
+ opMetadata: pendingMessage.opMetadata,
388
+ });
389
+
390
+ if (pendingMessage.opMetadata?.batch === false) {
391
+ break;
392
+ }
393
+ assert(remainingPendingMessagesCount > 0, 0x555 /* No batch end found */);
394
+
395
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
396
+ pendingMessage = this.pendingMessages.shift()!;
397
+ remainingPendingMessagesCount--;
398
+ assert(
399
+ pendingMessage.opMetadata?.batch !== true,
400
+ 0x556 /* Batch start needs a corresponding batch end */,
401
+ );
402
+ }
403
+
404
+ this.stateHandler.reSubmitBatch(batch);
405
+ } else {
406
+ this.stateHandler.reSubmit({
407
+ content: pendingMessage.content,
408
+ localOpMetadata: pendingMessage.localOpMetadata,
409
+ opMetadata: pendingMessage.opMetadata,
410
+ });
411
+ }
412
+ }
413
+
414
+ // pending ops should no longer depend on previous sequenced local ops after resubmit
415
+ this.savedOps = [];
416
+
417
+ // We replayPendingStates on read connections too - we expect these to get nack'd though, and to then reconnect
418
+ // on a write connection and replay again. This filters out the replay that happens on the read connection so
419
+ // we only see the replays on write connections (that have a chance to go through).
420
+ if (this.stateHandler.isActiveConnection()) {
421
+ this.logger?.sendTelemetryEvent({
422
+ eventName: "PendingStatesReplayed",
423
+ count: initialPendingMessagesCount,
424
+ clientId: this.stateHandler.clientId(),
425
+ });
426
+ }
427
+ }
497
428
  }