@fluidframework/container-runtime 2.0.0-internal.7.1.1 → 2.0.0-internal.7.2.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 (169) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-extractor.json +1 -13
  3. package/api-report/container-runtime.api.md +72 -9
  4. package/dist/blobManager.d.ts +3 -3
  5. package/dist/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager.js +41 -49
  7. package/dist/blobManager.js.map +1 -1
  8. package/dist/containerRuntime.d.ts +65 -19
  9. package/dist/containerRuntime.d.ts.map +1 -1
  10. package/dist/containerRuntime.js +52 -29
  11. package/dist/containerRuntime.js.map +1 -1
  12. package/dist/dataStore.js +2 -2
  13. package/dist/dataStore.js.map +1 -1
  14. package/dist/dataStoreContext.d.ts +8 -2
  15. package/dist/dataStoreContext.d.ts.map +1 -1
  16. package/dist/dataStoreContext.js +14 -3
  17. package/dist/dataStoreContext.js.map +1 -1
  18. package/dist/dataStoreRegistry.d.ts +3 -0
  19. package/dist/dataStoreRegistry.d.ts.map +1 -1
  20. package/dist/dataStoreRegistry.js +3 -0
  21. package/dist/dataStoreRegistry.js.map +1 -1
  22. package/dist/deltaManagerProxyBase.d.ts +1 -1
  23. package/dist/deltaManagerProxyBase.d.ts.map +1 -1
  24. package/dist/deltaManagerProxyBase.js +2 -2
  25. package/dist/deltaManagerProxyBase.js.map +1 -1
  26. package/dist/gc/gcDefinitions.d.ts +26 -5
  27. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  28. package/dist/gc/gcDefinitions.js +4 -1
  29. package/dist/gc/gcDefinitions.js.map +1 -1
  30. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  31. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  32. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  33. package/dist/gc/gcTelemetry.js +4 -4
  34. package/dist/gc/gcTelemetry.js.map +1 -1
  35. package/dist/id-compressor/utilities.d.ts +3 -0
  36. package/dist/id-compressor/utilities.d.ts.map +1 -1
  37. package/dist/id-compressor/utilities.js +3 -0
  38. package/dist/id-compressor/utilities.js.map +1 -1
  39. package/dist/index.d.ts +3 -2
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +3 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/messageTypes.d.ts +4 -1
  44. package/dist/messageTypes.d.ts.map +1 -1
  45. package/dist/messageTypes.js +3 -0
  46. package/dist/messageTypes.js.map +1 -1
  47. package/dist/opLifecycle/definitions.d.ts +3 -0
  48. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  49. package/dist/opLifecycle/definitions.js.map +1 -1
  50. package/dist/packageVersion.d.ts +1 -1
  51. package/dist/packageVersion.js +1 -1
  52. package/dist/packageVersion.js.map +1 -1
  53. package/dist/summary/orderedClientElection.d.ts +4 -1
  54. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  55. package/dist/summary/orderedClientElection.js.map +1 -1
  56. package/dist/summary/runWhileConnectedCoordinator.d.ts +5 -0
  57. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  58. package/dist/summary/runWhileConnectedCoordinator.js +1 -0
  59. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  60. package/dist/summary/summarizer.d.ts +1 -0
  61. package/dist/summary/summarizer.d.ts.map +1 -1
  62. package/dist/summary/summarizer.js +1 -0
  63. package/dist/summary/summarizer.js.map +1 -1
  64. package/dist/summary/summarizerTypes.d.ts +94 -10
  65. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  66. package/dist/summary/summarizerTypes.js.map +1 -1
  67. package/dist/summary/summaryCollection.d.ts +16 -0
  68. package/dist/summary/summaryCollection.d.ts.map +1 -1
  69. package/dist/summary/summaryCollection.js +1 -0
  70. package/dist/summary/summaryCollection.js.map +1 -1
  71. package/dist/summary/summaryFormat.d.ts +10 -1
  72. package/dist/summary/summaryFormat.d.ts.map +1 -1
  73. package/dist/summary/summaryFormat.js.map +1 -1
  74. package/lib/blobManager.d.ts +3 -3
  75. package/lib/blobManager.d.ts.map +1 -1
  76. package/lib/blobManager.js +42 -50
  77. package/lib/blobManager.js.map +1 -1
  78. package/lib/containerRuntime.d.ts +65 -19
  79. package/lib/containerRuntime.d.ts.map +1 -1
  80. package/lib/containerRuntime.js +52 -29
  81. package/lib/containerRuntime.js.map +1 -1
  82. package/lib/dataStore.js +2 -2
  83. package/lib/dataStore.js.map +1 -1
  84. package/lib/dataStoreContext.d.ts +8 -2
  85. package/lib/dataStoreContext.d.ts.map +1 -1
  86. package/lib/dataStoreContext.js +14 -3
  87. package/lib/dataStoreContext.js.map +1 -1
  88. package/lib/dataStoreRegistry.d.ts +3 -0
  89. package/lib/dataStoreRegistry.d.ts.map +1 -1
  90. package/lib/dataStoreRegistry.js +3 -0
  91. package/lib/dataStoreRegistry.js.map +1 -1
  92. package/lib/deltaManagerProxyBase.d.ts +1 -1
  93. package/lib/deltaManagerProxyBase.d.ts.map +1 -1
  94. package/lib/deltaManagerProxyBase.js +2 -2
  95. package/lib/deltaManagerProxyBase.js.map +1 -1
  96. package/lib/gc/gcDefinitions.d.ts +26 -5
  97. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  98. package/lib/gc/gcDefinitions.js +4 -1
  99. package/lib/gc/gcDefinitions.js.map +1 -1
  100. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  101. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  102. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  103. package/lib/gc/gcTelemetry.js +4 -4
  104. package/lib/gc/gcTelemetry.js.map +1 -1
  105. package/lib/id-compressor/utilities.d.ts +3 -0
  106. package/lib/id-compressor/utilities.d.ts.map +1 -1
  107. package/lib/id-compressor/utilities.js +3 -0
  108. package/lib/id-compressor/utilities.js.map +1 -1
  109. package/lib/index.d.ts +3 -2
  110. package/lib/index.d.ts.map +1 -1
  111. package/lib/index.js +1 -0
  112. package/lib/index.js.map +1 -1
  113. package/lib/messageTypes.d.ts +4 -1
  114. package/lib/messageTypes.d.ts.map +1 -1
  115. package/lib/messageTypes.js +3 -0
  116. package/lib/messageTypes.js.map +1 -1
  117. package/lib/opLifecycle/definitions.d.ts +3 -0
  118. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  119. package/lib/opLifecycle/definitions.js.map +1 -1
  120. package/lib/packageVersion.d.ts +1 -1
  121. package/lib/packageVersion.js +1 -1
  122. package/lib/packageVersion.js.map +1 -1
  123. package/lib/summary/orderedClientElection.d.ts +4 -1
  124. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  125. package/lib/summary/orderedClientElection.js.map +1 -1
  126. package/lib/summary/runWhileConnectedCoordinator.d.ts +5 -0
  127. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  128. package/lib/summary/runWhileConnectedCoordinator.js +1 -0
  129. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  130. package/lib/summary/summarizer.d.ts +1 -0
  131. package/lib/summary/summarizer.d.ts.map +1 -1
  132. package/lib/summary/summarizer.js +1 -0
  133. package/lib/summary/summarizer.js.map +1 -1
  134. package/lib/summary/summarizerTypes.d.ts +94 -10
  135. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  136. package/lib/summary/summarizerTypes.js.map +1 -1
  137. package/lib/summary/summaryCollection.d.ts +16 -0
  138. package/lib/summary/summaryCollection.d.ts.map +1 -1
  139. package/lib/summary/summaryCollection.js +1 -0
  140. package/lib/summary/summaryCollection.js.map +1 -1
  141. package/lib/summary/summaryFormat.d.ts +10 -1
  142. package/lib/summary/summaryFormat.d.ts.map +1 -1
  143. package/lib/summary/summaryFormat.js.map +1 -1
  144. package/package.json +19 -20
  145. package/src/blobManager.ts +58 -59
  146. package/src/containerRuntime.ts +79 -39
  147. package/src/dataStore.ts +2 -2
  148. package/src/dataStoreContext.ts +14 -3
  149. package/src/dataStoreRegistry.ts +3 -0
  150. package/src/deltaManagerProxyBase.ts +2 -2
  151. package/src/gc/gcDefinitions.ts +27 -5
  152. package/src/gc/gcSummaryDefinitions.ts +1 -1
  153. package/src/gc/gcTelemetry.ts +5 -4
  154. package/src/id-compressor/utilities.ts +3 -0
  155. package/src/index.ts +13 -1
  156. package/src/messageTypes.ts +4 -1
  157. package/src/opLifecycle/definitions.ts +3 -0
  158. package/src/packageVersion.ts +1 -1
  159. package/src/summary/orderedClientElection.ts +4 -1
  160. package/src/summary/runWhileConnectedCoordinator.ts +5 -1
  161. package/src/summary/summarizer.ts +1 -0
  162. package/src/summary/summarizerTypes.ts +95 -11
  163. package/src/summary/summaryCollection.ts +18 -1
  164. package/src/summary/summaryFormat.ts +11 -1
  165. package/dist/container-runtime-alpha.d.ts +0 -1554
  166. package/dist/container-runtime-beta.d.ts +0 -1554
  167. package/dist/container-runtime-public.d.ts +0 -1554
  168. package/dist/container-runtime.d.ts +0 -1611
  169. package/src/gc/gcEarlyAdoption.md +0 -145
@@ -68,6 +68,9 @@ function prepareLocalContainerRuntimeIdAllocationMessageForTransit(message) {
68
68
  delete message.contents.stashedState;
69
69
  }
70
70
  }
71
+ /**
72
+ * @public
73
+ */
71
74
  exports.DefaultSummaryConfiguration = {
72
75
  state: "enabled",
73
76
  minIdleTime: 0,
@@ -84,6 +87,7 @@ exports.DefaultSummaryConfiguration = {
84
87
  };
85
88
  /**
86
89
  * Accepted header keys for requests coming to the runtime.
90
+ * @public
87
91
  */
88
92
  var RuntimeHeaders;
89
93
  (function (RuntimeHeaders) {
@@ -92,13 +96,24 @@ var RuntimeHeaders;
92
96
  /** True if the request is coming from an IFluidHandle. */
93
97
  RuntimeHeaders["viaHandle"] = "viaHandle";
94
98
  })(RuntimeHeaders || (exports.RuntimeHeaders = RuntimeHeaders = {}));
95
- /** True if a tombstoned object should be returned without erroring */
99
+ /** True if a tombstoned object should be returned without erroring
100
+ * @public
101
+ */
96
102
  exports.AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
97
- /** [IRRELEVANT IF throwOnInactiveLoad OPTION NOT SET] True if an inactive object should be returned without erroring */
103
+ /**
104
+ * [IRRELEVANT IF throwOnInactiveLoad OPTION NOT SET] True if an inactive object should be returned without erroring
105
+ * @public
106
+ */
98
107
  exports.AllowInactiveRequestHeaderKey = "allowInactive"; // Belongs in the enum above, but avoiding the breaking change
99
- /** Tombstone error responses will have this header set to true */
108
+ /**
109
+ * Tombstone error responses will have this header set to true
110
+ * @public
111
+ */
100
112
  exports.TombstoneResponseHeaderKey = "isTombstoned";
101
- /** Inactive error responses will have this header set to true */
113
+ /**
114
+ * Inactive error responses will have this header set to true
115
+ * @public
116
+ */
102
117
  exports.InactiveResponseHeaderKey = "isInactive";
103
118
  /** Default values for Runtime Headers */
104
119
  exports.defaultRuntimeHeaderData = {
@@ -109,6 +124,7 @@ exports.defaultRuntimeHeaderData = {
109
124
  };
110
125
  /**
111
126
  * Available compression algorithms for op compression.
127
+ * @public
112
128
  */
113
129
  var CompressionAlgorithms;
114
130
  (function (CompressionAlgorithms) {
@@ -138,7 +154,8 @@ exports.defaultPendingOpsRetryDelayMs = 1000;
138
154
  */
139
155
  const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
140
156
  /**
141
- * @deprecated - use ContainerRuntimeMessageType instead
157
+ * @deprecated use ContainerRuntimeMessageType instead
158
+ * @public
142
159
  */
143
160
  var RuntimeMessage;
144
161
  (function (RuntimeMessage) {
@@ -151,7 +168,8 @@ var RuntimeMessage;
151
168
  RuntimeMessage["Operation"] = "op";
152
169
  })(RuntimeMessage || (exports.RuntimeMessage = RuntimeMessage = {}));
153
170
  /**
154
- * @deprecated - please use version in driver-utils
171
+ * @deprecated please use version in driver-utils
172
+ * @public
155
173
  */
156
174
  function isRuntimeMessage(message) {
157
175
  return Object.values(RuntimeMessage).includes(message.type);
@@ -161,6 +179,7 @@ exports.isRuntimeMessage = isRuntimeMessage;
161
179
  * Legacy ID for the built-in AgentScheduler. To minimize disruption while removing it, retaining this as a
162
180
  * special-case for document dirty state. Ultimately we should have no special-cases from the
163
181
  * ContainerRuntime's perspective.
182
+ * @public
164
183
  */
165
184
  exports.agentSchedulerId = "_scheduler";
166
185
  // safely check navigator and get the hardware spec value
@@ -230,6 +249,7 @@ async function createSummarizer(loader, url) {
230
249
  }
231
250
  /**
232
251
  * This function is not supported publicly and exists for e2e testing
252
+ * @internal
233
253
  */
234
254
  async function TEST_requestSummarizer(loader, url) {
235
255
  return createSummarizer(loader, url);
@@ -238,16 +258,17 @@ exports.TEST_requestSummarizer = TEST_requestSummarizer;
238
258
  /**
239
259
  * Represents the runtime of the container. Contains helper functions/state of the container.
240
260
  * It will define the store level mappings.
261
+ * @public
241
262
  */
242
263
  class ContainerRuntime extends client_utils_1.TypedEventEmitter {
243
264
  /**
244
- * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
265
+ * @deprecated Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
245
266
  */
246
267
  get IFluidRouter() {
247
268
  return this;
248
269
  }
249
270
  /**
250
- * @deprecated - use loadRuntime instead.
271
+ * @deprecated use loadRuntime instead.
251
272
  * Load the stores from a snapshot and returns the runtime.
252
273
  * @param context - Context of the container.
253
274
  * @param registryEntries - Mapping to the stores.
@@ -837,7 +858,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
837
858
  /**
838
859
  * Notifies this object about the request made to the container.
839
860
  * @param request - Request made to the handler.
840
- * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
861
+ * @deprecated Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
841
862
  */
842
863
  async request(request) {
843
864
  try {
@@ -1362,7 +1383,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1362
1383
  * Returns the runtime of the data store.
1363
1384
  * @param id - Id supplied during creating the data store.
1364
1385
  * @param wait - True if you want to wait for it.
1365
- * @deprecated - Use getAliasedDataStoreEntryPoint instead to get an aliased data store's entry point.
1386
+ * @deprecated Use getAliasedDataStoreEntryPoint instead to get an aliased data store's entry point.
1366
1387
  */
1367
1388
  // eslint-disable-next-line import/no-deprecated
1368
1389
  async getRootDataStore(id, wait = true) {
@@ -1531,15 +1552,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1531
1552
  * Submits the signal to be sent to other clients.
1532
1553
  * @param type - Type of the signal.
1533
1554
  * @param content - Content of the signal.
1555
+ * @param targetClientId - When specified, the signal is only sent to the provided client id.
1534
1556
  */
1535
- submitSignal(type, content) {
1557
+ submitSignal(type, content, targetClientId) {
1536
1558
  this.verifyNotClosed();
1537
1559
  const envelope = this.createNewSignalEnvelope(undefined /* address */, type, content);
1538
- return this.submitSignalFn(envelope);
1560
+ return this.submitSignalFn(envelope, targetClientId);
1539
1561
  }
1540
- submitDataStoreSignal(address, type, content) {
1562
+ /**
1563
+ * Submits the signal to be sent to other clients.
1564
+ * @param type - Type of the signal.
1565
+ * @param content - Content of the signal.
1566
+ * @param targetClientId - When specified, the signal is only sent to the provided client id.
1567
+ */
1568
+ submitDataStoreSignal(address, type, content, targetClientId) {
1541
1569
  const envelope = this.createNewSignalEnvelope(address, type, content);
1542
- return this.submitSignalFn(envelope);
1570
+ return this.submitSignalFn(envelope, targetClientId);
1543
1571
  }
1544
1572
  setAttachState(attachState) {
1545
1573
  if (attachState === container_definitions_1.AttachState.Attaching) {
@@ -1662,7 +1690,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
1662
1690
  this.dataStores.updateUnusedRoutes(dataStoreRoutes);
1663
1691
  }
1664
1692
  /**
1665
- * @deprecated - Replaced by deleteSweepReadyNodes.
1693
+ * @deprecated Replaced by deleteSweepReadyNodes.
1666
1694
  */
1667
1695
  deleteUnusedNodes(unusedRoutes) {
1668
1696
  throw new Error("deleteUnusedRoutes should not be called");
@@ -2398,11 +2426,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2398
2426
  * and then close as the current main client is likely to be re-elected as the parent summarizer again.
2399
2427
  */
2400
2428
  if (!result.isSummaryTracked && result.isSummaryNewer) {
2401
- const fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
2429
+ const fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
2402
2430
  eventName: "RefreshLatestSummaryAckFetch",
2403
2431
  ackHandle,
2404
2432
  targetSequenceNumber: summaryRefSeq,
2405
- }, readAndParseBlob, null);
2433
+ }, readAndParseBlob);
2406
2434
  /**
2407
2435
  * If the fetched snapshot is older than the one for which the ack was received, close the container.
2408
2436
  * This should never happen because an ack should be sent after the latest summary is updated in the server.
@@ -2438,9 +2466,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2438
2466
  const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
2439
2467
  // This is a performance optimization as the same parent is likely to be elected again, and would use its
2440
2468
  // cache to fetch the snapshot instead of the network.
2441
- await this.fetchSnapshotFromStorage(summaryLogger, {
2469
+ await this.fetchLatestSnapshotFromStorage(summaryLogger, {
2442
2470
  eventName: "RefreshLatestSummaryFromServerFetch",
2443
- }, readAndParseBlob, null);
2471
+ }, readAndParseBlob);
2444
2472
  await this.closeStaleSummarizer("RefreshLatestSummaryFromServerFetch");
2445
2473
  return {
2446
2474
  stage: "base",
@@ -2450,27 +2478,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2450
2478
  };
2451
2479
  }
2452
2480
  async closeStaleSummarizer(codePath) {
2453
- this.mc.logger.sendTelemetryEvent({
2454
- eventName: "ClosingSummarizerOnSummaryStale",
2455
- codePath,
2456
- message: "Stopping fetch from storage",
2457
- closeSummarizerDelayMs: this.closeSummarizerDelayMs,
2458
- }, new telemetry_utils_1.GenericError("Restarting summarizer instead of refreshing"));
2459
2481
  // Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
2460
2482
  await (0, core_utils_1.delay)(this.closeSummarizerDelayMs);
2461
2483
  this._summarizer?.stop("latestSummaryStateStale");
2462
2484
  this.disposeFn();
2463
2485
  }
2464
2486
  /**
2465
- * Downloads snapshot from storage with the given versionId or latest if versionId is null.
2487
+ * Downloads the latest snapshot from storage.
2466
2488
  * By default, it also closes the container after downloading the snapshot. However, this may be
2467
2489
  * overridden via options.
2468
2490
  */
2469
- async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
2491
+ async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
2470
2492
  return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
2471
2493
  const stats = {};
2472
2494
  const trace = client_utils_1.Trace.start();
2473
- const versions = await this.storage.getVersions(versionId, 1, "prefetchLatestSummaryBeforeClose", versionId === null ? driver_definitions_1.FetchSource.noCache : undefined);
2495
+ const versions = await this.storage.getVersions(null, 1, "prefetchLatestSummaryBeforeClose", driver_definitions_1.FetchSource.noCache);
2474
2496
  (0, core_utils_1.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
2475
2497
  stats.getVersionDuration = trace.trace().duration;
2476
2498
  const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
@@ -2495,6 +2517,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2495
2517
  }, async (event) => {
2496
2518
  this.verifyNotClosed();
2497
2519
  const waitBlobsToAttach = props?.notifyImminentClosure;
2520
+ const stopBlobAttachingSignal = props?.stopBlobAttachingSignal;
2498
2521
  if (this._orderSequentiallyCalls !== 0) {
2499
2522
  throw new telemetry_utils_1.UsageError("can't get state during orderSequentially");
2500
2523
  }
@@ -2503,7 +2526,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
2503
2526
  // to close current batch.
2504
2527
  this.flush();
2505
2528
  const pendingAttachmentBlobs = waitBlobsToAttach
2506
- ? await this.blobManager.attachAndGetPendingBlobs()
2529
+ ? await this.blobManager.attachAndGetPendingBlobs(stopBlobAttachingSignal)
2507
2530
  : undefined;
2508
2531
  const pending = this.pendingStateManager.getLocalState();
2509
2532
  if (!pendingAttachmentBlobs && !this.hasPendingMessages()) {