@fluidframework/container-runtime 2.0.0-rc.1.0.6 → 2.0.0-rc.2.0.1

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 (687) hide show
  1. package/{.eslintrc.js → .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 +63 -29
  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.js.map +1 -1
  13. package/{lib/dataStores.d.mts → dist/channelCollection.d.ts} +94 -27
  14. package/dist/channelCollection.d.ts.map +1 -0
  15. package/dist/{dataStores.js → channelCollection.js} +359 -84
  16. package/dist/channelCollection.js.map +1 -0
  17. package/dist/connectionTelemetry.d.ts +11 -1
  18. package/dist/connectionTelemetry.d.ts.map +1 -1
  19. package/dist/connectionTelemetry.js +42 -4
  20. package/dist/connectionTelemetry.js.map +1 -1
  21. package/dist/container-runtime-alpha.d.ts +93 -39
  22. package/dist/container-runtime-beta.d.ts +27 -9
  23. package/dist/container-runtime-public.d.ts +27 -9
  24. package/dist/container-runtime-untrimmed.d.ts +118 -39
  25. package/dist/containerHandleContext.d.ts +1 -1
  26. package/dist/containerHandleContext.d.ts.map +1 -1
  27. package/dist/containerHandleContext.js.map +1 -1
  28. package/dist/containerRuntime.d.ts +74 -54
  29. package/dist/containerRuntime.d.ts.map +1 -1
  30. package/dist/containerRuntime.js +534 -410
  31. package/dist/containerRuntime.js.map +1 -1
  32. package/dist/dataStore.d.ts +2 -3
  33. package/dist/dataStore.d.ts.map +1 -1
  34. package/dist/dataStore.js +12 -11
  35. package/dist/dataStore.js.map +1 -1
  36. package/dist/dataStoreContext.d.ts +34 -29
  37. package/dist/dataStoreContext.d.ts.map +1 -1
  38. package/dist/dataStoreContext.js +157 -133
  39. package/dist/dataStoreContext.js.map +1 -1
  40. package/dist/dataStoreContexts.d.ts +1 -1
  41. package/dist/dataStoreContexts.d.ts.map +1 -1
  42. package/dist/dataStoreContexts.js.map +1 -1
  43. package/dist/deltaManagerSummarizerProxy.d.ts +29 -4
  44. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
  45. package/dist/deltaManagerSummarizerProxy.js +91 -5
  46. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  47. package/dist/gc/garbageCollection.d.ts +5 -4
  48. package/dist/gc/garbageCollection.d.ts.map +1 -1
  49. package/dist/gc/garbageCollection.js +64 -53
  50. package/dist/gc/garbageCollection.js.map +1 -1
  51. package/dist/gc/gcConfigs.d.ts +2 -2
  52. package/dist/gc/gcConfigs.d.ts.map +1 -1
  53. package/dist/gc/gcConfigs.js +21 -21
  54. package/dist/gc/gcConfigs.js.map +1 -1
  55. package/dist/gc/gcDefinitions.d.ts +10 -3
  56. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  57. package/dist/gc/gcDefinitions.js.map +1 -1
  58. package/dist/gc/gcHelpers.d.ts +2 -2
  59. package/dist/gc/gcHelpers.d.ts.map +1 -1
  60. package/dist/gc/gcHelpers.js.map +1 -1
  61. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +1 -1
  62. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -1
  63. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  64. package/dist/gc/gcSummaryStateTracker.d.ts +4 -4
  65. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  66. package/dist/gc/gcSummaryStateTracker.js +5 -5
  67. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  68. package/dist/gc/gcTelemetry.d.ts +6 -7
  69. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  70. package/dist/gc/gcTelemetry.js +17 -17
  71. package/dist/gc/gcTelemetry.js.map +1 -1
  72. package/dist/gc/gcUnreferencedStateTracker.d.ts +1 -1
  73. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  74. package/dist/gc/gcUnreferencedStateTracker.js +10 -10
  75. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  76. package/dist/gc/index.d.ts +8 -8
  77. package/dist/gc/index.d.ts.map +1 -1
  78. package/dist/gc/index.js +39 -39
  79. package/dist/gc/index.js.map +1 -1
  80. package/dist/index.d.ts +8 -20
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +28 -40
  83. package/dist/index.js.map +1 -1
  84. package/dist/messageTypes.d.ts +4 -4
  85. package/dist/messageTypes.d.ts.map +1 -1
  86. package/dist/messageTypes.js.map +1 -1
  87. package/dist/opLifecycle/batchManager.d.ts +2 -2
  88. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  89. package/dist/opLifecycle/batchManager.js.map +1 -1
  90. package/dist/opLifecycle/definitions.d.ts +2 -2
  91. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  92. package/dist/opLifecycle/definitions.js.map +1 -1
  93. package/dist/opLifecycle/index.d.ts +8 -8
  94. package/dist/opLifecycle/index.d.ts.map +1 -1
  95. package/dist/opLifecycle/index.js +18 -18
  96. package/dist/opLifecycle/index.js.map +1 -1
  97. package/dist/opLifecycle/opCompressor.d.ts +1 -1
  98. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  99. package/dist/opLifecycle/opCompressor.js +4 -4
  100. package/dist/opLifecycle/opCompressor.js.map +1 -1
  101. package/dist/opLifecycle/opDecompressor.d.ts +1 -1
  102. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  103. package/dist/opLifecycle/opDecompressor.js +3 -3
  104. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  105. package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
  106. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  107. package/dist/opLifecycle/opGroupingManager.js +1 -10
  108. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  109. package/dist/opLifecycle/opSplitter.d.ts +1 -1
  110. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  111. package/dist/opLifecycle/opSplitter.js +5 -5
  112. package/dist/opLifecycle/opSplitter.js.map +1 -1
  113. package/dist/opLifecycle/outbox.d.ts +7 -7
  114. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  115. package/dist/opLifecycle/outbox.js +20 -12
  116. package/dist/opLifecycle/outbox.js.map +1 -1
  117. package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -4
  118. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  119. package/dist/opLifecycle/remoteMessageProcessor.js +2 -2
  120. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  121. package/dist/package.json +3 -0
  122. package/dist/packageVersion.d.ts +1 -1
  123. package/dist/packageVersion.js +1 -1
  124. package/dist/packageVersion.js.map +1 -1
  125. package/dist/pendingStateManager.d.ts +2 -1
  126. package/dist/pendingStateManager.d.ts.map +1 -1
  127. package/dist/pendingStateManager.js +18 -10
  128. package/dist/pendingStateManager.js.map +1 -1
  129. package/dist/scheduleManager.d.ts +1 -2
  130. package/dist/scheduleManager.d.ts.map +1 -1
  131. package/dist/scheduleManager.js +5 -5
  132. package/dist/scheduleManager.js.map +1 -1
  133. package/dist/summary/index.d.ts +12 -12
  134. package/dist/summary/index.d.ts.map +1 -1
  135. package/dist/summary/index.js +43 -43
  136. package/dist/summary/index.js.map +1 -1
  137. package/dist/summary/orderedClientElection.js +8 -8
  138. package/dist/summary/orderedClientElection.js.map +1 -1
  139. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
  140. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  141. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  142. package/dist/summary/runningSummarizer.d.ts +11 -10
  143. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  144. package/dist/summary/runningSummarizer.js +114 -81
  145. package/dist/summary/runningSummarizer.js.map +1 -1
  146. package/dist/summary/summarizer.d.ts +4 -4
  147. package/dist/summary/summarizer.d.ts.map +1 -1
  148. package/dist/summary/summarizer.js +6 -6
  149. package/dist/summary/summarizer.js.map +1 -1
  150. package/dist/summary/summarizerClientElection.d.ts +2 -2
  151. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  152. package/dist/summary/summarizerClientElection.js.map +1 -1
  153. package/dist/summary/summarizerHeuristics.d.ts +3 -3
  154. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  155. package/dist/summary/summarizerHeuristics.js.map +1 -1
  156. package/dist/summary/summarizerNode/index.d.ts +3 -3
  157. package/dist/summary/summarizerNode/index.d.ts.map +1 -1
  158. package/dist/summary/summarizerNode/index.js +4 -4
  159. package/dist/summary/summarizerNode/index.js.map +1 -1
  160. package/dist/summary/summarizerNode/summarizerNode.d.ts +17 -7
  161. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  162. package/dist/summary/summarizerNode/summarizerNode.js +45 -57
  163. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  164. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +10 -19
  165. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  166. package/dist/summary/summarizerNode/summarizerNodeUtils.js +1 -21
  167. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  168. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +5 -6
  169. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  170. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +16 -16
  171. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  172. package/dist/summary/summarizerTypes.d.ts +10 -21
  173. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  174. package/dist/summary/summarizerTypes.js.map +1 -1
  175. package/dist/summary/summaryFormat.d.ts +15 -2
  176. package/dist/summary/summaryFormat.d.ts.map +1 -1
  177. package/dist/summary/summaryFormat.js.map +1 -1
  178. package/dist/summary/summaryGenerator.d.ts +6 -5
  179. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  180. package/dist/summary/summaryGenerator.js +10 -1
  181. package/dist/summary/summaryGenerator.js.map +1 -1
  182. package/dist/summary/summaryManager.d.ts +5 -6
  183. package/dist/summary/summaryManager.d.ts.map +1 -1
  184. package/dist/summary/summaryManager.js +4 -5
  185. package/dist/summary/summaryManager.js.map +1 -1
  186. package/dist/tsdoc-metadata.json +1 -1
  187. package/lib/{batchTracker.d.mts → batchTracker.d.ts} +2 -3
  188. package/lib/batchTracker.d.ts.map +1 -0
  189. package/lib/{batchTracker.mjs → batchTracker.js} +1 -1
  190. package/lib/batchTracker.js.map +1 -0
  191. package/lib/{blobManager.d.mts → blobManager.d.ts} +1 -1
  192. package/lib/blobManager.d.ts.map +1 -0
  193. package/lib/{blobManager.mjs → blobManager.js} +1 -1
  194. package/lib/blobManager.js.map +1 -0
  195. package/{dist/dataStores.d.ts → lib/channelCollection.d.ts} +94 -27
  196. package/lib/channelCollection.d.ts.map +1 -0
  197. package/lib/{dataStores.mjs → channelCollection.js} +345 -73
  198. package/lib/channelCollection.js.map +1 -0
  199. package/lib/{connectionTelemetry.d.mts → connectionTelemetry.d.ts} +12 -2
  200. package/lib/connectionTelemetry.d.ts.map +1 -0
  201. package/lib/{connectionTelemetry.mjs → connectionTelemetry.js} +43 -5
  202. package/lib/connectionTelemetry.js.map +1 -0
  203. package/lib/{container-runtime-alpha.d.mts → container-runtime-alpha.d.ts} +93 -39
  204. package/lib/{container-runtime-public.d.mts → container-runtime-beta.d.ts} +27 -9
  205. package/lib/{container-runtime-beta.d.mts → container-runtime-public.d.ts} +27 -9
  206. package/lib/{container-runtime-untrimmed.d.mts → container-runtime-untrimmed.d.ts} +118 -39
  207. package/lib/{containerHandleContext.d.mts → containerHandleContext.d.ts} +2 -2
  208. package/lib/containerHandleContext.d.ts.map +1 -0
  209. package/lib/{containerHandleContext.mjs → containerHandleContext.js} +1 -1
  210. package/lib/containerHandleContext.js.map +1 -0
  211. package/lib/{containerRuntime.d.mts → containerRuntime.d.ts} +79 -55
  212. package/lib/containerRuntime.d.ts.map +1 -0
  213. package/lib/{containerRuntime.mjs → containerRuntime.js} +453 -331
  214. package/lib/containerRuntime.js.map +1 -0
  215. package/lib/{dataStore.d.mts → dataStore.d.ts} +3 -4
  216. package/lib/dataStore.d.ts.map +1 -0
  217. package/lib/{dataStore.mjs → dataStore.js} +13 -12
  218. package/lib/dataStore.js.map +1 -0
  219. package/lib/{dataStoreContext.d.mts → dataStoreContext.d.ts} +35 -30
  220. package/lib/dataStoreContext.d.ts.map +1 -0
  221. package/lib/{dataStoreContext.mjs → dataStoreContext.js} +146 -122
  222. package/lib/dataStoreContext.js.map +1 -0
  223. package/lib/{dataStoreContexts.d.mts → dataStoreContexts.d.ts} +2 -2
  224. package/lib/dataStoreContexts.d.ts.map +1 -0
  225. package/lib/{dataStoreContexts.mjs → dataStoreContexts.js} +1 -1
  226. package/lib/dataStoreContexts.js.map +1 -0
  227. package/lib/{dataStoreRegistry.d.mts → dataStoreRegistry.d.ts} +1 -1
  228. package/lib/dataStoreRegistry.d.ts.map +1 -0
  229. package/lib/{dataStoreRegistry.mjs → dataStoreRegistry.js} +5 -1
  230. package/lib/dataStoreRegistry.js.map +1 -0
  231. package/{dist/deltaManagerProxyBase.d.ts → lib/deltaManagerSummarizerProxy.d.ts} +16 -7
  232. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
  233. package/lib/deltaManagerSummarizerProxy.js +124 -0
  234. package/lib/deltaManagerSummarizerProxy.js.map +1 -0
  235. package/lib/{deltaScheduler.d.mts → deltaScheduler.d.ts} +1 -1
  236. package/lib/deltaScheduler.d.ts.map +1 -0
  237. package/lib/{deltaScheduler.mjs → deltaScheduler.js} +1 -1
  238. package/lib/deltaScheduler.js.map +1 -0
  239. package/lib/{error.d.mts → error.d.ts} +1 -1
  240. package/lib/error.d.ts.map +1 -0
  241. package/lib/{error.mjs → error.js} +1 -1
  242. package/lib/error.js.map +1 -0
  243. package/lib/gc/{garbageCollection.d.mts → garbageCollection.d.ts} +6 -5
  244. package/lib/gc/garbageCollection.d.ts.map +1 -0
  245. package/lib/gc/{garbageCollection.mjs → garbageCollection.js} +25 -14
  246. package/lib/gc/garbageCollection.js.map +1 -0
  247. package/lib/gc/{gcConfigs.d.mts → gcConfigs.d.ts} +3 -3
  248. package/lib/gc/gcConfigs.d.ts.map +1 -0
  249. package/lib/gc/{gcConfigs.mjs → gcConfigs.js} +3 -3
  250. package/lib/gc/gcConfigs.js.map +1 -0
  251. package/lib/gc/{gcDefinitions.d.mts → gcDefinitions.d.ts} +11 -4
  252. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  253. package/lib/gc/{gcDefinitions.mjs → gcDefinitions.js} +1 -1
  254. package/lib/gc/gcDefinitions.js.map +1 -0
  255. package/lib/gc/{gcHelpers.d.mts → gcHelpers.d.ts} +3 -3
  256. package/lib/gc/{gcHelpers.d.mts.map → gcHelpers.d.ts.map} +1 -1
  257. package/lib/gc/{gcHelpers.mjs → gcHelpers.js} +1 -1
  258. package/lib/gc/gcHelpers.js.map +1 -0
  259. package/lib/gc/{gcReferenceGraphAlgorithm.d.mts → gcReferenceGraphAlgorithm.d.ts} +2 -2
  260. package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  261. package/lib/gc/{gcReferenceGraphAlgorithm.mjs → gcReferenceGraphAlgorithm.js} +1 -1
  262. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  263. package/lib/gc/{gcSummaryDefinitions.d.mts → gcSummaryDefinitions.d.ts} +1 -1
  264. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -0
  265. package/lib/gc/{gcSummaryDefinitions.mjs → gcSummaryDefinitions.js} +1 -1
  266. package/lib/gc/gcSummaryDefinitions.js.map +1 -0
  267. package/lib/gc/{gcSummaryStateTracker.d.mts → gcSummaryStateTracker.d.ts} +5 -5
  268. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  269. package/lib/gc/{gcSummaryStateTracker.mjs → gcSummaryStateTracker.js} +4 -4
  270. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  271. package/lib/gc/{gcTelemetry.d.mts → gcTelemetry.d.ts} +7 -8
  272. package/lib/gc/gcTelemetry.d.ts.map +1 -0
  273. package/lib/gc/{gcTelemetry.mjs → gcTelemetry.js} +2 -2
  274. package/lib/gc/gcTelemetry.js.map +1 -0
  275. package/lib/gc/{gcUnreferencedStateTracker.d.mts → gcUnreferencedStateTracker.d.ts} +2 -2
  276. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  277. package/lib/gc/{gcUnreferencedStateTracker.mjs → gcUnreferencedStateTracker.js} +2 -2
  278. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  279. package/lib/gc/{index.d.mts → index.d.ts} +9 -9
  280. package/lib/gc/index.d.ts.map +1 -0
  281. package/lib/gc/{index.mjs → index.js} +8 -8
  282. package/lib/gc/index.js.map +1 -0
  283. package/lib/{index.d.mts → index.d.ts} +9 -21
  284. package/lib/index.d.ts.map +1 -0
  285. package/lib/index.js +12 -0
  286. package/lib/index.js.map +1 -0
  287. package/lib/{messageTypes.d.mts → messageTypes.d.ts} +5 -5
  288. package/lib/messageTypes.d.ts.map +1 -0
  289. package/lib/{messageTypes.mjs → messageTypes.js} +1 -1
  290. package/lib/messageTypes.js.map +1 -0
  291. package/lib/{metadata.d.mts → metadata.d.ts} +1 -1
  292. package/lib/metadata.d.ts.map +1 -0
  293. package/lib/{metadata.mjs → metadata.js} +1 -1
  294. package/lib/metadata.js.map +1 -0
  295. package/lib/opLifecycle/{batchManager.d.mts → batchManager.d.ts} +3 -3
  296. package/lib/opLifecycle/batchManager.d.ts.map +1 -0
  297. package/lib/opLifecycle/{batchManager.mjs → batchManager.js} +1 -1
  298. package/lib/opLifecycle/batchManager.js.map +1 -0
  299. package/lib/opLifecycle/{definitions.d.mts → definitions.d.ts} +3 -3
  300. package/lib/opLifecycle/definitions.d.ts.map +1 -0
  301. package/lib/opLifecycle/{definitions.mjs → definitions.js} +1 -1
  302. package/lib/opLifecycle/definitions.js.map +1 -0
  303. package/lib/opLifecycle/index.d.ts +13 -0
  304. package/lib/opLifecycle/index.d.ts.map +1 -0
  305. package/lib/opLifecycle/index.js +12 -0
  306. package/lib/opLifecycle/index.js.map +1 -0
  307. package/lib/opLifecycle/{opCompressor.d.mts → opCompressor.d.ts} +2 -2
  308. package/lib/opLifecycle/opCompressor.d.ts.map +1 -0
  309. package/lib/opLifecycle/{opCompressor.mjs → opCompressor.js} +3 -3
  310. package/lib/opLifecycle/opCompressor.js.map +1 -0
  311. package/lib/opLifecycle/{opDecompressor.d.mts → opDecompressor.d.ts} +2 -2
  312. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -0
  313. package/lib/opLifecycle/{opDecompressor.mjs → opDecompressor.js} +2 -2
  314. package/lib/opLifecycle/opDecompressor.js.map +1 -0
  315. package/lib/opLifecycle/{opGroupingManager.d.mts → opGroupingManager.d.ts} +2 -2
  316. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -0
  317. package/lib/opLifecycle/{opGroupingManager.mjs → opGroupingManager.js} +2 -11
  318. package/lib/opLifecycle/opGroupingManager.js.map +1 -0
  319. package/lib/opLifecycle/{opSplitter.d.mts → opSplitter.d.ts} +2 -2
  320. package/lib/opLifecycle/opSplitter.d.ts.map +1 -0
  321. package/lib/opLifecycle/{opSplitter.mjs → opSplitter.js} +3 -3
  322. package/lib/opLifecycle/opSplitter.js.map +1 -0
  323. package/lib/opLifecycle/{outbox.d.mts → outbox.d.ts} +8 -8
  324. package/lib/opLifecycle/outbox.d.ts.map +1 -0
  325. package/lib/opLifecycle/{outbox.mjs → outbox.js} +12 -4
  326. package/lib/opLifecycle/outbox.js.map +1 -0
  327. package/lib/opLifecycle/{remoteMessageProcessor.d.mts → remoteMessageProcessor.d.ts} +5 -5
  328. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
  329. package/lib/opLifecycle/{remoteMessageProcessor.mjs → remoteMessageProcessor.js} +2 -2
  330. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -0
  331. package/lib/{opProperties.d.mts → opProperties.d.ts} +1 -1
  332. package/lib/opProperties.d.ts.map +1 -0
  333. package/lib/{opProperties.mjs → opProperties.js} +1 -1
  334. package/lib/opProperties.js.map +1 -0
  335. package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
  336. package/lib/packageVersion.d.ts.map +1 -0
  337. package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
  338. package/lib/packageVersion.js.map +1 -0
  339. package/lib/{pendingStateManager.d.mts → pendingStateManager.d.ts} +3 -2
  340. package/lib/pendingStateManager.d.ts.map +1 -0
  341. package/lib/{pendingStateManager.mjs → pendingStateManager.js} +18 -10
  342. package/lib/pendingStateManager.js.map +1 -0
  343. package/lib/{scheduleManager.d.mts → scheduleManager.d.ts} +6 -3
  344. package/lib/scheduleManager.d.ts.map +1 -0
  345. package/lib/{scheduleManager.mjs → scheduleManager.js} +3 -3
  346. package/lib/scheduleManager.js.map +1 -0
  347. package/lib/{storageServiceWithAttachBlobs.d.mts → storageServiceWithAttachBlobs.d.ts} +1 -1
  348. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
  349. package/lib/{storageServiceWithAttachBlobs.mjs → storageServiceWithAttachBlobs.js} +1 -1
  350. package/lib/storageServiceWithAttachBlobs.js.map +1 -0
  351. package/lib/summary/{index.d.mts → index.d.ts} +13 -13
  352. package/lib/summary/index.d.ts.map +1 -0
  353. package/lib/summary/{index.mjs → index.js} +12 -12
  354. package/lib/summary/index.js.map +1 -0
  355. package/lib/summary/{orderedClientElection.d.mts → orderedClientElection.d.ts} +5 -1
  356. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  357. package/lib/summary/{orderedClientElection.mjs → orderedClientElection.js} +2 -2
  358. package/lib/summary/orderedClientElection.js.map +1 -0
  359. package/lib/summary/{runWhileConnectedCoordinator.d.mts → runWhileConnectedCoordinator.d.ts} +2 -2
  360. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  361. package/lib/summary/{runWhileConnectedCoordinator.mjs → runWhileConnectedCoordinator.js} +1 -1
  362. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  363. package/lib/summary/{runningSummarizer.d.mts → runningSummarizer.d.ts} +12 -11
  364. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  365. package/lib/summary/{runningSummarizer.mjs → runningSummarizer.js} +108 -75
  366. package/lib/summary/runningSummarizer.js.map +1 -0
  367. package/lib/summary/{summarizer.d.mts → summarizer.d.ts} +5 -5
  368. package/lib/summary/summarizer.d.ts.map +1 -0
  369. package/lib/summary/{summarizer.mjs → summarizer.js} +4 -4
  370. package/lib/summary/summarizer.js.map +1 -0
  371. package/lib/summary/{summarizerClientElection.d.mts → summarizerClientElection.d.ts} +3 -3
  372. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  373. package/lib/summary/{summarizerClientElection.mjs → summarizerClientElection.js} +1 -1
  374. package/lib/summary/summarizerClientElection.js.map +1 -0
  375. package/lib/summary/{summarizerHeuristics.d.mts → summarizerHeuristics.d.ts} +4 -4
  376. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  377. package/lib/summary/{summarizerHeuristics.mjs → summarizerHeuristics.js} +1 -1
  378. package/lib/summary/summarizerHeuristics.js.map +1 -0
  379. package/lib/summary/summarizerNode/{index.d.mts → index.d.ts} +4 -4
  380. package/lib/summary/summarizerNode/index.d.ts.map +1 -0
  381. package/lib/summary/summarizerNode/index.js +7 -0
  382. package/lib/summary/summarizerNode/index.js.map +1 -0
  383. package/lib/summary/summarizerNode/{summarizerNode.d.mts → summarizerNode.d.ts} +18 -8
  384. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  385. package/lib/summary/summarizerNode/{summarizerNode.mjs → summarizerNode.js} +41 -53
  386. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -0
  387. package/lib/summary/summarizerNode/{summarizerNodeUtils.d.mts → summarizerNodeUtils.d.ts} +11 -20
  388. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  389. package/lib/summary/summarizerNode/{summarizerNodeUtils.mjs → summarizerNodeUtils.js} +1 -20
  390. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  391. package/lib/summary/summarizerNode/{summarizerNodeWithGc.d.mts → summarizerNodeWithGc.d.ts} +6 -7
  392. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  393. package/lib/summary/summarizerNode/{summarizerNodeWithGc.mjs → summarizerNodeWithGc.js} +12 -12
  394. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  395. package/lib/summary/{summarizerTypes.d.mts → summarizerTypes.d.ts} +11 -22
  396. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  397. package/lib/summary/{summarizerTypes.mjs → summarizerTypes.js} +1 -1
  398. package/lib/summary/summarizerTypes.js.map +1 -0
  399. package/lib/summary/{summaryCollection.d.mts → summaryCollection.d.ts} +1 -1
  400. package/lib/summary/summaryCollection.d.ts.map +1 -0
  401. package/lib/summary/{summaryCollection.mjs → summaryCollection.js} +1 -1
  402. package/lib/summary/summaryCollection.js.map +1 -0
  403. package/lib/summary/{summaryFormat.d.mts → summaryFormat.d.ts} +16 -3
  404. package/lib/summary/summaryFormat.d.ts.map +1 -0
  405. package/lib/summary/{summaryFormat.mjs → summaryFormat.js} +1 -1
  406. package/lib/summary/summaryFormat.js.map +1 -0
  407. package/lib/summary/{summaryGenerator.d.mts → summaryGenerator.d.ts} +7 -6
  408. package/lib/summary/summaryGenerator.d.ts.map +1 -0
  409. package/lib/summary/{summaryGenerator.mjs → summaryGenerator.js} +11 -2
  410. package/lib/summary/summaryGenerator.js.map +1 -0
  411. package/lib/summary/{summaryManager.d.mts → summaryManager.d.ts} +6 -7
  412. package/lib/summary/summaryManager.d.ts.map +1 -0
  413. package/lib/summary/{summaryManager.mjs → summaryManager.js} +4 -5
  414. package/lib/summary/summaryManager.js.map +1 -0
  415. package/lib/test/batchTracker.spec.js +88 -0
  416. package/lib/test/batchTracker.spec.js.map +1 -0
  417. package/lib/test/blobManager.spec.js +835 -0
  418. package/lib/test/blobManager.spec.js.map +1 -0
  419. package/lib/test/channelCollection.spec.js +141 -0
  420. package/lib/test/channelCollection.spec.js.map +1 -0
  421. package/lib/test/containerRuntime.spec.js +1748 -0
  422. package/lib/test/containerRuntime.spec.js.map +1 -0
  423. package/lib/test/dataStoreContext.spec.js +801 -0
  424. package/lib/test/dataStoreContext.spec.js.map +1 -0
  425. package/lib/test/dataStoreCreation.spec.js +312 -0
  426. package/lib/test/dataStoreCreation.spec.js.map +1 -0
  427. package/lib/test/dataStoreRegistry.spec.js +26 -0
  428. package/lib/test/dataStoreRegistry.spec.js.map +1 -0
  429. package/lib/test/fuzz/fuzzUtils.js +66 -0
  430. package/lib/test/fuzz/fuzzUtils.js.map +1 -0
  431. package/lib/test/fuzz/summarizer.fuzz.spec.js +31 -0
  432. package/lib/test/fuzz/summarizer.fuzz.spec.js.map +1 -0
  433. package/lib/test/fuzz/summarizerFuzzMocks.js +162 -0
  434. package/lib/test/fuzz/summarizerFuzzMocks.js.map +1 -0
  435. package/lib/test/fuzz/summarizerFuzzSuite.js +106 -0
  436. package/lib/test/fuzz/summarizerFuzzSuite.js.map +1 -0
  437. package/lib/test/gc/garbageCollection.spec.js +1465 -0
  438. package/lib/test/gc/garbageCollection.spec.js.map +1 -0
  439. package/lib/test/gc/gcConfigs.spec.js +690 -0
  440. package/lib/test/gc/gcConfigs.spec.js.map +1 -0
  441. package/lib/test/gc/gcHelpers.spec.js +110 -0
  442. package/lib/test/gc/gcHelpers.spec.js.map +1 -0
  443. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js +68 -0
  444. package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js.map +1 -0
  445. package/lib/test/gc/gcStats.spec.js +391 -0
  446. package/lib/test/gc/gcStats.spec.js.map +1 -0
  447. package/lib/test/gc/gcSummaryStateTracker.spec.js +228 -0
  448. package/lib/test/gc/gcSummaryStateTracker.spec.js.map +1 -0
  449. package/lib/test/gc/gcTelemetry.spec.js +530 -0
  450. package/lib/test/gc/gcTelemetry.spec.js.map +1 -0
  451. package/lib/test/gc/gcUnitTestHelpers.js +29 -0
  452. package/lib/test/gc/gcUnitTestHelpers.js.map +1 -0
  453. package/lib/test/gc/gcUnreferencedStateTracker.spec.js +192 -0
  454. package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +1 -0
  455. package/lib/test/getPendingBlobs.spec.js +193 -0
  456. package/lib/test/getPendingBlobs.spec.js.map +1 -0
  457. package/lib/test/hardwareStats.spec.js +93 -0
  458. package/lib/test/hardwareStats.spec.js.map +1 -0
  459. package/lib/test/index.js +6 -0
  460. package/lib/test/index.js.map +1 -0
  461. package/lib/test/opLifecycle/OpGroupingManager.spec.js +225 -0
  462. package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +1 -0
  463. package/lib/test/opLifecycle/batchManager.spec.js +189 -0
  464. package/lib/test/opLifecycle/batchManager.spec.js.map +1 -0
  465. package/lib/test/opLifecycle/opCompressor.spec.js +74 -0
  466. package/lib/test/opLifecycle/opCompressor.spec.js.map +1 -0
  467. package/lib/test/opLifecycle/opDecompressor.spec.js +218 -0
  468. package/lib/test/opLifecycle/opDecompressor.spec.js.map +1 -0
  469. package/lib/test/opLifecycle/opSplitter.spec.js +272 -0
  470. package/lib/test/opLifecycle/opSplitter.spec.js.map +1 -0
  471. package/lib/test/opLifecycle/outbox.spec.js +675 -0
  472. package/lib/test/opLifecycle/outbox.spec.js.map +1 -0
  473. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +196 -0
  474. package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +1 -0
  475. package/lib/test/pendingStateManager.spec.js +329 -0
  476. package/lib/test/pendingStateManager.spec.js.map +1 -0
  477. package/lib/test/scheduleManager.spec.js +270 -0
  478. package/lib/test/scheduleManager.spec.js.map +1 -0
  479. package/lib/test/summarizerNode.spec.js +326 -0
  480. package/lib/test/summarizerNode.spec.js.map +1 -0
  481. package/lib/test/summarizerNodeWithGc.spec.js +318 -0
  482. package/lib/test/summarizerNodeWithGc.spec.js.map +1 -0
  483. package/lib/test/summary/orderedClientElection.spec.js +535 -0
  484. package/lib/test/summary/orderedClientElection.spec.js.map +1 -0
  485. package/lib/test/summary/runningSummarizer.spec.js +1349 -0
  486. package/lib/test/summary/runningSummarizer.spec.js.map +1 -0
  487. package/lib/test/summary/summarizer.spec.js +29 -0
  488. package/lib/test/summary/summarizer.spec.js.map +1 -0
  489. package/lib/test/summary/summarizerClientElection.spec.js +436 -0
  490. package/lib/test/summary/summarizerClientElection.spec.js.map +1 -0
  491. package/lib/test/summary/summarizerHeuristics.spec.js +289 -0
  492. package/lib/test/summary/summarizerHeuristics.spec.js.map +1 -0
  493. package/lib/test/summary/summaryCollection.spec.js +200 -0
  494. package/lib/test/summary/summaryCollection.spec.js.map +1 -0
  495. package/lib/test/summary/summaryManager.spec.js +430 -0
  496. package/lib/test/summary/summaryManager.spec.js.map +1 -0
  497. package/lib/test/summary/testQuorumClients.js +34 -0
  498. package/lib/test/summary/testQuorumClients.js.map +1 -0
  499. package/lib/test/throttler.spec.js +175 -0
  500. package/lib/test/throttler.spec.js.map +1 -0
  501. package/lib/test/types/validateContainerRuntimePrevious.generated.js +180 -0
  502. package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +1 -0
  503. package/lib/{throttler.d.mts → throttler.d.ts} +1 -1
  504. package/lib/throttler.d.ts.map +1 -0
  505. package/lib/{throttler.mjs → throttler.js} +1 -1
  506. package/lib/throttler.js.map +1 -0
  507. package/package.json +99 -88
  508. package/src/batchTracker.ts +1 -1
  509. package/src/blobManager.ts +1 -1
  510. package/src/{dataStores.ts → channelCollection.ts} +467 -88
  511. package/src/connectionTelemetry.ts +42 -3
  512. package/src/containerHandleContext.ts +1 -1
  513. package/src/containerRuntime.ts +649 -462
  514. package/src/dataStore.ts +13 -15
  515. package/src/dataStoreContext.ts +203 -173
  516. package/src/dataStoreContexts.ts +1 -1
  517. package/src/deltaManagerSummarizerProxy.ts +132 -7
  518. package/src/gc/garbageCollection.ts +29 -16
  519. package/src/gc/gcConfigs.ts +3 -3
  520. package/src/gc/gcDefinitions.ts +10 -3
  521. package/src/gc/gcHelpers.ts +2 -2
  522. package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
  523. package/src/gc/gcSummaryStateTracker.ts +5 -6
  524. package/src/gc/gcTelemetry.ts +6 -6
  525. package/src/gc/gcUnreferencedStateTracker.ts +1 -1
  526. package/src/gc/index.ts +8 -8
  527. package/src/index.ts +16 -27
  528. package/src/messageTypes.ts +4 -4
  529. package/src/opLifecycle/README.md +2 -4
  530. package/src/opLifecycle/batchManager.ts +2 -2
  531. package/src/opLifecycle/definitions.ts +2 -2
  532. package/src/opLifecycle/index.ts +8 -8
  533. package/src/opLifecycle/opCompressor.ts +3 -3
  534. package/src/opLifecycle/opDecompressor.ts +3 -3
  535. package/src/opLifecycle/opGroupingManager.ts +3 -12
  536. package/src/opLifecycle/opSplitter.ts +3 -3
  537. package/src/opLifecycle/outbox.ts +29 -9
  538. package/src/opLifecycle/remoteMessageProcessor.ts +4 -4
  539. package/src/packageVersion.ts +1 -1
  540. package/src/pendingStateManager.ts +19 -13
  541. package/src/scheduleManager.ts +4 -4
  542. package/src/summary/index.ts +13 -12
  543. package/src/summary/orderedClientElection.ts +1 -1
  544. package/src/summary/runWhileConnectedCoordinator.ts +1 -1
  545. package/src/summary/runningSummarizer.ts +141 -93
  546. package/src/summary/summarizer.ts +7 -7
  547. package/src/summary/summarizerClientElection.ts +2 -2
  548. package/src/summary/summarizerHeuristics.ts +3 -3
  549. package/src/summary/summarizerNode/index.ts +6 -3
  550. package/src/summary/summarizerNode/summarizerNode.ts +54 -69
  551. package/src/summary/summarizerNode/summarizerNodeUtils.ts +16 -34
  552. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +11 -17
  553. package/src/summary/summarizerTypes.ts +12 -24
  554. package/src/summary/summaryFormat.ts +16 -2
  555. package/src/summary/summaryGenerator.ts +16 -4
  556. package/src/summary/summaryManager.ts +6 -7
  557. package/tsconfig.cjs.json +7 -0
  558. package/tsconfig.json +2 -5
  559. package/dist/dataStores.d.ts.map +0 -1
  560. package/dist/dataStores.js.map +0 -1
  561. package/dist/deltaManagerProxyBase.d.ts.map +0 -1
  562. package/dist/deltaManagerProxyBase.js +0 -77
  563. package/dist/deltaManagerProxyBase.js.map +0 -1
  564. package/lib/batchTracker.d.mts.map +0 -1
  565. package/lib/batchTracker.mjs.map +0 -1
  566. package/lib/blobManager.d.mts.map +0 -1
  567. package/lib/blobManager.mjs.map +0 -1
  568. package/lib/connectionTelemetry.d.mts.map +0 -1
  569. package/lib/connectionTelemetry.mjs.map +0 -1
  570. package/lib/containerHandleContext.d.mts.map +0 -1
  571. package/lib/containerHandleContext.mjs.map +0 -1
  572. package/lib/containerRuntime.d.mts.map +0 -1
  573. package/lib/containerRuntime.mjs.map +0 -1
  574. package/lib/dataStore.d.mts.map +0 -1
  575. package/lib/dataStore.mjs.map +0 -1
  576. package/lib/dataStoreContext.d.mts.map +0 -1
  577. package/lib/dataStoreContext.mjs.map +0 -1
  578. package/lib/dataStoreContexts.d.mts.map +0 -1
  579. package/lib/dataStoreContexts.mjs.map +0 -1
  580. package/lib/dataStoreRegistry.d.mts.map +0 -1
  581. package/lib/dataStoreRegistry.mjs.map +0 -1
  582. package/lib/dataStores.d.mts.map +0 -1
  583. package/lib/dataStores.mjs.map +0 -1
  584. package/lib/deltaManagerProxyBase.d.mts +0 -35
  585. package/lib/deltaManagerProxyBase.d.mts.map +0 -1
  586. package/lib/deltaManagerProxyBase.mjs +0 -73
  587. package/lib/deltaManagerProxyBase.mjs.map +0 -1
  588. package/lib/deltaManagerSummarizerProxy.d.mts +0 -19
  589. package/lib/deltaManagerSummarizerProxy.d.mts.map +0 -1
  590. package/lib/deltaManagerSummarizerProxy.mjs +0 -38
  591. package/lib/deltaManagerSummarizerProxy.mjs.map +0 -1
  592. package/lib/deltaScheduler.d.mts.map +0 -1
  593. package/lib/deltaScheduler.mjs.map +0 -1
  594. package/lib/error.d.mts.map +0 -1
  595. package/lib/error.mjs.map +0 -1
  596. package/lib/gc/garbageCollection.d.mts.map +0 -1
  597. package/lib/gc/garbageCollection.mjs.map +0 -1
  598. package/lib/gc/gcConfigs.d.mts.map +0 -1
  599. package/lib/gc/gcConfigs.mjs.map +0 -1
  600. package/lib/gc/gcDefinitions.d.mts.map +0 -1
  601. package/lib/gc/gcDefinitions.mjs.map +0 -1
  602. package/lib/gc/gcHelpers.mjs.map +0 -1
  603. package/lib/gc/gcReferenceGraphAlgorithm.d.mts.map +0 -1
  604. package/lib/gc/gcReferenceGraphAlgorithm.mjs.map +0 -1
  605. package/lib/gc/gcSummaryDefinitions.d.mts.map +0 -1
  606. package/lib/gc/gcSummaryDefinitions.mjs.map +0 -1
  607. package/lib/gc/gcSummaryStateTracker.d.mts.map +0 -1
  608. package/lib/gc/gcSummaryStateTracker.mjs.map +0 -1
  609. package/lib/gc/gcTelemetry.d.mts.map +0 -1
  610. package/lib/gc/gcTelemetry.mjs.map +0 -1
  611. package/lib/gc/gcUnreferencedStateTracker.d.mts.map +0 -1
  612. package/lib/gc/gcUnreferencedStateTracker.mjs.map +0 -1
  613. package/lib/gc/index.d.mts.map +0 -1
  614. package/lib/gc/index.mjs.map +0 -1
  615. package/lib/index.d.mts.map +0 -1
  616. package/lib/index.mjs +0 -24
  617. package/lib/index.mjs.map +0 -1
  618. package/lib/messageTypes.d.mts.map +0 -1
  619. package/lib/messageTypes.mjs.map +0 -1
  620. package/lib/metadata.d.mts.map +0 -1
  621. package/lib/metadata.mjs.map +0 -1
  622. package/lib/opLifecycle/batchManager.d.mts.map +0 -1
  623. package/lib/opLifecycle/batchManager.mjs.map +0 -1
  624. package/lib/opLifecycle/definitions.d.mts.map +0 -1
  625. package/lib/opLifecycle/definitions.mjs.map +0 -1
  626. package/lib/opLifecycle/index.d.mts +0 -13
  627. package/lib/opLifecycle/index.d.mts.map +0 -1
  628. package/lib/opLifecycle/index.mjs +0 -12
  629. package/lib/opLifecycle/index.mjs.map +0 -1
  630. package/lib/opLifecycle/opCompressor.d.mts.map +0 -1
  631. package/lib/opLifecycle/opCompressor.mjs.map +0 -1
  632. package/lib/opLifecycle/opDecompressor.d.mts.map +0 -1
  633. package/lib/opLifecycle/opDecompressor.mjs.map +0 -1
  634. package/lib/opLifecycle/opGroupingManager.d.mts.map +0 -1
  635. package/lib/opLifecycle/opGroupingManager.mjs.map +0 -1
  636. package/lib/opLifecycle/opSplitter.d.mts.map +0 -1
  637. package/lib/opLifecycle/opSplitter.mjs.map +0 -1
  638. package/lib/opLifecycle/outbox.d.mts.map +0 -1
  639. package/lib/opLifecycle/outbox.mjs.map +0 -1
  640. package/lib/opLifecycle/remoteMessageProcessor.d.mts.map +0 -1
  641. package/lib/opLifecycle/remoteMessageProcessor.mjs.map +0 -1
  642. package/lib/opProperties.d.mts.map +0 -1
  643. package/lib/opProperties.mjs.map +0 -1
  644. package/lib/packageVersion.d.mts.map +0 -1
  645. package/lib/packageVersion.mjs.map +0 -1
  646. package/lib/pendingStateManager.d.mts.map +0 -1
  647. package/lib/pendingStateManager.mjs.map +0 -1
  648. package/lib/scheduleManager.d.mts.map +0 -1
  649. package/lib/scheduleManager.mjs.map +0 -1
  650. package/lib/storageServiceWithAttachBlobs.d.mts.map +0 -1
  651. package/lib/storageServiceWithAttachBlobs.mjs.map +0 -1
  652. package/lib/summary/index.d.mts.map +0 -1
  653. package/lib/summary/index.mjs.map +0 -1
  654. package/lib/summary/orderedClientElection.d.mts.map +0 -1
  655. package/lib/summary/orderedClientElection.mjs.map +0 -1
  656. package/lib/summary/runWhileConnectedCoordinator.d.mts.map +0 -1
  657. package/lib/summary/runWhileConnectedCoordinator.mjs.map +0 -1
  658. package/lib/summary/runningSummarizer.d.mts.map +0 -1
  659. package/lib/summary/runningSummarizer.mjs.map +0 -1
  660. package/lib/summary/summarizer.d.mts.map +0 -1
  661. package/lib/summary/summarizer.mjs.map +0 -1
  662. package/lib/summary/summarizerClientElection.d.mts.map +0 -1
  663. package/lib/summary/summarizerClientElection.mjs.map +0 -1
  664. package/lib/summary/summarizerHeuristics.d.mts.map +0 -1
  665. package/lib/summary/summarizerHeuristics.mjs.map +0 -1
  666. package/lib/summary/summarizerNode/index.d.mts.map +0 -1
  667. package/lib/summary/summarizerNode/index.mjs +0 -7
  668. package/lib/summary/summarizerNode/index.mjs.map +0 -1
  669. package/lib/summary/summarizerNode/summarizerNode.d.mts.map +0 -1
  670. package/lib/summary/summarizerNode/summarizerNode.mjs.map +0 -1
  671. package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts.map +0 -1
  672. package/lib/summary/summarizerNode/summarizerNodeUtils.mjs.map +0 -1
  673. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts.map +0 -1
  674. package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs.map +0 -1
  675. package/lib/summary/summarizerTypes.d.mts.map +0 -1
  676. package/lib/summary/summarizerTypes.mjs.map +0 -1
  677. package/lib/summary/summaryCollection.d.mts.map +0 -1
  678. package/lib/summary/summaryCollection.mjs.map +0 -1
  679. package/lib/summary/summaryFormat.d.mts.map +0 -1
  680. package/lib/summary/summaryFormat.mjs.map +0 -1
  681. package/lib/summary/summaryGenerator.d.mts.map +0 -1
  682. package/lib/summary/summaryGenerator.mjs.map +0 -1
  683. package/lib/summary/summaryManager.d.mts.map +0 -1
  684. package/lib/summary/summaryManager.mjs.map +0 -1
  685. package/lib/throttler.d.mts.map +0 -1
  686. package/lib/throttler.mjs.map +0 -1
  687. package/src/deltaManagerProxyBase.ts +0 -111
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  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;
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.DefaultSummaryConfiguration = void 0;
4
4
  const container_definitions_1 = require("@fluidframework/container-definitions");
5
5
  const core_utils_1 = require("@fluidframework/core-utils");
6
6
  const client_utils_1 = require("@fluid-internal/client-utils");
@@ -11,22 +11,22 @@ const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
11
11
  const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
12
12
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
13
13
  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");
14
+ const containerHandleContext_js_1 = require("./containerHandleContext.js");
15
+ const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
16
+ const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
17
+ const pendingStateManager_js_1 = require("./pendingStateManager.js");
18
+ const packageVersion_js_1 = require("./packageVersion.js");
19
+ const blobManager_js_1 = require("./blobManager.js");
20
+ const channelCollection_js_1 = require("./channelCollection.js");
21
+ const index_js_1 = require("./summary/index.js");
22
+ const throttler_js_1 = require("./throttler.js");
23
+ const index_js_2 = require("./gc/index.js");
24
+ const dataStore_js_1 = require("./dataStore.js");
25
+ const batchTracker_js_1 = require("./batchTracker.js");
26
+ const scheduleManager_js_1 = require("./scheduleManager.js");
27
+ const index_js_3 = require("./opLifecycle/index.js");
28
+ const deltaManagerSummarizerProxy_js_1 = require("./deltaManagerSummarizerProxy.js");
29
+ const messageTypes_js_1 = require("./messageTypes.js");
30
30
  /**
31
31
  * Utility to implement compat behaviors given an unknown message type
32
32
  * The parameters are typed to support compile-time enforcement of handling all known types/behaviors
@@ -56,26 +56,6 @@ exports.DefaultSummaryConfiguration = {
56
56
  runtimeOpWeight: 1.0,
57
57
  nonRuntimeHeuristicThreshold: 20,
58
58
  };
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
59
  /**
80
60
  * Tombstone error responses will have this header set to true
81
61
  * @alpha
@@ -192,7 +172,7 @@ async function createSummarizer(loader, url) {
192
172
  [container_definitions_1.LoaderHeader.cache]: false,
193
173
  [container_definitions_1.LoaderHeader.clientDetails]: {
194
174
  capabilities: { interactive: false },
195
- type: summary_1.summarizerClientType,
175
+ type: index_js_1.summarizerClientType,
196
176
  },
197
177
  [driver_definitions_1.DriverHeader.summarizingClient]: true,
198
178
  [container_definitions_1.LoaderHeader.reconnect]: false,
@@ -247,18 +227,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
247
227
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
248
228
  const backCompatContext = context;
249
229
  const passLogger = backCompatContext.taggedLogger ??
250
- // eslint-disable-next-line import/no-deprecated
251
230
  new telemetry_utils_1.TaggedLoggerAdapter(backCompatContext.logger);
252
231
  const logger = (0, telemetry_utils_1.createChildLogger)({
253
232
  logger: passLogger,
254
233
  properties: {
255
234
  all: {
256
- runtimeVersion: packageVersion_1.pkgVersion,
235
+ runtimeVersion: packageVersion_js_1.pkgVersion,
257
236
  },
258
237
  },
259
238
  });
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);
239
+ const mc = (0, telemetry_utils_1.loggerToMonitoringContext)(logger);
240
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = "off", chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
241
+ const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
262
242
  const tryFetchBlob = async (blobName) => {
263
243
  const blobId = context.baseSnapshot?.blobs[blobName];
264
244
  if (context.baseSnapshot && blobId) {
@@ -269,14 +249,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
269
249
  }
270
250
  };
271
251
  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),
252
+ tryFetchBlob(index_js_1.chunksBlobName),
253
+ tryFetchBlob(index_js_1.metadataBlobName),
254
+ tryFetchBlob(index_js_1.electedSummarizerBlobName),
255
+ tryFetchBlob(index_js_1.aliasBlobName),
256
+ tryFetchBlob(index_js_1.idCompressorBlobName),
277
257
  ]);
278
258
  // read snapshot blobs needed for BlobManager to load
279
- const blobManagerSnapshot = await blobManager_1.BlobManager.load(context.baseSnapshot?.trees[summary_1.blobsTreeName], async (id) => {
259
+ const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_1.blobsTreeName], async (id) => {
280
260
  // IContainerContext storage api return type still has undefined in 0.39 package version.
281
261
  // So once we release 0.40 container-defn package we can remove this check.
282
262
  (0, core_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
@@ -293,7 +273,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
293
273
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
294
274
  const error = new telemetry_utils_1.DataCorruptionError(
295
275
  // pre-0.58 error message: SummaryMetadataMismatch
296
- "Summary metadata mismatch", { runtimeVersion: packageVersion_1.pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
276
+ "Summary metadata mismatch", { runtimeVersion: packageVersion_js_1.pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
297
277
  if (loadSequenceNumberVerification === "log") {
298
278
  logger.sendErrorEvent({ eventName: "SequenceNumberMismatch" }, error);
299
279
  }
@@ -302,21 +282,62 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
302
282
  }
303
283
  }
304
284
  }
305
- const idCompressorEnabled = metadata?.idCompressorEnabled ?? runtimeOptions.enableRuntimeIdCompressor ?? false;
306
- let idCompressor;
307
- if (idCompressorEnabled) {
285
+ // Enabling the IdCompressor is a one-way operation and we only want to
286
+ // allow new containers to turn it on
287
+ let idCompressorMode;
288
+ if (existing) {
289
+ // This setting has to be sticky for correctness:
290
+ // 1) if compressior is OFF, it can't be enabled, as already running clients (in given document session) do not know
291
+ // how to process compressor ops
292
+ // 2) if it's ON, then all sessions should load compressor right away
293
+ // 3) Same logic applies for "delayed" mode
294
+ // Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
295
+ // We could do "off" -> "on" transtition too, if all clients start loading compressor (but not using it initially) and do so for a while -
296
+ // this will allow clients to eventually to disregard "off" setting (when it's safe so) and start using compressor in future sessions.
297
+ // Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
298
+ idCompressorMode = metadata?.idCompressorMode ?? "off";
299
+ }
300
+ else {
301
+ // FG overwrite
302
+ const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
303
+ switch (enabled) {
304
+ case true:
305
+ idCompressorMode = "on";
306
+ break;
307
+ case false:
308
+ idCompressorMode = "off";
309
+ break;
310
+ default:
311
+ idCompressorMode = enableRuntimeIdCompressor;
312
+ break;
313
+ }
314
+ }
315
+ const createIdCompressorFn = async () => {
308
316
  const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor");
317
+ /**
318
+ * Because the IdCompressor emits so much telemetry, this function is used to sample
319
+ * approximately 5% of all clients. Only the given percentage of sessions will emit telemetry.
320
+ */
321
+ const idCompressorEventSampler = (() => {
322
+ const isIdCompressorTelemetryEnabled = Math.random() < 0.05;
323
+ return {
324
+ sample: () => {
325
+ return isIdCompressorTelemetryEnabled;
326
+ },
327
+ };
328
+ })();
329
+ const compressorLogger = (0, telemetry_utils_1.createSampledLogger)(logger, idCompressorEventSampler);
309
330
  const pendingLocalState = context.pendingLocalState;
310
331
  if (pendingLocalState?.pendingIdCompressorState !== undefined) {
311
- idCompressor = deserializeIdCompressor(pendingLocalState.pendingIdCompressorState);
332
+ return deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
312
333
  }
313
334
  else if (serializedIdCompressor !== undefined) {
314
- idCompressor = deserializeIdCompressor(serializedIdCompressor, createSessionId());
335
+ return deserializeIdCompressor(serializedIdCompressor, createSessionId(), compressorLogger);
315
336
  }
316
337
  else {
317
- idCompressor = createIdCompressor(logger);
338
+ return createIdCompressor(compressorLogger);
318
339
  }
319
- }
340
+ };
320
341
  const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
321
342
  summaryOptions,
322
343
  gcOptions,
@@ -328,7 +349,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
328
349
  enableRuntimeIdCompressor,
329
350
  enableOpReentryCheck,
330
351
  enableGroupedBatching,
331
- }, containerScope, logger, existing, blobManagerSnapshot, context.storage, idCompressor, provideEntryPoint, requestHandler, undefined);
352
+ }, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, idCompressorMode, provideEntryPoint, requestHandler, undefined);
332
353
  // Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
333
354
  // or zero. This must be done before Container replays saved ops.
334
355
  await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
@@ -342,6 +363,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
342
363
  get storage() {
343
364
  return this._storage;
344
365
  }
366
+ get containerRuntime() {
367
+ return this;
368
+ }
345
369
  get flushMode() {
346
370
  return this._flushMode;
347
371
  }
@@ -354,6 +378,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
354
378
  get attachState() {
355
379
  return this._getAttachState();
356
380
  }
381
+ /**
382
+ * See IContainerRuntimeBase.idCompressor() for details.
383
+ */
384
+ get idCompressor() {
385
+ // Expose ID Compressor only if it's On from the start.
386
+ // If container uses delayed mode, then we can only expose generateDocumentUniqueId() and nothing else.
387
+ // That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
388
+ // to reason over such things as session ID space.
389
+ if (this.idCompressorMode === "on") {
390
+ (0, core_utils_1.assert)(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
391
+ return this._idCompressor;
392
+ }
393
+ }
394
+ /**
395
+ * See IContainerRuntimeBase.generateDocumentUniqueId() for details.
396
+ */
397
+ generateDocumentUniqueId() {
398
+ return this._idCompressor?.generateDocumentUniqueId() ?? (0, uuid_1.v4)();
399
+ }
357
400
  get IFluidHandleContext() {
358
401
  return this.handleContext;
359
402
  }
@@ -391,9 +434,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
391
434
  isSummariesDisabled() {
392
435
  return this.summaryConfiguration.state === "disabled";
393
436
  }
394
- isHeuristicsDisabled() {
395
- return this.summaryConfiguration.state === "disableHeuristics";
396
- }
397
437
  getMaxOpsSinceLastSummary() {
398
438
  return this.summaryConfiguration.state !== "disabled"
399
439
  ? this.summaryConfiguration.maxOpsSinceLastSummary
@@ -418,7 +458,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
418
458
  return this.garbageCollector.throwOnTombstoneUsage;
419
459
  }
420
460
  /***/
421
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, provideEntryPoint, requestHandler, summaryConfiguration = {
461
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, idCompressorMode, provideEntryPoint, requestHandler, summaryConfiguration = {
422
462
  // the defaults
423
463
  ...exports.DefaultSummaryConfiguration,
424
464
  // the runtime configuration overrides
@@ -426,13 +466,24 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
426
466
  }) {
427
467
  super();
428
468
  this.registry = registry;
469
+ this.metadata = metadata;
429
470
  this.runtimeOptions = runtimeOptions;
430
471
  this.containerScope = containerScope;
431
472
  this.logger = logger;
432
473
  this._storage = _storage;
474
+ this.createIdCompressor = createIdCompressor;
475
+ this.idCompressorMode = idCompressorMode;
433
476
  this.requestHandler = requestHandler;
434
477
  this.summaryConfiguration = summaryConfiguration;
435
478
  this.imminentClosure = false;
479
+ // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
480
+ // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
481
+ this.pendingIdCompressorOps = [];
482
+ /**
483
+ * True if we have ID compressor loading in-flight (async operation). Useful only for
484
+ * this.idCompressorMode === "delayed" mode
485
+ */
486
+ this.compressorLoadInitiated = false;
436
487
  this.defaultMaxConsecutiveReconnects = 7;
437
488
  this._orderSequentiallyCalls = 0;
438
489
  this.flushTaskExists = false;
@@ -454,18 +505,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
454
505
  signalTimestamp: 0,
455
506
  trackingSignalSequenceNumber: undefined,
456
507
  };
508
+ /**
509
+ * It a cache for holding mapping for loading groupIds with its snapshot from the service. Add expiry policy of 1 minute.
510
+ * Starting with 1 min and based on recorded usage we can tweak it later on.
511
+ */
512
+ this.snapshotCacheForLoadingGroupIds = new core_utils_1.PromiseCache({
513
+ expiry: { policy: "absolute", durationMs: 60000 },
514
+ });
457
515
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
458
516
  this.innerDeltaManager = deltaManager;
459
- this.deltaManager = new deltaManagerSummarizerProxy_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
517
+ this.deltaManager = new deltaManagerSummarizerProxy_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
460
518
  // Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
461
519
  // This makes ContainerRuntime the final gatekeeper for outgoing messages.
462
520
  this.submitFn = submitFn;
463
521
  this.submitBatchFn = submitBatchFn;
464
522
  this.submitSummaryFn = submitSummaryFn;
465
523
  this.submitSignalFn = submitSignalFn;
466
- this.options = options;
524
+ // TODO: After IContainerContext.options is removed, we'll just create a new blank object {} here.
525
+ // Values are generally expected to be set from the runtime side.
526
+ this.options = options ?? {};
467
527
  this.clientDetails = clientDetails;
468
- this.isSummarizerClient = this.clientDetails.type === summary_1.summarizerClientType;
528
+ this.isSummarizerClient = this.clientDetails.type === index_js_1.summarizerClientType;
469
529
  this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
470
530
  this._getClientId = () => context.clientId;
471
531
  this._getAttachState = () => context.attachState;
@@ -501,19 +561,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
501
561
  // summaryNumber was renamed from summaryCount. For older docs that haven't been opened for a long time,
502
562
  // the count is reset to 0.
503
563
  loadSummaryNumber = metadata?.summaryNumber ?? 0;
504
- // Enabling the IdCompressor is a one-way operation and we only want to
505
- // allow new containers to turn it on
506
- this.idCompressorEnabled = metadata?.idCompressorEnabled ?? false;
507
564
  }
508
565
  else {
509
566
  this.createContainerMetadata = {
510
- createContainerRuntimeVersion: packageVersion_1.pkgVersion,
567
+ createContainerRuntimeVersion: packageVersion_js_1.pkgVersion,
511
568
  createContainerTimestamp: Date.now(),
512
569
  };
513
570
  loadSummaryNumber = 0;
514
- this.idCompressorEnabled =
515
- this.mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled") ??
516
- idCompressor !== undefined;
517
571
  }
518
572
  this.nextSummaryNumber = loadSummaryNumber + 1;
519
573
  this.messageAtLastSummary = metadata?.message;
@@ -524,21 +578,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
524
578
  eventName: "GCFeatureMatrix",
525
579
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
526
580
  inputs: JSON.stringify({
527
- gcOptions_gcGeneration: this.runtimeOptions.gcOptions[gc_1.gcGenerationOptionName],
581
+ gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_2.gcGenerationOptionName],
528
582
  }),
529
583
  });
530
584
  this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
531
585
  this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
532
586
  const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
533
- const opGroupingManager = new opLifecycle_1.OpGroupingManager({
587
+ const opGroupingManager = new index_js_3.OpGroupingManager({
534
588
  groupedBatchingEnabled: this.groupedBatchingEnabled,
535
589
  opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
536
590
  reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
537
591
  true,
538
592
  }, this.mc.logger);
539
- const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
540
- this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor(this.mc.logger), opGroupingManager);
541
- this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
593
+ const opSplitter = new index_js_3.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
594
+ this.remoteMessageProcessor = new index_js_3.RemoteMessageProcessor(opSplitter, new index_js_3.OpDecompressor(this.mc.logger), opGroupingManager);
595
+ this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
542
596
  if (this.summaryConfiguration.state === "enabled") {
543
597
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
544
598
  }
@@ -548,12 +602,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
548
602
  // Allow for a break-glass config to override the options
549
603
  disableOpReentryCheck !== true;
550
604
  this.summariesDisabled = this.isSummariesDisabled();
551
- this.heuristicsDisabled = this.isHeuristicsDisabled();
552
605
  this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
553
606
  this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
554
- if (this.idCompressorEnabled) {
555
- this.idCompressor = idCompressor;
556
- }
557
607
  this.maxConsecutiveReconnects =
558
608
  this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
559
609
  this.defaultMaxConsecutiveReconnects;
@@ -567,15 +617,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
567
617
  this._flushMode = runtimeOptions.flushMode;
568
618
  }
569
619
  const pendingRuntimeState = pendingLocalState;
570
- const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
571
- if (maxSnapshotCacheDurationMs !== undefined &&
572
- maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
573
- // This is a runtime enforcement of what's already explicit in the policy's type itself,
574
- // which dictates the value is either undefined or exactly 5 days in ms.
575
- // As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
576
- throw new telemetry_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
577
- }
578
- this.garbageCollector = gc_1.GarbageCollector.create({
620
+ if (context.attachState === container_definitions_1.AttachState.Attached) {
621
+ const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
622
+ if (maxSnapshotCacheDurationMs !== undefined &&
623
+ maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
624
+ // This is a runtime enforcement of what's already explicit in the policy's type itself,
625
+ // which dictates the value is either undefined or exactly 5 days in ms.
626
+ // As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
627
+ throw new telemetry_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
628
+ }
629
+ }
630
+ this.garbageCollector = index_js_2.GarbageCollector.create({
579
631
  runtime: this,
580
632
  gcOptions: this.runtimeOptions.gcOptions,
581
633
  baseSnapshot,
@@ -588,9 +640,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
588
640
  getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
589
641
  readAndParseBlob: async (id) => (0, driver_utils_1.readAndParse)(this.storage, id),
590
642
  submitMessage: (message) => this.submit(message),
643
+ sessionExpiryTimerStarted: pendingRuntimeState?.sessionExpiryTimerStarted,
591
644
  });
592
645
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
593
- this.summarizerNode = (0, summary_1.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
646
+ this.summarizerNode = (0, index_js_1.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
594
647
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
595
648
  async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
596
649
  // Latest change sequence number, no changes since summary applied yet
@@ -600,9 +653,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
600
653
  // Must set to false to prevent sending summary handle which would be pointing to
601
654
  // a summary with an older protocol state.
602
655
  canReuseHandle: false,
603
- // Must set to true to throw on any data stores failure that was too severe to be handled.
604
- // We also are not decoding the base summaries at the root.
605
- throwOnFailure: true,
606
656
  // If GC should not run, let the summarizer node know so that it does not track GC state.
607
657
  gcDisabled: !this.garbageCollector.shouldRunGC,
608
658
  },
@@ -613,17 +663,26 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
613
663
  if (baseSnapshot) {
614
664
  this.summarizerNode.updateBaseSummaryState(baseSnapshot);
615
665
  }
616
- 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));
617
- this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
666
+ const parentContext = (0, channelCollection_js_1.wrapContext)(this);
667
+ // Due to a mismatch between different layers in terms of
668
+ // what is the interface of passing signals, we need the
669
+ // downstream stores to wrap the signal.
670
+ parentContext.submitSignal = (type, content, targetClientId) => {
671
+ const envelope1 = content;
672
+ const envelope2 = this.createNewSignalEnvelope(envelope1.address, type, envelope1.contents);
673
+ return this.submitSignalFn(envelope2, targetClientId);
674
+ };
675
+ 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);
676
+ this.blobManager = new blobManager_js_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
618
677
  if (!this.disposed) {
619
- this.submit({ type: messageTypes_1.ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
678
+ this.submit({ type: messageTypes_js_1.ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
620
679
  localId,
621
680
  blobId,
622
681
  });
623
682
  }
624
683
  }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState?.pendingAttachmentBlobs, (error) => this.closeFn(error));
625
- this.scheduleManager = new scheduleManager_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
626
- this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
684
+ this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
685
+ this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
627
686
  applyStashedOp: this.applyStashedOp.bind(this),
628
687
  clientId: () => this.clientId,
629
688
  close: this.closeFn,
@@ -631,6 +690,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
631
690
  reSubmit: this.reSubmit.bind(this),
632
691
  reSubmitBatch: this.reSubmitBatch.bind(this),
633
692
  isActiveConnection: () => this.innerDeltaManager.active,
693
+ isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
634
694
  }, pendingRuntimeState?.pending, this.logger);
635
695
  const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
636
696
  const compressionOptions = disableCompression === true
@@ -641,12 +701,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
641
701
  : runtimeOptions.compressionOptions;
642
702
  const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
643
703
  const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
644
- this.outbox = new opLifecycle_1.Outbox({
704
+ this.outbox = new index_js_3.Outbox({
645
705
  shouldSend: () => this.canSendOps(),
646
706
  pendingStateManager: this.pendingStateManager,
647
707
  submitBatchFn: this.submitBatchFn,
648
708
  legacySendBatchFn,
649
- compressor: new opLifecycle_1.OpCompressor(this.mc.logger),
709
+ compressor: new index_js_3.OpCompressor(this.mc.logger),
650
710
  splitter: opSplitter,
651
711
  config: {
652
712
  compressionOptions,
@@ -673,7 +733,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
673
733
  this.closeSummarizerDelayMs = closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
674
734
  this.validateSummaryBeforeUpload =
675
735
  this.mc.config.getBoolean("Fluid.Summarizer.ValidateSummaryBeforeUpload") ?? false;
676
- this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
736
+ this.summaryCollection = new index_js_1.SummaryCollection(this.deltaManager, this.logger);
677
737
  this.dirtyContainer =
678
738
  this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
679
739
  context.updateDirtyContainerState(this.dirtyContainer);
@@ -685,16 +745,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
685
745
  logger: this.logger,
686
746
  namespace: "OrderedClientElection",
687
747
  });
688
- const orderedClientCollection = new summary_1.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
689
- const orderedClientElectionForSummarizer = new summary_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, summary_1.SummarizerClientElection.isClientEligible);
690
- this.summarizerClientElection = new summary_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
748
+ const orderedClientCollection = new index_js_1.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
749
+ const orderedClientElectionForSummarizer = new index_js_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_1.SummarizerClientElection.isClientEligible);
750
+ this.summarizerClientElection = new index_js_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
691
751
  if (this.isSummarizerClient) {
692
- this._summarizer = new summary_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => summary_1.RunWhileConnectedCoordinator.create(runtime,
752
+ 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,
693
753
  // Summarization runs in summarizer client and needs access to the real (non-proxy) active
694
754
  // information. The proxy delta manager would always return false for summarizer client.
695
755
  () => this.innerDeltaManager.active));
696
756
  }
697
- else if (summary_1.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
757
+ else if (index_js_1.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
698
758
  // Only create a SummaryManager and SummarizerClientElection
699
759
  // if summaries are enabled and we are not the summarizer client.
700
760
  const defaultAction = () => {
@@ -716,13 +776,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
716
776
  };
717
777
  this.summaryCollection.on("default", defaultAction);
718
778
  // Create the SummaryManager and mark the initial state
719
- this.summaryManager = new summary_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
720
- this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_1.Throttler(60 * 1000, // 60 sec delay window
779
+ this.summaryManager = new index_js_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
780
+ this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
721
781
  30 * 1000, // 30 sec max delay
722
782
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
723
- (0, throttler_1.formExponentialFn)({ coefficient: 20, initialDelay: 0 })), {
783
+ (0, throttler_js_1.formExponentialFn)({ coefficient: 20, initialDelay: 0 })), {
724
784
  initialDelayMs: this.initialSummarizerDelayMs,
725
- }, this.heuristicsDisabled);
785
+ });
726
786
  this.summaryManager.on("summarize", (eventProps) => {
727
787
  this.emit("summarize", eventProps);
728
788
  });
@@ -737,26 +797,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
737
797
  this.mc.logger.sendTelemetryEvent({
738
798
  eventName: "ContainerLoadStats",
739
799
  ...this.createContainerMetadata,
740
- ...this.dataStores.containerLoadStats,
800
+ ...this.channelCollection.containerLoadStats,
741
801
  summaryNumber: loadSummaryNumber,
742
802
  summaryFormatVersion: metadata?.summaryFormatVersion,
743
803
  disableIsolatedChannels: metadata?.disableIsolatedChannels,
744
804
  gcVersion: metadata?.gcFeature,
745
805
  options: JSON.stringify(runtimeOptions),
806
+ idCompressorModeMetadata: metadata?.idCompressorMode,
807
+ idCompressorMode: this.idCompressorMode,
746
808
  featureGates: JSON.stringify({
747
809
  disableCompression,
748
810
  disableOpReentryCheck,
749
811
  disableChunking,
750
812
  disableAttachReorder: this.disableAttachReorder,
751
813
  disablePartialFlush,
752
- idCompressorEnabled: this.idCompressorEnabled,
753
814
  closeSummarizerDelayOverride,
754
815
  }),
755
816
  telemetryDocumentId: this.telemetryDocumentId,
756
817
  groupedBatchingEnabled: this.groupedBatchingEnabled,
757
818
  });
758
- (0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this.logger);
759
- (0, batchTracker_1.BindBatchTracker)(this, this.logger);
819
+ (0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this, this.logger);
820
+ (0, batchTracker_js_1.BindBatchTracker)(this, this.logger);
760
821
  this.entryPoint = new core_utils_1.LazyPromise(async () => {
761
822
  if (this.isSummarizerClient) {
762
823
  (0, core_utils_1.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
@@ -764,11 +825,29 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
764
825
  }
765
826
  return provideEntryPoint(this);
766
827
  });
828
+ // If we loaded from pending state, then we need to skip any ops that are already accounted in such
829
+ // saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
830
+ this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
831
+ }
832
+ getCreateChildSummarizerNodeFn(id, createParam) {
833
+ return (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn);
834
+ }
835
+ deleteChildSummarizerNode(id) {
836
+ return this.summarizerNode.deleteChild(id);
837
+ }
838
+ makeLocallyVisible() {
839
+ (0, core_utils_1.assert)(false, 0x8eb /* should not be called */);
767
840
  }
768
841
  /**
769
842
  * Initializes the state from the base snapshot this container runtime loaded from.
770
843
  */
771
844
  async initializeBaseState() {
845
+ if (this.idCompressorMode === "on" ||
846
+ (this.idCompressorMode === "delayed" && this.connected)) {
847
+ // This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
848
+ (0, core_utils_1.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
849
+ this._idCompressor = await this.createIdCompressor();
850
+ }
772
851
  await this.garbageCollector.initializeBaseState();
773
852
  }
774
853
  dispose(error) {
@@ -787,11 +866,110 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
787
866
  }
788
867
  this.garbageCollector.dispose();
789
868
  this._summarizer?.dispose();
790
- this.dataStores.dispose();
869
+ this.channelCollection.dispose();
791
870
  this.pendingStateManager.dispose();
792
871
  this.emit("dispose");
793
872
  this.removeAllListeners();
794
873
  }
874
+ /**
875
+ * Api to fetch the snapshot from the service for a loadingGroupIds.
876
+ * @param loadingGroupIds - LoadingGroupId for which the snapshot is asked for.
877
+ * @param pathParts - Parts of the path, which we want to extract from the snapshot tree.
878
+ * @returns - snapshotTree and the sequence number of the snapshot.
879
+ */
880
+ async getSnapshotForLoadingGroupId(loadingGroupIds, pathParts) {
881
+ const sortedLoadingGroupIds = loadingGroupIds.sort();
882
+ (0, core_utils_1.assert)(this.storage.getSnapshot !== undefined, 0x8ed /* getSnapshot api should be defined if used */);
883
+ let loadedFromCache = true;
884
+ // Lookup up in the cache, if not present then make the network call as multiple datastores could
885
+ // be in same loading group. So, once we have fetched the snapshot for that loading group on
886
+ // any request, then cache that as same group could be requested in future too.
887
+ const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(), async () => {
888
+ (0, core_utils_1.assert)(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
889
+ loadedFromCache = false;
890
+ return this.storage.getSnapshot({
891
+ cacheSnapshot: false,
892
+ scenarioName: "snapshotForLoadingGroupId",
893
+ loadingGroupIds: sortedLoadingGroupIds,
894
+ });
895
+ });
896
+ this.logger.sendTelemetryEvent({
897
+ eventName: "GroupIdSnapshotFetched",
898
+ details: JSON.stringify({
899
+ fromCache: loadedFromCache,
900
+ loadingGroupIds: loadingGroupIds.join(","),
901
+ }),
902
+ });
903
+ // Find the snapshotTree inside the returned snapshot based on the path as given in the request.
904
+ const hasIsolatedChannels = (0, index_js_1.rootHasIsolatedChannels)(this.metadata);
905
+ const snapshotTreeForPath = this.getSnapshotTreeForPath(snapshot.snapshotTree, pathParts, hasIsolatedChannels);
906
+ (0, core_utils_1.assert)(snapshotTreeForPath !== undefined, 0x8ef /* no snapshotTree for the path */);
907
+ const snapshotSeqNumber = snapshot.sequenceNumber;
908
+ (0, core_utils_1.assert)(snapshotSeqNumber !== undefined, 0x8f0 /* snapshotSeqNumber should be present */);
909
+ // This assert fires if we get a snapshot older than the snapshot we loaded from. This is a service issue.
910
+ // Snapshots should only move forward. If we observe an older snapshot than the one we loaded from, then likely
911
+ // the file has been overwritten or service lost data.
912
+ if (snapshotSeqNumber < this.deltaManager.initialSequenceNumber) {
913
+ throw telemetry_utils_1.DataProcessingError.create("Downloaded snapshot older than snapshot we loaded from", "getSnapshotForLoadingGroupId", undefined, {
914
+ loadingGroupIds: sortedLoadingGroupIds.join(","),
915
+ snapshotSeqNumber,
916
+ initialSequenceNumber: this.deltaManager.initialSequenceNumber,
917
+ });
918
+ }
919
+ // If the snapshot is ahead of the last seq number of the delta manager, then catch up before
920
+ // returning the snapshot.
921
+ if (snapshotSeqNumber > this.deltaManager.lastSequenceNumber) {
922
+ // If this is a summarizer client, which is trying to load a group and it finds that there is
923
+ // another snapshot from which the summarizer loaded and it is behind, then just give up as
924
+ // the summarizer state is not up to date.
925
+ // This should be a recoverable scenario and shouldn't happen as we should process the ack first.
926
+ if (this.isSummarizerClient) {
927
+ throw new Error("Summarizer client behind, loaded newer snapshot with loadingGroupId");
928
+ }
929
+ // We want to catchup from sequenceNumber to targetSequenceNumber
930
+ const props = {
931
+ eventName: "GroupIdSnapshotCatchup",
932
+ loadingGroupIds: sortedLoadingGroupIds.join(","),
933
+ targetSequenceNumber: snapshotSeqNumber,
934
+ sequenceNumber: this.deltaManager.lastSequenceNumber, // This is so we reuse some columns in telemetry
935
+ };
936
+ const event = telemetry_utils_1.PerformanceEvent.start(this.mc.logger, {
937
+ ...props,
938
+ });
939
+ // If the inbound deltas queue is paused or disconnected, we expect a reconnect and unpause
940
+ // as long as it's not a summarizer client.
941
+ if (this.deltaManager.inbound.paused) {
942
+ props.inboundPaused = this.deltaManager.inbound.paused; // reusing telemetry
943
+ }
944
+ const defP = new core_utils_1.Deferred();
945
+ this.deltaManager.on("op", (message) => {
946
+ if (message.sequenceNumber >= snapshotSeqNumber) {
947
+ defP.resolve(true);
948
+ }
949
+ });
950
+ await defP.promise;
951
+ event.end(props);
952
+ }
953
+ return { snapshotTree: snapshotTreeForPath, sequenceNumber: snapshotSeqNumber };
954
+ }
955
+ /**
956
+ * Api to find a snapshot tree inside a bigger snapshot tree based on the path in the pathParts array.
957
+ * @param snapshotTree - snapshot tree to look into.
958
+ * @param pathParts - Part of the path, which we want to extract from the snapshot tree.
959
+ * @param hasIsolatedChannels - whether the channels are present inside ".channels" subtree. Older
960
+ * snapshots will not have trees inside ".channels", so check that.
961
+ * @returns - requested snapshot tree based on the path parts.
962
+ */
963
+ getSnapshotTreeForPath(snapshotTree, pathParts, hasIsolatedChannels) {
964
+ let childTree = snapshotTree;
965
+ for (const part of pathParts) {
966
+ if (hasIsolatedChannels) {
967
+ childTree = childTree?.trees[runtime_definitions_1.channelsTreeName];
968
+ }
969
+ childTree = childTree?.trees[part];
970
+ }
971
+ return childTree;
972
+ }
795
973
  /**
796
974
  * Notifies this object about the request made to the container.
797
975
  * @param request - Request made to the handler.
@@ -834,7 +1012,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
834
1012
  // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
835
1013
  return this.resolveHandle(requestParser.createSubRequest(1));
836
1014
  }
837
- if (id === blobManager_1.BlobManager.basePath && requestParser.isLeaf(2)) {
1015
+ if (id === blobManager_js_1.BlobManager.basePath && requestParser.isLeaf(2)) {
838
1016
  const blob = await this.blobManager.getBlob(requestParser.pathParts[1]);
839
1017
  return blob
840
1018
  ? {
@@ -845,15 +1023,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
845
1023
  : (0, runtime_utils_1.create404Response)(request);
846
1024
  }
847
1025
  else if (requestParser.pathParts.length > 0) {
848
- // Differentiate between requesting the dataStore directly, or one of its children
849
- const requestForChild = !requestParser.isLeaf(1);
850
- const dataStore = await this.getDataStoreFromRequest(id, request, requestForChild);
851
- const subRequest = requestParser.createSubRequest(1);
852
- // We always expect createSubRequest to include a leading slash, but asserting here to protect against
853
- // unintentionally modifying the url if that changes.
854
- (0, core_utils_1.assert)(subRequest.url.startsWith("/"), 0x126 /* "Expected createSubRequest url to include a leading slash" */);
855
- // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
856
- return dataStore.request(subRequest);
1026
+ return await this.channelCollection.request(request);
857
1027
  }
858
1028
  return (0, runtime_utils_1.create404Response)(request);
859
1029
  }
@@ -868,38 +1038,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
868
1038
  return this.entryPoint;
869
1039
  }
870
1040
  internalId(maybeAlias) {
871
- return this.dataStores.aliases.get(maybeAlias) ?? maybeAlias;
872
- }
873
- async getDataStoreFromRequest(id, request, requestForChild) {
874
- const headerData = {};
875
- if (typeof request.headers?.[RuntimeHeaders.wait] === "boolean") {
876
- headerData.wait = request.headers[RuntimeHeaders.wait];
877
- }
878
- if (typeof request.headers?.[RuntimeHeaders.viaHandle] === "boolean") {
879
- headerData.viaHandle = request.headers[RuntimeHeaders.viaHandle];
880
- }
881
- if (typeof request.headers?.[exports.AllowTombstoneRequestHeaderKey] === "boolean") {
882
- headerData.allowTombstone = request.headers[exports.AllowTombstoneRequestHeaderKey];
883
- }
884
- if (typeof request.headers?.[exports.AllowInactiveRequestHeaderKey] === "boolean") {
885
- headerData.allowInactive = request.headers[exports.AllowInactiveRequestHeaderKey];
886
- }
887
- // We allow Tombstone requests for sub-DataStore objects
888
- if (requestForChild) {
889
- headerData.allowTombstone = true;
890
- }
891
- await this.dataStores.waitIfPendingAlias(id);
892
- const internalId = this.internalId(id);
893
- const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
894
- // Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
895
- // the same as GC nodes id.
896
- const urlWithoutQuery = (0, gc_1.trimLeadingAndTrailingSlashes)(request.url.split("?")[0]);
897
- // Get the initial snapshot details which contain the data store package path.
898
- const details = await dataStoreContext.getInitialSnapshotDetails();
899
- // Note that this will throw if the data store is inactive or tombstoned and throwing on incorrect usage
900
- // is configured.
901
- this.garbageCollector.nodeUpdated(`/${urlWithoutQuery}`, "Loaded", undefined /* timestampMs */, details.pkg, request, headerData);
902
- return dataStoreContext.realize();
1041
+ return this.channelCollection.internalId(maybeAlias);
903
1042
  }
904
1043
  /** Adds the container's metadata to the given summary tree. */
905
1044
  addMetadataToSummary(summaryTree) {
@@ -911,37 +1050,36 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
911
1050
  ...this.garbageCollector.getMetadata(),
912
1051
  // The last message processed at the time of summary. If there are no new messages, use the message from the
913
1052
  // last summary.
914
- message: (0, summary_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
1053
+ message: (0, index_js_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
915
1054
  this.messageAtLastSummary,
916
1055
  telemetryDocumentId: this.telemetryDocumentId,
917
- idCompressorEnabled: this.idCompressorEnabled ? true : undefined,
1056
+ idCompressorMode: this.idCompressorMode,
918
1057
  };
919
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.metadataBlobName, JSON.stringify(metadata));
1058
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.metadataBlobName, JSON.stringify(metadata));
920
1059
  }
921
1060
  addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
922
1061
  this.addMetadataToSummary(summaryTree);
923
- if (this.idCompressorEnabled) {
924
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67a /* IdCompressor should be defined if enabled */);
925
- const idCompressorState = JSON.stringify(this.idCompressor.serialize(false));
926
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.idCompressorBlobName, idCompressorState);
1062
+ if (this._idCompressor) {
1063
+ const idCompressorState = JSON.stringify(this._idCompressor.serialize(false));
1064
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.idCompressorBlobName, idCompressorState);
927
1065
  }
928
1066
  if (this.remoteMessageProcessor.partialMessages.size > 0) {
929
1067
  const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
930
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.chunksBlobName, content);
1068
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.chunksBlobName, content);
931
1069
  }
932
- const dataStoreAliases = this.dataStores.aliases;
1070
+ const dataStoreAliases = this.channelCollection.aliases;
933
1071
  if (dataStoreAliases.size > 0) {
934
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
1072
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
935
1073
  }
936
1074
  if (this.summarizerClientElection) {
937
1075
  const electedSummarizerContent = JSON.stringify(this.summarizerClientElection?.serialize());
938
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.electedSummarizerBlobName, electedSummarizerContent);
1076
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_1.electedSummarizerBlobName, electedSummarizerContent);
939
1077
  }
940
1078
  const blobManagerSummary = this.blobManager.summarize();
941
1079
  // Some storage (like git) doesn't allow empty tree, so we can omit it.
942
1080
  // and the blob manager can handle the tree not existing when loading
943
1081
  if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
944
- (0, runtime_utils_1.addTreeToSummary)(summaryTree, summary_1.blobsTreeName, blobManagerSummary);
1082
+ (0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, index_js_1.blobsTreeName, blobManagerSummary);
945
1083
  }
946
1084
  const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
947
1085
  if (gcSummary !== undefined) {
@@ -981,7 +1119,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
981
1119
  // in their own batches before the originating batch is sent.
982
1120
  // Therefore, receiving them while attempting to send the originating batch
983
1121
  // does not mean that the container is making any progress.
984
- if (message?.type !== messageTypes_1.ContainerMessageType.ChunkedOp) {
1122
+ if (message?.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp) {
985
1123
  this.consecutiveReconnects = 0;
986
1124
  }
987
1125
  }
@@ -1027,21 +1165,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1027
1165
  // Need to parse from string for back-compat
1028
1166
  const opContents = this.parseLocalOpContent(serializedOpContent);
1029
1167
  switch (opContents.type) {
1030
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
1031
- return this.dataStores.applyStashedOp(opContents.contents);
1032
- case messageTypes_1.ContainerMessageType.Attach:
1033
- return this.dataStores.applyStashedAttachOp(opContents.contents);
1034
- case messageTypes_1.ContainerMessageType.IdAllocation:
1035
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67b /* IdCompressor should be defined if enabled */);
1168
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
1169
+ case messageTypes_js_1.ContainerMessageType.Attach:
1170
+ case messageTypes_js_1.ContainerMessageType.Alias:
1171
+ return this.channelCollection.applyStashedOp(opContents);
1172
+ case messageTypes_js_1.ContainerMessageType.IdAllocation:
1173
+ (0, core_utils_1.assert)(this.idCompressorMode !== "off", 0x8f1 /* ID compressor should be in use */);
1036
1174
  return;
1037
- case messageTypes_1.ContainerMessageType.Alias:
1038
- case messageTypes_1.ContainerMessageType.BlobAttach:
1175
+ case messageTypes_js_1.ContainerMessageType.BlobAttach:
1039
1176
  return;
1040
- case messageTypes_1.ContainerMessageType.ChunkedOp:
1177
+ case messageTypes_js_1.ContainerMessageType.ChunkedOp:
1041
1178
  throw new Error("chunkedOp not expected here");
1042
- case messageTypes_1.ContainerMessageType.Rejoin:
1179
+ case messageTypes_js_1.ContainerMessageType.Rejoin:
1043
1180
  throw new Error("rejoin not expected here");
1044
- case messageTypes_1.ContainerMessageType.GC:
1181
+ case messageTypes_js_1.ContainerMessageType.GC:
1045
1182
  // GC op is only sent in summarizer which should never have stashed ops.
1046
1183
  throw new telemetry_utils_1.LoggingError("GC op not expected to be stashed in summarizer");
1047
1184
  default: {
@@ -1059,10 +1196,26 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1059
1196
  this.closeFn(error);
1060
1197
  throw error;
1061
1198
  }
1199
+ // Note: Even if its compat behavior allows it, we don't know how to apply this stashed op.
1200
+ // All we can do is ignore it (similar to on process).
1062
1201
  }
1063
1202
  }
1064
1203
  }
1065
1204
  setConnectionState(connected, clientId) {
1205
+ if (connected && this.idCompressorMode === "delayed" && !this.compressorLoadInitiated) {
1206
+ this.compressorLoadInitiated = true;
1207
+ this.createIdCompressor()
1208
+ .then((compressor) => {
1209
+ this._idCompressor = compressor;
1210
+ for (const range of this.pendingIdCompressorOps) {
1211
+ this._idCompressor.finalizeCreationRange(range);
1212
+ }
1213
+ this.pendingIdCompressorOps = [];
1214
+ })
1215
+ .catch((error) => {
1216
+ this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
1217
+ });
1218
+ }
1066
1219
  if (connected === false && this.delayConnectClientId !== undefined) {
1067
1220
  this.delayConnectClientId = undefined;
1068
1221
  this.mc.logger.sendTelemetryEvent({
@@ -1126,7 +1279,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1126
1279
  if (changeOfState) {
1127
1280
  this.replayPendingStates();
1128
1281
  }
1129
- this.dataStores.setConnectionState(connected, clientId);
1282
+ this.channelCollection.setConnectionState(connected, clientId);
1130
1283
  this.garbageCollector.setConnectionState(connected, clientId);
1131
1284
  (0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
1132
1285
  }
@@ -1176,7 +1329,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1176
1329
  let localOpMetadata;
1177
1330
  if (local &&
1178
1331
  messageWithContext.modernRuntimeMessage &&
1179
- message.type !== messageTypes_1.ContainerMessageType.ChunkedOp) {
1332
+ message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp) {
1180
1333
  localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
1181
1334
  }
1182
1335
  // If there are no more pending messages after processing a local message,
@@ -1208,31 +1361,36 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1208
1361
  // TODO: destructure message and modernRuntimeMessage once using typescript 5.2.2+
1209
1362
  const { local } = messageWithContext;
1210
1363
  switch (messageWithContext.message.type) {
1211
- case messageTypes_1.ContainerMessageType.Attach:
1212
- this.dataStores.processAttachMessage(messageWithContext.message, local);
1213
- break;
1214
- case messageTypes_1.ContainerMessageType.Alias:
1215
- this.dataStores.processAliasMessage(messageWithContext.message, localOpMetadata, local);
1364
+ case messageTypes_js_1.ContainerMessageType.Attach:
1365
+ case messageTypes_js_1.ContainerMessageType.Alias:
1366
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
1367
+ this.channelCollection.process(messageWithContext.message, local, localOpMetadata, (from, to) => this.garbageCollector.addedOutboundReference(from, to));
1216
1368
  break;
1217
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
1218
- this.dataStores.processFluidDataStoreOp(messageWithContext.message, local, localOpMetadata, (from, to) => this.garbageCollector.addedOutboundReference(from, to));
1219
- break;
1220
- case messageTypes_1.ContainerMessageType.BlobAttach:
1369
+ case messageTypes_js_1.ContainerMessageType.BlobAttach:
1221
1370
  this.blobManager.processBlobAttachOp(messageWithContext.message, local);
1222
1371
  break;
1223
- case messageTypes_1.ContainerMessageType.IdAllocation:
1224
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67c /* IdCompressor should be defined if enabled */);
1372
+ case messageTypes_js_1.ContainerMessageType.IdAllocation:
1225
1373
  // Don't re-finalize the range if we're processing a "savedOp" in
1226
1374
  // stashed ops flow. The compressor is stashed with these ops already processed.
1227
- if (messageWithContext.message.metadata?.savedOp !== true) {
1228
- this.idCompressor.finalizeCreationRange(messageWithContext.message.contents);
1375
+ // That said, in idCompressorMode === "delayed", we might not serialize ID compressor, and
1376
+ // thus we need to process all the ops.
1377
+ if (!(this.skipSavedCompressorOps &&
1378
+ messageWithContext.message.metadata?.savedOp ===
1379
+ true)) {
1380
+ const range = messageWithContext.message.contents;
1381
+ if (this._idCompressor === undefined) {
1382
+ this.pendingIdCompressorOps.push(range);
1383
+ }
1384
+ else {
1385
+ this._idCompressor.finalizeCreationRange(range);
1386
+ }
1229
1387
  }
1230
1388
  break;
1231
- case messageTypes_1.ContainerMessageType.GC:
1389
+ case messageTypes_js_1.ContainerMessageType.GC:
1232
1390
  this.garbageCollector.processMessage(messageWithContext.message, local);
1233
1391
  break;
1234
- case messageTypes_1.ContainerMessageType.ChunkedOp:
1235
- case messageTypes_1.ContainerMessageType.Rejoin:
1392
+ case messageTypes_js_1.ContainerMessageType.ChunkedOp:
1393
+ case messageTypes_js_1.ContainerMessageType.Rejoin:
1236
1394
  break;
1237
1395
  default: {
1238
1396
  // If we didn't necessarily expect a runtime message type, then no worries - just return
@@ -1312,7 +1470,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1312
1470
  this.emit("signal", transformed, local);
1313
1471
  return;
1314
1472
  }
1315
- this.dataStores.processSignal(envelope.address, transformed, local);
1473
+ // Due to a mismatch between different layers in terms of
1474
+ // what is the interface of passing signals, we need to adjust
1475
+ // the signal envelope before sending it to the datastores to be processed
1476
+ const envelope2 = {
1477
+ address: envelope.address,
1478
+ contents: transformed.content,
1479
+ };
1480
+ transformed.content = envelope2;
1481
+ this.channelCollection.processSignal(transformed, local);
1316
1482
  }
1317
1483
  /**
1318
1484
  * Flush the pending ops manually.
@@ -1376,9 +1542,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1376
1542
  * Returns undefined if no data store has been assigned the given alias.
1377
1543
  */
1378
1544
  async getAliasedDataStoreEntryPoint(alias) {
1379
- await this.dataStores.waitIfPendingAlias(alias);
1545
+ // Back-comapatibility:
1546
+ // There are old files that were created without using data store aliasing feature, but
1547
+ // used createRoot*DataStore*() (already removed) API. Such data stores will have isRoot = true,
1548
+ // and internalID provided by user. The expectation is that such files behave as new files, where
1549
+ // same data store instances created using aliasing feature.
1550
+ // Please also see note on name collisions in DataStores.createDataStoreId()
1551
+ await this.channelCollection.waitIfPendingAlias(alias);
1380
1552
  const internalId = this.internalId(alias);
1381
- const context = await this.dataStores.getDataStoreIfAvailable(internalId, { wait: false });
1553
+ const context = await this.channelCollection.getDataStoreIfAvailable(internalId, {
1554
+ wait: false,
1555
+ });
1382
1556
  // If the data store is not available or not an alias, return undefined.
1383
1557
  if (context === undefined || !(await context.isRoot())) {
1384
1558
  return undefined;
@@ -1390,28 +1564,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1390
1564
  this.garbageCollector.nodeUpdated(`/${internalId}`, "Loaded", undefined /* timestampMs */, context.packagePath);
1391
1565
  return channel.entryPoint;
1392
1566
  }
1393
- createDetachedRootDataStore(pkg, rootDataStoreId) {
1394
- if (rootDataStoreId.includes("/")) {
1395
- throw new telemetry_utils_1.UsageError(`Id cannot contain slashes: '${rootDataStoreId}'`);
1396
- }
1397
- return this.dataStores.createDetachedDataStoreCore(pkg, true, rootDataStoreId);
1398
- }
1399
- createDetachedDataStore(pkg) {
1400
- return this.dataStores.createDetachedDataStoreCore(pkg, false);
1567
+ createDetachedDataStore(pkg, loadingGroupId) {
1568
+ return this.channelCollection.createDetachedDataStoreCore(pkg, loadingGroupId);
1401
1569
  }
1402
- async createDataStore(pkg) {
1403
- const id = (0, uuid_1.v4)();
1404
- return (0, dataStore_1.channelToDataStore)(await this.dataStores
1405
- ._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id)
1406
- .realize(), id, this, this.dataStores, this.mc.logger);
1570
+ async createDataStore(pkg, loadingGroupId) {
1571
+ const context = this.channelCollection._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], undefined, // props
1572
+ loadingGroupId);
1573
+ return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
1407
1574
  }
1408
1575
  /**
1409
1576
  * @deprecated 0.16 Issue #1537, #3631
1410
1577
  */
1411
- async _createDataStoreWithProps(pkg, props, id = (0, uuid_1.v4)()) {
1412
- return (0, dataStore_1.channelToDataStore)(await this.dataStores
1413
- ._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
1414
- .realize(), id, this, this.dataStores, this.mc.logger);
1578
+ async _createDataStoreWithProps(pkg, props) {
1579
+ const context = this.channelCollection._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
1580
+ return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
1415
1581
  }
1416
1582
  canSendOps() {
1417
1583
  // Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
@@ -1441,21 +1607,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1441
1607
  // Certain container runtime messages should not mark the container dirty such as the old built-in
1442
1608
  // AgentScheduler and Garbage collector messages.
1443
1609
  switch (type) {
1444
- case messageTypes_1.ContainerMessageType.Attach: {
1610
+ case messageTypes_js_1.ContainerMessageType.Attach: {
1445
1611
  const attachMessage = contents;
1446
1612
  if (attachMessage.id === exports.agentSchedulerId) {
1447
1613
  return false;
1448
1614
  }
1449
1615
  break;
1450
1616
  }
1451
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp: {
1617
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp: {
1452
1618
  const envelope = contents;
1453
1619
  if (envelope.address === exports.agentSchedulerId) {
1454
1620
  return false;
1455
1621
  }
1456
1622
  break;
1457
1623
  }
1458
- case messageTypes_1.ContainerMessageType.GC: {
1624
+ case messageTypes_js_1.ContainerMessageType.GC: {
1459
1625
  return false;
1460
1626
  }
1461
1627
  default:
@@ -1489,16 +1655,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1489
1655
  const envelope = this.createNewSignalEnvelope(undefined /* address */, type, content);
1490
1656
  return this.submitSignalFn(envelope, targetClientId);
1491
1657
  }
1492
- /**
1493
- * Submits the signal to be sent to other clients.
1494
- * @param type - Type of the signal.
1495
- * @param content - Content of the signal.
1496
- * @param targetClientId - When specified, the signal is only sent to the provided client id.
1497
- */
1498
- submitDataStoreSignal(address, type, content, targetClientId) {
1499
- const envelope = this.createNewSignalEnvelope(address, type, content);
1500
- return this.submitSignalFn(envelope, targetClientId);
1501
- }
1502
1658
  setAttachState(attachState) {
1503
1659
  if (attachState === container_definitions_1.AttachState.Attaching) {
1504
1660
  (0, core_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attaching, 0x12d /* "Container Context should already be in attaching state" */);
@@ -1510,7 +1666,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1510
1666
  if (attachState === container_definitions_1.AttachState.Attached && !this.hasPendingMessages()) {
1511
1667
  this.updateDocumentDirtyState(false);
1512
1668
  }
1513
- this.dataStores.setAttachState(attachState);
1669
+ this.channelCollection.setAttachState(attachState);
1514
1670
  }
1515
1671
  /**
1516
1672
  * Create a summary. Used when attaching or serializing a detached container.
@@ -1525,20 +1681,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1525
1681
  this.blobManager.setRedirectTable(blobRedirectTable);
1526
1682
  }
1527
1683
  // We can finalize any allocated IDs since we're the only client
1528
- const idRange = this.idCompressor?.takeNextCreationRange();
1684
+ const idRange = this._idCompressor?.takeNextCreationRange();
1529
1685
  if (idRange !== undefined) {
1530
- this.idCompressor?.finalizeCreationRange(idRange);
1686
+ this._idCompressor?.finalizeCreationRange(idRange);
1531
1687
  }
1532
- const summarizeResult = this.dataStores.createSummary(telemetryContext);
1688
+ const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
1533
1689
  // Wrap data store summaries in .channels subtree.
1534
- (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1690
+ (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1535
1691
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
1536
1692
  return summarizeResult.summary;
1537
1693
  }
1538
1694
  async summarizeInternal(fullTree, trackState, telemetryContext) {
1539
- const summarizeResult = await this.dataStores.summarize(fullTree, trackState, telemetryContext);
1695
+ const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
1540
1696
  // Wrap data store summaries in .channels subtree.
1541
- (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1697
+ (0, index_js_1.wrapSummaryInChannelsTree)(summarizeResult);
1542
1698
  const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
1543
1699
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
1544
1700
  return {
@@ -1584,10 +1740,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1584
1740
  * @see IGarbageCollectionRuntime.updateStateBeforeGC
1585
1741
  */
1586
1742
  async updateStateBeforeGC() {
1587
- return this.dataStores.updateStateBeforeGC();
1743
+ return this.channelCollection.updateStateBeforeGC();
1588
1744
  }
1589
1745
  async getGCDataInternal(fullGC) {
1590
- return this.dataStores.getGCData(fullGC);
1746
+ return this.channelCollection.getGCData(fullGC);
1591
1747
  }
1592
1748
  /**
1593
1749
  * Generates and returns the GC data for this container.
@@ -1613,7 +1769,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1613
1769
  // always referenced, so the used routes is only self-route (empty string).
1614
1770
  this.summarizerNode.updateUsedRoutes([""]);
1615
1771
  const { dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(usedRoutes);
1616
- this.dataStores.updateUsedRoutes(dataStoreRoutes);
1772
+ this.channelCollection.updateUsedRoutes(dataStoreRoutes);
1617
1773
  }
1618
1774
  /**
1619
1775
  * This is called to update objects whose routes are unused.
@@ -1622,7 +1778,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1622
1778
  updateUnusedRoutes(unusedRoutes) {
1623
1779
  const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(unusedRoutes);
1624
1780
  this.blobManager.updateUnusedRoutes(blobManagerRoutes);
1625
- this.dataStores.updateUnusedRoutes(dataStoreRoutes);
1781
+ this.channelCollection.updateUnusedRoutes(dataStoreRoutes);
1626
1782
  }
1627
1783
  /**
1628
1784
  * @deprecated Replaced by deleteSweepReadyNodes.
@@ -1637,7 +1793,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1637
1793
  */
1638
1794
  deleteSweepReadyNodes(sweepReadyRoutes) {
1639
1795
  const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
1640
- const deletedRoutes = this.dataStores.deleteSweepReadyNodes(dataStoreRoutes);
1796
+ const deletedRoutes = this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes);
1641
1797
  return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
1642
1798
  }
1643
1799
  /**
@@ -1651,7 +1807,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1651
1807
  updateTombstonedRoutes(tombstonedRoutes) {
1652
1808
  const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(tombstonedRoutes);
1653
1809
  this.blobManager.updateTombstonedRoutes(blobManagerRoutes);
1654
- this.dataStores.updateTombstonedRoutes(dataStoreRoutes);
1810
+ this.channelCollection.updateTombstonedRoutes(dataStoreRoutes);
1655
1811
  }
1656
1812
  /**
1657
1813
  * Returns a server generated referenced timestamp to be used to track unreferenced nodes by GC.
@@ -1667,9 +1823,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1667
1823
  */
1668
1824
  getNodeType(nodePath) {
1669
1825
  if (this.isBlobPath(nodePath)) {
1670
- return gc_1.GCNodeType.Blob;
1826
+ return index_js_2.GCNodeType.Blob;
1671
1827
  }
1672
- return this.dataStores.getGCNodeType(nodePath) ?? gc_1.GCNodeType.Other;
1828
+ return this.channelCollection.getGCNodeType(nodePath) ?? index_js_2.GCNodeType.Other;
1673
1829
  }
1674
1830
  /**
1675
1831
  * Called by GC to retrieve the package path of the node with the given path. The node should belong to a
@@ -1682,11 +1838,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1682
1838
  return ["_gcRoot"];
1683
1839
  }
1684
1840
  switch (this.getNodeType(nodePath)) {
1685
- case gc_1.GCNodeType.Blob:
1686
- return [blobManager_1.BlobManager.basePath];
1687
- case gc_1.GCNodeType.DataStore:
1688
- case gc_1.GCNodeType.SubDataStore:
1689
- return this.dataStores.getDataStorePackagePath(nodePath);
1841
+ case index_js_2.GCNodeType.Blob:
1842
+ return [blobManager_js_1.BlobManager.basePath];
1843
+ case index_js_2.GCNodeType.DataStore:
1844
+ case index_js_2.GCNodeType.SubDataStore:
1845
+ return this.channelCollection.getDataStorePackagePath(nodePath);
1690
1846
  default:
1691
1847
  (0, core_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
1692
1848
  }
@@ -1696,7 +1852,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1696
1852
  */
1697
1853
  isBlobPath(path) {
1698
1854
  const pathParts = path.split("/");
1699
- if (pathParts.length < 2 || pathParts[1] !== blobManager_1.BlobManager.basePath) {
1855
+ if (pathParts.length < 2 || pathParts[1] !== blobManager_js_1.BlobManager.basePath) {
1700
1856
  return false;
1701
1857
  }
1702
1858
  return true;
@@ -1745,7 +1901,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1745
1901
  * @param options - options controlling how the summary is generated or submitted
1746
1902
  */
1747
1903
  async submitSummary(options) {
1748
- const { fullTree = false, finalAttempt = false, refreshLatestAck, summaryLogger } = options;
1904
+ const { fullTree = false, finalAttempt = false, refreshLatestAck, summaryLogger, latestSummaryRefSeqNum, } = options;
1749
1905
  // The summary number for this summary. This will be updated during the summary process, so get it now and
1750
1906
  // use it for all events logged during this summary.
1751
1907
  const summaryNumber = this.nextSummaryNumber;
@@ -1757,7 +1913,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1757
1913
  });
1758
1914
  (0, core_utils_1.assert)(this.outbox.isEmpty, 0x3d1 /* Can't trigger summary in the middle of a batch */);
1759
1915
  // We close the summarizer and download a new snapshot and reload the container
1760
- let latestSnapshotVersionId;
1761
1916
  if (refreshLatestAck === true) {
1762
1917
  return this.prefetchLatestSummaryThenClose((0, telemetry_utils_1.createChildLogger)({
1763
1918
  logger: summaryNumberLogger,
@@ -1799,6 +1954,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1799
1954
  }
1800
1955
  }
1801
1956
  const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
1957
+ const shouldValidatePreSummaryState = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.shouldValidatePreSummaryState") === true;
1802
1958
  let summaryRefSeqNum;
1803
1959
  try {
1804
1960
  await this.deltaManager.inbound.pause();
@@ -1809,7 +1965,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1809
1965
  const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
1810
1966
  const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
1811
1967
  const lastAck = this.summaryCollection.latestAck;
1812
- this.summarizerNode.startSummary(summaryRefSeqNum, summaryNumberLogger);
1968
+ const startSummaryResult = this.summarizerNode.startSummary(summaryRefSeqNum, summaryNumberLogger, latestSummaryRefSeqNum);
1969
+ if (startSummaryResult.invalidNodes > 0 ||
1970
+ startSummaryResult.mismatchNumbers.size > 0) {
1971
+ summaryLogger.sendErrorEvent({
1972
+ eventName: "LatestSummaryRefSeqNumMismatch",
1973
+ details: {
1974
+ ...startSummaryResult,
1975
+ mismatchNumbers: Array.from(startSummaryResult.mismatchNumbers),
1976
+ },
1977
+ });
1978
+ if (shouldValidatePreSummaryState && !finalAttempt) {
1979
+ return {
1980
+ stage: "base",
1981
+ referenceSequenceNumber: summaryRefSeqNum,
1982
+ minimumSequenceNumber,
1983
+ error: `Summarizer node state inconsistent with summarizer state.`,
1984
+ };
1985
+ }
1986
+ }
1813
1987
  // Helper function to check whether we should still continue between each async step.
1814
1988
  const checkContinue = () => {
1815
1989
  // Do not check for loss of connectivity directly! Instead leave it up to
@@ -1879,7 +2053,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1879
2053
  const validateResult = this.summarizerNode.validateSummary();
1880
2054
  if (!validateResult.success) {
1881
2055
  const { success, ...loggingProps } = validateResult;
1882
- const error = new summary_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
2056
+ const error = new index_js_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
1883
2057
  return {
1884
2058
  stage: "base",
1885
2059
  referenceSequenceNumber: summaryRefSeqNum,
@@ -1905,8 +2079,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1905
2079
  ? (0, runtime_utils_1.calculateStats)(summaryTree.tree[runtime_definitions_1.gcTreeKey])
1906
2080
  : undefined;
1907
2081
  const summaryStats = {
1908
- dataStoreCount: this.dataStores.size,
1909
- summarizedDataStoreCount: this.dataStores.size - handleCount,
2082
+ dataStoreCount: this.channelCollection.size,
2083
+ summarizedDataStoreCount: this.channelCollection.size - handleCount,
1910
2084
  gcStateUpdatedDataStoreCount: this.garbageCollector.updatedDSCountSinceLastSummary,
1911
2085
  gcBlobNodeCount: gcSummaryTreeStats?.blobNodeCount,
1912
2086
  gcTotalBlobsSize: gcSummaryTreeStats?.totalBlobSize,
@@ -1925,34 +2099,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1925
2099
  if (!continueResult.continue) {
1926
2100
  return { stage: "generate", ...generateSummaryData, error: continueResult.error };
1927
2101
  }
1928
- // It may happen that the lastAck it not correct due to missing summaryAck in case of single commit
1929
- // summary. So if the previous summarizer closes just after submitting the summary and before
1930
- // submitting the summaryOp then we can't rely on summaryAck. So in case we have
1931
- // latestSnapshotVersionId from storage and it does not match with the lastAck ackHandle, then use
1932
- // the one fetched from storage as parent as that is the latest.
1933
- let summaryContext;
1934
- if (lastAck?.summaryAck.contents.handle !== latestSnapshotVersionId &&
1935
- latestSnapshotVersionId !== undefined) {
1936
- summaryContext = {
1937
- proposalHandle: undefined,
1938
- ackHandle: latestSnapshotVersionId,
1939
- referenceSequenceNumber: summaryRefSeqNum,
1940
- };
1941
- }
1942
- else if (lastAck === undefined) {
1943
- summaryContext = {
2102
+ const summaryContext = lastAck === undefined
2103
+ ? {
1944
2104
  proposalHandle: undefined,
1945
2105
  ackHandle: this.loadedFromVersionId,
1946
2106
  referenceSequenceNumber: summaryRefSeqNum,
1947
- };
1948
- }
1949
- else {
1950
- summaryContext = {
2107
+ }
2108
+ : {
1951
2109
  proposalHandle: lastAck.summaryOp.contents.handle,
1952
2110
  ackHandle: lastAck.summaryAck.contents.handle,
1953
2111
  referenceSequenceNumber: summaryRefSeqNum,
1954
2112
  };
1955
- }
1956
2113
  let handle;
1957
2114
  try {
1958
2115
  handle = await this.storage.uploadSummaryWithContext(summarizeResult.summary, summaryContext);
@@ -2043,7 +2200,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2043
2200
  // based on telemetry while we decide on a stable number.
2044
2201
  const retryDelayMs = this.mc.config.getNumber("Fluid.Summarizer.PendingOpsRetryDelayMs") ??
2045
2202
  exports.defaultPendingOpsRetryDelayMs;
2046
- const error = new summary_1.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2203
+ const error = new index_js_1.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
2047
2204
  count: this.pendingMessagesCount,
2048
2205
  beforeGenerate: beforeSummaryGeneration,
2049
2206
  });
@@ -2077,48 +2234,29 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2077
2234
  this.emit(dirty ? "dirty" : "saved");
2078
2235
  }
2079
2236
  }
2080
- submitDataStoreOp(id, contents, localOpMetadata = undefined) {
2081
- const envelope = {
2082
- address: id,
2083
- contents,
2084
- };
2085
- this.submit({ type: messageTypes_1.ContainerMessageType.FluidDataStoreOp, contents: envelope }, localOpMetadata);
2086
- }
2087
- submitDataStoreAliasOp(contents, localOpMetadata) {
2088
- const aliasMessage = contents;
2089
- if (!(0, dataStore_1.isDataStoreAliasMessage)(aliasMessage)) {
2090
- throw new telemetry_utils_1.UsageError("malformedDataStoreAliasMessage");
2091
- }
2092
- this.submit({ type: messageTypes_1.ContainerMessageType.Alias, contents }, localOpMetadata);
2237
+ submitMessage(type, contents, localOpMetadata = undefined) {
2238
+ this.submit({ type, contents }, localOpMetadata);
2093
2239
  }
2094
2240
  async uploadBlob(blob, signal) {
2095
2241
  this.verifyNotClosed();
2096
2242
  return this.blobManager.createBlob(blob, signal);
2097
2243
  }
2098
- maybeSubmitIdAllocationOp(type) {
2099
- if (type !== messageTypes_1.ContainerMessageType.IdAllocation) {
2100
- let idAllocationBatchMessage;
2101
- let idRange;
2102
- if (this.idCompressorEnabled) {
2103
- (0, core_utils_1.assert)(this.idCompressor !== undefined, 0x67d /* IdCompressor should be defined if enabled */);
2104
- idRange = this.idCompressor.takeNextCreationRange();
2105
- // Don't include the idRange if there weren't any Ids allocated
2106
- idRange = idRange?.ids !== undefined ? idRange : undefined;
2107
- }
2108
- if (idRange !== undefined) {
2244
+ submitIdAllocationOpIfNeeded() {
2245
+ if (this._idCompressor) {
2246
+ const idRange = this._idCompressor.takeNextCreationRange();
2247
+ // Don't include the idRange if there weren't any Ids allocated
2248
+ if (idRange?.ids !== undefined) {
2109
2249
  const idAllocationMessage = {
2110
- type: messageTypes_1.ContainerMessageType.IdAllocation,
2250
+ type: messageTypes_js_1.ContainerMessageType.IdAllocation,
2111
2251
  contents: idRange,
2112
2252
  };
2113
- idAllocationBatchMessage = {
2253
+ const idAllocationBatchMessage = {
2114
2254
  contents: JSON.stringify(idAllocationMessage),
2115
2255
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2116
2256
  metadata: undefined,
2117
2257
  localOpMetadata: undefined,
2118
- type: messageTypes_1.ContainerMessageType.IdAllocation,
2258
+ type: messageTypes_js_1.ContainerMessageType.IdAllocation,
2119
2259
  };
2120
- }
2121
- if (idAllocationBatchMessage !== undefined) {
2122
2260
  this.outbox.submitIdAllocation(idAllocationBatchMessage);
2123
2261
  }
2124
2262
  }
@@ -2146,42 +2284,47 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2146
2284
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
2147
2285
  };
2148
2286
  try {
2149
- // Submit an IdAllocation op if any Ids have been generated since
2150
- // the last op was submitted. Don't submit another if it's an IdAllocation
2151
- // op as that means we're in resubmission flow and we don't want to send
2152
- // IdRanges out of order.
2153
- this.maybeSubmitIdAllocationOp(type);
2154
- // If this is attach message for new data store, and we are in a batch, send this op out of order
2155
- // Is it safe:
2156
- // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
2157
- // They become visible only when aliased, or handle to some sub-element of newly created datastore
2158
- // is stored in some DDS, i.e. only after some other op.
2159
- // Why:
2160
- // Attach ops are large, and expensive to process. Plus there are scenarios where a lot of new data
2161
- // stores are created, causing issues like relay service throttling (too many ops) and catastrophic
2162
- // failure (batch is too large). Pushing them earlier and outside of main batch should alleviate
2163
- // these issues.
2164
- // Cons:
2165
- // 1. With large batches, relay service may throttle clients. Clients may disconnect while throttled.
2166
- // This change creates new possibility of a lot of newly created data stores never being referenced
2167
- // because client died before it had a change to submit the rest of the ops. This will create more
2168
- // garbage that needs to be collected leveraging GC (Garbage Collection) feature.
2169
- // 2. Sending ops out of order means they are excluded from rollback functionality. This is not an issue
2170
- // today as rollback can't undo creation of data store. To some extent not sending them is a bigger
2171
- // issue than sending.
2172
- // Please note that this does not change file format, so it can be disabled in the future if this
2173
- // optimization no longer makes sense (for example, batch compression may make it less appealing).
2174
- if (this.currentlyBatching() &&
2175
- type === messageTypes_1.ContainerMessageType.Attach &&
2176
- this.disableAttachReorder !== true) {
2177
- this.outbox.submitAttach(message);
2178
- }
2179
- else if (type === messageTypes_1.ContainerMessageType.BlobAttach) {
2180
- // BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
2181
- this.outbox.submitBlobAttach(message);
2287
+ // If `message` is an allocation op, then we are in the resubmit path and we must redirect the allocation
2288
+ // op into the correct batch to avoid ranges being finalized out of order.
2289
+ // Otherwise, submit an IdAllocation op if any IDs have been generated since the last op was submitted, as
2290
+ // any of the other op types may contain those IDs and thus depend on the allocation op being sent first.
2291
+ if (type === messageTypes_js_1.ContainerMessageType.IdAllocation) {
2292
+ this.outbox.submitIdAllocation(message);
2182
2293
  }
2183
2294
  else {
2184
- this.outbox.submit(message);
2295
+ this.submitIdAllocationOpIfNeeded();
2296
+ // If this is attach message for new data store, and we are in a batch, send this op out of order
2297
+ // Is it safe:
2298
+ // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
2299
+ // They become visible only when aliased, or handle to some sub-element of newly created datastore
2300
+ // is stored in some DDS, i.e. only after some other op.
2301
+ // Why:
2302
+ // Attach ops are large, and expensive to process. Plus there are scenarios where a lot of new data
2303
+ // stores are created, causing issues like relay service throttling (too many ops) and catastrophic
2304
+ // failure (batch is too large). Pushing them earlier and outside of main batch should alleviate
2305
+ // these issues.
2306
+ // Cons:
2307
+ // 1. With large batches, relay service may throttle clients. Clients may disconnect while throttled.
2308
+ // This change creates new possibility of a lot of newly created data stores never being referenced
2309
+ // because client died before it had a change to submit the rest of the ops. This will create more
2310
+ // garbage that needs to be collected leveraging GC (Garbage Collection) feature.
2311
+ // 2. Sending ops out of order means they are excluded from rollback functionality. This is not an issue
2312
+ // today as rollback can't undo creation of data store. To some extent not sending them is a bigger
2313
+ // issue than sending.
2314
+ // Please note that this does not change file format, so it can be disabled in the future if this
2315
+ // optimization no longer makes sense (for example, batch compression may make it less appealing).
2316
+ if (this.currentlyBatching() &&
2317
+ type === messageTypes_js_1.ContainerMessageType.Attach &&
2318
+ this.disableAttachReorder !== true) {
2319
+ this.outbox.submitAttach(message);
2320
+ }
2321
+ else if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
2322
+ // BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
2323
+ this.outbox.submitBlobAttach(message);
2324
+ }
2325
+ else {
2326
+ this.outbox.submit(message);
2327
+ }
2185
2328
  }
2186
2329
  if (!this.currentlyBatching()) {
2187
2330
  this.flush();
@@ -2256,7 +2399,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2256
2399
  if (this.opReentryCallsToReport > 0) {
2257
2400
  this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
2258
2401
  // We need to capture the call stack in order to inspect the source of this usage pattern
2259
- (0, opLifecycle_1.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2402
+ (0, index_js_3.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2260
2403
  this.opReentryCallsToReport--;
2261
2404
  }
2262
2405
  // Creating ops while processing ops can lead
@@ -2297,35 +2440,36 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2297
2440
  * @param localOpMetadata - The local metadata associated with the original message.
2298
2441
  */
2299
2442
  reSubmitCore(message, localOpMetadata, opMetadata) {
2300
- (0, core_utils_1.assert)(!this.isSummarizerClient, "Summarizer never reconnects so should never resubmit");
2443
+ (0, core_utils_1.assert)(!this.isSummarizerClient, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
2301
2444
  switch (message.type) {
2302
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
2445
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
2446
+ case messageTypes_js_1.ContainerMessageType.Attach:
2447
+ case messageTypes_js_1.ContainerMessageType.Alias:
2303
2448
  // For Operations, call resubmitDataStoreOp which will find the right store
2304
2449
  // and trigger resubmission on it.
2305
- this.dataStores.resubmitDataStoreOp(message.contents, localOpMetadata);
2450
+ this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
2306
2451
  break;
2307
- case messageTypes_1.ContainerMessageType.Attach:
2308
- case messageTypes_1.ContainerMessageType.Alias:
2309
- case messageTypes_1.ContainerMessageType.IdAllocation: {
2452
+ case messageTypes_js_1.ContainerMessageType.IdAllocation: {
2310
2453
  this.submit(message, localOpMetadata);
2311
2454
  break;
2312
2455
  }
2313
- case messageTypes_1.ContainerMessageType.ChunkedOp:
2456
+ case messageTypes_js_1.ContainerMessageType.ChunkedOp:
2314
2457
  throw new Error(`chunkedOp not expected here`);
2315
- case messageTypes_1.ContainerMessageType.BlobAttach:
2458
+ case messageTypes_js_1.ContainerMessageType.BlobAttach:
2316
2459
  this.blobManager.reSubmit(opMetadata);
2317
2460
  break;
2318
- case messageTypes_1.ContainerMessageType.Rejoin:
2461
+ case messageTypes_js_1.ContainerMessageType.Rejoin:
2319
2462
  this.submit(message);
2320
2463
  break;
2321
- case messageTypes_1.ContainerMessageType.GC:
2464
+ case messageTypes_js_1.ContainerMessageType.GC:
2322
2465
  this.submit(message);
2323
2466
  break;
2324
2467
  default: {
2325
2468
  // This case should be very rare - it would imply an op was stashed from a
2326
- // future version of runtime code and now is being applied on an older version
2469
+ // future version of runtime code and now is being applied on an older version.
2327
2470
  const compatBehavior = message.compatDetails?.behavior;
2328
2471
  if (compatBehaviorAllowsMessageType(message.type, compatBehavior)) {
2472
+ // We do not ultimately resubmit it, to be consistent with this version of the code.
2329
2473
  this.logger.sendTelemetryEvent({
2330
2474
  eventName: "resubmitUnrecognizedMessageTypeAllowed",
2331
2475
  messageDetails: { type: message.type, compatBehavior },
@@ -2348,10 +2492,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2348
2492
  // Need to parse from string for back-compat
2349
2493
  const { type, contents } = this.parseLocalOpContent(content);
2350
2494
  switch (type) {
2351
- case messageTypes_1.ContainerMessageType.FluidDataStoreOp:
2495
+ case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
2352
2496
  // For operations, call rollbackDataStoreOp which will find the right store
2353
2497
  // and trigger rollback on it.
2354
- this.dataStores.rollbackDataStoreOp(contents, localOpMetadata);
2498
+ this.channelCollection.rollback(type, contents, localOpMetadata);
2355
2499
  break;
2356
2500
  default:
2357
2501
  // Don't check message.compatDetails because this is for rolling back a local op so the type will be known
@@ -2372,31 +2516,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2372
2516
  * and then close as the current main client is likely to be re-elected as the parent summarizer again.
2373
2517
  */
2374
2518
  if (!result.isSummaryTracked && result.isSummaryNewer) {
2375
- const fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
2519
+ await this.fetchLatestSnapshotFromStorage(summaryLogger, {
2376
2520
  eventName: "RefreshLatestSummaryAckFetch",
2377
2521
  ackHandle,
2378
2522
  targetSequenceNumber: summaryRefSeq,
2379
2523
  }, readAndParseBlob);
2380
- /**
2381
- * If the fetched snapshot is older than the one for which the ack was received, close the container.
2382
- * This should never happen because an ack should be sent after the latest summary is updated in the server.
2383
- * However, there are couple of scenarios where it's possible:
2384
- * 1. A file was modified externally resulting in modifying the snapshot's sequence number. This can lead to
2385
- * the document being unusable and we should not proceed.
2386
- * 2. The server DB failed after the ack was sent which may delete the corresponding snapshot. Ideally, in
2387
- * such cases, the file will be rolled back along with the ack and we will eventually reach a consistent
2388
- * state.
2389
- */
2390
- if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
2391
- const error = telemetry_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
2392
- ackHandle,
2393
- summaryRefSeq,
2394
- fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
2395
- });
2396
- this.disposeFn(error);
2397
- throw error;
2398
- }
2399
- await this.closeStaleSummarizer("RefreshLatestSummaryAckFetch");
2524
+ await this.closeStaleSummarizer();
2400
2525
  return;
2401
2526
  }
2402
2527
  // Notify the garbage collector so it can update its latest summary state.
@@ -2415,7 +2540,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2415
2540
  await this.fetchLatestSnapshotFromStorage(summaryLogger, {
2416
2541
  eventName: "RefreshLatestSummaryFromServerFetch",
2417
2542
  }, readAndParseBlob);
2418
- await this.closeStaleSummarizer("RefreshLatestSummaryFromServerFetch");
2543
+ await this.closeStaleSummarizer();
2419
2544
  return {
2420
2545
  stage: "base",
2421
2546
  error: "summary state stale - Unsupported option 'refreshLatestAck'",
@@ -2423,7 +2548,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2423
2548
  minimumSequenceNumber: this.deltaManager.minimumSequenceNumber,
2424
2549
  };
2425
2550
  }
2426
- async closeStaleSummarizer(codePath) {
2551
+ async closeStaleSummarizer() {
2427
2552
  // Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
2428
2553
  await (0, core_utils_1.delay)(this.closeSummarizerDelayMs);
2429
2554
  this._summarizer?.stop("latestSummaryStateStale");
@@ -2455,44 +2580,43 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2455
2580
  };
2456
2581
  });
2457
2582
  }
2458
- async getPendingLocalState(props) {
2459
- return telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, {
2460
- eventName: "getPendingLocalState",
2461
- notifyImminentClosure: props?.notifyImminentClosure,
2462
- }, async (event) => {
2463
- this.verifyNotClosed();
2464
- // in case imminentClosure is set to true by future code, we don't
2465
- // try to change its value
2466
- if (!this.imminentClosure) {
2467
- this.imminentClosure = props?.notifyImminentClosure ?? this.imminentClosure;
2468
- }
2469
- const stopBlobAttachingSignal = props?.stopBlobAttachingSignal;
2470
- if (this._orderSequentiallyCalls !== 0) {
2471
- throw new telemetry_utils_1.UsageError("can't get state during orderSequentially");
2472
- }
2473
- // Flush pending batch.
2474
- // getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
2475
- // to close current batch.
2476
- this.flush();
2477
- const pendingAttachmentBlobs = this.imminentClosure
2478
- ? await this.blobManager.attachAndGetPendingBlobs(stopBlobAttachingSignal)
2479
- : undefined;
2583
+ getPendingLocalState(props) {
2584
+ this.verifyNotClosed();
2585
+ if (this._orderSequentiallyCalls !== 0) {
2586
+ throw new telemetry_utils_1.UsageError("can't get state during orderSequentially");
2587
+ }
2588
+ this.imminentClosure || (this.imminentClosure = props?.notifyImminentClosure ?? false);
2589
+ const getSyncState = (pendingAttachmentBlobs) => {
2480
2590
  const pending = this.pendingStateManager.getLocalState();
2481
- if (!pendingAttachmentBlobs && !this.hasPendingMessages()) {
2591
+ if (pendingAttachmentBlobs === undefined && !this.hasPendingMessages()) {
2482
2592
  return; // no pending state to save
2483
2593
  }
2484
- const pendingIdCompressorState = this.idCompressor?.serialize(true);
2485
- const pendingState = {
2594
+ const pendingIdCompressorState = this._idCompressor?.serialize(true);
2595
+ return {
2486
2596
  pending,
2487
- pendingAttachmentBlobs,
2488
2597
  pendingIdCompressorState,
2598
+ pendingAttachmentBlobs,
2599
+ sessionExpiryTimerStarted: this.garbageCollector.sessionExpiryTimerStarted,
2489
2600
  };
2601
+ };
2602
+ const perfEvent = {
2603
+ eventName: "getPendingLocalState",
2604
+ notifyImminentClosure: props?.notifyImminentClosure,
2605
+ };
2606
+ const logAndReturnPendingState = (event, pendingState) => {
2490
2607
  event.end({
2491
- attachmentBlobsSize: Object.keys(pendingAttachmentBlobs ?? {}).length,
2492
- pendingOpsSize: pending?.pendingStates.length,
2608
+ attachmentBlobsSize: Object.keys(pendingState?.pendingAttachmentBlobs ?? {}).length,
2609
+ pendingOpsSize: pendingState?.pending?.pendingStates.length,
2493
2610
  });
2494
2611
  return pendingState;
2495
- });
2612
+ };
2613
+ // Flush pending batch.
2614
+ // getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
2615
+ // to close current batch.
2616
+ this.flush();
2617
+ return props?.notifyImminentClosure === true
2618
+ ? telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, perfEvent, async (event) => logAndReturnPendingState(event, getSyncState(await this.blobManager.attachAndGetPendingBlobs(props?.stopBlobAttachingSignal))))
2619
+ : telemetry_utils_1.PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
2496
2620
  }
2497
2621
  summarizeOnDemand(options) {
2498
2622
  if (this.isSummarizerClient) {