@fluidframework/container-runtime 2.118.1 → 3.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 (326) hide show
  1. package/CHANGELOG.md +68 -4
  2. package/README.md +53 -50
  3. package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
  4. package/api-report/container-runtime.legacy.alpha.api.md +3 -1
  5. package/api-report/container-runtime.legacy.beta.api.md +3 -1
  6. package/container-runtime.test-files.tar +0 -0
  7. package/dist/batchTracker.d.ts.map +1 -1
  8. package/dist/batchTracker.js +5 -1
  9. package/dist/batchTracker.js.map +1 -1
  10. package/dist/blobManager/blobManager.d.ts +1 -1
  11. package/dist/blobManager/blobManager.d.ts.map +1 -1
  12. package/dist/blobManager/blobManager.js +264 -231
  13. package/dist/blobManager/blobManager.js.map +1 -1
  14. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  15. package/dist/channelCollection.d.ts.map +1 -1
  16. package/dist/channelCollection.js +70 -58
  17. package/dist/channelCollection.js.map +1 -1
  18. package/dist/connectionTelemetry.js +38 -20
  19. package/dist/connectionTelemetry.js.map +1 -1
  20. package/dist/containerCompatibility.d.ts +3 -3
  21. package/dist/containerCompatibility.d.ts.map +1 -1
  22. package/dist/containerCompatibility.js +36 -45
  23. package/dist/containerCompatibility.js.map +1 -1
  24. package/dist/containerHandleContext.d.ts.map +1 -1
  25. package/dist/containerHandleContext.js +4 -0
  26. package/dist/containerHandleContext.js.map +1 -1
  27. package/dist/containerRuntime.d.ts +4 -4
  28. package/dist/containerRuntime.d.ts.map +1 -1
  29. package/dist/containerRuntime.js +346 -223
  30. package/dist/containerRuntime.js.map +1 -1
  31. package/dist/dataStore.d.ts.map +1 -1
  32. package/dist/dataStore.js +9 -1
  33. package/dist/dataStore.js.map +1 -1
  34. package/dist/dataStoreContext.d.ts.map +1 -1
  35. package/dist/dataStoreContext.js +184 -127
  36. package/dist/dataStoreContext.js.map +1 -1
  37. package/dist/dataStoreContexts.js +43 -42
  38. package/dist/dataStoreContexts.js.map +1 -1
  39. package/dist/dataStoreRegistry.js +1 -0
  40. package/dist/dataStoreRegistry.js.map +1 -1
  41. package/dist/deltaManagerProxies.js +5 -0
  42. package/dist/deltaManagerProxies.js.map +1 -1
  43. package/dist/deltaScheduler.js +104 -99
  44. package/dist/deltaScheduler.js.map +1 -1
  45. package/dist/error.js +2 -1
  46. package/dist/error.js.map +1 -1
  47. package/dist/gc/garbageCollection.js +85 -55
  48. package/dist/gc/garbageCollection.js.map +1 -1
  49. package/dist/gc/gcConfigs.js +2 -3
  50. package/dist/gc/gcConfigs.js.map +1 -1
  51. package/dist/gc/gcHelpers.js +12 -13
  52. package/dist/gc/gcHelpers.js.map +1 -1
  53. package/dist/gc/gcReferenceGraphAlgorithm.js +1 -2
  54. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  55. package/dist/gc/gcSummaryStateTracker.js +8 -3
  56. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  57. package/dist/gc/gcTelemetry.js +12 -5
  58. package/dist/gc/gcTelemetry.js.map +1 -1
  59. package/dist/gc/gcUnreferencedStateTracker.js +18 -1
  60. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  61. package/dist/inboundBatchAggregator.js +122 -117
  62. package/dist/inboundBatchAggregator.js.map +1 -1
  63. package/dist/metadata.d.ts.map +1 -1
  64. package/dist/metadata.js +3 -3
  65. package/dist/metadata.js.map +1 -1
  66. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  67. package/dist/opLifecycle/batchManager.js +11 -5
  68. package/dist/opLifecycle/batchManager.js.map +1 -1
  69. package/dist/opLifecycle/duplicateBatchDetector.js +18 -18
  70. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  71. package/dist/opLifecycle/index.d.ts +2 -2
  72. package/dist/opLifecycle/index.d.ts.map +1 -1
  73. package/dist/opLifecycle/index.js +2 -1
  74. package/dist/opLifecycle/index.js.map +1 -1
  75. package/dist/opLifecycle/opCompressor.js +2 -1
  76. package/dist/opLifecycle/opCompressor.js.map +1 -1
  77. package/dist/opLifecycle/opDecompressor.js +10 -6
  78. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  79. package/dist/opLifecycle/opGroupingManager.js +5 -3
  80. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  81. package/dist/opLifecycle/opSerialization.d.ts +11 -1
  82. package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
  83. package/dist/opLifecycle/opSerialization.js +22 -6
  84. package/dist/opLifecycle/opSerialization.js.map +1 -1
  85. package/dist/opLifecycle/opSplitter.d.ts +17 -1
  86. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  87. package/dist/opLifecycle/opSplitter.js +46 -9
  88. package/dist/opLifecycle/opSplitter.js.map +1 -1
  89. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  90. package/dist/opLifecycle/outbox.js +17 -13
  91. package/dist/opLifecycle/outbox.js.map +1 -1
  92. package/dist/opLifecycle/remoteMessageProcessor.js +6 -3
  93. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  94. package/dist/opProperties.d.ts.map +1 -1
  95. package/dist/packageVersion.d.ts +1 -1
  96. package/dist/packageVersion.d.ts.map +1 -1
  97. package/dist/packageVersion.js +1 -1
  98. package/dist/packageVersion.js.map +1 -1
  99. package/dist/pendingStateManager.js +54 -47
  100. package/dist/pendingStateManager.js.map +1 -1
  101. package/dist/runCounter.js +10 -30
  102. package/dist/runCounter.js.map +1 -1
  103. package/dist/runtimeLayerCompatState.d.ts +1 -1
  104. package/dist/runtimeLayerCompatState.d.ts.map +1 -1
  105. package/dist/runtimeLayerCompatState.js +31 -11
  106. package/dist/runtimeLayerCompatState.js.map +1 -1
  107. package/dist/signalTelemetryProcessing.js +15 -17
  108. package/dist/signalTelemetryProcessing.js.map +1 -1
  109. package/dist/storageServiceWithAttachBlobs.js +2 -0
  110. package/dist/storageServiceWithAttachBlobs.js.map +1 -1
  111. package/dist/summary/documentSchema.d.ts.map +1 -1
  112. package/dist/summary/documentSchema.js +51 -13
  113. package/dist/summary/documentSchema.js.map +1 -1
  114. package/dist/summary/orderedClientElection.js +25 -17
  115. package/dist/summary/orderedClientElection.js.map +1 -1
  116. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  117. package/dist/summary/summarizerClientElection.js +18 -7
  118. package/dist/summary/summarizerClientElection.js.map +1 -1
  119. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  120. package/dist/summary/summarizerNode/summarizerNode.js +22 -13
  121. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  122. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  123. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
  124. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  125. package/dist/summary/summarizerUtils.d.ts.map +1 -1
  126. package/dist/summary/summarizerUtils.js +4 -3
  127. package/dist/summary/summarizerUtils.js.map +1 -1
  128. package/dist/summary/summaryCollection.js +23 -11
  129. package/dist/summary/summaryCollection.js.map +1 -1
  130. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
  131. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  132. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  133. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
  134. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  135. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  136. package/dist/summary/summaryDelayLoadedModule/summarizer.js +15 -6
  137. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  138. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
  139. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  140. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
  141. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  142. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
  143. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  144. package/dist/summary/summaryFormat.d.ts.map +1 -1
  145. package/dist/summary/summaryFormat.js +7 -7
  146. package/dist/summary/summaryFormat.js.map +1 -1
  147. package/dist/summary/summaryHelpers.js +5 -5
  148. package/dist/summary/summaryHelpers.js.map +1 -1
  149. package/dist/summary/summaryManager.js +66 -54
  150. package/dist/summary/summaryManager.js.map +1 -1
  151. package/dist/throttler.d.ts.map +1 -1
  152. package/dist/throttler.js +4 -1
  153. package/dist/throttler.js.map +1 -1
  154. package/dist/versionMarks/inboundBatch.d.ts +8 -6
  155. package/dist/versionMarks/inboundBatch.d.ts.map +1 -1
  156. package/dist/versionMarks/inboundBatch.js +11 -7
  157. package/dist/versionMarks/inboundBatch.js.map +1 -1
  158. package/dist/versionMarks/versionMarkResolver.d.ts +30 -23
  159. package/dist/versionMarks/versionMarkResolver.d.ts.map +1 -1
  160. package/dist/versionMarks/versionMarkResolver.js +112 -63
  161. package/dist/versionMarks/versionMarkResolver.js.map +1 -1
  162. package/lib/batchTracker.d.ts.map +1 -1
  163. package/lib/batchTracker.js +5 -1
  164. package/lib/batchTracker.js.map +1 -1
  165. package/lib/blobManager/blobManager.d.ts +1 -1
  166. package/lib/blobManager/blobManager.d.ts.map +1 -1
  167. package/lib/blobManager/blobManager.js +264 -231
  168. package/lib/blobManager/blobManager.js.map +1 -1
  169. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  170. package/lib/channelCollection.d.ts.map +1 -1
  171. package/lib/channelCollection.js +65 -53
  172. package/lib/channelCollection.js.map +1 -1
  173. package/lib/connectionTelemetry.js +36 -18
  174. package/lib/connectionTelemetry.js.map +1 -1
  175. package/lib/containerCompatibility.d.ts +3 -3
  176. package/lib/containerCompatibility.d.ts.map +1 -1
  177. package/lib/containerCompatibility.js +33 -42
  178. package/lib/containerCompatibility.js.map +1 -1
  179. package/lib/containerHandleContext.d.ts.map +1 -1
  180. package/lib/containerHandleContext.js +4 -0
  181. package/lib/containerHandleContext.js.map +1 -1
  182. package/lib/containerRuntime.d.ts +4 -4
  183. package/lib/containerRuntime.d.ts.map +1 -1
  184. package/lib/containerRuntime.js +341 -218
  185. package/lib/containerRuntime.js.map +1 -1
  186. package/lib/dataStore.d.ts.map +1 -1
  187. package/lib/dataStore.js +9 -1
  188. package/lib/dataStore.js.map +1 -1
  189. package/lib/dataStoreContext.d.ts.map +1 -1
  190. package/lib/dataStoreContext.js +182 -125
  191. package/lib/dataStoreContext.js.map +1 -1
  192. package/lib/dataStoreContexts.js +43 -42
  193. package/lib/dataStoreContexts.js.map +1 -1
  194. package/lib/dataStoreRegistry.js +1 -0
  195. package/lib/dataStoreRegistry.js.map +1 -1
  196. package/lib/deltaManagerProxies.js +5 -0
  197. package/lib/deltaManagerProxies.js.map +1 -1
  198. package/lib/deltaScheduler.js +104 -99
  199. package/lib/deltaScheduler.js.map +1 -1
  200. package/lib/error.js +2 -1
  201. package/lib/error.js.map +1 -1
  202. package/lib/gc/garbageCollection.js +85 -55
  203. package/lib/gc/garbageCollection.js.map +1 -1
  204. package/lib/gc/gcSummaryStateTracker.js +8 -3
  205. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  206. package/lib/gc/gcTelemetry.js +12 -5
  207. package/lib/gc/gcTelemetry.js.map +1 -1
  208. package/lib/gc/gcUnreferencedStateTracker.js +18 -1
  209. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  210. package/lib/inboundBatchAggregator.js +122 -117
  211. package/lib/inboundBatchAggregator.js.map +1 -1
  212. package/lib/legacy.d.ts +1 -1
  213. package/lib/legacyAlpha.d.ts +1 -1
  214. package/lib/metadata.d.ts.map +1 -1
  215. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  216. package/lib/opLifecycle/batchManager.js +8 -2
  217. package/lib/opLifecycle/batchManager.js.map +1 -1
  218. package/lib/opLifecycle/duplicateBatchDetector.js +18 -18
  219. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  220. package/lib/opLifecycle/index.d.ts +2 -2
  221. package/lib/opLifecycle/index.d.ts.map +1 -1
  222. package/lib/opLifecycle/index.js +2 -2
  223. package/lib/opLifecycle/index.js.map +1 -1
  224. package/lib/opLifecycle/opCompressor.js +3 -2
  225. package/lib/opLifecycle/opCompressor.js.map +1 -1
  226. package/lib/opLifecycle/opDecompressor.js +10 -6
  227. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  228. package/lib/opLifecycle/opGroupingManager.js +3 -1
  229. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  230. package/lib/opLifecycle/opSerialization.d.ts +11 -1
  231. package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
  232. package/lib/opLifecycle/opSerialization.js +16 -0
  233. package/lib/opLifecycle/opSerialization.js.map +1 -1
  234. package/lib/opLifecycle/opSplitter.d.ts +17 -1
  235. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  236. package/lib/opLifecycle/opSplitter.js +44 -7
  237. package/lib/opLifecycle/opSplitter.js.map +1 -1
  238. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  239. package/lib/opLifecycle/outbox.js +14 -10
  240. package/lib/opLifecycle/outbox.js.map +1 -1
  241. package/lib/opLifecycle/remoteMessageProcessor.js +4 -1
  242. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  243. package/lib/opProperties.d.ts.map +1 -1
  244. package/lib/packageVersion.d.ts +1 -1
  245. package/lib/packageVersion.d.ts.map +1 -1
  246. package/lib/packageVersion.js +1 -1
  247. package/lib/packageVersion.js.map +1 -1
  248. package/lib/pendingStateManager.js +52 -45
  249. package/lib/pendingStateManager.js.map +1 -1
  250. package/lib/public.d.ts +1 -1
  251. package/lib/runCounter.js +10 -30
  252. package/lib/runCounter.js.map +1 -1
  253. package/lib/runtimeLayerCompatState.d.ts +1 -1
  254. package/lib/runtimeLayerCompatState.d.ts.map +1 -1
  255. package/lib/runtimeLayerCompatState.js +28 -8
  256. package/lib/runtimeLayerCompatState.js.map +1 -1
  257. package/lib/signalTelemetryProcessing.js +15 -17
  258. package/lib/signalTelemetryProcessing.js.map +1 -1
  259. package/lib/storageServiceWithAttachBlobs.js +2 -0
  260. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  261. package/lib/summary/documentSchema.d.ts.map +1 -1
  262. package/lib/summary/documentSchema.js +51 -13
  263. package/lib/summary/documentSchema.js.map +1 -1
  264. package/lib/summary/orderedClientElection.js +25 -17
  265. package/lib/summary/orderedClientElection.js.map +1 -1
  266. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  267. package/lib/summary/summarizerClientElection.js +18 -7
  268. package/lib/summary/summarizerClientElection.js.map +1 -1
  269. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  270. package/lib/summary/summarizerNode/summarizerNode.js +22 -13
  271. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  272. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  273. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
  274. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  275. package/lib/summary/summarizerUtils.d.ts.map +1 -1
  276. package/lib/summary/summarizerUtils.js +1 -0
  277. package/lib/summary/summarizerUtils.js.map +1 -1
  278. package/lib/summary/summaryCollection.js +23 -11
  279. package/lib/summary/summaryCollection.js.map +1 -1
  280. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
  281. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  282. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  283. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
  284. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  285. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  286. package/lib/summary/summaryDelayLoadedModule/summarizer.js +15 -6
  287. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  288. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
  289. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  290. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
  291. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  292. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
  293. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  294. package/lib/summary/summaryFormat.d.ts.map +1 -1
  295. package/lib/summary/summaryManager.js +66 -54
  296. package/lib/summary/summaryManager.js.map +1 -1
  297. package/lib/throttler.d.ts.map +1 -1
  298. package/lib/throttler.js +4 -1
  299. package/lib/throttler.js.map +1 -1
  300. package/lib/versionMarks/inboundBatch.d.ts +8 -6
  301. package/lib/versionMarks/inboundBatch.d.ts.map +1 -1
  302. package/lib/versionMarks/inboundBatch.js +10 -5
  303. package/lib/versionMarks/inboundBatch.js.map +1 -1
  304. package/lib/versionMarks/versionMarkResolver.d.ts +30 -23
  305. package/lib/versionMarks/versionMarkResolver.d.ts.map +1 -1
  306. package/lib/versionMarks/versionMarkResolver.js +112 -63
  307. package/lib/versionMarks/versionMarkResolver.js.map +1 -1
  308. package/package.json +60 -102
  309. package/src/containerCompatibility.ts +33 -42
  310. package/src/containerRuntime.ts +15 -12
  311. package/src/opLifecycle/index.ts +7 -1
  312. package/src/opLifecycle/opCompressor.ts +2 -2
  313. package/src/opLifecycle/opSerialization.ts +22 -1
  314. package/src/opLifecycle/opSplitter.ts +63 -6
  315. package/src/packageVersion.ts +1 -1
  316. package/src/runtimeLayerCompatState.ts +28 -21
  317. package/src/summary/documentSchema.ts +31 -6
  318. package/src/versionMarks/DEV.md +595 -157
  319. package/src/versionMarks/inboundBatch.ts +18 -8
  320. package/src/versionMarks/versionMarkResolver.ts +144 -75
  321. package/tsconfig.json +1 -1
  322. package/internal.d.ts +0 -11
  323. package/legacy/alpha.d.ts +0 -11
  324. package/legacy.d.ts +0 -11
  325. /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
  326. /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
@@ -4,7 +4,12 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.isContainerMessageDirtyable = exports.ContainerRuntime = exports.loadContainerRuntimeAlpha = exports.loadContainerRuntime = exports.getSingleUseLegacyLogCallback = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isUnpackedRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DeletedResponseHeaderKey = void 0;
7
+ exports.ContainerRuntime = exports.getSingleUseLegacyLogCallback = exports.makeLegacySendBatchFn = exports.agentSchedulerId = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DeletedResponseHeaderKey = void 0;
8
+ exports.isUnpackedRuntimeMessage = isUnpackedRuntimeMessage;
9
+ exports.getDeviceSpec = getDeviceSpec;
10
+ exports.loadContainerRuntime = loadContainerRuntime;
11
+ exports.loadContainerRuntimeAlpha = loadContainerRuntimeAlpha;
12
+ exports.isContainerMessageDirtyable = isContainerMessageDirtyable;
8
13
  const client_utils_1 = require("@fluid-internal/client-utils");
9
14
  const container_definitions_1 = require("@fluidframework/container-definitions");
10
15
  const internal_1 = require("@fluidframework/container-definitions/internal");
@@ -136,7 +141,6 @@ const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
136
141
  function isUnpackedRuntimeMessage(message) {
137
142
  return Object.values(messageTypes_js_1.ContainerMessageType).includes(message.type);
138
143
  }
139
- exports.isUnpackedRuntimeMessage = isUnpackedRuntimeMessage;
140
144
  /**
141
145
  * Legacy ID for the built-in AgentScheduler. To minimize disruption while removing it, retaining this as a
142
146
  * special-case for document dirty state. Ultimately we should have no special-cases from the
@@ -152,7 +156,6 @@ function getDeviceSpec() {
152
156
  hardwareConcurrency: navigator.hardwareConcurrency,
153
157
  };
154
158
  }
155
- exports.getDeviceSpec = getDeviceSpec;
156
159
  /**
157
160
  * Older loader doesn't have a submitBatchFn member, this is the older way of submitting a batch.
158
161
  * Rather than exposing the submitFn (now deprecated) and IDeltaManager (dangerous to hand out) to the Outbox,
@@ -211,7 +214,6 @@ async function loadContainerRuntime(params) {
211
214
  registry: new dataStoreRegistry_js_1.FluidDataStoreRegistry(params.registryEntries),
212
215
  });
213
216
  }
214
- exports.loadContainerRuntime = loadContainerRuntime;
215
217
  /**
216
218
  * Alpha variant of {@link loadContainerRuntime} that returns the runtime in an
217
219
  * extendable object, allowing additional properties to be added in the future.
@@ -231,7 +233,6 @@ async function loadContainerRuntimeAlpha(params) {
231
233
  registry: new dataStoreRegistry_js_1.FluidDataStoreRegistry(params.registryEntries),
232
234
  });
233
235
  }
234
- exports.loadContainerRuntimeAlpha = loadContainerRuntimeAlpha;
235
236
  const defaultMaxConsecutiveReconnects = 7;
236
237
  /**
237
238
  * These are the ONLY message types that are allowed to be submitted while in staging mode
@@ -254,6 +255,17 @@ function canStageMessageOfType(type) {
254
255
  * @internal
255
256
  */
256
257
  class ContainerRuntime extends client_utils_1.TypedEventEmitter {
258
+ registry;
259
+ metadata;
260
+ electedSummarizerData;
261
+ runtimeOptions;
262
+ containerScope;
263
+ _storage;
264
+ createIdCompressorFn;
265
+ documentsSchemaController;
266
+ minVersionForCollab;
267
+ requestHandler;
268
+ summaryConfiguration;
257
269
  /**
258
270
  * Load the stores from a snapshot and returns the runtime.
259
271
  * @param params - An object housing the runtime properties.
@@ -272,6 +284,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
272
284
  static async loadRuntime(params) {
273
285
  return ContainerRuntime.loadRuntime2(params).then((r) => r.runtime);
274
286
  }
287
+ /**
288
+ * Hack to allow test-utils to detect which version of loadRuntime API to expect.
289
+ * See note in loadRuntime's private remarks.
290
+ */
291
+ static loadRuntimeAPIVersion = 2;
275
292
  /**
276
293
  * Load the stores from a snapshot and returns an object containing the runtime.
277
294
  * @remarks
@@ -310,8 +327,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
310
327
  const mc = (0, internal_8.loggerToMonitoringContext)(logger);
311
328
  // Some options require a minimum version of the FF runtime to operate, so the default configs will be generated
312
329
  // based on the minVersionForCollab.
313
- // For example, if minVersionForCollab is set to "1.0.0", the default configs will ensure compatibility with FF runtime
314
- // 1.0.0 or later. If the minVersionForCollab is set to "2.10.0", the default values will be generated to ensure compatibility
330
+ // For example, if minVersionForCollab is set to "2.0.0", the default configs will ensure compatibility with FF runtime
331
+ // 2.0.0 or later. If the minVersionForCollab is set to "2.10.0", the default values will be generated to ensure compatibility
315
332
  // with FF runtime 2.10.0 or later.
316
333
  if (!(0, internal_7.isValidMinVersionForCollab)(minVersionForCollab)) {
317
334
  throw new internal_8.UsageError(`Invalid minVersionForCollab: ${minVersionForCollab}. It must be an existing FF version (i.e. 2.22.1).`);
@@ -522,15 +539,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
522
539
  await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
523
540
  return { runtime };
524
541
  }
542
+ options;
543
+ _getClientId;
525
544
  get clientId() {
526
545
  return this._getClientId();
527
546
  }
547
+ clientDetails;
548
+ isSummarizerClient;
528
549
  get storage() {
529
550
  return this._storage;
530
551
  }
531
552
  get containerRuntime() {
532
553
  return this;
533
554
  }
555
+ submitSummaryFn;
556
+ submitSignalFn;
557
+ disposeFn;
558
+ /**
559
+ * Initiate closing of the container due to a critical error.
560
+ * @param error - The critical error that caused the container to close.
561
+ */
562
+ closeFn;
534
563
  get flushMode() {
535
564
  return this._flushMode;
536
565
  }
@@ -540,9 +569,29 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
540
569
  get IFluidDataStoreRegistry() {
541
570
  return this.registry;
542
571
  }
572
+ _getAttachState;
543
573
  get attachState() {
544
574
  return this._getAttachState();
545
575
  }
576
+ /**
577
+ * Whether local op submission is currently disallowed.
578
+ *
579
+ * This is `true` in two distinct situations.
580
+ *
581
+ * First: the delta manager reports a read-only connection (host/service-imposed permission or connection state — the historical meaning of `readOnly`).
582
+ *
583
+ * Second: the `PendingStateManager` is replaying stashed ops (`isApplyingStashedOps`). During this window DDSes must not submit new local ops, as doing so would interleave fresh content ahead of the stashed pending stream and corrupt pending local state. Surfacing it through `isReadOnly()` lets DDSes that consult `readOnly` at realize time self-suppress; see the apply-lifecycle docs on `PendingStateManager` for the full rationale.
584
+ *
585
+ * Note this layers a third meaning ("transiently quiescing for stashed-op replay") onto the `readOnly` predicate, which is broader than its host/connection-permission origin.
586
+ */
587
+ isReadOnly = () =>
588
+ // `_deltaManager` and `pendingStateManager` are both assigned partway
589
+ // through the constructor; `baseLogger` is built earlier and stamps
590
+ // `isReadOnly` on every error event (e.g. layer-compat failures
591
+ // during construction), so this can be called before either is
592
+ // assigned. Optional chains keep that window safe.
593
+ this._deltaManager?.readOnlyInfo.readonly === true ||
594
+ this.pendingStateManager?.isApplyingStashedOps === true;
546
595
  /**
547
596
  * Current session schema - defines what options are on & off.
548
597
  * It's overlap of document schema (controlled by summary & ops) and options controlling this session.
@@ -556,6 +605,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
556
605
  get sessionSchema() {
557
606
  return this.documentsSchemaController.sessionSchema.runtime;
558
607
  }
608
+ _idCompressor;
609
+ // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
610
+ // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
611
+ pendingIdCompressorOps = [];
612
+ // Id Compressor serializes final state (see getPendingLocalState()). As result, it needs to skip all ops that preceeded that state
613
+ // (such ops will be marked by Loader layer as savedOp === true)
614
+ // That said, in "delayed" mode it's possible that Id Compressor was never initialized before getPendingLocalState() is called.
615
+ // In such case we have to process all ops, including those marked with savedOp === true.
616
+ skipSavedCompressorOps;
559
617
  /**
560
618
  * {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.idCompressor}
561
619
  */
@@ -578,6 +636,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
578
636
  get IFluidHandleContext() {
579
637
  return this.handleContext;
580
638
  }
639
+ handleContext;
581
640
  /**
582
641
  * This is a proxy to the delta manager provided by the container context (innerDeltaManager). It restricts certain
583
642
  * accesses such as sets "read-only" mode for the summarizer client. This is the default delta manager that should
@@ -586,6 +645,41 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
586
645
  get deltaManager() {
587
646
  return this._deltaManager;
588
647
  }
648
+ _deltaManager;
649
+ /**
650
+ * The delta manager provided by the container context. By default, using the default delta manager (proxy)
651
+ * should be sufficient. This should be used only if necessary. For example, for validating and propagating connected
652
+ * events which requires access to the actual real only info, this is needed.
653
+ */
654
+ innerDeltaManager;
655
+ // internal logger for ContainerRuntime. Use this.logger for stores, summaries, etc.
656
+ mc;
657
+ summarizerClientElection;
658
+ /**
659
+ * summaryManager will only be created if this client is permitted to spawn a summarizing client
660
+ * It is created only by interactive client, i.e. summarizer client, as well as non-interactive bots
661
+ * do not create it (see SummarizerClientElection.clientDetailsPermitElection() for details)
662
+ */
663
+ summaryManager;
664
+ summarizerNode;
665
+ maxConsecutiveReconnects;
666
+ batchRunner = new runCounter_js_1.BatchRunCounter();
667
+ _flushMode;
668
+ stagingModeAutoFlushThreshold;
669
+ /**
670
+ * BatchId tracking is needed whenever there's a possibility of a "forked Container",
671
+ * where the same local state is pending in two different running Containers, each of
672
+ * which is trying to ensure it's persisted.
673
+ * "Offline Load" from serialized pending state is one such scenario since two Containers
674
+ * could load from the same serialized pending state.
675
+ */
676
+ batchIdTrackingEnabled;
677
+ flushScheduled = false;
678
+ canSendOps;
679
+ canSendSignals;
680
+ getConnectionState;
681
+ consecutiveReconnects = 0;
682
+ dataModelChangeRunner = new runCounter_js_1.RunCounter();
589
683
  /**
590
684
  * Invokes the given callback and expects that no ops are submitted
591
685
  * until execution finishes. If an op is submitted, it will be marked as reentrant.
@@ -608,15 +702,50 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
608
702
  get summarizerClientId() {
609
703
  return this.summarizerClientElection?.electedClientId;
610
704
  }
705
+ _disposed = false;
611
706
  get disposed() {
612
707
  return this._disposed;
613
708
  }
709
+ lastEmittedDirty;
710
+ emitDirtyDocumentEvent = true;
711
+ lastEmittedHasStagedChanges;
712
+ useDeltaManagerOpsProxy;
713
+ closeSummarizerDelayMs;
714
+ signalTelemetryManager = new signalTelemetryProcessing_js_1.SignalTelemetryManager();
715
+ /**
716
+ * Summarizer is responsible for coordinating when to send generate and send summaries.
717
+ * It is the main entry point for summary work.
718
+ * It is created only by summarizing container (i.e. one with clientType === "summarizer")
719
+ */
720
+ _summarizer;
721
+ deltaScheduler;
722
+ inboundBatchAggregator;
723
+ blobManager;
724
+ pendingStateManager;
725
+ duplicateBatchDetector;
726
+ versionMarkResolverInternal;
614
727
  /**
615
728
  * Host-facing version mark resolver.
616
729
  */
617
730
  get versionMarkResolver() {
618
731
  return this.versionMarkResolverInternal;
619
732
  }
733
+ outbox;
734
+ garbageCollector;
735
+ channelCollection;
736
+ remoteMessageProcessor;
737
+ versionMarkInboundBatchId;
738
+ /**
739
+ * The last message processed at the time of the last summary.
740
+ */
741
+ messageAtLastSummary;
742
+ summariesDisabled;
743
+ createContainerMetadata;
744
+ /**
745
+ * The summary number of the next summary that will be generated for this container. This is incremented every time
746
+ * a summary is generated.
747
+ */
748
+ nextSummaryNumber;
620
749
  /**
621
750
  * If false, loading or using a Tombstoned object should merely log, not fail.
622
751
  * @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.
@@ -633,6 +762,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
633
762
  get gcThrowOnTombstoneUsage() {
634
763
  return false;
635
764
  }
765
+ /**
766
+ * GUID to identify a document in telemetry
767
+ * ! Note: should not be used for anything other than telemetry and is not considered a stable GUID
768
+ */
769
+ telemetryDocumentId;
770
+ /**
771
+ * The id of the version used to initially load this runtime, or undefined if it's newly created.
772
+ */
773
+ loadedFromVersionId;
774
+ isSnapshotInstanceOfISnapshot;
775
+ /**
776
+ * The summary context of the last acked summary. The properties from this as used when uploading a summary.
777
+ */
778
+ lastAckedSummaryContext;
779
+ /**
780
+ * It a cache for holding mapping for loading groupIds with its snapshot from the service. Add expiry policy of 1 minute.
781
+ * Starting with 1 min and based on recorded usage we can tweak it later on.
782
+ */
783
+ snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
784
+ expiry: { policy: "absolute", durationMs: 60000 },
785
+ });
636
786
  /**
637
787
  * The compatibility details of the Runtime layer that is exposed to the Loader layer
638
788
  * for validating Loader-Runtime compatibility.
@@ -640,6 +790,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
640
790
  get ILayerCompatDetails() {
641
791
  return runtimeLayerCompatState_js_1.runtimeCompatDetailsForLoader;
642
792
  }
793
+ extensions = new Map();
794
+ baseLogger;
643
795
  /***/
644
796
  constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope,
645
797
  // Create a custom ITelemetryBaseLogger to output telemetry events.
@@ -663,206 +815,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
663
815
  this.minVersionForCollab = minVersionForCollab;
664
816
  this.requestHandler = requestHandler;
665
817
  this.summaryConfiguration = summaryConfiguration;
666
- /**
667
- * Whether local op submission is currently disallowed.
668
- *
669
- * This is `true` in two distinct situations.
670
- *
671
- * First: the delta manager reports a read-only connection (host/service-imposed permission or connection state — the historical meaning of `readOnly`).
672
- *
673
- * Second: the `PendingStateManager` is replaying stashed ops (`isApplyingStashedOps`). During this window DDSes must not submit new local ops, as doing so would interleave fresh content ahead of the stashed pending stream and corrupt pending local state. Surfacing it through `isReadOnly()` lets DDSes that consult `readOnly` at realize time self-suppress; see the apply-lifecycle docs on `PendingStateManager` for the full rationale.
674
- *
675
- * Note this layers a third meaning ("transiently quiescing for stashed-op replay") onto the `readOnly` predicate, which is broader than its host/connection-permission origin.
676
- */
677
- this.isReadOnly = () =>
678
- // `_deltaManager` and `pendingStateManager` are both assigned partway
679
- // through the constructor; `baseLogger` is built earlier and stamps
680
- // `isReadOnly` on every error event (e.g. layer-compat failures
681
- // during construction), so this can be called before either is
682
- // assigned. Optional chains keep that window safe.
683
- this._deltaManager?.readOnlyInfo.readonly === true ||
684
- this.pendingStateManager?.isApplyingStashedOps === true;
685
- // We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
686
- // Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
687
- this.pendingIdCompressorOps = [];
688
- this.batchRunner = new runCounter_js_1.BatchRunCounter();
689
- this.flushScheduled = false;
690
- this.consecutiveReconnects = 0;
691
- this.dataModelChangeRunner = new runCounter_js_1.RunCounter();
692
- this._disposed = false;
693
- this.emitDirtyDocumentEvent = true;
694
- this.signalTelemetryManager = new signalTelemetryProcessing_js_1.SignalTelemetryManager();
695
- /**
696
- * It a cache for holding mapping for loading groupIds with its snapshot from the service. Add expiry policy of 1 minute.
697
- * Starting with 1 min and based on recorded usage we can tweak it later on.
698
- */
699
- this.snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
700
- expiry: { policy: "absolute", durationMs: 60000 },
701
- });
702
- this.extensions = new Map();
703
- // Boolean payload from the `"readonly"` delta-manager event is intentionally
704
- // ignored — `isReadOnly()` aggregates delta-manager readonly with the PSM
705
- // apply window, and that aggregation is the source of truth for fanout.
706
- // `channelCollection?.` guards against future wiring changes; both callers
707
- // today (the `"readonly"` listener and `onAfterStashedOpsApplied`) fire
708
- // after `channelCollection` is assigned.
709
- this.notifyReadOnlyState = (_readonly) => this.channelCollection?.notifyReadOnlyState(this.isReadOnly());
710
- /**
711
- * Enter Staging Mode, such that ops submitted to the ContainerRuntime will not be sent to the ordering service.
712
- * To exit Staging Mode, call either discardChanges or commitChanges on the Stage Controls returned from this method.
713
- *
714
- * @remarks
715
- * The `stagingModeChanged` event is emitted when staging mode is entered or exited via this method.
716
- * It is NOT emitted when staging mode is used internally (e.g. by `orderSequentially` for rollback support).
717
- *
718
- * @returns Controls for exiting Staging Mode.
719
- */
720
- this.enterStagingMode = () => this.enterStagingModeCore(false);
721
- /**
722
- * Internal implementation of enterStagingMode.
723
- * @param silent - When true, suppresses `stagingModeChanged` event emission.
724
- * Pass `true` when staging mode is used as an internal implementation detail (e.g. by
725
- * `orderSequentially` for rollback support) so that external listeners only observe
726
- * user-initiated staging mode transitions. Pass `false` for all public entry points.
727
- */
728
- this.enterStagingModeCore = (silent) => {
729
- if (this.stageControls !== undefined) {
730
- throw new internal_8.UsageError("Already in staging mode");
731
- }
732
- if (this.attachState === container_definitions_1.AttachState.Detached) {
733
- throw new internal_8.UsageError("Cannot enter staging mode while Detached");
734
- }
735
- // Make sure Outbox is empty before entering staging mode,
736
- // since we mark whole batches as "staged" or not to indicate whether to submit them.
737
- this.flush();
738
- // Note: `silent` is captured from the enclosing `enterStagingModeCore` call.
739
- // When `true`, both enter and exit events are suppressed (see orderSequentially).
740
- const exitStagingMode = (discardOrCommit, exitMethod) => {
741
- if (this.stageControls !== stageControls) {
742
- throw new internal_8.UsageError("Not in staging mode");
743
- }
744
- try {
745
- internal_8.PerformanceEvent.timedExec(this.mc.logger, {
746
- eventName: `ExitStagingMode_${exitMethod}`,
747
- }, (event) => {
748
- // Final flush of any last staged changes
749
- // NOTE: We can't use this.flush() here, because orderSequentially uses StagingMode and in the rollback case we'll hit assert 0x24c
750
- this.outbox.flush();
751
- this.stageControls = undefined;
752
- const batchInfos = discardOrCommit();
753
- event.reportProgress({
754
- details: {
755
- autoFlushThreshold: this.stagingModeAutoFlushThreshold,
756
- batches: batchInfos.length,
757
- batchesAtOrOverThreshold: batchInfos.filter((b) => b.length >= this.stagingModeAutoFlushThreshold).length,
758
- },
759
- });
760
- this.channelCollection.notifyStagingMode(false);
761
- });
762
- }
763
- catch (error) {
764
- const normalizedError = (0, internal_8.normalizeError)(error);
765
- this.closeFn(normalizedError);
766
- throw normalizedError;
767
- }
768
- if (!silent) {
769
- this.emit("stagingModeChanged", {
770
- inStagingMode: false,
771
- commit: exitMethod === "commit",
772
- });
773
- }
774
- };
775
- const stageControls = {
776
- discardChanges: () => exitStagingMode(() => {
777
- // Pop all staged batches from the PSM and roll them back in LIFO order
778
- const batchInfos = this.pendingStateManager.popStagedBatches(({ runtimeOp, localOpMetadata }) => {
779
- this.rollbackStagedChange(runtimeOp, localOpMetadata);
780
- });
781
- this.updateDocumentDirtyState();
782
- this.updateHasStagedChangesState();
783
- return batchInfos;
784
- }, "discard"),
785
- commitChanges: (options) => {
786
- const { squash } = { ...defaultStagingCommitOptions, ...options };
787
- exitStagingMode(() => {
788
- // Replay all staged batches in typical FIFO order.
789
- // We'll be out of staging mode so they'll be sent to the service finally.
790
- const batchInfos = this.pendingStateManager.replayPendingStates({
791
- committingStagedBatches: true,
792
- squash,
793
- });
794
- this.updateHasStagedChangesState();
795
- return batchInfos;
796
- }, "commit");
797
- },
798
- };
799
- this.stageControls = stageControls;
800
- this.channelCollection.notifyStagingMode(true);
801
- if (!silent) {
802
- try {
803
- this.emit("stagingModeChanged", { inStagingMode: true });
804
- }
805
- catch (error) {
806
- // Don't let a listener error prevent the caller from receiving stage controls.
807
- this.mc.logger.sendErrorEvent({ eventName: "StagingModeChangedError" }, error);
808
- }
809
- }
810
- return stageControls;
811
- };
812
- this.readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
813
- /**
814
- * ContainerRuntime knows about additional restrictions on when blob sharing can be resumed as compared
815
- * to BlobManager. In particular, it wants to avoid sharing blobs while in readonly state, and it also
816
- * wants to avoid sharing blobs before connection completes (otherwise it may cause the sharing to happen
817
- * before processing shared ops).
818
- *
819
- * This method can be called safely before those conditions are met. In the background, it will wait until
820
- * it is safe before initiating sharing. It will close the container on any error.
821
- */
822
- this.sharePendingBlobs = () => {
823
- new Promise((resolve) => {
824
- // eslint-disable-next-line unicorn/consistent-function-scoping
825
- const canStartSharing = () => this.connected && this.deltaManager.readOnlyInfo.readonly !== true;
826
- if (canStartSharing()) {
827
- resolve();
828
- return;
829
- }
830
- const checkCanShare = (readonly) => {
831
- if (canStartSharing()) {
832
- this.deltaManager.off("readonly", checkCanShare);
833
- this.off("connected", checkCanShare);
834
- resolve();
835
- }
836
- };
837
- this.deltaManager.on("readonly", checkCanShare);
838
- this.on("connected", checkCanShare);
839
- })
840
- .then(this.blobManager.sharePendingBlobs)
841
- // It may not be necessary to close the container on failures - this should just mean there's
842
- // a handle in the container that is stuck pending, which is a scenario that customers need to
843
- // handle anyway. Starting with this more aggressive/restrictive behavior to be cautious.
844
- .catch(this.closeFn);
845
- };
846
- // While internal, ContainerRuntime has not been converted to use the new events support.
847
- // Recreate the required events (new pattern) with injected, wrapper new emitter.
848
- // It is lazily create to avoid listeners (old events) that ultimately go nowhere.
849
- this.lazyEventsForExtensions = new internal_2.Lazy(() => {
850
- const eventEmitter = (0, client_utils_1.createEmitter)();
851
- if (this.getConnectionState) {
852
- this.on("connectedToService", (clientId, canWrite) => {
853
- eventEmitter.emit("joined", { clientId, canWrite });
854
- });
855
- this.on("disconnectedFromService", () => eventEmitter.emit("disconnected"));
856
- this.on("operabilityChanged", (canWrite) => eventEmitter.emit("operabilityChanged", canWrite));
857
- }
858
- else {
859
- this.on("connected", (clientId) => {
860
- eventEmitter.emit("joined", { clientId, canWrite: true });
861
- });
862
- this.on("disconnected", () => eventEmitter.emit("disconnected"));
863
- }
864
- return eventEmitter;
865
- });
866
818
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, signalAudience, pendingLocalState, snapshotWithContents, getConnectionState, } = context;
867
819
  this.getConnectionState = getConnectionState;
868
820
  // In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
@@ -1021,6 +973,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1021
973
  const fetchOps = context.fetchOps;
1022
974
  this.versionMarkResolverInternal = new index_js_4.VersionMarkResolver({
1023
975
  getCurrentSequenceNumber: () => this.deltaManager.lastSequenceNumber,
976
+ getCurrentTimestamp: () => this.getCurrentReferenceTimestampMs(),
1024
977
  getCurrentMinimumSequenceNumber: () => this.deltaManager.minimumSequenceNumber,
1025
978
  getCurrentPendingBatchId: () => this.pendingStateManager.getMostRecentPendingBatchId(),
1026
979
  logger: (0, internal_8.createChildLogger)({
@@ -1030,7 +983,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1030
983
  // Seal the current outbound batch so a just-submitted edit gets a stable batchId in the pending
1031
984
  // state before sealAndCaptureVersionMark reads it (a batchId is only assigned when flushed).
1032
985
  flushPendingBatch: () => this.flush(),
1033
- // Wire the container-provided op reader (if any) so resolution can read historical ops.
986
+ // Keep this optional while a supported older loader may not provide fetchOps. AB#81034 tracks
987
+ // making it required once the Runtime -> Loader compatibility window reaches generation 21.
1034
988
  getHistoricalOpReader: fetchOps ? () => ({ fetchMessages: fetchOps }) : undefined,
1035
989
  // Unpack scanned historical ops through the same pipeline the live inbound path uses, so a
1036
990
  // chunked batch's batchId (only restored after reassembly) is observed by the history scan too.
@@ -1038,15 +992,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1038
992
  ? () => {
1039
993
  // A fresh processor per scan: it holds chunk-reassembly state, so it must not share
1040
994
  // the live inbound processor's state. submit/size args are unused on the read path.
1041
- const scanProcessor = new index_js_3.RemoteMessageProcessor(new index_js_3.OpSplitter([], submitBatchFn, runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger), new index_js_3.OpDecompressor(this.mc.logger), new index_js_3.OpGroupingManager({ groupedBatchingEnabled: this.groupedBatchingEnabled }, this.mc.logger));
995
+ const scanProcessor = new index_js_3.RemoteMessageProcessor(new index_js_3.OpSplitter([], submitBatchFn, runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger, { allowInitialPartialChunkStream: true }), new index_js_3.OpDecompressor(this.mc.logger), new index_js_3.OpGroupingManager({ groupedBatchingEnabled: this.groupedBatchingEnabled }, this.mc.logger));
1042
996
  return (op) => {
1043
- // Mirror the live path: only modern runtime-envelope ops (type Operation, with a
1044
- // client id) carry batches; skip system/server ops.
1045
- if (op.type !== internal_3.MessageType.Operation || typeof op.clientId !== "string") {
997
+ // Only runtime ops carry batches; deserialize a copy so the reader-owned op stays untouched.
998
+ const messageCopy = (0, index_js_3.tryGetDeserializedRuntimeOpCopy)(op);
999
+ if (messageCopy === undefined) {
1046
1000
  return undefined;
1047
1001
  }
1048
- const messageCopy = { ...op };
1049
- (0, index_js_3.ensureContentsDeserialized)(messageCopy);
1050
1002
  return scanProcessor.process(messageCopy, (0, exports.getSingleUseLegacyLogCallback)(this.mc.logger, messageCopy.type));
1051
1003
  };
1052
1004
  }
@@ -1270,10 +1222,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1270
1222
  const clientId = this._getClientId();
1271
1223
  return clientId === undefined
1272
1224
  ? undefined
1273
- : ({
1225
+ : {
1274
1226
  clientId,
1275
1227
  client: audience.getMember(clientId),
1276
- });
1228
+ };
1277
1229
  };
1278
1230
  let oldClientId = this.clientId;
1279
1231
  this.on("connected", () => {
@@ -1685,6 +1637,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1685
1637
  async getEntryPoint() {
1686
1638
  return this.entryPoint;
1687
1639
  }
1640
+ entryPoint;
1688
1641
  internalId(maybeAlias) {
1689
1642
  return this.channelCollection.internalId(maybeAlias);
1690
1643
  }
@@ -1903,6 +1856,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1903
1856
  (0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x976 /* No new ops added */);
1904
1857
  }
1905
1858
  }
1859
+ // Boolean payload from the `"readonly"` delta-manager event is intentionally
1860
+ // ignored — `isReadOnly()` aggregates delta-manager readonly with the PSM
1861
+ // apply window, and that aggregation is the source of truth for fanout.
1862
+ // `channelCollection?.` guards against future wiring changes; both callers
1863
+ // today (the `"readonly"` listener and `onAfterStashedOpsApplied`) fire
1864
+ // after `channelCollection` is assigned.
1865
+ notifyReadOnlyState = (_readonly) => this.channelCollection?.notifyReadOnlyState(this.isReadOnly());
1906
1866
  setConnectionState(canSendOps, clientId) {
1907
1867
  this.setConnectionStateToConnectedOrDisconnected(canSendOps, clientId);
1908
1868
  }
@@ -2125,7 +2085,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2125
2085
  if (this.versionMarkResolverInternal.isTracking) {
2126
2086
  const versionMarkUpdate = (0, index_js_4.inboundVersionMarkUpdate)(inboundResult, this.versionMarkInboundBatchId);
2127
2087
  if (versionMarkUpdate.sequenced !== undefined) {
2128
- this.versionMarkResolverInternal.processInboundBatch(versionMarkUpdate.sequenced.batchId, versionMarkUpdate.sequenced.sequenceNumber);
2088
+ this.versionMarkResolverInternal.processInboundBatch(versionMarkUpdate.sequenced.batchId, versionMarkUpdate.sequenced.sequenceNumber, versionMarkUpdate.sequenced.timestamp);
2129
2089
  }
2130
2090
  this.versionMarkInboundBatchId = versionMarkUpdate.carriedBatchId;
2131
2091
  }
@@ -2175,6 +2135,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2175
2135
  this.resetReconnectCount();
2176
2136
  }
2177
2137
  }
2138
+ _processedClientSequenceNumber;
2178
2139
  /**
2179
2140
  * Processes inbound message(s). It calls delta scheduler according to the messages' location in the batch.
2180
2141
  * @param messagesWithMetadata - messages to process along with their metadata.
@@ -2511,6 +2472,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2511
2472
  }
2512
2473
  return result;
2513
2474
  }
2475
+ stageControls;
2514
2476
  /**
2515
2477
  * If true, the ContainerRuntime is not submitting any new ops to the ordering service.
2516
2478
  * Ops submitted to the ContainerRuntime while in Staging Mode will be queued in the PendingStateManager,
@@ -2519,6 +2481,108 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2519
2481
  get inStagingMode() {
2520
2482
  return this.stageControls !== undefined;
2521
2483
  }
2484
+ /**
2485
+ * Enter Staging Mode, such that ops submitted to the ContainerRuntime will not be sent to the ordering service.
2486
+ * To exit Staging Mode, call either discardChanges or commitChanges on the Stage Controls returned from this method.
2487
+ *
2488
+ * @remarks
2489
+ * The `stagingModeChanged` event is emitted when staging mode is entered or exited via this method.
2490
+ * It is NOT emitted when staging mode is used internally (e.g. by `orderSequentially` for rollback support).
2491
+ *
2492
+ * @returns Controls for exiting Staging Mode.
2493
+ */
2494
+ enterStagingMode = () => this.enterStagingModeCore(false);
2495
+ /**
2496
+ * Internal implementation of enterStagingMode.
2497
+ * @param silent - When true, suppresses `stagingModeChanged` event emission.
2498
+ * Pass `true` when staging mode is used as an internal implementation detail (e.g. by
2499
+ * `orderSequentially` for rollback support) so that external listeners only observe
2500
+ * user-initiated staging mode transitions. Pass `false` for all public entry points.
2501
+ */
2502
+ enterStagingModeCore = (silent) => {
2503
+ if (this.stageControls !== undefined) {
2504
+ throw new internal_8.UsageError("Already in staging mode");
2505
+ }
2506
+ if (this.attachState === container_definitions_1.AttachState.Detached) {
2507
+ throw new internal_8.UsageError("Cannot enter staging mode while Detached");
2508
+ }
2509
+ // Make sure Outbox is empty before entering staging mode,
2510
+ // since we mark whole batches as "staged" or not to indicate whether to submit them.
2511
+ this.flush();
2512
+ // Note: `silent` is captured from the enclosing `enterStagingModeCore` call.
2513
+ // When `true`, both enter and exit events are suppressed (see orderSequentially).
2514
+ const exitStagingMode = (discardOrCommit, exitMethod) => {
2515
+ if (this.stageControls !== stageControls) {
2516
+ throw new internal_8.UsageError("Not in staging mode");
2517
+ }
2518
+ try {
2519
+ internal_8.PerformanceEvent.timedExec(this.mc.logger, {
2520
+ eventName: `ExitStagingMode_${exitMethod}`,
2521
+ }, (event) => {
2522
+ // Final flush of any last staged changes
2523
+ // NOTE: We can't use this.flush() here, because orderSequentially uses StagingMode and in the rollback case we'll hit assert 0x24c
2524
+ this.outbox.flush();
2525
+ this.stageControls = undefined;
2526
+ const batchInfos = discardOrCommit();
2527
+ event.reportProgress({
2528
+ details: {
2529
+ autoFlushThreshold: this.stagingModeAutoFlushThreshold,
2530
+ batches: batchInfos.length,
2531
+ batchesAtOrOverThreshold: batchInfos.filter((b) => b.length >= this.stagingModeAutoFlushThreshold).length,
2532
+ },
2533
+ });
2534
+ this.channelCollection.notifyStagingMode(false);
2535
+ });
2536
+ }
2537
+ catch (error) {
2538
+ const normalizedError = (0, internal_8.normalizeError)(error);
2539
+ this.closeFn(normalizedError);
2540
+ throw normalizedError;
2541
+ }
2542
+ if (!silent) {
2543
+ this.emit("stagingModeChanged", {
2544
+ inStagingMode: false,
2545
+ commit: exitMethod === "commit",
2546
+ });
2547
+ }
2548
+ };
2549
+ const stageControls = {
2550
+ discardChanges: () => exitStagingMode(() => {
2551
+ // Pop all staged batches from the PSM and roll them back in LIFO order
2552
+ const batchInfos = this.pendingStateManager.popStagedBatches(({ runtimeOp, localOpMetadata }) => {
2553
+ this.rollbackStagedChange(runtimeOp, localOpMetadata);
2554
+ });
2555
+ this.updateDocumentDirtyState();
2556
+ this.updateHasStagedChangesState();
2557
+ return batchInfos;
2558
+ }, "discard"),
2559
+ commitChanges: (options) => {
2560
+ const { squash } = { ...defaultStagingCommitOptions, ...options };
2561
+ exitStagingMode(() => {
2562
+ // Replay all staged batches in typical FIFO order.
2563
+ // We'll be out of staging mode so they'll be sent to the service finally.
2564
+ const batchInfos = this.pendingStateManager.replayPendingStates({
2565
+ committingStagedBatches: true,
2566
+ squash,
2567
+ });
2568
+ this.updateHasStagedChangesState();
2569
+ return batchInfos;
2570
+ }, "commit");
2571
+ },
2572
+ };
2573
+ this.stageControls = stageControls;
2574
+ this.channelCollection.notifyStagingMode(true);
2575
+ if (!silent) {
2576
+ try {
2577
+ this.emit("stagingModeChanged", { inStagingMode: true });
2578
+ }
2579
+ catch (error) {
2580
+ // Don't let a listener error prevent the caller from receiving stage controls.
2581
+ this.mc.logger.sendErrorEvent({ eventName: "StagingModeChangedError" }, error);
2582
+ }
2583
+ }
2584
+ return stageControls;
2585
+ };
2522
2586
  /**
2523
2587
  * Returns the aliased data store's entryPoint, given the alias.
2524
2588
  * @param alias - The alias for the data store.
@@ -2565,12 +2629,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2565
2629
  // container runtime's ability to send ops depend on the actual readonly state of the delta manager.
2566
2630
  return this.connected && this.innerDeltaManager.readOnlyInfo.readonly !== true;
2567
2631
  }
2632
+ _quorum;
2568
2633
  getQuorum() {
2569
2634
  return this._quorum;
2570
2635
  }
2636
+ _audience;
2571
2637
  getAudience() {
2572
2638
  return this._audience;
2573
2639
  }
2640
+ /**
2641
+ * When defined, this {@link @fluidframework/container-definitions#IAudience}
2642
+ * maintains member list using signals only.
2643
+ * Thus "write" members may be known earlier than quorum and avoid noise from
2644
+ * un-summarized quorum history.
2645
+ */
2646
+ signalAudience;
2574
2647
  /**
2575
2648
  * Returns true of container is dirty, i.e. there are some pending local changes that
2576
2649
  * either were not sent out to delta stream or were not yet acknowledged.
@@ -2670,6 +2743,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2670
2743
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
2671
2744
  return summarizeResult.summary;
2672
2745
  }
2746
+ getAbsoluteUrl;
2673
2747
  /**
2674
2748
  * Builds the Summary tree including all the channels and the container state.
2675
2749
  *
@@ -3610,6 +3684,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
3610
3684
  referenceSequenceNumber: summaryRefSeq,
3611
3685
  };
3612
3686
  }
3687
+ readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
3613
3688
  /**
3614
3689
  * Fetches the latest snapshot from storage. If the fetched snapshot is same or newer than the one for which ack
3615
3690
  * was received, close this client. Fetching the snapshot will update the cache for this client so if it's
@@ -3701,6 +3776,39 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
3701
3776
  return pendingRuntimeState;
3702
3777
  });
3703
3778
  }
3779
+ /**
3780
+ * ContainerRuntime knows about additional restrictions on when blob sharing can be resumed as compared
3781
+ * to BlobManager. In particular, it wants to avoid sharing blobs while in readonly state, and it also
3782
+ * wants to avoid sharing blobs before connection completes (otherwise it may cause the sharing to happen
3783
+ * before processing shared ops).
3784
+ *
3785
+ * This method can be called safely before those conditions are met. In the background, it will wait until
3786
+ * it is safe before initiating sharing. It will close the container on any error.
3787
+ */
3788
+ sharePendingBlobs = () => {
3789
+ new Promise((resolve) => {
3790
+ // eslint-disable-next-line unicorn/consistent-function-scoping
3791
+ const canStartSharing = () => this.connected && this.deltaManager.readOnlyInfo.readonly !== true;
3792
+ if (canStartSharing()) {
3793
+ resolve();
3794
+ return;
3795
+ }
3796
+ const checkCanShare = (readonly) => {
3797
+ if (canStartSharing()) {
3798
+ this.deltaManager.off("readonly", checkCanShare);
3799
+ this.off("connected", checkCanShare);
3800
+ resolve();
3801
+ }
3802
+ };
3803
+ this.deltaManager.on("readonly", checkCanShare);
3804
+ this.on("connected", checkCanShare);
3805
+ })
3806
+ .then(this.blobManager.sharePendingBlobs)
3807
+ // It may not be necessary to close the container on failures - this should just mean there's
3808
+ // a handle in the container that is stuck pending, which is a scenario that customers need to
3809
+ // handle anyway. Starting with this more aggressive/restrictive behavior to be cautious.
3810
+ .catch(this.closeFn);
3811
+ };
3704
3812
  summarizeOnDemand(options) {
3705
3813
  if (this._summarizer !== undefined) {
3706
3814
  return this._summarizer.summarizeOnDemand(options);
@@ -3729,6 +3837,26 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
3729
3837
  return this.summaryManager.enqueueSummarize(options);
3730
3838
  }
3731
3839
  }
3840
+ // While internal, ContainerRuntime has not been converted to use the new events support.
3841
+ // Recreate the required events (new pattern) with injected, wrapper new emitter.
3842
+ // It is lazily create to avoid listeners (old events) that ultimately go nowhere.
3843
+ lazyEventsForExtensions = new internal_2.Lazy(() => {
3844
+ const eventEmitter = (0, client_utils_1.createEmitter)();
3845
+ if (this.getConnectionState) {
3846
+ this.on("connectedToService", (clientId, canWrite) => {
3847
+ eventEmitter.emit("joined", { clientId, canWrite });
3848
+ });
3849
+ this.on("disconnectedFromService", () => eventEmitter.emit("disconnected"));
3850
+ this.on("operabilityChanged", (canWrite) => eventEmitter.emit("operabilityChanged", canWrite));
3851
+ }
3852
+ else {
3853
+ this.on("connected", (clientId) => {
3854
+ eventEmitter.emit("joined", { clientId, canWrite: true });
3855
+ });
3856
+ this.on("disconnected", () => eventEmitter.emit("disconnected"));
3857
+ }
3858
+ return eventEmitter;
3859
+ });
3732
3860
  getJoinedStatus() {
3733
3861
  const getConnectionState = this.getConnectionState;
3734
3862
  if (getConnectionState) {
@@ -3744,6 +3872,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
3744
3872
  }
3745
3873
  return "disconnected";
3746
3874
  }
3875
+ submitExtensionSignal;
3747
3876
  acquireExtension(id, factory, ...useContext) {
3748
3877
  return this.acquireExtensionInternal(
3749
3878
  /* injectionPermitted */ true, id, factory, ...useContext);
@@ -3823,11 +3952,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
3823
3952
  }
3824
3953
  }
3825
3954
  exports.ContainerRuntime = ContainerRuntime;
3826
- /**
3827
- * Hack to allow test-utils to detect which version of loadRuntime API to expect.
3828
- * See note in loadRuntime's private remarks.
3829
- */
3830
- ContainerRuntime.loadRuntimeAPIVersion = 2;
3831
3955
  function isContainerMessageDirtyable({ type, contents, }) {
3832
3956
  // Certain container runtime messages should not mark the container dirty such as the old built-in
3833
3957
  // AgentScheduler and Garbage collector messages.
@@ -3857,5 +3981,4 @@ function isContainerMessageDirtyable({ type, contents, }) {
3857
3981
  }
3858
3982
  return true;
3859
3983
  }
3860
- exports.isContainerMessageDirtyable = isContainerMessageDirtyable;
3861
3984
  //# sourceMappingURL=containerRuntime.js.map