@fluidframework/container-runtime 2.0.0-dev-rc.1.0.0.232845 → 2.0.0-dev-rc.2.0.0.246488

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 (700) hide show
  1. package/.eslintrc.cjs +5 -5
  2. package/{.mocharc.js → .mocharc.cjs} +1 -1
  3. package/CHANGELOG.md +54 -0
  4. package/README.md +45 -0
  5. package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
  6. package/api-extractor-lint.json +1 -1
  7. package/api-extractor.json +1 -1
  8. package/api-report/container-runtime.api.md +426 -33
  9. package/dist/batchTracker.d.ts +1 -2
  10. package/dist/batchTracker.d.ts.map +1 -1
  11. package/dist/batchTracker.js.map +1 -1
  12. package/dist/blobManager.d.ts +0 -5
  13. package/dist/blobManager.d.ts.map +1 -1
  14. package/dist/blobManager.js +0 -12
  15. package/dist/blobManager.js.map +1 -1
  16. package/dist/channelCollection.d.ts +226 -0
  17. package/dist/channelCollection.d.ts.map +1 -0
  18. package/dist/{dataStores.js → channelCollection.js} +455 -150
  19. package/dist/channelCollection.js.map +1 -0
  20. package/dist/connectionTelemetry.d.ts +11 -1
  21. package/dist/connectionTelemetry.d.ts.map +1 -1
  22. package/dist/connectionTelemetry.js +42 -4
  23. package/dist/connectionTelemetry.js.map +1 -1
  24. package/dist/container-runtime-alpha.d.ts +128 -48
  25. package/dist/container-runtime-beta.d.ts +67 -9
  26. package/dist/container-runtime-public.d.ts +67 -9
  27. package/dist/container-runtime-untrimmed.d.ts +692 -49
  28. package/dist/containerHandleContext.d.ts +1 -1
  29. package/dist/containerHandleContext.d.ts.map +1 -1
  30. package/dist/containerHandleContext.js.map +1 -1
  31. package/dist/containerRuntime.d.ts +81 -64
  32. package/dist/containerRuntime.d.ts.map +1 -1
  33. package/dist/containerRuntime.js +522 -379
  34. package/dist/containerRuntime.js.map +1 -1
  35. package/dist/dataStore.d.ts +2 -3
  36. package/dist/dataStore.d.ts.map +1 -1
  37. package/dist/dataStore.js +12 -11
  38. package/dist/dataStore.js.map +1 -1
  39. package/dist/dataStoreContext.d.ts +118 -41
  40. package/dist/dataStoreContext.d.ts.map +1 -1
  41. package/dist/dataStoreContext.js +248 -159
  42. package/dist/dataStoreContext.js.map +1 -1
  43. package/dist/dataStoreContexts.d.ts +2 -1
  44. package/dist/dataStoreContexts.d.ts.map +1 -1
  45. package/dist/dataStoreContexts.js +1 -0
  46. package/dist/dataStoreContexts.js.map +1 -1
  47. package/dist/dataStoreRegistry.d.ts +4 -0
  48. package/dist/dataStoreRegistry.d.ts.map +1 -1
  49. package/dist/dataStoreRegistry.js +2 -2
  50. package/dist/dataStoreRegistry.js.map +1 -1
  51. package/dist/deltaManagerSummarizerProxy.d.ts +29 -4
  52. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
  53. package/dist/deltaManagerSummarizerProxy.js +91 -5
  54. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  55. package/dist/gc/garbageCollection.d.ts +12 -6
  56. package/dist/gc/garbageCollection.d.ts.map +1 -1
  57. package/dist/gc/garbageCollection.js +116 -78
  58. package/dist/gc/garbageCollection.js.map +1 -1
  59. package/dist/gc/gcConfigs.d.ts +2 -2
  60. package/dist/gc/gcConfigs.d.ts.map +1 -1
  61. package/dist/gc/gcConfigs.js +30 -23
  62. package/dist/gc/gcConfigs.js.map +1 -1
  63. package/dist/gc/gcDefinitions.d.ts +22 -13
  64. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  65. package/dist/gc/gcDefinitions.js +7 -4
  66. package/dist/gc/gcDefinitions.js.map +1 -1
  67. package/dist/gc/gcHelpers.d.ts +2 -2
  68. package/dist/gc/gcHelpers.d.ts.map +1 -1
  69. package/dist/gc/gcHelpers.js.map +1 -1
  70. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +1 -1
  71. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -1
  72. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  73. package/dist/gc/gcSummaryStateTracker.d.ts +12 -5
  74. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  75. package/dist/gc/gcSummaryStateTracker.js +18 -6
  76. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  77. package/dist/gc/gcTelemetry.d.ts +6 -7
  78. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  79. package/dist/gc/gcTelemetry.js +20 -18
  80. package/dist/gc/gcTelemetry.js.map +1 -1
  81. package/dist/gc/gcUnreferencedStateTracker.d.ts +1 -1
  82. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  83. package/dist/gc/gcUnreferencedStateTracker.js +10 -10
  84. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  85. package/dist/gc/index.d.ts +8 -8
  86. package/dist/gc/index.d.ts.map +1 -1
  87. package/dist/gc/index.js +40 -39
  88. package/dist/gc/index.js.map +1 -1
  89. package/dist/index.d.ts +11 -21
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +36 -42
  92. package/dist/index.js.map +1 -1
  93. package/dist/messageTypes.d.ts +3 -3
  94. package/dist/messageTypes.d.ts.map +1 -1
  95. package/dist/messageTypes.js.map +1 -1
  96. package/dist/opLifecycle/batchManager.d.ts +2 -2
  97. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  98. package/dist/opLifecycle/batchManager.js.map +1 -1
  99. package/dist/opLifecycle/definitions.d.ts +2 -2
  100. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  101. package/dist/opLifecycle/definitions.js.map +1 -1
  102. package/dist/opLifecycle/index.d.ts +8 -8
  103. package/dist/opLifecycle/index.d.ts.map +1 -1
  104. package/dist/opLifecycle/index.js +18 -18
  105. package/dist/opLifecycle/index.js.map +1 -1
  106. package/dist/opLifecycle/opCompressor.d.ts +1 -1
  107. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  108. package/dist/opLifecycle/opCompressor.js +4 -4
  109. package/dist/opLifecycle/opCompressor.js.map +1 -1
  110. package/dist/opLifecycle/opDecompressor.d.ts +1 -1
  111. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  112. package/dist/opLifecycle/opDecompressor.js +3 -3
  113. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  114. package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
  115. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  116. package/dist/opLifecycle/opGroupingManager.js +1 -10
  117. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  118. package/dist/opLifecycle/opSplitter.d.ts +1 -1
  119. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  120. package/dist/opLifecycle/opSplitter.js +5 -5
  121. package/dist/opLifecycle/opSplitter.js.map +1 -1
  122. package/dist/opLifecycle/outbox.d.ts +7 -7
  123. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  124. package/dist/opLifecycle/outbox.js +32 -18
  125. package/dist/opLifecycle/outbox.js.map +1 -1
  126. package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -4
  127. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  128. package/dist/opLifecycle/remoteMessageProcessor.js +7 -4
  129. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  130. package/dist/package.json +3 -0
  131. package/dist/packageVersion.d.ts +1 -1
  132. package/dist/packageVersion.js +1 -1
  133. package/dist/packageVersion.js.map +1 -1
  134. package/dist/pendingStateManager.d.ts +2 -1
  135. package/dist/pendingStateManager.d.ts.map +1 -1
  136. package/dist/pendingStateManager.js +18 -10
  137. package/dist/pendingStateManager.js.map +1 -1
  138. package/dist/scheduleManager.d.ts +1 -2
  139. package/dist/scheduleManager.d.ts.map +1 -1
  140. package/dist/scheduleManager.js +9 -5
  141. package/dist/scheduleManager.js.map +1 -1
  142. package/dist/summary/index.d.ts +12 -12
  143. package/dist/summary/index.d.ts.map +1 -1
  144. package/dist/summary/index.js +43 -43
  145. package/dist/summary/index.js.map +1 -1
  146. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  147. package/dist/summary/orderedClientElection.js +12 -8
  148. package/dist/summary/orderedClientElection.js.map +1 -1
  149. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
  150. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  151. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  152. package/dist/summary/runningSummarizer.d.ts +5 -4
  153. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  154. package/dist/summary/runningSummarizer.js +47 -32
  155. package/dist/summary/runningSummarizer.js.map +1 -1
  156. package/dist/summary/summarizer.d.ts +4 -4
  157. package/dist/summary/summarizer.d.ts.map +1 -1
  158. package/dist/summary/summarizer.js +6 -6
  159. package/dist/summary/summarizer.js.map +1 -1
  160. package/dist/summary/summarizerClientElection.d.ts +2 -2
  161. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  162. package/dist/summary/summarizerClientElection.js.map +1 -1
  163. package/dist/summary/summarizerHeuristics.d.ts +3 -3
  164. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  165. package/dist/summary/summarizerHeuristics.js.map +1 -1
  166. package/dist/summary/summarizerNode/index.d.ts +3 -3
  167. package/dist/summary/summarizerNode/index.d.ts.map +1 -1
  168. package/dist/summary/summarizerNode/index.js +4 -4
  169. package/dist/summary/summarizerNode/index.js.map +1 -1
  170. package/dist/summary/summarizerNode/summarizerNode.d.ts +16 -5
  171. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  172. package/dist/summary/summarizerNode/summarizerNode.js +40 -10
  173. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  174. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +9 -1
  175. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  176. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  177. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +3 -4
  178. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  179. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +12 -12
  180. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  181. package/dist/summary/summarizerTypes.d.ts +9 -20
  182. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  183. package/dist/summary/summarizerTypes.js.map +1 -1
  184. package/dist/summary/summaryFormat.d.ts +15 -2
  185. package/dist/summary/summaryFormat.d.ts.map +1 -1
  186. package/dist/summary/summaryFormat.js.map +1 -1
  187. package/dist/summary/summaryGenerator.d.ts +6 -5
  188. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  189. package/dist/summary/summaryGenerator.js +10 -1
  190. package/dist/summary/summaryGenerator.js.map +1 -1
  191. package/dist/summary/summaryManager.d.ts +5 -6
  192. package/dist/summary/summaryManager.d.ts.map +1 -1
  193. package/dist/summary/summaryManager.js +4 -5
  194. package/dist/summary/summaryManager.js.map +1 -1
  195. package/dist/tsdoc-metadata.json +1 -1
  196. package/lib/{batchTracker.d.mts → batchTracker.d.ts} +2 -3
  197. package/lib/batchTracker.d.ts.map +1 -0
  198. package/lib/{batchTracker.mjs → batchTracker.js} +1 -1
  199. package/lib/batchTracker.js.map +1 -0
  200. package/lib/{blobManager.d.mts → blobManager.d.ts} +1 -6
  201. package/lib/blobManager.d.ts.map +1 -0
  202. package/lib/{blobManager.mjs → blobManager.js} +1 -13
  203. package/lib/blobManager.js.map +1 -0
  204. package/lib/channelCollection.d.ts +226 -0
  205. package/lib/channelCollection.d.ts.map +1 -0
  206. package/lib/{dataStores.mjs → channelCollection.js} +442 -140
  207. package/lib/channelCollection.js.map +1 -0
  208. package/lib/{connectionTelemetry.d.mts → connectionTelemetry.d.ts} +12 -2
  209. package/lib/connectionTelemetry.d.ts.map +1 -0
  210. package/lib/{connectionTelemetry.mjs → connectionTelemetry.js} +43 -5
  211. package/lib/connectionTelemetry.js.map +1 -0
  212. package/lib/{container-runtime-alpha.d.mts → container-runtime-alpha.d.ts} +128 -48
  213. package/lib/{container-runtime-beta.d.mts → container-runtime-beta.d.ts} +67 -9
  214. package/lib/{container-runtime-public.d.mts → container-runtime-public.d.ts} +67 -9
  215. package/lib/{container-runtime-untrimmed.d.mts → container-runtime-untrimmed.d.ts} +692 -49
  216. package/lib/{containerHandleContext.d.mts → containerHandleContext.d.ts} +2 -2
  217. package/lib/containerHandleContext.d.ts.map +1 -0
  218. package/lib/{containerHandleContext.mjs → containerHandleContext.js} +1 -1
  219. package/lib/containerHandleContext.js.map +1 -0
  220. package/lib/{containerRuntime.d.mts → containerRuntime.d.ts} +86 -65
  221. package/lib/containerRuntime.d.ts.map +1 -0
  222. package/lib/{containerRuntime.mjs → containerRuntime.js} +444 -303
  223. package/lib/containerRuntime.js.map +1 -0
  224. package/lib/{dataStore.d.mts → dataStore.d.ts} +3 -4
  225. package/lib/dataStore.d.ts.map +1 -0
  226. package/lib/{dataStore.mjs → dataStore.js} +13 -12
  227. package/lib/dataStore.js.map +1 -0
  228. package/lib/{dataStoreContext.d.mts → dataStoreContext.d.ts} +119 -42
  229. package/lib/dataStoreContext.d.ts.map +1 -0
  230. package/lib/{dataStoreContext.mjs → dataStoreContext.js} +240 -151
  231. package/lib/dataStoreContext.js.map +1 -0
  232. package/lib/{dataStoreContexts.d.mts → dataStoreContexts.d.ts} +3 -2
  233. package/lib/dataStoreContexts.d.ts.map +1 -0
  234. package/lib/{dataStoreContexts.mjs → dataStoreContexts.js} +2 -1
  235. package/lib/dataStoreContexts.js.map +1 -0
  236. package/lib/{dataStoreRegistry.d.mts → dataStoreRegistry.d.ts} +5 -1
  237. package/lib/dataStoreRegistry.d.ts.map +1 -0
  238. package/lib/{dataStoreRegistry.mjs → dataStoreRegistry.js} +5 -1
  239. package/lib/dataStoreRegistry.js.map +1 -0
  240. package/{dist/deltaManagerProxyBase.d.ts → lib/deltaManagerSummarizerProxy.d.ts} +16 -7
  241. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
  242. package/lib/deltaManagerSummarizerProxy.js +124 -0
  243. package/lib/deltaManagerSummarizerProxy.js.map +1 -0
  244. package/lib/{deltaScheduler.d.mts → deltaScheduler.d.ts} +1 -1
  245. package/lib/deltaScheduler.d.ts.map +1 -0
  246. package/lib/{deltaScheduler.mjs → deltaScheduler.js} +1 -1
  247. package/lib/deltaScheduler.js.map +1 -0
  248. package/lib/{error.d.mts → error.d.ts} +1 -1
  249. package/lib/error.d.ts.map +1 -0
  250. package/lib/{error.mjs → error.js} +1 -1
  251. package/lib/error.js.map +1 -0
  252. package/lib/gc/{garbageCollection.d.mts → garbageCollection.d.ts} +13 -7
  253. package/lib/gc/garbageCollection.d.ts.map +1 -0
  254. package/lib/gc/{garbageCollection.mjs → garbageCollection.js} +79 -41
  255. package/lib/gc/garbageCollection.js.map +1 -0
  256. package/lib/gc/{gcConfigs.d.mts → gcConfigs.d.ts} +3 -3
  257. package/lib/gc/gcConfigs.d.ts.map +1 -0
  258. package/lib/gc/{gcConfigs.mjs → gcConfigs.js} +14 -7
  259. package/lib/gc/gcConfigs.js.map +1 -0
  260. package/lib/gc/{gcDefinitions.d.mts → gcDefinitions.d.ts} +23 -14
  261. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  262. package/lib/gc/{gcDefinitions.mjs → gcDefinitions.js} +7 -4
  263. package/lib/gc/gcDefinitions.js.map +1 -0
  264. package/lib/gc/{gcHelpers.d.mts → gcHelpers.d.ts} +3 -3
  265. package/lib/gc/{gcHelpers.d.mts.map → gcHelpers.d.ts.map} +1 -1
  266. package/lib/gc/{gcHelpers.mjs → gcHelpers.js} +1 -1
  267. package/lib/gc/gcHelpers.js.map +1 -0
  268. package/lib/gc/{gcReferenceGraphAlgorithm.d.mts → gcReferenceGraphAlgorithm.d.ts} +2 -2
  269. package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  270. package/lib/gc/{gcReferenceGraphAlgorithm.mjs → gcReferenceGraphAlgorithm.js} +1 -1
  271. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  272. package/lib/gc/{gcSummaryDefinitions.d.mts → gcSummaryDefinitions.d.ts} +1 -1
  273. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -0
  274. package/lib/gc/{gcSummaryDefinitions.mjs → gcSummaryDefinitions.js} +1 -1
  275. package/lib/gc/gcSummaryDefinitions.js.map +1 -0
  276. package/lib/gc/{gcSummaryStateTracker.d.mts → gcSummaryStateTracker.d.ts} +13 -6
  277. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  278. package/lib/gc/{gcSummaryStateTracker.mjs → gcSummaryStateTracker.js} +17 -5
  279. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  280. package/lib/gc/{gcTelemetry.d.mts → gcTelemetry.d.ts} +7 -8
  281. package/lib/gc/gcTelemetry.d.ts.map +1 -0
  282. package/lib/gc/{gcTelemetry.mjs → gcTelemetry.js} +5 -3
  283. package/lib/gc/gcTelemetry.js.map +1 -0
  284. package/lib/gc/{gcUnreferencedStateTracker.d.mts → gcUnreferencedStateTracker.d.ts} +2 -2
  285. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  286. package/lib/gc/{gcUnreferencedStateTracker.mjs → gcUnreferencedStateTracker.js} +2 -2
  287. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  288. package/lib/gc/index.d.ts +13 -0
  289. package/lib/gc/index.d.ts.map +1 -0
  290. package/lib/gc/{index.mjs → index.js} +8 -8
  291. package/lib/gc/index.js.map +1 -0
  292. package/lib/{index.d.mts → index.d.ts} +12 -22
  293. package/lib/index.d.ts.map +1 -0
  294. package/lib/index.js +15 -0
  295. package/lib/index.js.map +1 -0
  296. package/lib/{messageTypes.d.mts → messageTypes.d.ts} +4 -4
  297. package/lib/messageTypes.d.ts.map +1 -0
  298. package/lib/{messageTypes.mjs → messageTypes.js} +1 -1
  299. package/lib/messageTypes.js.map +1 -0
  300. package/lib/{metadata.d.mts → metadata.d.ts} +1 -1
  301. package/lib/metadata.d.ts.map +1 -0
  302. package/lib/{metadata.mjs → metadata.js} +1 -1
  303. package/lib/metadata.js.map +1 -0
  304. package/lib/opLifecycle/{batchManager.d.mts → batchManager.d.ts} +3 -3
  305. package/lib/opLifecycle/batchManager.d.ts.map +1 -0
  306. package/lib/opLifecycle/{batchManager.mjs → batchManager.js} +1 -1
  307. package/lib/opLifecycle/batchManager.js.map +1 -0
  308. package/lib/opLifecycle/{definitions.d.mts → definitions.d.ts} +3 -3
  309. package/lib/opLifecycle/definitions.d.ts.map +1 -0
  310. package/lib/opLifecycle/{definitions.mjs → definitions.js} +1 -1
  311. package/lib/opLifecycle/definitions.js.map +1 -0
  312. package/lib/opLifecycle/index.d.ts +13 -0
  313. package/lib/opLifecycle/index.d.ts.map +1 -0
  314. package/lib/opLifecycle/index.js +12 -0
  315. package/lib/opLifecycle/index.js.map +1 -0
  316. package/lib/opLifecycle/{opCompressor.d.mts → opCompressor.d.ts} +2 -2
  317. package/lib/opLifecycle/opCompressor.d.ts.map +1 -0
  318. package/lib/opLifecycle/{opCompressor.mjs → opCompressor.js} +3 -3
  319. package/lib/opLifecycle/opCompressor.js.map +1 -0
  320. package/lib/opLifecycle/{opDecompressor.d.mts → opDecompressor.d.ts} +2 -2
  321. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -0
  322. package/lib/opLifecycle/{opDecompressor.mjs → opDecompressor.js} +2 -2
  323. package/lib/opLifecycle/opDecompressor.js.map +1 -0
  324. package/lib/opLifecycle/{opGroupingManager.d.mts → opGroupingManager.d.ts} +2 -2
  325. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -0
  326. package/lib/opLifecycle/{opGroupingManager.mjs → opGroupingManager.js} +2 -11
  327. package/lib/opLifecycle/opGroupingManager.js.map +1 -0
  328. package/lib/opLifecycle/{opSplitter.d.mts → opSplitter.d.ts} +2 -2
  329. package/lib/opLifecycle/opSplitter.d.ts.map +1 -0
  330. package/lib/opLifecycle/{opSplitter.mjs → opSplitter.js} +3 -3
  331. package/lib/opLifecycle/opSplitter.js.map +1 -0
  332. package/lib/opLifecycle/{outbox.d.mts → outbox.d.ts} +8 -8
  333. package/lib/opLifecycle/outbox.d.ts.map +1 -0
  334. package/lib/opLifecycle/{outbox.mjs → outbox.js} +24 -10
  335. package/lib/opLifecycle/outbox.js.map +1 -0
  336. package/lib/opLifecycle/{remoteMessageProcessor.d.mts → remoteMessageProcessor.d.ts} +5 -5
  337. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
  338. package/lib/opLifecycle/{remoteMessageProcessor.mjs → remoteMessageProcessor.js} +7 -4
  339. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -0
  340. package/lib/{opProperties.d.mts → opProperties.d.ts} +1 -1
  341. package/lib/opProperties.d.ts.map +1 -0
  342. package/lib/{opProperties.mjs → opProperties.js} +1 -1
  343. package/lib/opProperties.js.map +1 -0
  344. package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
  345. package/lib/packageVersion.d.ts.map +1 -0
  346. package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
  347. package/lib/packageVersion.js.map +1 -0
  348. package/lib/{pendingStateManager.d.mts → pendingStateManager.d.ts} +3 -2
  349. package/lib/pendingStateManager.d.ts.map +1 -0
  350. package/lib/{pendingStateManager.mjs → pendingStateManager.js} +18 -10
  351. package/lib/pendingStateManager.js.map +1 -0
  352. package/lib/{scheduleManager.d.mts → scheduleManager.d.ts} +6 -3
  353. package/lib/scheduleManager.d.ts.map +1 -0
  354. package/lib/{scheduleManager.mjs → scheduleManager.js} +7 -3
  355. package/lib/scheduleManager.js.map +1 -0
  356. package/lib/{storageServiceWithAttachBlobs.d.mts → storageServiceWithAttachBlobs.d.ts} +1 -1
  357. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
  358. package/lib/{storageServiceWithAttachBlobs.mjs → storageServiceWithAttachBlobs.js} +1 -1
  359. package/lib/storageServiceWithAttachBlobs.js.map +1 -0
  360. package/lib/summary/{index.d.mts → index.d.ts} +13 -13
  361. package/lib/summary/index.d.ts.map +1 -0
  362. package/lib/summary/{index.mjs → index.js} +12 -12
  363. package/lib/summary/index.js.map +1 -0
  364. package/lib/summary/{orderedClientElection.d.mts → orderedClientElection.d.ts} +5 -1
  365. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  366. package/lib/summary/{orderedClientElection.mjs → orderedClientElection.js} +6 -2
  367. package/lib/summary/orderedClientElection.js.map +1 -0
  368. package/lib/summary/{runWhileConnectedCoordinator.d.mts → runWhileConnectedCoordinator.d.ts} +2 -2
  369. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  370. package/lib/summary/{runWhileConnectedCoordinator.mjs → runWhileConnectedCoordinator.js} +1 -1
  371. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  372. package/lib/summary/{runningSummarizer.d.mts → runningSummarizer.d.ts} +6 -5
  373. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  374. package/lib/summary/{runningSummarizer.mjs → runningSummarizer.js} +41 -26
  375. package/lib/summary/runningSummarizer.js.map +1 -0
  376. package/lib/summary/{summarizer.d.mts → summarizer.d.ts} +5 -5
  377. package/lib/summary/summarizer.d.ts.map +1 -0
  378. package/lib/summary/{summarizer.mjs → summarizer.js} +4 -4
  379. package/lib/summary/summarizer.js.map +1 -0
  380. package/lib/summary/{summarizerClientElection.d.mts → summarizerClientElection.d.ts} +3 -3
  381. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  382. package/lib/summary/{summarizerClientElection.mjs → summarizerClientElection.js} +1 -1
  383. package/lib/summary/summarizerClientElection.js.map +1 -0
  384. package/lib/summary/{summarizerHeuristics.d.mts → summarizerHeuristics.d.ts} +4 -4
  385. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  386. package/lib/summary/{summarizerHeuristics.mjs → summarizerHeuristics.js} +1 -1
  387. package/lib/summary/summarizerHeuristics.js.map +1 -0
  388. package/lib/summary/summarizerNode/{index.d.mts → index.d.ts} +4 -4
  389. package/lib/summary/summarizerNode/index.d.ts.map +1 -0
  390. package/lib/summary/summarizerNode/index.js +7 -0
  391. package/lib/summary/summarizerNode/index.js.map +1 -0
  392. package/lib/summary/summarizerNode/{summarizerNode.d.mts → summarizerNode.d.ts} +17 -6
  393. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  394. package/lib/summary/summarizerNode/{summarizerNode.mjs → summarizerNode.js} +34 -4
  395. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -0
  396. package/lib/summary/summarizerNode/{summarizerNodeUtils.d.mts → summarizerNodeUtils.d.ts} +10 -2
  397. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  398. package/lib/summary/summarizerNode/{summarizerNodeUtils.mjs → summarizerNodeUtils.js} +1 -1
  399. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  400. package/lib/summary/summarizerNode/{summarizerNodeWithGc.d.mts → summarizerNodeWithGc.d.ts} +4 -5
  401. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  402. package/lib/summary/summarizerNode/{summarizerNodeWithGc.mjs → summarizerNodeWithGc.js} +7 -7
  403. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  404. package/lib/summary/{summarizerTypes.d.mts → summarizerTypes.d.ts} +10 -21
  405. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  406. package/lib/summary/{summarizerTypes.mjs → summarizerTypes.js} +1 -1
  407. package/lib/summary/summarizerTypes.js.map +1 -0
  408. package/lib/summary/{summaryCollection.d.mts → summaryCollection.d.ts} +1 -1
  409. package/lib/summary/summaryCollection.d.ts.map +1 -0
  410. package/lib/summary/{summaryCollection.mjs → summaryCollection.js} +1 -1
  411. package/lib/summary/summaryCollection.js.map +1 -0
  412. package/lib/summary/{summaryFormat.d.mts → summaryFormat.d.ts} +16 -3
  413. package/lib/summary/summaryFormat.d.ts.map +1 -0
  414. package/lib/summary/{summaryFormat.mjs → summaryFormat.js} +1 -1
  415. package/lib/summary/summaryFormat.js.map +1 -0
  416. package/lib/summary/{summaryGenerator.d.mts → summaryGenerator.d.ts} +7 -6
  417. package/lib/summary/summaryGenerator.d.ts.map +1 -0
  418. package/lib/summary/{summaryGenerator.mjs → summaryGenerator.js} +11 -2
  419. package/lib/summary/summaryGenerator.js.map +1 -0
  420. package/lib/summary/{summaryManager.d.mts → summaryManager.d.ts} +6 -7
  421. package/lib/summary/summaryManager.d.ts.map +1 -0
  422. package/lib/summary/{summaryManager.mjs → summaryManager.js} +4 -5
  423. package/lib/summary/summaryManager.js.map +1 -0
  424. package/lib/test/batchTracker.spec.js +88 -0
  425. package/lib/test/batchTracker.spec.js.map +1 -0
  426. package/lib/test/blobManager.spec.js +835 -0
  427. package/lib/test/blobManager.spec.js.map +1 -0
  428. package/lib/test/channelCollection.spec.js +138 -0
  429. package/lib/test/channelCollection.spec.js.map +1 -0
  430. package/lib/test/containerRuntime.spec.js +1748 -0
  431. package/lib/test/containerRuntime.spec.js.map +1 -0
  432. package/lib/test/dataStoreContext.spec.js +771 -0
  433. package/lib/test/dataStoreContext.spec.js.map +1 -0
  434. package/lib/test/dataStoreCreation.spec.js +303 -0
  435. package/lib/test/dataStoreCreation.spec.js.map +1 -0
  436. package/lib/test/dataStoreRegistry.spec.js +26 -0
  437. package/lib/test/dataStoreRegistry.spec.js.map +1 -0
  438. package/lib/test/fuzz/fuzzUtils.js +66 -0
  439. package/lib/test/fuzz/fuzzUtils.js.map +1 -0
  440. package/lib/test/fuzz/summarizer.fuzz.spec.js +31 -0
  441. package/lib/test/fuzz/summarizer.fuzz.spec.js.map +1 -0
  442. package/lib/test/fuzz/summarizerFuzzMocks.js +162 -0
  443. package/lib/test/fuzz/summarizerFuzzMocks.js.map +1 -0
  444. package/lib/test/fuzz/summarizerFuzzSuite.js +106 -0
  445. package/lib/test/fuzz/summarizerFuzzSuite.js.map +1 -0
  446. package/lib/test/gc/garbageCollection.spec.js +1464 -0
  447. package/lib/test/gc/garbageCollection.spec.js.map +1 -0
  448. package/lib/test/gc/gcConfigs.spec.js +689 -0
  449. package/lib/test/gc/gcConfigs.spec.js.map +1 -0
  450. package/lib/test/gc/gcHelpers.spec.js +110 -0
  451. package/lib/test/gc/gcHelpers.spec.js.map +1 -0
  452. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js +68 -0
  453. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js.map +1 -0
  454. package/lib/test/gc/gcStats.spec.js +390 -0
  455. package/lib/test/gc/gcStats.spec.js.map +1 -0
  456. package/lib/test/gc/gcSummaryStateTracker.spec.js +228 -0
  457. package/lib/test/gc/gcSummaryStateTracker.spec.js.map +1 -0
  458. package/lib/test/gc/gcTelemetry.spec.js +530 -0
  459. package/lib/test/gc/gcTelemetry.spec.js.map +1 -0
  460. package/lib/test/gc/gcUnitTestHelpers.js +29 -0
  461. package/lib/test/gc/gcUnitTestHelpers.js.map +1 -0
  462. package/lib/test/gc/gcUnreferencedStateTracker.spec.js +192 -0
  463. package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +1 -0
  464. package/lib/test/getPendingBlobs.spec.js +193 -0
  465. package/lib/test/getPendingBlobs.spec.js.map +1 -0
  466. package/lib/test/hardwareStats.spec.js +93 -0
  467. package/lib/test/hardwareStats.spec.js.map +1 -0
  468. package/lib/test/index.js +6 -0
  469. package/lib/test/index.js.map +1 -0
  470. package/lib/test/opLifecycle/OpGroupingManager.spec.js +225 -0
  471. package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +1 -0
  472. package/lib/test/opLifecycle/batchManager.spec.js +189 -0
  473. package/lib/test/opLifecycle/batchManager.spec.js.map +1 -0
  474. package/lib/test/opLifecycle/opCompressor.spec.js +74 -0
  475. package/lib/test/opLifecycle/opCompressor.spec.js.map +1 -0
  476. package/lib/test/opLifecycle/opDecompressor.spec.js +218 -0
  477. package/lib/test/opLifecycle/opDecompressor.spec.js.map +1 -0
  478. package/lib/test/opLifecycle/opSplitter.spec.js +272 -0
  479. package/lib/test/opLifecycle/opSplitter.spec.js.map +1 -0
  480. package/lib/test/opLifecycle/outbox.spec.js +675 -0
  481. package/lib/test/opLifecycle/outbox.spec.js.map +1 -0
  482. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +196 -0
  483. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +1 -0
  484. package/lib/test/pendingStateManager.spec.js +329 -0
  485. package/lib/test/pendingStateManager.spec.js.map +1 -0
  486. package/lib/test/scheduleManager.spec.js +270 -0
  487. package/lib/test/scheduleManager.spec.js.map +1 -0
  488. package/lib/test/summarizerNode.spec.js +326 -0
  489. package/lib/test/summarizerNode.spec.js.map +1 -0
  490. package/lib/test/summarizerNodeWithGc.spec.js +318 -0
  491. package/lib/test/summarizerNodeWithGc.spec.js.map +1 -0
  492. package/lib/test/summary/orderedClientElection.spec.js +535 -0
  493. package/lib/test/summary/orderedClientElection.spec.js.map +1 -0
  494. package/lib/test/summary/runningSummarizer.spec.js +1349 -0
  495. package/lib/test/summary/runningSummarizer.spec.js.map +1 -0
  496. package/lib/test/summary/summarizer.spec.js +29 -0
  497. package/lib/test/summary/summarizer.spec.js.map +1 -0
  498. package/lib/test/summary/summarizerClientElection.spec.js +436 -0
  499. package/lib/test/summary/summarizerClientElection.spec.js.map +1 -0
  500. package/lib/test/summary/summarizerHeuristics.spec.js +289 -0
  501. package/lib/test/summary/summarizerHeuristics.spec.js.map +1 -0
  502. package/lib/test/summary/summaryCollection.spec.js +200 -0
  503. package/lib/test/summary/summaryCollection.spec.js.map +1 -0
  504. package/lib/test/summary/summaryManager.spec.js +430 -0
  505. package/lib/test/summary/summaryManager.spec.js.map +1 -0
  506. package/lib/test/summary/testQuorumClients.js +34 -0
  507. package/lib/test/summary/testQuorumClients.js.map +1 -0
  508. package/lib/test/throttler.spec.js +175 -0
  509. package/lib/test/throttler.spec.js.map +1 -0
  510. package/lib/test/types/validateContainerRuntimePrevious.generated.js +180 -0
  511. package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +1 -0
  512. package/lib/{throttler.d.mts → throttler.d.ts} +1 -1
  513. package/lib/throttler.d.ts.map +1 -0
  514. package/lib/{throttler.mjs → throttler.js} +1 -1
  515. package/lib/throttler.js.map +1 -0
  516. package/package.json +101 -88
  517. package/src/batchTracker.ts +1 -1
  518. package/src/blobManager.ts +1 -15
  519. package/src/{dataStores.ts → channelCollection.ts} +629 -178
  520. package/src/connectionTelemetry.ts +42 -3
  521. package/src/containerHandleContext.ts +1 -1
  522. package/src/containerRuntime.ts +626 -430
  523. package/src/dataStore.ts +16 -15
  524. package/src/dataStoreContext.ts +376 -216
  525. package/src/dataStoreContexts.ts +2 -1
  526. package/src/dataStoreRegistry.ts +1 -0
  527. package/src/deltaManagerSummarizerProxy.ts +132 -7
  528. package/src/gc/garbageCollection.ts +84 -44
  529. package/src/gc/gcConfigs.ts +17 -7
  530. package/src/gc/gcDefinitions.ts +23 -13
  531. package/src/gc/gcHelpers.ts +2 -2
  532. package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
  533. package/src/gc/gcSummaryStateTracker.ts +19 -7
  534. package/src/gc/gcTelemetry.ts +9 -7
  535. package/src/gc/gcUnreferencedStateTracker.ts +1 -1
  536. package/src/gc/index.ts +10 -9
  537. package/src/index.ts +28 -27
  538. package/src/messageTypes.ts +3 -3
  539. package/src/opLifecycle/README.md +2 -4
  540. package/src/opLifecycle/batchManager.ts +2 -2
  541. package/src/opLifecycle/definitions.ts +2 -2
  542. package/src/opLifecycle/index.ts +8 -8
  543. package/src/opLifecycle/opCompressor.ts +3 -3
  544. package/src/opLifecycle/opDecompressor.ts +3 -3
  545. package/src/opLifecycle/opGroupingManager.ts +3 -12
  546. package/src/opLifecycle/opSplitter.ts +3 -3
  547. package/src/opLifecycle/outbox.ts +43 -16
  548. package/src/opLifecycle/remoteMessageProcessor.ts +10 -6
  549. package/src/packageVersion.ts +1 -1
  550. package/src/pendingStateManager.ts +19 -13
  551. package/src/scheduleManager.ts +5 -4
  552. package/src/summary/index.ts +13 -12
  553. package/src/summary/orderedClientElection.ts +2 -1
  554. package/src/summary/runWhileConnectedCoordinator.ts +1 -1
  555. package/src/summary/runningSummarizer.ts +52 -32
  556. package/src/summary/summarizer.ts +7 -7
  557. package/src/summary/summarizerClientElection.ts +2 -2
  558. package/src/summary/summarizerHeuristics.ts +3 -3
  559. package/src/summary/summarizerNode/index.ts +6 -3
  560. package/src/summary/summarizerNode/summarizerNode.ts +50 -5
  561. package/src/summary/summarizerNode/summarizerNodeUtils.ts +14 -1
  562. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +11 -11
  563. package/src/summary/summarizerTypes.ts +11 -23
  564. package/src/summary/summaryFormat.ts +16 -2
  565. package/src/summary/summaryGenerator.ts +16 -4
  566. package/src/summary/summaryManager.ts +6 -7
  567. package/tsconfig.cjs.json +7 -0
  568. package/tsconfig.json +2 -5
  569. package/dist/dataStores.d.ts +0 -151
  570. package/dist/dataStores.d.ts.map +0 -1
  571. package/dist/dataStores.js.map +0 -1
  572. package/dist/deltaManagerProxyBase.d.ts.map +0 -1
  573. package/dist/deltaManagerProxyBase.js +0 -77
  574. package/dist/deltaManagerProxyBase.js.map +0 -1
  575. package/lib/batchTracker.d.mts.map +0 -1
  576. package/lib/batchTracker.mjs.map +0 -1
  577. package/lib/blobManager.d.mts.map +0 -1
  578. package/lib/blobManager.mjs.map +0 -1
  579. package/lib/connectionTelemetry.d.mts.map +0 -1
  580. package/lib/connectionTelemetry.mjs.map +0 -1
  581. package/lib/containerHandleContext.d.mts.map +0 -1
  582. package/lib/containerHandleContext.mjs.map +0 -1
  583. package/lib/containerRuntime.d.mts.map +0 -1
  584. package/lib/containerRuntime.mjs.map +0 -1
  585. package/lib/dataStore.d.mts.map +0 -1
  586. package/lib/dataStore.mjs.map +0 -1
  587. package/lib/dataStoreContext.d.mts.map +0 -1
  588. package/lib/dataStoreContext.mjs.map +0 -1
  589. package/lib/dataStoreContexts.d.mts.map +0 -1
  590. package/lib/dataStoreContexts.mjs.map +0 -1
  591. package/lib/dataStoreRegistry.d.mts.map +0 -1
  592. package/lib/dataStoreRegistry.mjs.map +0 -1
  593. package/lib/dataStores.d.mts +0 -151
  594. package/lib/dataStores.d.mts.map +0 -1
  595. package/lib/dataStores.mjs.map +0 -1
  596. package/lib/deltaManagerProxyBase.d.mts +0 -35
  597. package/lib/deltaManagerProxyBase.d.mts.map +0 -1
  598. package/lib/deltaManagerProxyBase.mjs +0 -73
  599. package/lib/deltaManagerProxyBase.mjs.map +0 -1
  600. package/lib/deltaManagerSummarizerProxy.d.mts +0 -19
  601. package/lib/deltaManagerSummarizerProxy.d.mts.map +0 -1
  602. package/lib/deltaManagerSummarizerProxy.mjs +0 -38
  603. package/lib/deltaManagerSummarizerProxy.mjs.map +0 -1
  604. package/lib/deltaScheduler.d.mts.map +0 -1
  605. package/lib/deltaScheduler.mjs.map +0 -1
  606. package/lib/error.d.mts.map +0 -1
  607. package/lib/error.mjs.map +0 -1
  608. package/lib/gc/garbageCollection.d.mts.map +0 -1
  609. package/lib/gc/garbageCollection.mjs.map +0 -1
  610. package/lib/gc/gcConfigs.d.mts.map +0 -1
  611. package/lib/gc/gcConfigs.mjs.map +0 -1
  612. package/lib/gc/gcDefinitions.d.mts.map +0 -1
  613. package/lib/gc/gcDefinitions.mjs.map +0 -1
  614. package/lib/gc/gcHelpers.mjs.map +0 -1
  615. package/lib/gc/gcReferenceGraphAlgorithm.d.mts.map +0 -1
  616. package/lib/gc/gcReferenceGraphAlgorithm.mjs.map +0 -1
  617. package/lib/gc/gcSummaryDefinitions.d.mts.map +0 -1
  618. package/lib/gc/gcSummaryDefinitions.mjs.map +0 -1
  619. package/lib/gc/gcSummaryStateTracker.d.mts.map +0 -1
  620. package/lib/gc/gcSummaryStateTracker.mjs.map +0 -1
  621. package/lib/gc/gcTelemetry.d.mts.map +0 -1
  622. package/lib/gc/gcTelemetry.mjs.map +0 -1
  623. package/lib/gc/gcUnreferencedStateTracker.d.mts.map +0 -1
  624. package/lib/gc/gcUnreferencedStateTracker.mjs.map +0 -1
  625. package/lib/gc/index.d.mts +0 -13
  626. package/lib/gc/index.d.mts.map +0 -1
  627. package/lib/gc/index.mjs.map +0 -1
  628. package/lib/index.d.mts.map +0 -1
  629. package/lib/index.mjs +0 -25
  630. package/lib/index.mjs.map +0 -1
  631. package/lib/messageTypes.d.mts.map +0 -1
  632. package/lib/messageTypes.mjs.map +0 -1
  633. package/lib/metadata.d.mts.map +0 -1
  634. package/lib/metadata.mjs.map +0 -1
  635. package/lib/opLifecycle/batchManager.d.mts.map +0 -1
  636. package/lib/opLifecycle/batchManager.mjs.map +0 -1
  637. package/lib/opLifecycle/definitions.d.mts.map +0 -1
  638. package/lib/opLifecycle/definitions.mjs.map +0 -1
  639. package/lib/opLifecycle/index.d.mts +0 -13
  640. package/lib/opLifecycle/index.d.mts.map +0 -1
  641. package/lib/opLifecycle/index.mjs +0 -12
  642. package/lib/opLifecycle/index.mjs.map +0 -1
  643. package/lib/opLifecycle/opCompressor.d.mts.map +0 -1
  644. package/lib/opLifecycle/opCompressor.mjs.map +0 -1
  645. package/lib/opLifecycle/opDecompressor.d.mts.map +0 -1
  646. package/lib/opLifecycle/opDecompressor.mjs.map +0 -1
  647. package/lib/opLifecycle/opGroupingManager.d.mts.map +0 -1
  648. package/lib/opLifecycle/opGroupingManager.mjs.map +0 -1
  649. package/lib/opLifecycle/opSplitter.d.mts.map +0 -1
  650. package/lib/opLifecycle/opSplitter.mjs.map +0 -1
  651. package/lib/opLifecycle/outbox.d.mts.map +0 -1
  652. package/lib/opLifecycle/outbox.mjs.map +0 -1
  653. package/lib/opLifecycle/remoteMessageProcessor.d.mts.map +0 -1
  654. package/lib/opLifecycle/remoteMessageProcessor.mjs.map +0 -1
  655. package/lib/opProperties.d.mts.map +0 -1
  656. package/lib/opProperties.mjs.map +0 -1
  657. package/lib/packageVersion.d.mts.map +0 -1
  658. package/lib/packageVersion.mjs.map +0 -1
  659. package/lib/pendingStateManager.d.mts.map +0 -1
  660. package/lib/pendingStateManager.mjs.map +0 -1
  661. package/lib/scheduleManager.d.mts.map +0 -1
  662. package/lib/scheduleManager.mjs.map +0 -1
  663. package/lib/storageServiceWithAttachBlobs.d.mts.map +0 -1
  664. package/lib/storageServiceWithAttachBlobs.mjs.map +0 -1
  665. package/lib/summary/index.d.mts.map +0 -1
  666. package/lib/summary/index.mjs.map +0 -1
  667. package/lib/summary/orderedClientElection.d.mts.map +0 -1
  668. package/lib/summary/orderedClientElection.mjs.map +0 -1
  669. package/lib/summary/runWhileConnectedCoordinator.d.mts.map +0 -1
  670. package/lib/summary/runWhileConnectedCoordinator.mjs.map +0 -1
  671. package/lib/summary/runningSummarizer.d.mts.map +0 -1
  672. package/lib/summary/runningSummarizer.mjs.map +0 -1
  673. package/lib/summary/summarizer.d.mts.map +0 -1
  674. package/lib/summary/summarizer.mjs.map +0 -1
  675. package/lib/summary/summarizerClientElection.d.mts.map +0 -1
  676. package/lib/summary/summarizerClientElection.mjs.map +0 -1
  677. package/lib/summary/summarizerHeuristics.d.mts.map +0 -1
  678. package/lib/summary/summarizerHeuristics.mjs.map +0 -1
  679. package/lib/summary/summarizerNode/index.d.mts.map +0 -1
  680. package/lib/summary/summarizerNode/index.mjs +0 -7
  681. package/lib/summary/summarizerNode/index.mjs.map +0 -1
  682. package/lib/summary/summarizerNode/summarizerNode.d.mts.map +0 -1
  683. package/lib/summary/summarizerNode/summarizerNode.mjs.map +0 -1
  684. package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts.map +0 -1
  685. package/lib/summary/summarizerNode/summarizerNodeUtils.mjs.map +0 -1
  686. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts.map +0 -1
  687. package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs.map +0 -1
  688. package/lib/summary/summarizerTypes.d.mts.map +0 -1
  689. package/lib/summary/summarizerTypes.mjs.map +0 -1
  690. package/lib/summary/summaryCollection.d.mts.map +0 -1
  691. package/lib/summary/summaryCollection.mjs.map +0 -1
  692. package/lib/summary/summaryFormat.d.mts.map +0 -1
  693. package/lib/summary/summaryFormat.mjs.map +0 -1
  694. package/lib/summary/summaryGenerator.d.mts.map +0 -1
  695. package/lib/summary/summaryGenerator.mjs.map +0 -1
  696. package/lib/summary/summaryManager.d.mts.map +0 -1
  697. package/lib/summary/summaryManager.mjs.map +0 -1
  698. package/lib/throttler.d.mts.map +0 -1
  699. package/lib/throttler.mjs.map +0 -1
  700. package/src/deltaManagerProxyBase.ts +0 -111
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
2
6
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.AllowInactiveRequestHeaderKey = exports.AllowTombstoneRequestHeaderKey = exports.RuntimeHeaders = exports.DefaultSummaryConfiguration = void 0;
7
+ exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
4
8
  const container_definitions_1 = require("@fluidframework/container-definitions");
5
9
  const core_utils_1 = require("@fluidframework/core-utils");
6
10
  const client_utils_1 = require("@fluid-internal/client-utils");
@@ -11,22 +15,22 @@ const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
11
15
  const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
12
16
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
13
17
  const uuid_1 = require("uuid");
14
- const containerHandleContext_1 = require("./containerHandleContext");
15
- const dataStoreRegistry_1 = require("./dataStoreRegistry");
16
- const connectionTelemetry_1 = require("./connectionTelemetry");
17
- const pendingStateManager_1 = require("./pendingStateManager");
18
- const packageVersion_1 = require("./packageVersion");
19
- const blobManager_1 = require("./blobManager");
20
- const dataStores_1 = require("./dataStores");
21
- const summary_1 = require("./summary");
22
- const throttler_1 = require("./throttler");
23
- const gc_1 = require("./gc");
24
- const dataStore_1 = require("./dataStore");
25
- const batchTracker_1 = require("./batchTracker");
26
- const scheduleManager_1 = require("./scheduleManager");
27
- const opLifecycle_1 = require("./opLifecycle");
28
- const deltaManagerSummarizerProxy_1 = require("./deltaManagerSummarizerProxy");
29
- const messageTypes_1 = require("./messageTypes");
18
+ const containerHandleContext_js_1 = require("./containerHandleContext.js");
19
+ const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
20
+ const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
21
+ const pendingStateManager_js_1 = require("./pendingStateManager.js");
22
+ const packageVersion_js_1 = require("./packageVersion.js");
23
+ const blobManager_js_1 = require("./blobManager.js");
24
+ const channelCollection_js_1 = require("./channelCollection.js");
25
+ const index_js_1 = require("./summary/index.js");
26
+ const throttler_js_1 = require("./throttler.js");
27
+ const index_js_2 = require("./gc/index.js");
28
+ const dataStore_js_1 = require("./dataStore.js");
29
+ const batchTracker_js_1 = require("./batchTracker.js");
30
+ const scheduleManager_js_1 = require("./scheduleManager.js");
31
+ const index_js_3 = require("./opLifecycle/index.js");
32
+ const deltaManagerSummarizerProxy_js_1 = require("./deltaManagerSummarizerProxy.js");
33
+ const messageTypes_js_1 = require("./messageTypes.js");
30
34
  /**
31
35
  * Utility to implement compat behaviors given an unknown message type
32
36
  * The parameters are typed to support compile-time enforcement of handling all known types/behaviors
@@ -56,26 +60,6 @@ exports.DefaultSummaryConfiguration = {
56
60
  runtimeOpWeight: 1.0,
57
61
  nonRuntimeHeuristicThreshold: 20,
58
62
  };
59
- /**
60
- * Accepted header keys for requests coming to the runtime.
61
- * @internal
62
- */
63
- var RuntimeHeaders;
64
- (function (RuntimeHeaders) {
65
- /** True to wait for a data store to be created and loaded before returning it. */
66
- RuntimeHeaders["wait"] = "wait";
67
- /** True if the request is coming from an IFluidHandle. */
68
- RuntimeHeaders["viaHandle"] = "viaHandle";
69
- })(RuntimeHeaders || (exports.RuntimeHeaders = RuntimeHeaders = {}));
70
- /** True if a tombstoned object should be returned without erroring
71
- * @alpha
72
- */
73
- exports.AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
74
- /**
75
- * [IRRELEVANT IF throwOnInactiveLoad OPTION NOT SET] True if an inactive object should be returned without erroring
76
- * @internal
77
- */
78
- exports.AllowInactiveRequestHeaderKey = "allowInactive"; // Belongs in the enum above, but avoiding the breaking change
79
63
  /**
80
64
  * Tombstone error responses will have this header set to true
81
65
  * @alpha
@@ -192,7 +176,7 @@ async function createSummarizer(loader, url) {
192
176
  [container_definitions_1.LoaderHeader.cache]: false,
193
177
  [container_definitions_1.LoaderHeader.clientDetails]: {
194
178
  capabilities: { interactive: false },
195
- type: summary_1.summarizerClientType,
179
+ type: index_js_1.summarizerClientType,
196
180
  },
197
181
  [driver_definitions_1.DriverHeader.summarizingClient]: true,
198
182
  [container_definitions_1.LoaderHeader.reconnect]: false,
@@ -247,18 +231,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
247
231
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
248
232
  const backCompatContext = context;
249
233
  const passLogger = backCompatContext.taggedLogger ??
250
- // eslint-disable-next-line import/no-deprecated
251
234
  new telemetry_utils_1.TaggedLoggerAdapter(backCompatContext.logger);
252
235
  const logger = (0, telemetry_utils_1.createChildLogger)({
253
236
  logger: passLogger,
254
237
  properties: {
255
238
  all: {
256
- runtimeVersion: packageVersion_1.pkgVersion,
239
+ runtimeVersion: packageVersion_js_1.pkgVersion,
257
240
  },
258
241
  },
259
242
  });
260
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = false, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
261
- const registry = new dataStoreRegistry_1.FluidDataStoreRegistry(registryEntries);
243
+ const mc = (0, telemetry_utils_1.loggerToMonitoringContext)(logger);
244
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = "off", chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
245
+ const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
262
246
  const tryFetchBlob = async (blobName) => {
263
247
  const blobId = context.baseSnapshot?.blobs[blobName];
264
248
  if (context.baseSnapshot && blobId) {
@@ -269,14 +253,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
269
253
  }
270
254
  };
271
255
  const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
272
- tryFetchBlob(summary_1.chunksBlobName),
273
- tryFetchBlob(summary_1.metadataBlobName),
274
- tryFetchBlob(summary_1.electedSummarizerBlobName),
275
- tryFetchBlob(summary_1.aliasBlobName),
276
- tryFetchBlob(summary_1.idCompressorBlobName),
256
+ tryFetchBlob(index_js_1.chunksBlobName),
257
+ tryFetchBlob(index_js_1.metadataBlobName),
258
+ tryFetchBlob(index_js_1.electedSummarizerBlobName),
259
+ tryFetchBlob(index_js_1.aliasBlobName),
260
+ tryFetchBlob(index_js_1.idCompressorBlobName),
277
261
  ]);
278
262
  // read snapshot blobs needed for BlobManager to load
279
- const blobManagerSnapshot = await blobManager_1.BlobManager.load(context.baseSnapshot?.trees[summary_1.blobsTreeName], async (id) => {
263
+ const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_1.blobsTreeName], async (id) => {
280
264
  // IContainerContext storage api return type still has undefined in 0.39 package version.
281
265
  // So once we release 0.40 container-defn package we can remove this check.
282
266
  (0, core_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
@@ -293,7 +277,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
293
277
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
294
278
  const error = new telemetry_utils_1.DataCorruptionError(
295
279
  // pre-0.58 error message: SummaryMetadataMismatch
296
- "Summary metadata mismatch", { runtimeVersion: packageVersion_1.pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
280
+ "Summary metadata mismatch", { runtimeVersion: packageVersion_js_1.pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
297
281
  if (loadSequenceNumberVerification === "log") {
298
282
  logger.sendErrorEvent({ eventName: "SequenceNumberMismatch" }, error);
299
283
  }
@@ -302,9 +286,37 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
302
286
  }
303
287
  }
304
288
  }
305
- const idCompressorEnabled = metadata?.idCompressorEnabled ?? runtimeOptions.enableRuntimeIdCompressor ?? false;
306
- let idCompressor;
307
- if (idCompressorEnabled) {
289
+ // Enabling the IdCompressor is a one-way operation and we only want to
290
+ // allow new containers to turn it on
291
+ let idCompressorMode;
292
+ if (existing) {
293
+ // This setting has to be sticky for correctness:
294
+ // 1) if compressior is OFF, it can't be enabled, as already running clients (in given document session) do not know
295
+ // how to process compressor ops
296
+ // 2) if it's ON, then all sessions should load compressor right away
297
+ // 3) Same logic applies for "delayed" mode
298
+ // Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
299
+ // We could do "off" -> "on" transtition too, if all clients start loading compressor (but not using it initially) and do so for a while -
300
+ // this will allow clients to eventually to disregard "off" setting (when it's safe so) and start using compressor in future sessions.
301
+ // Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
302
+ idCompressorMode = metadata?.idCompressorMode ?? "off";
303
+ }
304
+ else {
305
+ // FG overwrite
306
+ const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
307
+ switch (enabled) {
308
+ case true:
309
+ idCompressorMode = "on";
310
+ break;
311
+ case false:
312
+ idCompressorMode = "off";
313
+ break;
314
+ default:
315
+ idCompressorMode = enableRuntimeIdCompressor;
316
+ break;
317
+ }
318
+ }
319
+ const createIdCompressorFn = async () => {
308
320
  const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor");
309
321
  /**
310
322
  * Because the IdCompressor emits so much telemetry, this function is used to sample
@@ -321,15 +333,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
321
333
  const compressorLogger = (0, telemetry_utils_1.createSampledLogger)(logger, idCompressorEventSampler);
322
334
  const pendingLocalState = context.pendingLocalState;
323
335
  if (pendingLocalState?.pendingIdCompressorState !== undefined) {
324
- idCompressor = deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
336
+ return deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
325
337
  }
326
338
  else if (serializedIdCompressor !== undefined) {
327
- idCompressor = deserializeIdCompressor(serializedIdCompressor, createSessionId(), compressorLogger);
339
+ return deserializeIdCompressor(serializedIdCompressor, createSessionId(), compressorLogger);
328
340
  }
329
341
  else {
330
- idCompressor = createIdCompressor(compressorLogger);
342
+ return createIdCompressor(compressorLogger);
331
343
  }
332
- }
344
+ };
333
345
  const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
334
346
  summaryOptions,
335
347
  gcOptions,
@@ -341,7 +353,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
341
353
  enableRuntimeIdCompressor,
342
354
  enableOpReentryCheck,
343
355
  enableGroupedBatching,
344
- }, containerScope, logger, existing, blobManagerSnapshot, context.storage, idCompressor, provideEntryPoint, requestHandler, undefined);
356
+ }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, idCompressorMode, provideEntryPoint, requestHandler, undefined);
345
357
  // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
346
358
  // or zero. This must be done before Container replays saved ops.
347
359
  await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
@@ -355,6 +367,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
355
367
  get storage() {
356
368
  return this._storage;
357
369
  }
370
+ get containerRuntime() {
371
+ return this;
372
+ }
358
373
  get flushMode() {
359
374
  return this._flushMode;
360
375
  }
@@ -367,6 +382,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
367
382
  get attachState() {
368
383
  return this._getAttachState();
369
384
  }
385
+ /**
386
+ * See IContainerRuntimeBase.idCompressor() for details.
387
+ */
388
+ get idCompressor() {
389
+ // Expose ID Compressor only if it's On from the start.
390
+ // If container uses delayed mode, then we can only expose generateDocumentUniqueId() and nothing else.
391
+ // That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
392
+ // to reason over such things as session ID space.
393
+ if (this.idCompressorMode === "on") {
394
+ (0, core_utils_1.assert)(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
395
+ return this._idCompressor;
396
+ }
397
+ }
398
+ /**
399
+ * See IContainerRuntimeBase.generateDocumentUniqueId() for details.
400
+ */
401
+ generateDocumentUniqueId() {
402
+ return this._idCompressor?.generateDocumentUniqueId() ?? (0, uuid_1.v4)();
403
+ }
370
404
  get IFluidHandleContext() {
371
405
  return this.handleContext;
372
406
  }
@@ -404,9 +438,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
404
438
  isSummariesDisabled() {
405
439
  return this.summaryConfiguration.state === "disabled";
406
440
  }
407
- isHeuristicsDisabled() {
408
- return this.summaryConfiguration.state === "disableHeuristics";
409
- }
410
441
  getMaxOpsSinceLastSummary() {
411
442
  return this.summaryConfiguration.state !== "disabled"
412
443
  ? this.summaryConfiguration.maxOpsSinceLastSummary
@@ -431,7 +462,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
431
462
  return this.garbageCollector.throwOnTombstoneUsage;
432
463
  }
433
464
  /***/
434
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, provideEntryPoint, requestHandler, summaryConfiguration = {
465
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, idCompressorMode, provideEntryPoint, requestHandler, summaryConfiguration = {
435
466
  // the defaults
436
467
  ...exports.DefaultSummaryConfiguration,
437
468
  // the runtime configuration overrides
@@ -439,13 +470,24 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
439
470
  }) {
440
471
  super();
441
472
  this.registry = registry;
473
+ this.metadata = metadata;
442
474
  this.runtimeOptions = runtimeOptions;
443
475
  this.containerScope = containerScope;
444
476
  this.logger = logger;
445
477
  this._storage = _storage;
478
+ this.createIdCompressor = createIdCompressor;
479
+ this.idCompressorMode = idCompressorMode;
446
480
  this.requestHandler = requestHandler;
447
481
  this.summaryConfiguration = summaryConfiguration;
448
482
  this.imminentClosure = false;
483
+ // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
484
+ // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
485
+ this.pendingIdCompressorOps = [];
486
+ /**
487
+ * True if we have ID compressor loading in-flight (async operation). Useful only for
488
+ * this.idCompressorMode === "delayed" mode
489
+ */
490
+ this.compressorLoadInitiated = false;
449
491
  this.defaultMaxConsecutiveReconnects = 7;
450
492
  this._orderSequentiallyCalls = 0;
451
493
  this.flushTaskExists = false;
@@ -467,18 +509,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
467
509
  signalTimestamp: 0,
468
510
  trackingSignalSequenceNumber: undefined,
469
511
  };
512
+ /**
513
+ * It a cache for holding mapping for loading groupIds with its snapshot from the service. Add expiry policy of 1 minute.
514
+ * Starting with 1 min and based on recorded usage we can tweak it later on.
515
+ */
516
+ this.snapshotCacheForLoadingGroupIds = new core_utils_1.PromiseCache({
517
+ expiry: { policy: "absolute", durationMs: 60000 },
518
+ });
470
519
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
471
520
  this.innerDeltaManager = deltaManager;
472
- this.deltaManager = new deltaManagerSummarizerProxy_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
521
+ this.deltaManager = new deltaManagerSummarizerProxy_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
473
522
  // Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
474
523
  // This makes ContainerRuntime the final gatekeeper for outgoing messages.
475
524
  this.submitFn = submitFn;
476
525
  this.submitBatchFn = submitBatchFn;
477
526
  this.submitSummaryFn = submitSummaryFn;
478
527
  this.submitSignalFn = submitSignalFn;
479
- this.options = options;
528
+ // TODO: After IContainerContext.options is removed, we'll just create a new blank object {} here.
529
+ // Values are generally expected to be set from the runtime side.
530
+ this.options = options ?? {};
480
531
  this.clientDetails = clientDetails;
481
- this.isSummarizerClient = this.clientDetails.type === summary_1.summarizerClientType;
532
+ this.isSummarizerClient = this.clientDetails.type === index_js_1.summarizerClientType;
482
533
  this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
483
534
  this._getClientId = () => context.clientId;
484
535
  this._getAttachState = () => context.attachState;
@@ -514,19 +565,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
514
565
  // summaryNumber was renamed from summaryCount. For older docs that haven't been opened for a long time,
515
566
  // the count is reset to 0.
516
567
  loadSummaryNumber = metadata?.summaryNumber ?? 0;
517
- // Enabling the IdCompressor is a one-way operation and we only want to
518
- // allow new containers to turn it on
519
- this.idCompressorEnabled = metadata?.idCompressorEnabled ?? false;
520
568
  }
521
569
  else {
522
570
  this.createContainerMetadata = {
523
- createContainerRuntimeVersion: packageVersion_1.pkgVersion,
571
+ createContainerRuntimeVersion: packageVersion_js_1.pkgVersion,
524
572
  createContainerTimestamp: Date.now(),
525
573
  };
526
574
  loadSummaryNumber = 0;
527
- this.idCompressorEnabled =
528
- this.mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled") ??
529
- idCompressor !== undefined;
530
575
  }
531
576
  this.nextSummaryNumber = loadSummaryNumber + 1;
532
577
  this.messageAtLastSummary = metadata?.message;
@@ -537,21 +582,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
537
582
  eventName: "GCFeatureMatrix",
538
583
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
539
584
  inputs: JSON.stringify({
540
- gcOptions_gcGeneration: this.runtimeOptions.gcOptions[gc_1.gcGenerationOptionName],
585
+ gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_2.gcGenerationOptionName],
541
586
  }),
542
587
  });
543
588
  this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
544
589
  this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
545
590
  const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
546
- const opGroupingManager = new opLifecycle_1.OpGroupingManager({
591
+ const opGroupingManager = new index_js_3.OpGroupingManager({
547
592
  groupedBatchingEnabled: this.groupedBatchingEnabled,
548
593
  opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
549
594
  reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
550
595
  true,
551
596
  }, this.mc.logger);
552
- const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
553
- this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor(this.mc.logger), opGroupingManager);
554
- this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
597
+ const opSplitter = new index_js_3.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
598
+ this.remoteMessageProcessor = new index_js_3.RemoteMessageProcessor(opSplitter, new index_js_3.OpDecompressor(this.mc.logger), opGroupingManager);
599
+ this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
555
600
  if (this.summaryConfiguration.state === "enabled") {
556
601
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
557
602
  }
@@ -561,12 +606,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
561
606
  // Allow for a break-glass config to override the options
562
607
  disableOpReentryCheck !== true;
563
608
  this.summariesDisabled = this.isSummariesDisabled();
564
- this.heuristicsDisabled = this.isHeuristicsDisabled();
565
609
  this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
566
610
  this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
567
- if (this.idCompressorEnabled) {
568
- this.idCompressor = idCompressor;
569
- }
570
611
  this.maxConsecutiveReconnects =
571
612
  this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
572
613
  this.defaultMaxConsecutiveReconnects;
@@ -590,7 +631,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
590
631
  throw new telemetry_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
591
632
  }
592
633
  }
593
- this.garbageCollector = gc_1.GarbageCollector.create({
634
+ this.garbageCollector = index_js_2.GarbageCollector.create({
594
635
  runtime: this,
595
636
  gcOptions: this.runtimeOptions.gcOptions,
596
637
  baseSnapshot,
@@ -603,9 +644,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
603
644
  getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
604
645
  readAndParseBlob: async (id) => (0, driver_utils_1.readAndParse)(this.storage, id),
605
646
  submitMessage: (message) => this.submit(message),
647
+ sessionExpiryTimerStarted: pendingRuntimeState?.sessionExpiryTimerStarted,
606
648
  });
607
649
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
608
- this.summarizerNode = (0, summary_1.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
650
+ this.summarizerNode = (0, index_js_1.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
609
651
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
610
652
  async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
611
653
  // Latest change sequence number, no changes since summary applied yet
@@ -625,24 +667,37 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
625
667
  if (baseSnapshot) {
626
668
  this.summarizerNode.updateBaseSummaryState(baseSnapshot);
627
669
  }
628
- this.dataStores = new dataStores_1.DataStores((0, dataStores_1.getSummaryForDatastores)(baseSnapshot, metadata), this, (attachMsg) => this.submit({ type: messageTypes_1.ContainerMessageType.Attach, contents: attachMsg }), (id, createParam) => (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap));
629
- this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
670
+ const parentContext = (0, channelCollection_js_1.wrapContext)(this);
671
+ // Due to a mismatch between different layers in terms of
672
+ // what is the interface of passing signals, we need the
673
+ // downstream stores to wrap the signal.
674
+ parentContext.submitSignal = (type, content, targetClientId) => {
675
+ const envelope1 = content;
676
+ const envelope2 = this.createNewSignalEnvelope(envelope1.address, type, envelope1.contents);
677
+ return this.submitSignalFn(envelope2, targetClientId);
678
+ };
679
+ this.channelCollection = new channelCollection_js_1.ChannelCollection((0, channelCollection_js_1.getSummaryForDatastores)(baseSnapshot, metadata), parentContext, this.mc.logger, (path, reason, timestampMs, packagePath, request, headerData) => this.garbageCollector.nodeUpdated(path, reason, timestampMs, packagePath, request, headerData), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap), async (runtime) => provideEntryPoint);
680
+ this.blobManager = new blobManager_js_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
630
681
  if (!this.disposed) {
631
- this.submit({ type: messageTypes_1.ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
682
+ this.submit({ type: messageTypes_js_1.ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
632
683
  localId,
633
684
  blobId,
634
685
  });
635
686
  }
636
687
  }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState?.pendingAttachmentBlobs, (error) => this.closeFn(error));
637
- this.scheduleManager = new scheduleManager_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
638
- this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
688
+ this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
689
+ this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
639
690
  applyStashedOp: this.applyStashedOp.bind(this),
640
691
  clientId: () => this.clientId,
641
692
  close: this.closeFn,
642
693
  connected: () => this.connected,
643
- reSubmit: this.reSubmit.bind(this),
694
+ reSubmit: (message) => {
695
+ this.reSubmit(message);
696
+ this.flush();
697
+ },
644
698
  reSubmitBatch: this.reSubmitBatch.bind(this),
645
699
  isActiveConnection: () => this.innerDeltaManager.active,
700
+ isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
646
701
  }, pendingRuntimeState?.pending, this.logger);
647
702
  const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
648
703
  const compressionOptions = disableCompression === true
@@ -653,12 +708,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
653
708
  : runtimeOptions.compressionOptions;
654
709
  const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
655
710
  const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
656
- this.outbox = new opLifecycle_1.Outbox({
711
+ this.outbox = new index_js_3.Outbox({
657
712
  shouldSend: () => this.canSendOps(),
658
713
  pendingStateManager: this.pendingStateManager,
659
714
  submitBatchFn: this.submitBatchFn,
660
715
  legacySendBatchFn,
661
- compressor: new opLifecycle_1.OpCompressor(this.mc.logger),
716
+ compressor: new index_js_3.OpCompressor(this.mc.logger),
662
717
  splitter: opSplitter,
663
718
  config: {
664
719
  compressionOptions,
@@ -685,7 +740,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
685
740
  this.closeSummarizerDelayMs = closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
686
741
  this.validateSummaryBeforeUpload =
687
742
  this.mc.config.getBoolean("Fluid.Summarizer.ValidateSummaryBeforeUpload") ?? false;
688
- this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
743
+ this.summaryCollection = new index_js_1.SummaryCollection(this.deltaManager, this.logger);
689
744
  this.dirtyContainer =
690
745
  this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
691
746
  context.updateDirtyContainerState(this.dirtyContainer);
@@ -697,16 +752,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
697
752
  logger: this.logger,
698
753
  namespace: "OrderedClientElection",
699
754
  });
700
- const orderedClientCollection = new summary_1.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
701
- const orderedClientElectionForSummarizer = new summary_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, summary_1.SummarizerClientElection.isClientEligible);
702
- this.summarizerClientElection = new summary_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
755
+ const orderedClientCollection = new index_js_1.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
756
+ const orderedClientElectionForSummarizer = new index_js_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_1.SummarizerClientElection.isClientEligible);
757
+ this.summarizerClientElection = new index_js_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
703
758
  if (this.isSummarizerClient) {
704
- this._summarizer = new summary_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => summary_1.RunWhileConnectedCoordinator.create(runtime,
759
+ this._summarizer = new index_js_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_1.RunWhileConnectedCoordinator.create(runtime,
705
760
  // Summarization runs in summarizer client and needs access to the real (non-proxy) active
706
761
  // information. The proxy delta manager would always return false for summarizer client.
707
762
  () => this.innerDeltaManager.active));
708
763
  }
709
- else if (summary_1.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
764
+ else if (index_js_1.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
710
765
  // Only create a SummaryManager and SummarizerClientElection
711
766
  // if summaries are enabled and we are not the summarizer client.
712
767
  const defaultAction = () => {
@@ -728,13 +783,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
728
783
  };
729
784
  this.summaryCollection.on("default", defaultAction);
730
785
  // Create the SummaryManager and mark the initial state
731
- this.summaryManager = new summary_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
732
- this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_1.Throttler(60 * 1000, // 60 sec delay window
786
+ this.summaryManager = new index_js_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
787
+ this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
733
788
  30 * 1000, // 30 sec max delay
734
789
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
735
- (0, throttler_1.formExponentialFn)({ coefficient: 20, initialDelay: 0 })), {
790
+ (0, throttler_js_1.formExponentialFn)({ coefficient: 20, initialDelay: 0 })), {
736
791
  initialDelayMs: this.initialSummarizerDelayMs,
737
- }, this.heuristicsDisabled);
792
+ });
738
793
  this.summaryManager.on("summarize", (eventProps) => {
739
794
  this.emit("summarize", eventProps);
740
795
  });
@@ -749,26 +804,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
749
804
  this.mc.logger.sendTelemetryEvent({
750
805
  eventName: "ContainerLoadStats",
751
806
  ...this.createContainerMetadata,
752
- ...this.dataStores.containerLoadStats,
807
+ ...this.channelCollection.containerLoadStats,
753
808
  summaryNumber: loadSummaryNumber,
754
809
  summaryFormatVersion: metadata?.summaryFormatVersion,
755
810
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
756
811
  gcVersion: metadata?.gcFeature,
757
812
  options: JSON.stringify(runtimeOptions),
813
+ idCompressorModeMetadata: metadata?.idCompressorMode,
814
+ idCompressorMode: this.idCompressorMode,
758
815
  featureGates: JSON.stringify({
759
816
  disableCompression,
760
817
  disableOpReentryCheck,
761
818
  disableChunking,
762
819
  disableAttachReorder: this.disableAttachReorder,
763
820
  disablePartialFlush,
764
- idCompressorEnabled: this.idCompressorEnabled,
765
821
  closeSummarizerDelayOverride,
766
822
  }),
767
823
  telemetryDocumentId: this.telemetryDocumentId,
768
824
  groupedBatchingEnabled: this.groupedBatchingEnabled,
769
825
  });
770
- (0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this.logger);
771
- (0, batchTracker_1.BindBatchTracker)(this, this.logger);
826
+ (0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this, this.logger);
827
+ (0, batchTracker_js_1.BindBatchTracker)(this, this.logger);
772
828
  this.entryPoint = new core_utils_1.LazyPromise(async () => {
773
829
  if (this.isSummarizerClient) {
774
830
  (0, core_utils_1.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
@@ -776,11 +832,33 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
776
832
  }
777
833
  return provideEntryPoint(this);
778
834
  });
835
+ // If we loaded from pending state, then we need to skip any ops that are already accounted in such
836
+ // saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
837
+ this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
838
+ }
839
+ getCreateChildSummarizerNodeFn(id, createParam) {
840
+ return (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn);
841
+ }
842
+ deleteChildSummarizerNode(id) {
843
+ return this.summarizerNode.deleteChild(id);
844
+ }
845
+ /* IFluidParentContext APIs that should not be called on Root */
846
+ makeLocallyVisible() {
847
+ (0, core_utils_1.assert)(false, 0x8eb /* should not be called */);
848
+ }
849
+ setChannelDirty(address) {
850
+ (0, core_utils_1.assert)(false, 0x909 /* should not be called */);
779
851
  }
780
852
  /**
781
853
  * Initializes the state from the base snapshot this container runtime loaded from.
782
854
  */
783
855
  async initializeBaseState() {
856
+ if (this.idCompressorMode === "on" ||
857
+ (this.idCompressorMode === "delayed" && this.connected)) {
858
+ // This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
859
+ (0, core_utils_1.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
860
+ this._idCompressor = await this.createIdCompressor();
861
+ }
784
862
  await this.garbageCollector.initializeBaseState();
785
863
  }
786
864
  dispose(error) {
@@ -799,11 +877,110 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
799
877
  }
800
878
  this.garbageCollector.dispose();
801
879
  this._summarizer?.dispose();
802
- this.dataStores.dispose();
880
+ this.channelCollection.dispose();
803
881
  this.pendingStateManager.dispose();
804
882
  this.emit("dispose");
805
883
  this.removeAllListeners();
806
884
  }
885
+ /**
886
+ * Api to fetch the snapshot from the service for a loadingGroupIds.
887
+ * @param loadingGroupIds - LoadingGroupId for which the snapshot is asked for.
888
+ * @param pathParts - Parts of the path, which we want to extract from the snapshot tree.
889
+ * @returns - snapshotTree and the sequence number of the snapshot.
890
+ */
891
+ async getSnapshotForLoadingGroupId(loadingGroupIds, pathParts) {
892
+ const sortedLoadingGroupIds = loadingGroupIds.sort();
893
+ (0, core_utils_1.assert)(this.storage.getSnapshot !== undefined, 0x8ed /* getSnapshot api should be defined if used */);
894
+ let loadedFromCache = true;
895
+ // Lookup up in the cache, if not present then make the network call as multiple datastores could
896
+ // be in same loading group. So, once we have fetched the snapshot for that loading group on
897
+ // any request, then cache that as same group could be requested in future too.
898
+ const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(), async () => {
899
+ (0, core_utils_1.assert)(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
900
+ loadedFromCache = false;
901
+ return this.storage.getSnapshot({
902
+ cacheSnapshot: false,
903
+ scenarioName: "snapshotForLoadingGroupId",
904
+ loadingGroupIds: sortedLoadingGroupIds,
905
+ });
906
+ });
907
+ this.logger.sendTelemetryEvent({
908
+ eventName: "GroupIdSnapshotFetched",
909
+ details: JSON.stringify({
910
+ fromCache: loadedFromCache,
911
+ loadingGroupIds: loadingGroupIds.join(","),
912
+ }),
913
+ });
914
+ // Find the snapshotTree inside the returned snapshot based on the path as given in the request.
915
+ const hasIsolatedChannels = (0, index_js_1.rootHasIsolatedChannels)(this.metadata);
916
+ const snapshotTreeForPath = this.getSnapshotTreeForPath(snapshot.snapshotTree, pathParts, hasIsolatedChannels);
917
+ (0, core_utils_1.assert)(snapshotTreeForPath !== undefined, 0x8ef /* no snapshotTree for the path */);
918
+ const snapshotSeqNumber = snapshot.sequenceNumber;
919
+ (0, core_utils_1.assert)(snapshotSeqNumber !== undefined, 0x8f0 /* snapshotSeqNumber should be present */);
920
+ // This assert fires if we get a snapshot older than the snapshot we loaded from. This is a service issue.
921
+ // Snapshots should only move forward. If we observe an older snapshot than the one we loaded from, then likely
922
+ // the file has been overwritten or service lost data.
923
+ if (snapshotSeqNumber < this.deltaManager.initialSequenceNumber) {
924
+ throw telemetry_utils_1.DataProcessingError.create("Downloaded snapshot older than snapshot we loaded from", "getSnapshotForLoadingGroupId", undefined, {
925
+ loadingGroupIds: sortedLoadingGroupIds.join(","),
926
+ snapshotSeqNumber,
927
+ initialSequenceNumber: this.deltaManager.initialSequenceNumber,
928
+ });
929
+ }
930
+ // If the snapshot is ahead of the last seq number of the delta manager, then catch up before
931
+ // returning the snapshot.
932
+ if (snapshotSeqNumber > this.deltaManager.lastSequenceNumber) {
933
+ // If this is a summarizer client, which is trying to load a group and it finds that there is
934
+ // another snapshot from which the summarizer loaded and it is behind, then just give up as
935
+ // the summarizer state is not up to date.
936
+ // This should be a recoverable scenario and shouldn't happen as we should process the ack first.
937
+ if (this.isSummarizerClient) {
938
+ throw new Error("Summarizer client behind, loaded newer snapshot with loadingGroupId");
939
+ }
940
+ // We want to catchup from sequenceNumber to targetSequenceNumber
941
+ const props = {
942
+ eventName: "GroupIdSnapshotCatchup",
943
+ loadingGroupIds: sortedLoadingGroupIds.join(","),
944
+ targetSequenceNumber: snapshotSeqNumber,
945
+ sequenceNumber: this.deltaManager.lastSequenceNumber, // This is so we reuse some columns in telemetry
946
+ };
947
+ const event = telemetry_utils_1.PerformanceEvent.start(this.mc.logger, {
948
+ ...props,
949
+ });
950
+ // If the inbound deltas queue is paused or disconnected, we expect a reconnect and unpause
951
+ // as long as it's not a summarizer client.
952
+ if (this.deltaManager.inbound.paused) {
953
+ props.inboundPaused = this.deltaManager.inbound.paused; // reusing telemetry
954
+ }
955
+ const defP = new core_utils_1.Deferred();
956
+ this.deltaManager.on("op", (message) => {
957
+ if (message.sequenceNumber >= snapshotSeqNumber) {
958
+ defP.resolve(true);
959
+ }
960
+ });
961
+ await defP.promise;
962
+ event.end(props);
963
+ }
964
+ return { snapshotTree: snapshotTreeForPath, sequenceNumber: snapshotSeqNumber };
965
+ }
966
+ /**
967
+ * Api to find a snapshot tree inside a bigger snapshot tree based on the path in the pathParts array.
968
+ * @param snapshotTree - snapshot tree to look into.
969
+ * @param pathParts - Part of the path, which we want to extract from the snapshot tree.
970
+ * @param hasIsolatedChannels - whether the channels are present inside ".channels" subtree. Older
971
+ * snapshots will not have trees inside ".channels", so check that.
972
+ * @returns - requested snapshot tree based on the path parts.
973
+ */
974
+ getSnapshotTreeForPath(snapshotTree, pathParts, hasIsolatedChannels) {
975
+ let childTree = snapshotTree;
976
+ for (const part of pathParts) {
977
+ if (hasIsolatedChannels) {
978
+ childTree = childTree?.trees[runtime_definitions_1.channelsTreeName];
979
+ }
980
+ childTree = childTree?.trees[part];
981
+ }
982
+ return childTree;
983
+ }
807
984
  /**
808
985
  * Notifies this object about the request made to the container.
809
986
  * @param request - Request made to the handler.
@@ -846,7 +1023,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
846
1023
  // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
847
1024
  return this.resolveHandle(requestParser.createSubRequest(1));
848
1025
  }
849
- if (id === blobManager_1.BlobManager.basePath && requestParser.isLeaf(2)) {
1026
+ if (id === blobManager_js_1.BlobManager.basePath && requestParser.isLeaf(2)) {
850
1027
  const blob = await this.blobManager.getBlob(requestParser.pathParts[1]);
851
1028
  return blob
852
1029
  ? {
@@ -857,15 +1034,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
857
1034
  : (0, runtime_utils_1.create404Response)(request);
858
1035
  }
859
1036
  else if (requestParser.pathParts.length > 0) {
860
- // Differentiate between requesting the dataStore directly, or one of its children
861
- const requestForChild = !requestParser.isLeaf(1);
862
- const dataStore = await this.getDataStoreFromRequest(id, request, requestForChild);
863
- const subRequest = requestParser.createSubRequest(1);
864
- // We always expect createSubRequest to include a leading slash, but asserting here to protect against
865
- // unintentionally modifying the url if that changes.
866
- (0, core_utils_1.assert)(subRequest.url.startsWith("/"), 0x126 /* "Expected createSubRequest url to include a leading slash" */);
867
- // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
868
- return dataStore.request(subRequest);
1037
+ return await this.channelCollection.request(request);
869
1038
  }
870
1039
  return (0, runtime_utils_1.create404Response)(request);
871
1040
  }
@@ -880,38 +1049,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
880
1049
  return this.entryPoint;
881
1050
  }
882
1051
  internalId(maybeAlias) {
883
- return this.dataStores.aliases.get(maybeAlias) ?? maybeAlias;
884
- }
885
- async getDataStoreFromRequest(id, request, requestForChild) {
886
- const headerData = {};
887
- if (typeof request.headers?.[RuntimeHeaders.wait] === "boolean") {
888
- headerData.wait = request.headers[RuntimeHeaders.wait];
889
- }
890
- if (typeof request.headers?.[RuntimeHeaders.viaHandle] === "boolean") {
891
- headerData.viaHandle = request.headers[RuntimeHeaders.viaHandle];
892
- }
893
- if (typeof request.headers?.[exports.AllowTombstoneRequestHeaderKey] === "boolean") {
894
- headerData.allowTombstone = request.headers[exports.AllowTombstoneRequestHeaderKey];
895
- }
896
- if (typeof request.headers?.[exports.AllowInactiveRequestHeaderKey] === "boolean") {
897
- headerData.allowInactive = request.headers[exports.AllowInactiveRequestHeaderKey];
898
- }
899
- // We allow Tombstone requests for sub-DataStore objects
900
- if (requestForChild) {
901
- headerData.allowTombstone = true;
902
- }
903
- await this.dataStores.waitIfPendingAlias(id);
904
- const internalId = this.internalId(id);
905
- const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
906
- // Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
907
- // the same as GC nodes id.
908
- const urlWithoutQuery = (0, gc_1.trimLeadingAndTrailingSlashes)(request.url.split("?")[0]);
909
- // Get the initial snapshot details which contain the data store package path.
910
- const details = await dataStoreContext.getInitialSnapshotDetails();
911
- // Note that this will throw if the data store is inactive or tombstoned and throwing on incorrect usage
912
- // is configured.
913
- this.garbageCollector.nodeUpdated(`/${urlWithoutQuery}`, "Loaded", undefined /* timestampMs */, details.pkg, request, headerData);
914
- return dataStoreContext.realize();
1052
+ return this.channelCollection.internalId(maybeAlias);
915
1053
  }
916
1054
  /** Adds the container's metadata to the given summary tree. */
917
1055
  addMetadataToSummary(summaryTree) {
@@ -923,37 +1061,36 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
923
1061
  ...this.garbageCollector.getMetadata(),
924
1062
  // The last message processed at the time of summary. If there are no new messages, use the message from the
925
1063
  // last summary.
926
- message: (0, summary_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
1064
+ message: (0, index_js_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
927
1065
  this.messageAtLastSummary,
928
1066
  telemetryDocumentId: this.telemetryDocumentId,
929
- idCompressorEnabled: this.idCompressorEnabled ? true : undefined,
1067
+ idCompressorMode: this.idCompressorMode,
930
1068
  };
931
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.metadataBlobName, JSON.stringify(metadata));
1069
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.metadataBlobName, JSON.stringify(metadata));
932
1070
  }
933
1071
  addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
934
1072
  this.addMetadataToSummary(summaryTree);
935
- if (this.idCompressorEnabled) {
936
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67a /* IdCompressor should be defined if enabled */);
937
- const idCompressorState = JSON.stringify(this.idCompressor.serialize(false));
938
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.idCompressorBlobName, idCompressorState);
1073
+ if (this._idCompressor) {
1074
+ const idCompressorState = JSON.stringify(this._idCompressor.serialize(false));
1075
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.idCompressorBlobName, idCompressorState);
939
1076
  }
940
1077
  if (this.remoteMessageProcessor.partialMessages.size > 0) {
941
1078
  const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
942
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.chunksBlobName, content);
1079
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.chunksBlobName, content);
943
1080
  }
944
- const dataStoreAliases = this.dataStores.aliases;
1081
+ const dataStoreAliases = this.channelCollection.aliases;
945
1082
  if (dataStoreAliases.size > 0) {
946
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
1083
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
947
1084
  }
948
1085
  if (this.summarizerClientElection) {
949
1086
  const electedSummarizerContent = JSON.stringify(this.summarizerClientElection?.serialize());
950
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.electedSummarizerBlobName, electedSummarizerContent);
1087
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.electedSummarizerBlobName, electedSummarizerContent);
951
1088
  }
952
1089
  const blobManagerSummary = this.blobManager.summarize();
953
1090
  // Some storage (like git) doesn't allow empty tree, so we can omit it.
954
1091
  // and the blob manager can handle the tree not existing when loading
955
1092
  if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
956
- (0, runtime_utils_1.addTreeToSummary)(summaryTree, summary_1.blobsTreeName, blobManagerSummary);
1093
+ (0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, index_js_1.blobsTreeName, blobManagerSummary);
957
1094
  }
958
1095
  const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
959
1096
  if (gcSummary !== undefined) {
@@ -988,14 +1125,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
988
1125
  }
989
1126
  return this.consecutiveReconnects < this.maxConsecutiveReconnects;
990
1127
  }
991
- resetReconnectCount(message) {
992
- // Chunked ops don't count towards making progress as they are sent
993
- // in their own batches before the originating batch is sent.
994
- // Therefore, receiving them while attempting to send the originating batch
995
- // does not mean that the container is making any progress.
996
- if (message?.type !== messageTypes_1.ContainerMessageType.ChunkedOp) {
997
- this.consecutiveReconnects = 0;
998
- }
1128
+ resetReconnectCount() {
1129
+ this.consecutiveReconnects = 0;
999
1130
  }
1000
1131
  replayPendingStates() {
1001
1132
  // We need to be able to send ops to replay states
@@ -1039,21 +1170,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1039
1170
  // Need to parse from string for back-compat
1040
1171
  const opContents = this.parseLocalOpContent(serializedOpContent);
1041
1172
  switch (opContents.type) {
1042
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
1043
- return this.dataStores.applyStashedOp(opContents.contents);
1044
- case messageTypes_1.ContainerMessageType.Attach:
1045
- return this.dataStores.applyStashedAttachOp(opContents.contents);
1046
- case messageTypes_1.ContainerMessageType.IdAllocation:
1047
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67b /* IdCompressor should be defined if enabled */);
1173
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
1174
+ case messageTypes_js_1.ContainerMessageType.Attach:
1175
+ case messageTypes_js_1.ContainerMessageType.Alias:
1176
+ return this.channelCollection.applyStashedOp(opContents);
1177
+ case messageTypes_js_1.ContainerMessageType.IdAllocation:
1178
+ (0, core_utils_1.assert)(this.idCompressorMode !== "off", 0x8f1 /* ID compressor should be in use */);
1048
1179
  return;
1049
- case messageTypes_1.ContainerMessageType.Alias:
1050
- case messageTypes_1.ContainerMessageType.BlobAttach:
1180
+ case messageTypes_js_1.ContainerMessageType.BlobAttach:
1051
1181
  return;
1052
- case messageTypes_1.ContainerMessageType.ChunkedOp:
1182
+ case messageTypes_js_1.ContainerMessageType.ChunkedOp:
1053
1183
  throw new Error("chunkedOp not expected here");
1054
- case messageTypes_1.ContainerMessageType.Rejoin:
1184
+ case messageTypes_js_1.ContainerMessageType.Rejoin:
1055
1185
  throw new Error("rejoin not expected here");
1056
- case messageTypes_1.ContainerMessageType.GC:
1186
+ case messageTypes_js_1.ContainerMessageType.GC:
1057
1187
  // GC op is only sent in summarizer which should never have stashed ops.
1058
1188
  throw new telemetry_utils_1.LoggingError("GC op not expected to be stashed in summarizer");
1059
1189
  default: {
@@ -1077,6 +1207,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1077
1207
  }
1078
1208
  }
1079
1209
  setConnectionState(connected, clientId) {
1210
+ if (connected && this.idCompressorMode === "delayed" && !this.compressorLoadInitiated) {
1211
+ this.compressorLoadInitiated = true;
1212
+ this.createIdCompressor()
1213
+ .then((compressor) => {
1214
+ this._idCompressor = compressor;
1215
+ for (const range of this.pendingIdCompressorOps) {
1216
+ this._idCompressor.finalizeCreationRange(range);
1217
+ }
1218
+ this.pendingIdCompressorOps = [];
1219
+ })
1220
+ .catch((error) => {
1221
+ this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
1222
+ });
1223
+ }
1080
1224
  if (connected === false && this.delayConnectClientId !== undefined) {
1081
1225
  this.delayConnectClientId = undefined;
1082
1226
  this.mc.logger.sendTelemetryEvent({
@@ -1140,7 +1284,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1140
1284
  if (changeOfState) {
1141
1285
  this.replayPendingStates();
1142
1286
  }
1143
- this.dataStores.setConnectionState(connected, clientId);
1287
+ this.channelCollection.setConnectionState(connected, clientId);
1144
1288
  this.garbageCollector.setConnectionState(connected, clientId);
1145
1289
  (0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
1146
1290
  }
@@ -1187,10 +1331,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1187
1331
  this.scheduleManager.beforeOpProcessing(message);
1188
1332
  this._processedClientSequenceNumber = message.clientSequenceNumber;
1189
1333
  try {
1334
+ // See commit that added this assert for more details.
1335
+ // These calls should be made for all but chunked ops:
1336
+ // 1) this.pendingStateManager.processPendingLocalMessage() below
1337
+ // 2) this.resetReconnectCount() below
1338
+ (0, core_utils_1.assert)(message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp, "we should never get here with chunked ops");
1190
1339
  let localOpMetadata;
1191
- if (local &&
1192
- messageWithContext.modernRuntimeMessage &&
1193
- message.type !== messageTypes_1.ContainerMessageType.ChunkedOp) {
1340
+ if (local && messageWithContext.modernRuntimeMessage) {
1194
1341
  localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
1195
1342
  }
1196
1343
  // If there are no more pending messages after processing a local message,
@@ -1205,7 +1352,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1205
1352
  // If we have processed a local op, this means that the container is
1206
1353
  // making progress and we can reset the counter for how many times
1207
1354
  // we have consecutively replayed the pending states
1208
- this.resetReconnectCount(message);
1355
+ this.resetReconnectCount();
1209
1356
  }
1210
1357
  }
1211
1358
  catch (e) {
@@ -1222,31 +1369,39 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1222
1369
  // TODO: destructure message and modernRuntimeMessage once using typescript 5.2.2+
1223
1370
  const { local } = messageWithContext;
1224
1371
  switch (messageWithContext.message.type) {
1225
- case messageTypes_1.ContainerMessageType.Attach:
1226
- this.dataStores.processAttachMessage(messageWithContext.message, local);
1227
- break;
1228
- case messageTypes_1.ContainerMessageType.Alias:
1229
- this.dataStores.processAliasMessage(messageWithContext.message, localOpMetadata, local);
1372
+ case messageTypes_js_1.ContainerMessageType.Attach:
1373
+ case messageTypes_js_1.ContainerMessageType.Alias:
1374
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
1375
+ this.channelCollection.process(messageWithContext.message, local, localOpMetadata, (from, to) => this.garbageCollector.addedOutboundReference(from, to));
1230
1376
  break;
1231
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
1232
- this.dataStores.processFluidDataStoreOp(messageWithContext.message, local, localOpMetadata, (from, to) => this.garbageCollector.addedOutboundReference(from, to));
1233
- break;
1234
- case messageTypes_1.ContainerMessageType.BlobAttach:
1377
+ case messageTypes_js_1.ContainerMessageType.BlobAttach:
1235
1378
  this.blobManager.processBlobAttachOp(messageWithContext.message, local);
1236
1379
  break;
1237
- case messageTypes_1.ContainerMessageType.IdAllocation:
1238
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67c /* IdCompressor should be defined if enabled */);
1380
+ case messageTypes_js_1.ContainerMessageType.IdAllocation:
1239
1381
  // Don't re-finalize the range if we're processing a "savedOp" in
1240
1382
  // stashed ops flow. The compressor is stashed with these ops already processed.
1241
- if (messageWithContext.message.metadata?.savedOp !== true) {
1242
- this.idCompressor.finalizeCreationRange(messageWithContext.message.contents);
1383
+ // That said, in idCompressorMode === "delayed", we might not serialize ID compressor, and
1384
+ // thus we need to process all the ops.
1385
+ if (!(this.skipSavedCompressorOps &&
1386
+ messageWithContext.message.metadata?.savedOp ===
1387
+ true)) {
1388
+ const range = messageWithContext.message.contents;
1389
+ if (this._idCompressor === undefined) {
1390
+ this.pendingIdCompressorOps.push(range);
1391
+ }
1392
+ else {
1393
+ this._idCompressor.finalizeCreationRange(range);
1394
+ }
1243
1395
  }
1244
1396
  break;
1245
- case messageTypes_1.ContainerMessageType.GC:
1397
+ case messageTypes_js_1.ContainerMessageType.GC:
1246
1398
  this.garbageCollector.processMessage(messageWithContext.message, local);
1247
1399
  break;
1248
- case messageTypes_1.ContainerMessageType.ChunkedOp:
1249
- case messageTypes_1.ContainerMessageType.Rejoin:
1400
+ case messageTypes_js_1.ContainerMessageType.ChunkedOp:
1401
+ // From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
1402
+ // Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
1403
+ (0, core_utils_1.assert)(false, "should not even get here");
1404
+ case messageTypes_js_1.ContainerMessageType.Rejoin:
1250
1405
  break;
1251
1406
  default: {
1252
1407
  // If we didn't necessarily expect a runtime message type, then no worries - just return
@@ -1326,7 +1481,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1326
1481
  this.emit("signal", transformed, local);
1327
1482
  return;
1328
1483
  }
1329
- this.dataStores.processSignal(envelope.address, transformed, local);
1484
+ // Due to a mismatch between different layers in terms of
1485
+ // what is the interface of passing signals, we need to adjust
1486
+ // the signal envelope before sending it to the datastores to be processed
1487
+ const envelope2 = {
1488
+ address: envelope.address,
1489
+ contents: transformed.content,
1490
+ };
1491
+ transformed.content = envelope2;
1492
+ this.channelCollection.processSignal(transformed, local);
1330
1493
  }
1331
1494
  /**
1332
1495
  * Flush the pending ops manually.
@@ -1390,9 +1553,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1390
1553
  * Returns undefined if no data store has been assigned the given alias.
1391
1554
  */
1392
1555
  async getAliasedDataStoreEntryPoint(alias) {
1393
- await this.dataStores.waitIfPendingAlias(alias);
1556
+ // Back-comapatibility:
1557
+ // There are old files that were created without using data store aliasing feature, but
1558
+ // used createRoot*DataStore*() (already removed) API. Such data stores will have isRoot = true,
1559
+ // and internalID provided by user. The expectation is that such files behave as new files, where
1560
+ // same data store instances created using aliasing feature.
1561
+ // Please also see note on name collisions in DataStores.createDataStoreId()
1562
+ await this.channelCollection.waitIfPendingAlias(alias);
1394
1563
  const internalId = this.internalId(alias);
1395
- const context = await this.dataStores.getDataStoreIfAvailable(internalId, { wait: false });
1564
+ const context = await this.channelCollection.getDataStoreIfAvailable(internalId, {
1565
+ wait: false,
1566
+ });
1396
1567
  // If the data store is not available or not an alias, return undefined.
1397
1568
  if (context === undefined || !(await context.isRoot())) {
1398
1569
  return undefined;
@@ -1404,28 +1575,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1404
1575
  this.garbageCollector.nodeUpdated(`/${internalId}`, "Loaded", undefined /* timestampMs */, context.packagePath);
1405
1576
  return channel.entryPoint;
1406
1577
  }
1407
- createDetachedRootDataStore(pkg, rootDataStoreId) {
1408
- if (rootDataStoreId.includes("/")) {
1409
- throw new telemetry_utils_1.UsageError(`Id cannot contain slashes: '${rootDataStoreId}'`);
1410
- }
1411
- return this.dataStores.createDetachedDataStoreCore(pkg, true, rootDataStoreId);
1578
+ createDetachedDataStore(pkg, loadingGroupId) {
1579
+ return this.channelCollection.createDetachedDataStore(pkg, loadingGroupId);
1412
1580
  }
1413
- createDetachedDataStore(pkg, groupId) {
1414
- return this.dataStores.createDetachedDataStoreCore(pkg, false, undefined, groupId);
1415
- }
1416
- async createDataStore(pkg, groupId) {
1417
- const id = (0, uuid_1.v4)();
1418
- return (0, dataStore_1.channelToDataStore)(await this.dataStores
1419
- ._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, undefined, groupId)
1420
- .realize(), id, this, this.dataStores, this.mc.logger);
1581
+ async createDataStore(pkg, loadingGroupId) {
1582
+ const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], undefined, // props
1583
+ loadingGroupId);
1584
+ return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
1421
1585
  }
1422
1586
  /**
1423
1587
  * @deprecated 0.16 Issue #1537, #3631
1424
1588
  */
1425
- async _createDataStoreWithProps(pkg, props, id = (0, uuid_1.v4)()) {
1426
- return (0, dataStore_1.channelToDataStore)(await this.dataStores
1427
- ._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
1428
- .realize(), id, this, this.dataStores, this.mc.logger);
1589
+ async _createDataStoreWithProps(pkg, props) {
1590
+ const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
1591
+ return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
1429
1592
  }
1430
1593
  canSendOps() {
1431
1594
  // Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
@@ -1455,21 +1618,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1455
1618
  // Certain container runtime messages should not mark the container dirty such as the old built-in
1456
1619
  // AgentScheduler and Garbage collector messages.
1457
1620
  switch (type) {
1458
- case messageTypes_1.ContainerMessageType.Attach: {
1621
+ case messageTypes_js_1.ContainerMessageType.Attach: {
1459
1622
  const attachMessage = contents;
1460
1623
  if (attachMessage.id === exports.agentSchedulerId) {
1461
1624
  return false;
1462
1625
  }
1463
1626
  break;
1464
1627
  }
1465
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp: {
1628
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp: {
1466
1629
  const envelope = contents;
1467
1630
  if (envelope.address === exports.agentSchedulerId) {
1468
1631
  return false;
1469
1632
  }
1470
1633
  break;
1471
1634
  }
1472
- case messageTypes_1.ContainerMessageType.GC: {
1635
+ case messageTypes_js_1.ContainerMessageType.IdAllocation:
1636
+ case messageTypes_js_1.ContainerMessageType.GC: {
1473
1637
  return false;
1474
1638
  }
1475
1639
  default:
@@ -1503,16 +1667,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1503
1667
  const envelope = this.createNewSignalEnvelope(undefined /* address */, type, content);
1504
1668
  return this.submitSignalFn(envelope, targetClientId);
1505
1669
  }
1506
- /**
1507
- * Submits the signal to be sent to other clients.
1508
- * @param type - Type of the signal.
1509
- * @param content - Content of the signal.
1510
- * @param targetClientId - When specified, the signal is only sent to the provided client id.
1511
- */
1512
- submitDataStoreSignal(address, type, content, targetClientId) {
1513
- const envelope = this.createNewSignalEnvelope(address, type, content);
1514
- return this.submitSignalFn(envelope, targetClientId);
1515
- }
1516
1670
  setAttachState(attachState) {
1517
1671
  if (attachState === container_definitions_1.AttachState.Attaching) {
1518
1672
  (0, core_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attaching, 0x12d /* "Container Context should already be in attaching state" */);
@@ -1524,7 +1678,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1524
1678
  if (attachState === container_definitions_1.AttachState.Attached && !this.hasPendingMessages()) {
1525
1679
  this.updateDocumentDirtyState(false);
1526
1680
  }
1527
- this.dataStores.setAttachState(attachState);
1681
+ this.channelCollection.setAttachState(attachState);
1528
1682
  }
1529
1683
  /**
1530
1684
  * Create a summary. Used when attaching or serializing a detached container.
@@ -1539,20 +1693,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1539
1693
  this.blobManager.setRedirectTable(blobRedirectTable);
1540
1694
  }
1541
1695
  // We can finalize any allocated IDs since we're the only client
1542
- const idRange = this.idCompressor?.takeNextCreationRange();
1696
+ const idRange = this._idCompressor?.takeNextCreationRange();
1543
1697
  if (idRange !== undefined) {
1544
- this.idCompressor?.finalizeCreationRange(idRange);
1698
+ this._idCompressor?.finalizeCreationRange(idRange);
1545
1699
  }
1546
- const summarizeResult = this.dataStores.createSummary(telemetryContext);
1700
+ const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
1547
1701
  // Wrap data store summaries in .channels subtree.
1548
- (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1702
+ (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1549
1703
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
1550
1704
  return summarizeResult.summary;
1551
1705
  }
1552
1706
  async summarizeInternal(fullTree, trackState, telemetryContext) {
1553
- const summarizeResult = await this.dataStores.summarize(fullTree, trackState, telemetryContext);
1707
+ const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
1554
1708
  // Wrap data store summaries in .channels subtree.
1555
- (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1709
+ (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1556
1710
  const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
1557
1711
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
1558
1712
  return {
@@ -1598,10 +1752,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1598
1752
  * @see IGarbageCollectionRuntime.updateStateBeforeGC
1599
1753
  */
1600
1754
  async updateStateBeforeGC() {
1601
- return this.dataStores.updateStateBeforeGC();
1755
+ return this.channelCollection.updateStateBeforeGC();
1602
1756
  }
1603
1757
  async getGCDataInternal(fullGC) {
1604
- return this.dataStores.getGCData(fullGC);
1758
+ return this.channelCollection.getGCData(fullGC);
1605
1759
  }
1606
1760
  /**
1607
1761
  * Generates and returns the GC data for this container.
@@ -1627,22 +1781,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1627
1781
  // always referenced, so the used routes is only self-route (empty string).
1628
1782
  this.summarizerNode.updateUsedRoutes([""]);
1629
1783
  const { dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(usedRoutes);
1630
- this.dataStores.updateUsedRoutes(dataStoreRoutes);
1631
- }
1632
- /**
1633
- * This is called to update objects whose routes are unused.
1634
- * @param unusedRoutes - Data store and attachment blob routes that are unused in this Container.
1635
- */
1636
- updateUnusedRoutes(unusedRoutes) {
1637
- const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(unusedRoutes);
1638
- this.blobManager.updateUnusedRoutes(blobManagerRoutes);
1639
- this.dataStores.updateUnusedRoutes(dataStoreRoutes);
1640
- }
1641
- /**
1642
- * @deprecated Replaced by deleteSweepReadyNodes.
1643
- */
1644
- deleteUnusedNodes(unusedRoutes) {
1645
- throw new Error("deleteUnusedRoutes should not be called");
1784
+ this.channelCollection.updateUsedRoutes(dataStoreRoutes);
1646
1785
  }
1647
1786
  /**
1648
1787
  * After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
@@ -1651,7 +1790,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1651
1790
  */
1652
1791
  deleteSweepReadyNodes(sweepReadyRoutes) {
1653
1792
  const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
1654
- const deletedRoutes = this.dataStores.deleteSweepReadyNodes(dataStoreRoutes);
1793
+ const deletedRoutes = this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes);
1655
1794
  return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
1656
1795
  }
1657
1796
  /**
@@ -1665,7 +1804,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1665
1804
  updateTombstonedRoutes(tombstonedRoutes) {
1666
1805
  const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(tombstonedRoutes);
1667
1806
  this.blobManager.updateTombstonedRoutes(blobManagerRoutes);
1668
- this.dataStores.updateTombstonedRoutes(dataStoreRoutes);
1807
+ this.channelCollection.updateTombstonedRoutes(dataStoreRoutes);
1669
1808
  }
1670
1809
  /**
1671
1810
  * Returns a server generated referenced timestamp to be used to track unreferenced nodes by GC.
@@ -1681,9 +1820,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1681
1820
  */
1682
1821
  getNodeType(nodePath) {
1683
1822
  if (this.isBlobPath(nodePath)) {
1684
- return gc_1.GCNodeType.Blob;
1823
+ return index_js_2.GCNodeType.Blob;
1685
1824
  }
1686
- return this.dataStores.getGCNodeType(nodePath) ?? gc_1.GCNodeType.Other;
1825
+ return this.channelCollection.getGCNodeType(nodePath) ?? index_js_2.GCNodeType.Other;
1687
1826
  }
1688
1827
  /**
1689
1828
  * Called by GC to retrieve the package path of the node with the given path. The node should belong to a
@@ -1693,14 +1832,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1693
1832
  // GC uses "/" when adding "root" references, e.g. for Aliasing or as part of Tombstone Auto-Recovery.
1694
1833
  // These have no package path so return a special value.
1695
1834
  if (nodePath === "/") {
1696
- return ["<GCROOT>"];
1835
+ return ["_gcRoot"];
1697
1836
  }
1698
1837
  switch (this.getNodeType(nodePath)) {
1699
- case gc_1.GCNodeType.Blob:
1700
- return [blobManager_1.BlobManager.basePath];
1701
- case gc_1.GCNodeType.DataStore:
1702
- case gc_1.GCNodeType.SubDataStore:
1703
- return this.dataStores.getDataStorePackagePath(nodePath);
1838
+ case index_js_2.GCNodeType.Blob:
1839
+ return [blobManager_js_1.BlobManager.basePath];
1840
+ case index_js_2.GCNodeType.DataStore:
1841
+ case index_js_2.GCNodeType.SubDataStore:
1842
+ return this.channelCollection.getDataStorePackagePath(nodePath);
1704
1843
  default:
1705
1844
  (0, core_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
1706
1845
  }
@@ -1710,7 +1849,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1710
1849
  */
1711
1850
  isBlobPath(path) {
1712
1851
  const pathParts = path.split("/");
1713
- if (pathParts.length < 2 || pathParts[1] !== blobManager_1.BlobManager.basePath) {
1852
+ if (pathParts.length < 2 || pathParts[1] !== blobManager_js_1.BlobManager.basePath) {
1714
1853
  return false;
1715
1854
  }
1716
1855
  return true;
@@ -1759,7 +1898,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1759
1898
  * @param options - options controlling how the summary is generated or submitted
1760
1899
  */
1761
1900
  async submitSummary(options) {
1762
- const { fullTree = false, finalAttempt = false, refreshLatestAck, summaryLogger } = options;
1901
+ const { fullTree = false, finalAttempt = false, refreshLatestAck, summaryLogger, latestSummaryRefSeqNum, } = options;
1763
1902
  // The summary number for this summary. This will be updated during the summary process, so get it now and
1764
1903
  // use it for all events logged during this summary.
1765
1904
  const summaryNumber = this.nextSummaryNumber;
@@ -1812,6 +1951,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1812
1951
  }
1813
1952
  }
1814
1953
  const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
1954
+ const shouldValidatePreSummaryState = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.shouldValidatePreSummaryState") === true;
1815
1955
  let summaryRefSeqNum;
1816
1956
  try {
1817
1957
  await this.deltaManager.inbound.pause();
@@ -1822,7 +1962,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1822
1962
  const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
1823
1963
  const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
1824
1964
  const lastAck = this.summaryCollection.latestAck;
1825
- this.summarizerNode.startSummary(summaryRefSeqNum, summaryNumberLogger);
1965
+ const startSummaryResult = this.summarizerNode.startSummary(summaryRefSeqNum, summaryNumberLogger, latestSummaryRefSeqNum);
1966
+ if (startSummaryResult.invalidNodes > 0 ||
1967
+ startSummaryResult.mismatchNumbers.size > 0) {
1968
+ summaryLogger.sendErrorEvent({
1969
+ eventName: "LatestSummaryRefSeqNumMismatch",
1970
+ details: {
1971
+ ...startSummaryResult,
1972
+ mismatchNumbers: Array.from(startSummaryResult.mismatchNumbers),
1973
+ },
1974
+ });
1975
+ if (shouldValidatePreSummaryState && !finalAttempt) {
1976
+ return {
1977
+ stage: "base",
1978
+ referenceSequenceNumber: summaryRefSeqNum,
1979
+ minimumSequenceNumber,
1980
+ error: `Summarizer node state inconsistent with summarizer state.`,
1981
+ };
1982
+ }
1983
+ }
1826
1984
  // Helper function to check whether we should still continue between each async step.
1827
1985
  const checkContinue = () => {
1828
1986
  // Do not check for loss of connectivity directly! Instead leave it up to
@@ -1892,7 +2050,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1892
2050
  const validateResult = this.summarizerNode.validateSummary();
1893
2051
  if (!validateResult.success) {
1894
2052
  const { success, ...loggingProps } = validateResult;
1895
- const error = new summary_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
2053
+ const error = new index_js_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
1896
2054
  return {
1897
2055
  stage: "base",
1898
2056
  referenceSequenceNumber: summaryRefSeqNum,
@@ -1918,8 +2076,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1918
2076
  ? (0, runtime_utils_1.calculateStats)(summaryTree.tree[runtime_definitions_1.gcTreeKey])
1919
2077
  : undefined;
1920
2078
  const summaryStats = {
1921
- dataStoreCount: this.dataStores.size,
1922
- summarizedDataStoreCount: this.dataStores.size - handleCount,
2079
+ dataStoreCount: this.channelCollection.size,
2080
+ summarizedDataStoreCount: this.channelCollection.size - handleCount,
1923
2081
  gcStateUpdatedDataStoreCount: this.garbageCollector.updatedDSCountSinceLastSummary,
1924
2082
  gcBlobNodeCount: gcSummaryTreeStats?.blobNodeCount,
1925
2083
  gcTotalBlobsSize: gcSummaryTreeStats?.totalBlobSize,
@@ -2039,7 +2197,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2039
2197
  // based on telemetry while we decide on a stable number.
2040
2198
  const retryDelayMs = this.mc.config.getNumber("Fluid.Summarizer.PendingOpsRetryDelayMs") ??
2041
2199
  exports.defaultPendingOpsRetryDelayMs;
2042
- const error = new summary_1.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2200
+ const error = new index_js_1.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2043
2201
  count: this.pendingMessagesCount,
2044
2202
  beforeGenerate: beforeSummaryGeneration,
2045
2203
  });
@@ -2073,48 +2231,29 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2073
2231
  this.emit(dirty ? "dirty" : "saved");
2074
2232
  }
2075
2233
  }
2076
- submitDataStoreOp(id, contents, localOpMetadata = undefined) {
2077
- const envelope = {
2078
- address: id,
2079
- contents,
2080
- };
2081
- this.submit({ type: messageTypes_1.ContainerMessageType.FluidDataStoreOp, contents: envelope }, localOpMetadata);
2082
- }
2083
- submitDataStoreAliasOp(contents, localOpMetadata) {
2084
- const aliasMessage = contents;
2085
- if (!(0, dataStore_1.isDataStoreAliasMessage)(aliasMessage)) {
2086
- throw new telemetry_utils_1.UsageError("malformedDataStoreAliasMessage");
2087
- }
2088
- this.submit({ type: messageTypes_1.ContainerMessageType.Alias, contents }, localOpMetadata);
2234
+ submitMessage(type, contents, localOpMetadata = undefined) {
2235
+ this.submit({ type, contents }, localOpMetadata);
2089
2236
  }
2090
2237
  async uploadBlob(blob, signal) {
2091
2238
  this.verifyNotClosed();
2092
2239
  return this.blobManager.createBlob(blob, signal);
2093
2240
  }
2094
- maybeSubmitIdAllocationOp(type) {
2095
- if (type !== messageTypes_1.ContainerMessageType.IdAllocation) {
2096
- let idAllocationBatchMessage;
2097
- let idRange;
2098
- if (this.idCompressorEnabled) {
2099
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67d /* IdCompressor should be defined if enabled */);
2100
- idRange = this.idCompressor.takeNextCreationRange();
2101
- // Don't include the idRange if there weren't any Ids allocated
2102
- idRange = idRange?.ids !== undefined ? idRange : undefined;
2103
- }
2104
- if (idRange !== undefined) {
2241
+ submitIdAllocationOpIfNeeded() {
2242
+ if (this._idCompressor) {
2243
+ const idRange = this._idCompressor.takeNextCreationRange();
2244
+ // Don't include the idRange if there weren't any Ids allocated
2245
+ if (idRange?.ids !== undefined) {
2105
2246
  const idAllocationMessage = {
2106
- type: messageTypes_1.ContainerMessageType.IdAllocation,
2247
+ type: messageTypes_js_1.ContainerMessageType.IdAllocation,
2107
2248
  contents: idRange,
2108
2249
  };
2109
- idAllocationBatchMessage = {
2250
+ const idAllocationBatchMessage = {
2110
2251
  contents: JSON.stringify(idAllocationMessage),
2111
2252
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2112
2253
  metadata: undefined,
2113
2254
  localOpMetadata: undefined,
2114
- type: messageTypes_1.ContainerMessageType.IdAllocation,
2255
+ type: messageTypes_js_1.ContainerMessageType.IdAllocation,
2115
2256
  };
2116
- }
2117
- if (idAllocationBatchMessage !== undefined) {
2118
2257
  this.outbox.submitIdAllocation(idAllocationBatchMessage);
2119
2258
  }
2120
2259
  }
@@ -2142,42 +2281,47 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2142
2281
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2143
2282
  };
2144
2283
  try {
2145
- // Submit an IdAllocation op if any Ids have been generated since
2146
- // the last op was submitted. Don't submit another if it's an IdAllocation
2147
- // op as that means we're in resubmission flow and we don't want to send
2148
- // IdRanges out of order.
2149
- this.maybeSubmitIdAllocationOp(type);
2150
- // If this is attach message for new data store, and we are in a batch, send this op out of order
2151
- // Is it safe:
2152
- // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
2153
- // They become visible only when aliased, or handle to some sub-element of newly created datastore
2154
- // is stored in some DDS, i.e. only after some other op.
2155
- // Why:
2156
- // Attach ops are large, and expensive to process. Plus there are scenarios where a lot of new data
2157
- // stores are created, causing issues like relay service throttling (too many ops) and catastrophic
2158
- // failure (batch is too large). Pushing them earlier and outside of main batch should alleviate
2159
- // these issues.
2160
- // Cons:
2161
- // 1. With large batches, relay service may throttle clients. Clients may disconnect while throttled.
2162
- // This change creates new possibility of a lot of newly created data stores never being referenced
2163
- // because client died before it had a change to submit the rest of the ops. This will create more
2164
- // garbage that needs to be collected leveraging GC (Garbage Collection) feature.
2165
- // 2. Sending ops out of order means they are excluded from rollback functionality. This is not an issue
2166
- // today as rollback can't undo creation of data store. To some extent not sending them is a bigger
2167
- // issue than sending.
2168
- // Please note that this does not change file format, so it can be disabled in the future if this
2169
- // optimization no longer makes sense (for example, batch compression may make it less appealing).
2170
- if (this.currentlyBatching() &&
2171
- type === messageTypes_1.ContainerMessageType.Attach &&
2172
- this.disableAttachReorder !== true) {
2173
- this.outbox.submitAttach(message);
2174
- }
2175
- else if (type === messageTypes_1.ContainerMessageType.BlobAttach) {
2176
- // BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
2177
- this.outbox.submitBlobAttach(message);
2284
+ // If `message` is an allocation op, then we are in the resubmit path and we must redirect the allocation
2285
+ // op into the correct batch to avoid ranges being finalized out of order.
2286
+ // Otherwise, submit an IdAllocation op if any IDs have been generated since the last op was submitted, as
2287
+ // any of the other op types may contain those IDs and thus depend on the allocation op being sent first.
2288
+ if (type === messageTypes_js_1.ContainerMessageType.IdAllocation) {
2289
+ this.outbox.submitIdAllocation(message);
2178
2290
  }
2179
2291
  else {
2180
- this.outbox.submit(message);
2292
+ this.submitIdAllocationOpIfNeeded();
2293
+ // If this is attach message for new data store, and we are in a batch, send this op out of order
2294
+ // Is it safe:
2295
+ // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
2296
+ // They become visible only when aliased, or handle to some sub-element of newly created datastore
2297
+ // is stored in some DDS, i.e. only after some other op.
2298
+ // Why:
2299
+ // Attach ops are large, and expensive to process. Plus there are scenarios where a lot of new data
2300
+ // stores are created, causing issues like relay service throttling (too many ops) and catastrophic
2301
+ // failure (batch is too large). Pushing them earlier and outside of main batch should alleviate
2302
+ // these issues.
2303
+ // Cons:
2304
+ // 1. With large batches, relay service may throttle clients. Clients may disconnect while throttled.
2305
+ // This change creates new possibility of a lot of newly created data stores never being referenced
2306
+ // because client died before it had a change to submit the rest of the ops. This will create more
2307
+ // garbage that needs to be collected leveraging GC (Garbage Collection) feature.
2308
+ // 2. Sending ops out of order means they are excluded from rollback functionality. This is not an issue
2309
+ // today as rollback can't undo creation of data store. To some extent not sending them is a bigger
2310
+ // issue than sending.
2311
+ // Please note that this does not change file format, so it can be disabled in the future if this
2312
+ // optimization no longer makes sense (for example, batch compression may make it less appealing).
2313
+ if (this.currentlyBatching() &&
2314
+ type === messageTypes_js_1.ContainerMessageType.Attach &&
2315
+ this.disableAttachReorder !== true) {
2316
+ this.outbox.submitAttach(message);
2317
+ }
2318
+ else if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
2319
+ // BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
2320
+ this.outbox.submitBlobAttach(message);
2321
+ }
2322
+ else {
2323
+ this.outbox.submit(message);
2324
+ }
2181
2325
  }
2182
2326
  if (!this.currentlyBatching()) {
2183
2327
  this.flush();
@@ -2252,7 +2396,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2252
2396
  if (this.opReentryCallsToReport > 0) {
2253
2397
  this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
2254
2398
  // We need to capture the call stack in order to inspect the source of this usage pattern
2255
- (0, opLifecycle_1.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2399
+ (0, index_js_3.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2256
2400
  this.opReentryCallsToReport--;
2257
2401
  }
2258
2402
  // Creating ops while processing ops can lead
@@ -2293,28 +2437,28 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2293
2437
  * @param localOpMetadata - The local metadata associated with the original message.
2294
2438
  */
2295
2439
  reSubmitCore(message, localOpMetadata, opMetadata) {
2296
- (0, core_utils_1.assert)(!this.isSummarizerClient, "Summarizer never reconnects so should never resubmit");
2440
+ (0, core_utils_1.assert)(!this.isSummarizerClient, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
2297
2441
  switch (message.type) {
2298
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
2442
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
2443
+ case messageTypes_js_1.ContainerMessageType.Attach:
2444
+ case messageTypes_js_1.ContainerMessageType.Alias:
2299
2445
  // For Operations, call resubmitDataStoreOp which will find the right store
2300
2446
  // and trigger resubmission on it.
2301
- this.dataStores.resubmitDataStoreOp(message.contents, localOpMetadata);
2447
+ this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
2302
2448
  break;
2303
- case messageTypes_1.ContainerMessageType.Attach:
2304
- case messageTypes_1.ContainerMessageType.Alias:
2305
- case messageTypes_1.ContainerMessageType.IdAllocation: {
2449
+ case messageTypes_js_1.ContainerMessageType.IdAllocation: {
2306
2450
  this.submit(message, localOpMetadata);
2307
2451
  break;
2308
2452
  }
2309
- case messageTypes_1.ContainerMessageType.ChunkedOp:
2453
+ case messageTypes_js_1.ContainerMessageType.ChunkedOp:
2310
2454
  throw new Error(`chunkedOp not expected here`);
2311
- case messageTypes_1.ContainerMessageType.BlobAttach:
2455
+ case messageTypes_js_1.ContainerMessageType.BlobAttach:
2312
2456
  this.blobManager.reSubmit(opMetadata);
2313
2457
  break;
2314
- case messageTypes_1.ContainerMessageType.Rejoin:
2458
+ case messageTypes_js_1.ContainerMessageType.Rejoin:
2315
2459
  this.submit(message);
2316
2460
  break;
2317
- case messageTypes_1.ContainerMessageType.GC:
2461
+ case messageTypes_js_1.ContainerMessageType.GC:
2318
2462
  this.submit(message);
2319
2463
  break;
2320
2464
  default: {
@@ -2345,10 +2489,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2345
2489
  // Need to parse from string for back-compat
2346
2490
  const { type, contents } = this.parseLocalOpContent(content);
2347
2491
  switch (type) {
2348
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
2492
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
2349
2493
  // For operations, call rollbackDataStoreOp which will find the right store
2350
2494
  // and trigger rollback on it.
2351
- this.dataStores.rollbackDataStoreOp(contents, localOpMetadata);
2495
+ this.channelCollection.rollback(type, contents, localOpMetadata);
2352
2496
  break;
2353
2497
  default:
2354
2498
  // Don't check message.compatDetails because this is for rolling back a local op so the type will be known
@@ -2433,44 +2577,43 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2433
2577
  };
2434
2578
  });
2435
2579
  }
2436
- async getPendingLocalState(props) {
2437
- return telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, {
2438
- eventName: "getPendingLocalState",
2439
- notifyImminentClosure: props?.notifyImminentClosure,
2440
- }, async (event) => {
2441
- this.verifyNotClosed();
2442
- // in case imminentClosure is set to true by future code, we don't
2443
- // try to change its value
2444
- if (!this.imminentClosure) {
2445
- this.imminentClosure = props?.notifyImminentClosure ?? this.imminentClosure;
2446
- }
2447
- const stopBlobAttachingSignal = props?.stopBlobAttachingSignal;
2448
- if (this._orderSequentiallyCalls !== 0) {
2449
- throw new telemetry_utils_1.UsageError("can't get state during orderSequentially");
2450
- }
2451
- // Flush pending batch.
2452
- // getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
2453
- // to close current batch.
2454
- this.flush();
2455
- const pendingAttachmentBlobs = this.imminentClosure
2456
- ? await this.blobManager.attachAndGetPendingBlobs(stopBlobAttachingSignal)
2457
- : undefined;
2580
+ getPendingLocalState(props) {
2581
+ this.verifyNotClosed();
2582
+ if (this._orderSequentiallyCalls !== 0) {
2583
+ throw new telemetry_utils_1.UsageError("can't get state during orderSequentially");
2584
+ }
2585
+ this.imminentClosure || (this.imminentClosure = props?.notifyImminentClosure ?? false);
2586
+ const getSyncState = (pendingAttachmentBlobs) => {
2458
2587
  const pending = this.pendingStateManager.getLocalState();
2459
- if (!pendingAttachmentBlobs && !this.hasPendingMessages()) {
2588
+ if (pendingAttachmentBlobs === undefined && !this.hasPendingMessages()) {
2460
2589
  return; // no pending state to save
2461
2590
  }
2462
- const pendingIdCompressorState = this.idCompressor?.serialize(true);
2463
- const pendingState = {
2591
+ const pendingIdCompressorState = this._idCompressor?.serialize(true);
2592
+ return {
2464
2593
  pending,
2465
- pendingAttachmentBlobs,
2466
2594
  pendingIdCompressorState,
2595
+ pendingAttachmentBlobs,
2596
+ sessionExpiryTimerStarted: this.garbageCollector.sessionExpiryTimerStarted,
2467
2597
  };
2598
+ };
2599
+ const perfEvent = {
2600
+ eventName: "getPendingLocalState",
2601
+ notifyImminentClosure: props?.notifyImminentClosure,
2602
+ };
2603
+ const logAndReturnPendingState = (event, pendingState) => {
2468
2604
  event.end({
2469
- attachmentBlobsSize: Object.keys(pendingAttachmentBlobs ?? {}).length,
2470
- pendingOpsSize: pending?.pendingStates.length,
2605
+ attachmentBlobsSize: Object.keys(pendingState?.pendingAttachmentBlobs ?? {}).length,
2606
+ pendingOpsSize: pendingState?.pending?.pendingStates.length,
2471
2607
  });
2472
2608
  return pendingState;
2473
- });
2609
+ };
2610
+ // Flush pending batch.
2611
+ // getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
2612
+ // to close current batch.
2613
+ this.flush();
2614
+ return props?.notifyImminentClosure === true
2615
+ ? telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, perfEvent, async (event) => logAndReturnPendingState(event, getSyncState(await this.blobManager.attachAndGetPendingBlobs(props?.stopBlobAttachingSignal))))
2616
+ : telemetry_utils_1.PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
2474
2617
  }
2475
2618
  summarizeOnDemand(options) {
2476
2619
  if (this.isSummarizerClient) {