@fluidframework/container-loader 2.0.2 → 2.1.0-276326

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 (227) hide show
  1. package/.eslintrc.cjs +2 -5
  2. package/api-extractor/api-extractor.legacy.json +4 -0
  3. package/api-report/container-loader.beta.api.md +0 -27
  4. package/api-report/{container-loader.alpha.api.md → container-loader.legacy.alpha.api.md} +0 -27
  5. package/api-report/container-loader.public.api.md +0 -27
  6. package/dist/attachment.d.ts +2 -1
  7. package/dist/attachment.d.ts.map +1 -1
  8. package/dist/attachment.js.map +1 -1
  9. package/dist/audience.d.ts.map +1 -1
  10. package/dist/audience.js +4 -4
  11. package/dist/audience.js.map +1 -1
  12. package/dist/catchUpMonitor.d.ts +15 -4
  13. package/dist/catchUpMonitor.d.ts.map +1 -1
  14. package/dist/catchUpMonitor.js +12 -3
  15. package/dist/catchUpMonitor.js.map +1 -1
  16. package/dist/connectionManager.d.ts +24 -8
  17. package/dist/connectionManager.d.ts.map +1 -1
  18. package/dist/connectionManager.js +36 -23
  19. package/dist/connectionManager.js.map +1 -1
  20. package/dist/connectionStateHandler.d.ts +30 -20
  21. package/dist/connectionStateHandler.d.ts.map +1 -1
  22. package/dist/connectionStateHandler.js +15 -11
  23. package/dist/connectionStateHandler.js.map +1 -1
  24. package/dist/container.d.ts +7 -2
  25. package/dist/container.d.ts.map +1 -1
  26. package/dist/container.js +45 -28
  27. package/dist/container.js.map +1 -1
  28. package/dist/containerContext.d.ts +8 -4
  29. package/dist/containerContext.d.ts.map +1 -1
  30. package/dist/containerContext.js +3 -1
  31. package/dist/containerContext.js.map +1 -1
  32. package/dist/containerStorageAdapter.d.ts +1 -1
  33. package/dist/containerStorageAdapter.d.ts.map +1 -1
  34. package/dist/containerStorageAdapter.js +12 -6
  35. package/dist/containerStorageAdapter.js.map +1 -1
  36. package/dist/contracts.d.ts +17 -8
  37. package/dist/contracts.d.ts.map +1 -1
  38. package/dist/contracts.js +4 -2
  39. package/dist/contracts.js.map +1 -1
  40. package/dist/debugLogger.js +3 -3
  41. package/dist/debugLogger.js.map +1 -1
  42. package/dist/deltaManager.d.ts +13 -9
  43. package/dist/deltaManager.d.ts.map +1 -1
  44. package/dist/deltaManager.js +32 -23
  45. package/dist/deltaManager.js.map +1 -1
  46. package/dist/deltaQueue.d.ts +1 -4
  47. package/dist/deltaQueue.d.ts.map +1 -1
  48. package/dist/deltaQueue.js +2 -2
  49. package/dist/deltaQueue.js.map +1 -1
  50. package/dist/disposal.d.ts +1 -1
  51. package/dist/disposal.d.ts.map +1 -1
  52. package/dist/disposal.js.map +1 -1
  53. package/dist/error.d.ts.map +1 -1
  54. package/dist/error.js.map +1 -1
  55. package/dist/legacy.d.ts +1 -1
  56. package/dist/loadPaused.d.ts +2 -2
  57. package/dist/loadPaused.d.ts.map +1 -1
  58. package/dist/loadPaused.js +7 -3
  59. package/dist/loadPaused.js.map +1 -1
  60. package/dist/loader.d.ts +10 -1
  61. package/dist/loader.d.ts.map +1 -1
  62. package/dist/loader.js +11 -1
  63. package/dist/loader.js.map +1 -1
  64. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -1
  65. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  66. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +3 -1
  67. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  68. package/dist/memoryBlobStorage.d.ts.map +1 -1
  69. package/dist/memoryBlobStorage.js +4 -2
  70. package/dist/memoryBlobStorage.js.map +1 -1
  71. package/dist/noopHeuristic.js +1 -1
  72. package/dist/noopHeuristic.js.map +1 -1
  73. package/dist/packageVersion.d.ts +1 -1
  74. package/dist/packageVersion.d.ts.map +1 -1
  75. package/dist/packageVersion.js +1 -1
  76. package/dist/packageVersion.js.map +1 -1
  77. package/dist/protocol/protocol.d.ts +4 -3
  78. package/dist/protocol/protocol.d.ts.map +1 -1
  79. package/dist/protocol/protocol.js +6 -5
  80. package/dist/protocol/protocol.js.map +1 -1
  81. package/dist/protocol/quorum.d.ts +11 -8
  82. package/dist/protocol/quorum.d.ts.map +1 -1
  83. package/dist/protocol/quorum.js +8 -8
  84. package/dist/protocol/quorum.js.map +1 -1
  85. package/dist/protocol.d.ts +2 -0
  86. package/dist/protocol.d.ts.map +1 -1
  87. package/dist/protocol.js +7 -2
  88. package/dist/protocol.js.map +1 -1
  89. package/dist/protocolTreeDocumentStorageService.d.ts +2 -2
  90. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  91. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  92. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  93. package/dist/retriableDocumentStorageService.js +4 -1
  94. package/dist/retriableDocumentStorageService.js.map +1 -1
  95. package/dist/serializedStateManager.d.ts +29 -12
  96. package/dist/serializedStateManager.d.ts.map +1 -1
  97. package/dist/serializedStateManager.js +55 -24
  98. package/dist/serializedStateManager.js.map +1 -1
  99. package/dist/utils.d.ts +4 -2
  100. package/dist/utils.d.ts.map +1 -1
  101. package/dist/utils.js +15 -6
  102. package/dist/utils.js.map +1 -1
  103. package/lib/attachment.d.ts +2 -1
  104. package/lib/attachment.d.ts.map +1 -1
  105. package/lib/attachment.js.map +1 -1
  106. package/lib/audience.d.ts.map +1 -1
  107. package/lib/audience.js +4 -4
  108. package/lib/audience.js.map +1 -1
  109. package/lib/catchUpMonitor.d.ts +15 -4
  110. package/lib/catchUpMonitor.d.ts.map +1 -1
  111. package/lib/catchUpMonitor.js +12 -3
  112. package/lib/catchUpMonitor.js.map +1 -1
  113. package/lib/connectionManager.d.ts +24 -8
  114. package/lib/connectionManager.d.ts.map +1 -1
  115. package/lib/connectionManager.js +36 -23
  116. package/lib/connectionManager.js.map +1 -1
  117. package/lib/connectionStateHandler.d.ts +30 -20
  118. package/lib/connectionStateHandler.d.ts.map +1 -1
  119. package/lib/connectionStateHandler.js +14 -12
  120. package/lib/connectionStateHandler.js.map +1 -1
  121. package/lib/container.d.ts +7 -2
  122. package/lib/container.d.ts.map +1 -1
  123. package/lib/container.js +45 -28
  124. package/lib/container.js.map +1 -1
  125. package/lib/containerContext.d.ts +8 -4
  126. package/lib/containerContext.d.ts.map +1 -1
  127. package/lib/containerContext.js +3 -1
  128. package/lib/containerContext.js.map +1 -1
  129. package/lib/containerStorageAdapter.d.ts +1 -1
  130. package/lib/containerStorageAdapter.d.ts.map +1 -1
  131. package/lib/containerStorageAdapter.js +12 -6
  132. package/lib/containerStorageAdapter.js.map +1 -1
  133. package/lib/contracts.d.ts +17 -8
  134. package/lib/contracts.d.ts.map +1 -1
  135. package/lib/contracts.js +4 -2
  136. package/lib/contracts.js.map +1 -1
  137. package/lib/debugLogger.js +3 -3
  138. package/lib/debugLogger.js.map +1 -1
  139. package/lib/deltaManager.d.ts +13 -9
  140. package/lib/deltaManager.d.ts.map +1 -1
  141. package/lib/deltaManager.js +32 -23
  142. package/lib/deltaManager.js.map +1 -1
  143. package/lib/deltaQueue.d.ts +1 -4
  144. package/lib/deltaQueue.d.ts.map +1 -1
  145. package/lib/deltaQueue.js +2 -2
  146. package/lib/deltaQueue.js.map +1 -1
  147. package/lib/disposal.d.ts +1 -1
  148. package/lib/disposal.d.ts.map +1 -1
  149. package/lib/disposal.js.map +1 -1
  150. package/lib/error.d.ts.map +1 -1
  151. package/lib/error.js.map +1 -1
  152. package/lib/legacy.d.ts +1 -1
  153. package/lib/loadPaused.d.ts +2 -2
  154. package/lib/loadPaused.d.ts.map +1 -1
  155. package/lib/loadPaused.js +8 -4
  156. package/lib/loadPaused.js.map +1 -1
  157. package/lib/loader.d.ts +10 -1
  158. package/lib/loader.d.ts.map +1 -1
  159. package/lib/loader.js +11 -1
  160. package/lib/loader.js.map +1 -1
  161. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -1
  162. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  163. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +3 -1
  164. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  165. package/lib/memoryBlobStorage.d.ts.map +1 -1
  166. package/lib/memoryBlobStorage.js +4 -2
  167. package/lib/memoryBlobStorage.js.map +1 -1
  168. package/lib/noopHeuristic.js +1 -1
  169. package/lib/noopHeuristic.js.map +1 -1
  170. package/lib/packageVersion.d.ts +1 -1
  171. package/lib/packageVersion.d.ts.map +1 -1
  172. package/lib/packageVersion.js +1 -1
  173. package/lib/packageVersion.js.map +1 -1
  174. package/lib/protocol/protocol.d.ts +4 -3
  175. package/lib/protocol/protocol.d.ts.map +1 -1
  176. package/lib/protocol/protocol.js +6 -5
  177. package/lib/protocol/protocol.js.map +1 -1
  178. package/lib/protocol/quorum.d.ts +11 -8
  179. package/lib/protocol/quorum.d.ts.map +1 -1
  180. package/lib/protocol/quorum.js +8 -8
  181. package/lib/protocol/quorum.js.map +1 -1
  182. package/lib/protocol.d.ts +2 -0
  183. package/lib/protocol.d.ts.map +1 -1
  184. package/lib/protocol.js +7 -2
  185. package/lib/protocol.js.map +1 -1
  186. package/lib/protocolTreeDocumentStorageService.d.ts +2 -2
  187. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  188. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  189. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  190. package/lib/retriableDocumentStorageService.js +4 -1
  191. package/lib/retriableDocumentStorageService.js.map +1 -1
  192. package/lib/serializedStateManager.d.ts +29 -12
  193. package/lib/serializedStateManager.d.ts.map +1 -1
  194. package/lib/serializedStateManager.js +56 -25
  195. package/lib/serializedStateManager.js.map +1 -1
  196. package/lib/utils.d.ts +4 -2
  197. package/lib/utils.d.ts.map +1 -1
  198. package/lib/utils.js +16 -7
  199. package/lib/utils.js.map +1 -1
  200. package/package.json +21 -17
  201. package/src/attachment.ts +2 -1
  202. package/src/audience.ts +4 -4
  203. package/src/catchUpMonitor.ts +23 -8
  204. package/src/connectionManager.ts +85 -60
  205. package/src/connectionStateHandler.ts +85 -63
  206. package/src/container.ts +118 -84
  207. package/src/containerContext.ts +5 -3
  208. package/src/containerStorageAdapter.ts +20 -13
  209. package/src/contracts.ts +21 -9
  210. package/src/debugLogger.ts +4 -4
  211. package/src/deltaManager.ts +75 -56
  212. package/src/deltaQueue.ts +16 -10
  213. package/src/disposal.ts +3 -3
  214. package/src/error.ts +2 -1
  215. package/src/loadPaused.ts +16 -8
  216. package/src/loader.ts +20 -2
  217. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +7 -3
  218. package/src/memoryBlobStorage.ts +5 -3
  219. package/src/noopHeuristic.ts +1 -1
  220. package/src/packageVersion.ts +1 -1
  221. package/src/protocol/protocol.ts +12 -11
  222. package/src/protocol/quorum.ts +49 -40
  223. package/src/protocol.ts +12 -4
  224. package/src/protocolTreeDocumentStorageService.ts +3 -2
  225. package/src/retriableDocumentStorageService.ts +6 -3
  226. package/src/serializedStateManager.ts +95 -39
  227. package/src/utils.ts +26 -10
@@ -74,15 +74,17 @@ export class ContainerContext implements IContainerContext {
74
74
  public readonly loader: ILoader,
75
75
  public readonly submitFn: (
76
76
  type: MessageType,
77
- contents: any,
77
+ contents: unknown,
78
78
  batch: boolean,
79
- appData: any,
79
+ appData: unknown,
80
80
  ) => number,
81
81
  public readonly submitSummaryFn: (
82
82
  summaryOp: ISummaryContent,
83
83
  referenceSequenceNumber?: number,
84
84
  ) => number,
85
- /** @returns clientSequenceNumber of last message in a batch */
85
+ /**
86
+ * @returns clientSequenceNumber of last message in a batch
87
+ */
86
88
  public readonly submitBatchFn: (
87
89
  batch: IBatchMessage[],
88
90
  referenceSequenceNumber?: number,
@@ -57,7 +57,7 @@ export class ContainerStorageAdapter
57
57
  /**
58
58
  * Whether the adapter will enforce sending combined summary trees.
59
59
  */
60
- public get summarizeProtocolTree() {
60
+ public get summarizeProtocolTree(): boolean {
61
61
  return this._summarizeProtocolTree === true;
62
62
  }
63
63
 
@@ -77,7 +77,7 @@ export class ContainerStorageAdapter
77
77
  * @param loadingGroupIdSnapshotsFromPendingState - in offline mode, any loading group snapshots we've downloaded from the service that were stored in the pending state
78
78
  * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to
79
79
  * upload, and fix it up with a protocol tree if needed
80
- * @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
80
+ * @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
81
81
  */
82
82
  public constructor(
83
83
  // eslint-disable-next-line import/no-deprecated
@@ -140,13 +140,13 @@ export class ContainerStorageAdapter
140
140
  );
141
141
  }
142
142
 
143
- public loadSnapshotFromSnapshotBlobs(snapshotBlobs: ISerializableBlobContents) {
143
+ public loadSnapshotFromSnapshotBlobs(snapshotBlobs: ISerializableBlobContents): void {
144
144
  for (const [id, value] of Object.entries(snapshotBlobs)) {
145
145
  this.blobContents[id] = value;
146
146
  }
147
147
  }
148
148
 
149
- public clearPendingState() {
149
+ public clearPendingState(): void {
150
150
  this.loadingGroupIdSnapshotsFromPendingState = undefined;
151
151
  }
152
152
 
@@ -155,13 +155,17 @@ export class ContainerStorageAdapter
155
155
  // and storage is always present in >=0.41.
156
156
  try {
157
157
  return this._storageService.policies;
158
- } catch (e) {}
158
+ } catch {
159
+ // No-op
160
+ }
159
161
  return undefined;
160
162
  }
161
163
 
162
164
  public async getSnapshotTree(
163
165
  version?: IVersion,
164
166
  scenarioName?: string,
167
+ // API called below uses null
168
+ // eslint-disable-next-line @rushstack/no-new-null
165
169
  ): Promise<ISnapshotTree | null> {
166
170
  return this._storageService.getSnapshotTree(version, scenarioName);
167
171
  }
@@ -220,6 +224,8 @@ export class ContainerStorageAdapter
220
224
  }
221
225
 
222
226
  public async getVersions(
227
+ // API used below uses null
228
+ // eslint-disable-next-line @rushstack/no-new-null
223
229
  versionId: string | null,
224
230
  count: number,
225
231
  scenarioName?: string,
@@ -276,6 +282,7 @@ class BlobOnlyStorage implements IDocumentStorageService {
276
282
  }
277
283
 
278
284
  /* eslint-disable @typescript-eslint/unbound-method */
285
+ // eslint-disable-next-line @rushstack/no-new-null
279
286
  public getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;
280
287
  public getSnapshot: () => Promise<ISnapshot> = this.notCalled;
281
288
  public getVersions: () => Promise<IVersion[]> = this.notCalled;
@@ -289,9 +296,9 @@ class BlobOnlyStorage implements IDocumentStorageService {
289
296
  try {
290
297
  // some browsers may not populate stack unless exception is thrown
291
298
  throw new Error("BlobOnlyStorage not implemented method used");
292
- } catch (err) {
293
- this.logger.sendTelemetryEvent({ eventName: "BlobOnlyStorageWrongCall" }, err);
294
- throw err;
299
+ } catch (error) {
300
+ this.logger.sendTelemetryEvent({ eventName: "BlobOnlyStorageWrongCall" }, error);
301
+ throw error;
295
302
  }
296
303
  }
297
304
  }
@@ -321,8 +328,8 @@ async function getBlobContentsFromTreeCore(
321
328
  blobs: ISerializableBlobContents,
322
329
  storage: Pick<IDocumentStorageService, "readBlob">,
323
330
  root = true,
324
- ) {
325
- const treePs: Promise<any>[] = [];
331
+ ): Promise<unknown[]> {
332
+ const treePs: Promise<unknown>[] = [];
326
333
  for (const [key, subTree] of Object.entries(tree.trees)) {
327
334
  if (root && key === blobsTreeName) {
328
335
  treePs.push(getBlobManagerTreeFromTree(subTree, blobs, storage));
@@ -343,7 +350,7 @@ async function getBlobManagerTreeFromTree(
343
350
  tree: ISnapshotTree,
344
351
  blobs: ISerializableBlobContents,
345
352
  storage: Pick<IDocumentStorageService, "readBlob">,
346
- ) {
353
+ ): Promise<void> {
347
354
  const id = tree.blobs[redirectTableBlobName];
348
355
  const blob = await storage.readBlob(id);
349
356
  // ArrayBufferLike will not survive JSON.stringify()
@@ -365,7 +372,7 @@ function getBlobContentsFromTreeWithBlobContentsCore(
365
372
  tree: ISnapshotTreeWithBlobContents,
366
373
  blobs: ISerializableBlobContents,
367
374
  root = true,
368
- ) {
375
+ ): void {
369
376
  for (const [key, subTree] of Object.entries(tree.trees)) {
370
377
  if (root && key === blobsTreeName) {
371
378
  getBlobManagerTreeFromTreeWithBlobContents(subTree, blobs);
@@ -385,7 +392,7 @@ function getBlobContentsFromTreeWithBlobContentsCore(
385
392
  function getBlobManagerTreeFromTreeWithBlobContents(
386
393
  tree: ISnapshotTreeWithBlobContents,
387
394
  blobs: ISerializableBlobContents,
388
- ) {
395
+ ): void {
389
396
  const id = tree.blobs[redirectTableBlobName];
390
397
  const blob = tree.blobsContents?.[id];
391
398
  assert(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);
package/src/contracts.ts CHANGED
@@ -52,19 +52,29 @@ export interface IConnectionManager {
52
52
 
53
53
  readonly clientId: string | undefined;
54
54
 
55
- /** The queue of outbound delta messages */
55
+ /**
56
+ * The queue of outbound delta messages
57
+ */
56
58
  readonly outbound: IDeltaQueue<IDocumentMessage[]>;
57
59
 
58
- /** Details of client */
60
+ /**
61
+ * Details of client
62
+ */
59
63
  readonly clientDetails: IClientDetails;
60
64
 
61
- /** Protocol version being used to communicate with the service */
65
+ /**
66
+ * Protocol version being used to communicate with the service
67
+ */
62
68
  readonly version: string;
63
69
 
64
- /** Max message size allowed to the delta manager */
70
+ /**
71
+ * Max message size allowed to the delta manager
72
+ */
65
73
  readonly maxMessageSize: number;
66
74
 
67
- /** Service configuration provided by the service. */
75
+ /**
76
+ * Service configuration provided by the service.
77
+ */
68
78
  readonly serviceConfiguration: IClientConfiguration | undefined;
69
79
 
70
80
  readonly readOnlyInfo: ReadOnlyInfo;
@@ -149,7 +159,7 @@ export interface IConnectionManagerFactoryArgs {
149
159
  * Called by connection manager whenever critical error happens and container should be closed.
150
160
  * Expects dispose() call in response to this call.
151
161
  */
152
- readonly closeHandler: (error?: any) => void;
162
+ readonly closeHandler: (error?: IErrorBase) => void;
153
163
 
154
164
  /**
155
165
  * Called whenever connection to relay service is lost.
@@ -197,14 +207,15 @@ export interface IConnectionManagerFactoryArgs {
197
207
  }
198
208
 
199
209
  /**
200
- *
210
+ * Gets the name of the Fluid package.
201
211
  * @param codeDetails- - Data structure used to describe the code to load on the Fluid document
202
- * @returns The name of the Fluid package
203
212
  */
204
213
  export const getPackageName = (
205
214
  codeDetails: IFluidCodeDetails | undefined,
206
215
  ): IContainerPackageInfo => {
207
- let containerPackageName;
216
+ // TODO: use a real type
217
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
+ let containerPackageName: any;
208
219
  if (codeDetails && "name" in codeDetails) {
209
220
  containerPackageName = codeDetails;
210
221
  } else if (isFluidPackage(codeDetails?.package)) {
@@ -212,5 +223,6 @@ export const getPackageName = (
212
223
  } else {
213
224
  containerPackageName = codeDetails?.package;
214
225
  }
226
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
215
227
  return { name: containerPackageName };
216
228
  };
@@ -45,7 +45,7 @@ export class DebugLogger implements ITelemetryBaseLogger {
45
45
  // Create one for errors that is always enabled
46
46
  // It can be silenced by replacing console.error if the debug namespace is not enabled.
47
47
  const debugErr = registerDebug(namespace);
48
- debugErr.log = function (...args) {
48
+ debugErr.log = function (...args: unknown[]): void {
49
49
  if (debug.enabled === true) {
50
50
  // if the namespace is enabled, just use the default logger
51
51
  registerDebug.log(...args);
@@ -81,9 +81,9 @@ export class DebugLogger implements ITelemetryBaseLogger {
81
81
 
82
82
  // Use debug's coloring schema for base of the event
83
83
  const index = event.eventName.lastIndexOf(eventNamespaceSeparator);
84
- const name = event.eventName.substring(index + 1);
84
+ const name = event.eventName.slice(Math.max(0, index + 1));
85
85
  if (index > 0) {
86
- logger = logger.extend(event.eventName.substring(0, index));
86
+ logger = logger.extend(event.eventName.slice(0, index));
87
87
  }
88
88
  newEvent.eventName = undefined;
89
89
 
@@ -100,7 +100,7 @@ export class DebugLogger implements ITelemetryBaseLogger {
100
100
  let payload: string;
101
101
  try {
102
102
  payload = JSON.stringify(newEvent);
103
- } catch (error) {
103
+ } catch {
104
104
  newEvent.error = undefined;
105
105
  payload = JSON.stringify(newEvent);
106
106
  }
@@ -8,6 +8,8 @@ import {
8
8
  IDeltaManager,
9
9
  IDeltaManagerEvents,
10
10
  IDeltaQueue,
11
+ type IDeltaSender,
12
+ type ReadOnlyInfo,
11
13
  } from "@fluidframework/container-definitions/internal";
12
14
  import {
13
15
  IEventProvider,
@@ -25,6 +27,8 @@ import {
25
27
  MessageType,
26
28
  ISequencedDocumentMessage,
27
29
  ISignalMessage,
30
+ type IClientDetails,
31
+ type IClientConfiguration,
28
32
  } from "@fluidframework/driver-definitions/internal";
29
33
  import {
30
34
  MessageType2,
@@ -113,10 +117,12 @@ function isClientMessage(message: ISequencedDocumentMessage | IDocumentMessage):
113
117
  case MessageType.Reject:
114
118
  case MessageType.NoOp:
115
119
  case MessageType2.Accept:
116
- case MessageType.Summarize:
120
+ case MessageType.Summarize: {
117
121
  return true;
118
- default:
122
+ }
123
+ default: {
119
124
  return false;
125
+ }
120
126
  }
121
127
  }
122
128
 
@@ -159,11 +165,11 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
159
165
  return this._active();
160
166
  }
161
167
 
162
- public get disposed() {
168
+ public get disposed(): boolean {
163
169
  return this._closed;
164
170
  }
165
171
 
166
- public get IDeltaSender() {
172
+ public get IDeltaSender(): IDeltaSender {
167
173
  return this;
168
174
  }
169
175
 
@@ -188,9 +194,13 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
188
194
  private lastProcessedSequenceNumber: number = 0;
189
195
  private lastProcessedMessage: ISequencedDocumentMessage | undefined;
190
196
 
191
- /** count number of noops sent by the client which may not be acked */
197
+ /**
198
+ * Count the number of noops sent by the client which may not be acked
199
+ */
192
200
  private noOpCount: number = 0;
193
- /** Track clientSequenceNumber of the last op */
201
+ /**
202
+ * Track clientSequenceNumber of the last op
203
+ */
194
204
  private lastClientSequenceNumber: number = 0;
195
205
 
196
206
  /**
@@ -242,11 +252,11 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
242
252
  return this.lastProcessedSequenceNumber;
243
253
  }
244
254
 
245
- public get lastMessage() {
255
+ public get lastMessage(): ISequencedDocumentMessage | undefined {
246
256
  return this.lastProcessedMessage;
247
257
  }
248
258
 
249
- public get lastKnownSeqNumber() {
259
+ public get lastKnownSeqNumber(): number {
250
260
  return this.lastObservedSeqNumber;
251
261
  }
252
262
 
@@ -258,7 +268,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
258
268
  * Tells if current connection has checkpoint information.
259
269
  * I.e. we know how far behind the client was at the time of establishing connection
260
270
  */
261
- public get hasCheckpointSequenceNumber() {
271
+ public get hasCheckpointSequenceNumber(): boolean {
262
272
  // Valid to be called only if we have active connection.
263
273
  assert(this.connectionManager.connected, 0x0df /* "Missing active connection" */);
264
274
  return this._checkpointSequenceNumber !== undefined;
@@ -268,19 +278,19 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
268
278
  public get maxMessageSize(): number {
269
279
  return this.connectionManager.maxMessageSize;
270
280
  }
271
- public get version() {
281
+ public get version(): string {
272
282
  return this.connectionManager.version;
273
283
  }
274
- public get serviceConfiguration() {
284
+ public get serviceConfiguration(): IClientConfiguration | undefined {
275
285
  return this.connectionManager.serviceConfiguration;
276
286
  }
277
- public get outbound() {
287
+ public get outbound(): IDeltaQueue<IDocumentMessage[]> {
278
288
  return this.connectionManager.outbound;
279
289
  }
280
- public get readOnlyInfo() {
290
+ public get readOnlyInfo(): ReadOnlyInfo {
281
291
  return this.connectionManager.readOnlyInfo;
282
292
  }
283
- public get clientDetails() {
293
+ public get clientDetails(): IClientDetails {
284
294
  return this.connectionManager.clientDetails;
285
295
  }
286
296
 
@@ -288,10 +298,10 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
288
298
  type: MessageType,
289
299
  contents?: string,
290
300
  batch = false,
291
- metadata?: any,
301
+ metadata?: unknown,
292
302
  compression?: string,
293
303
  referenceSequenceNumber?: number,
294
- ) {
304
+ ): number {
295
305
  // Back-compat ADO:3455
296
306
  const backCompatRefSeqNum = referenceSequenceNumber ?? this.lastProcessedSequenceNumber;
297
307
  const messagePartial: Omit<IDocumentMessage, "clientSequenceNumber"> = {
@@ -330,11 +340,11 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
330
340
  return message.clientSequenceNumber;
331
341
  }
332
342
 
333
- public submitSignal(content: string, targetClientId?: string) {
343
+ public submitSignal(content: string, targetClientId?: string): void {
334
344
  return this.connectionManager.submitSignal(content, targetClientId);
335
345
  }
336
346
 
337
- public flush() {
347
+ public flush(): void {
338
348
  const batch = this.messageBuffer;
339
349
  if (batch.length === 0) {
340
350
  return;
@@ -381,7 +391,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
381
391
  * we stop processing ops that results in no processing join op and thus moving to connected state)
382
392
  * @param event - Event to log.
383
393
  */
384
- public logConnectionIssue(event: ITelemetryErrorEventExt) {
394
+ public logConnectionIssue(event: ITelemetryErrorEventExt): void {
385
395
  assert(this.connectionManager.connected, 0x238 /* "called only in connected state" */);
386
396
 
387
397
  const pendingSorted = this.pending.sort((a, b) => a.sequenceNumber - b.sequenceNumber);
@@ -436,7 +446,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
436
446
  },
437
447
  reconnectionDelayHandler: (delayMs: number, error: unknown) =>
438
448
  this.emitDelayInfo(this.deltaStreamDelayId, delayMs, error),
439
- closeHandler: (error: any) => this.close(error),
449
+ closeHandler: (error: ICriticalContainerError | undefined) => this.close(error),
440
450
  disconnectHandler: (reason: IConnectionStateChangeReason) =>
441
451
  this.disconnectHandler(reason),
442
452
  connectHandler: (connection: IConnectionDetailsInternal) =>
@@ -489,15 +499,15 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
489
499
  // - inbound & inboundSignal are resumed in attachOpHandler() when we have handler setup
490
500
  }
491
501
 
492
- private cancelEstablishingConnection(reason: IConnectionStateChangeReason) {
502
+ private cancelEstablishingConnection(reason: IConnectionStateChangeReason): void {
493
503
  this.emit("cancelEstablishingConnection", reason);
494
504
  }
495
505
 
496
- private establishingConnection(reason: IConnectionStateChangeReason) {
506
+ private establishingConnection(reason: IConnectionStateChangeReason): void {
497
507
  this.emit("establishingConnection", reason);
498
508
  }
499
509
 
500
- private connectHandler(connection: IConnectionDetailsInternal) {
510
+ private connectHandler(connection: IConnectionDetailsInternal): void {
501
511
  this.refreshDelayInfo(this.deltaStreamDelayId);
502
512
 
503
513
  const props = this.connectionManager.connectionVerboseProps;
@@ -526,9 +536,9 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
526
536
  this.emit(
527
537
  "connect",
528
538
  connection,
529
- checkpointSequenceNumber !== undefined
530
- ? this.lastObservedSeqNumber - this.lastSequenceNumber
531
- : undefined,
539
+ checkpointSequenceNumber === undefined
540
+ ? undefined
541
+ : this.lastObservedSeqNumber - this.lastSequenceNumber,
532
542
  );
533
543
 
534
544
  // If we got some initial ops, then we know the gap and call above fetched ops to fill it.
@@ -558,7 +568,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
558
568
  handler: IDeltaHandlerStrategy,
559
569
  prefetchType: "cached" | "all" | "none" = "none",
560
570
  lastProcessedSequenceNumber: number = snapshotSequenceNumber,
561
- ) {
571
+ ): Promise<void> {
562
572
  this.initSequenceNumber = snapshotSequenceNumber;
563
573
  this.lastProcessedSequenceNumber = lastProcessedSequenceNumber;
564
574
  this.minSequenceNumber = minSequenceNumber;
@@ -572,7 +582,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
572
582
  );
573
583
  this.handler = handler;
574
584
  // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
575
- assert(!!(this.handler as any), 0x0e3 /* "Newly set op handler is null/undefined!" */);
585
+ assert(!!this.handler, 0x0e3 /* "Newly set op handler is null/undefined!" */);
576
586
 
577
587
  // There should be no pending fetch!
578
588
  // This API is called right after attachOpHandler by Container.load().
@@ -612,7 +622,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
612
622
  );
613
623
  }
614
624
 
615
- public connect(args: IConnectionArgs) {
625
+ public connect(args: IConnectionArgs): void {
616
626
  const fetchOpsFromStorage = args.fetchOpsFromStorage ?? true;
617
627
  logIfFalse(
618
628
  this.handler !== undefined || !fetchOpsFromStorage,
@@ -643,7 +653,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
643
653
  fetchReason: string,
644
654
  callback: (messages: ISequencedDocumentMessage[]) => void,
645
655
  cacheOnly: boolean,
646
- ) {
656
+ ): Promise<void> {
647
657
  const docService = this.serviceProvider();
648
658
  if (docService === undefined) {
649
659
  throw new Error("Delta manager is not attached");
@@ -655,7 +665,14 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
655
665
 
656
666
  let cancelFetch: (op: ISequencedDocumentMessage) => boolean;
657
667
 
658
- if (to !== undefined) {
668
+ if (to === undefined) {
669
+ // Unbound requests are made to proactively fetch ops, but also get up to date in cases where socket
670
+ // is silent (and connection is "read", thus we might not have any data on how far client is behind).
671
+ // Once we have any op coming in from socket, we can cancel it as it's not needed any more.
672
+ // That said, if we have socket connection, make sure we got ops up to checkpointSequenceNumber!
673
+ cancelFetch = (op: ISequencedDocumentMessage): boolean =>
674
+ op.sequenceNumber >= this.lastObservedSeqNumber;
675
+ } else {
659
676
  const lastExpectedOp = to - 1; // make it inclusive!
660
677
 
661
678
  // It is possible that due to asynchrony (including await above), required ops were already
@@ -677,20 +694,14 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
677
694
  // detected gap, this gap can't be filled in later on through websocket).
678
695
  // And in practice that does look like the case. The place where this code gets hit is if we lost
679
696
  // connection and reconnected (likely to another box), and new socket's initial ops contains these ops.
680
- cancelFetch = (op: ISequencedDocumentMessage) => op.sequenceNumber >= lastExpectedOp;
681
- } else {
682
- // Unbound requests are made to proactively fetch ops, but also get up to date in cases where socket
683
- // is silent (and connection is "read", thus we might not have any data on how far client is behind).
684
- // Once we have any op coming in from socket, we can cancel it as it's not needed any more.
685
- // That said, if we have socket connection, make sure we got ops up to checkpointSequenceNumber!
686
- cancelFetch = (op: ISequencedDocumentMessage) =>
687
- op.sequenceNumber >= this.lastObservedSeqNumber;
697
+ cancelFetch = (op: ISequencedDocumentMessage): boolean =>
698
+ op.sequenceNumber >= lastExpectedOp;
688
699
  }
689
700
 
690
701
  const controller = new AbortController();
691
702
  let opsFromFetch = false;
692
703
 
693
- const opListener = (op: ISequencedDocumentMessage) => {
704
+ const opListener = (op: ISequencedDocumentMessage): void => {
694
705
  assert(op.sequenceNumber === this.lastQueuedSequenceNumber, 0x23a /* "seq#'s" */);
695
706
  // Ops that are coming from this request should not cancel itself.
696
707
  // This is useless for known ranges (to is defined) as it means request is over either way.
@@ -704,8 +715,9 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
704
715
  try {
705
716
  this._inbound.on("push", opListener);
706
717
  assert(this.closeAbortController.signal.onabort === null, 0x1e8 /* "reentrancy" */);
707
- this.closeAbortController.signal.onabort = () =>
708
- controller.abort(this.closeAbortController.signal.reason);
718
+ this.closeAbortController.signal.addEventListener("abort", () =>
719
+ controller.abort(this.closeAbortController.signal.reason),
720
+ );
709
721
 
710
722
  const stream = this.deltaStorage.fetchMessages(
711
723
  from, // inclusive
@@ -733,9 +745,11 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
733
745
  this.logger.sendTelemetryEvent({
734
746
  eventName: "DeltaManager_GetDeltasAborted",
735
747
  fetchReason,
748
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
736
749
  reason: controller.signal.reason,
737
750
  });
738
751
  }
752
+ // eslint-disable-next-line unicorn/no-null, unicorn/prefer-add-event-listener
739
753
  this.closeAbortController.signal.onabort = null;
740
754
  this._inbound.off("push", opListener);
741
755
  assert(!opsFromFetch, 0x289 /* "logic error" */);
@@ -789,7 +803,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
789
803
  this.removeAllListeners();
790
804
  }
791
805
 
792
- private clearQueues() {
806
+ private clearQueues(): void {
793
807
  this.closeAbortController.abort("DeltaManager is closed");
794
808
 
795
809
  this._inbound.clear();
@@ -804,14 +818,14 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
804
818
  this.pending = [];
805
819
  }
806
820
 
807
- public refreshDelayInfo(id: string) {
821
+ public refreshDelayInfo(id: string): void {
808
822
  this.throttlingIdSet.delete(id);
809
823
  if (this.throttlingIdSet.size === 0) {
810
824
  this.timeTillThrottling = 0;
811
825
  }
812
826
  }
813
827
 
814
- private disconnectHandler(reason: IConnectionStateChangeReason) {
828
+ private disconnectHandler(reason: IConnectionStateChangeReason): void {
815
829
  this.messageBuffer.length = 0;
816
830
  this.emit("disconnect", reason.text, reason.error);
817
831
  }
@@ -822,7 +836,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
822
836
  * @param delayMs - Duration of the delay
823
837
  * @param error - error object indicating the throttling
824
838
  */
825
- public emitDelayInfo(id: string, delayMs: number, error: unknown) {
839
+ public emitDelayInfo(id: string, delayMs: number, error: unknown): void {
826
840
  const timeNow = Date.now();
827
841
  this.throttlingIdSet.add(id);
828
842
  if (delayMs > 0 && timeNow + delayMs > this.timeTillThrottling) {
@@ -844,7 +858,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
844
858
  // reuse.
845
859
  // Also payload goes to telemetry, so no content or anything else that shouldn't be logged for privacy reasons
846
860
  // Note: It's possible for a duplicate op to be broadcasted and have everything the same except the timestamp.
847
- private comparableMessagePayload(m: ISequencedDocumentMessage) {
861
+ private comparableMessagePayload(m: ISequencedDocumentMessage): string {
848
862
  return `${m.clientId}-${m.type}-${m.minimumSequenceNumber}-${m.referenceSequenceNumber}-${m.timestamp}`;
849
863
  }
850
864
 
@@ -859,7 +873,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
859
873
  // and thus faster than attachOpHandler() is called
860
874
  // this.lastProcessedSequenceNumber is still zero, so we can't rely on this.fetchMissingDeltas()
861
875
  // to do the right thing.
862
- this.pending = this.pending.concat(messages);
876
+ this.pending = [...this.pending, ...messages];
863
877
  return;
864
878
  }
865
879
 
@@ -937,7 +951,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
937
951
  length: messages.length,
938
952
  fetchReason: this.fetchReason,
939
953
  duplicate: duplicate > 0 ? duplicate : undefined,
940
- initialGap: initialGap !== 0 ? initialGap : undefined,
954
+ initialGap: initialGap === 0 ? undefined : initialGap,
941
955
  gap: gap > 0 ? gap : undefined,
942
956
  firstMissing,
943
957
  dmInitialSeqNumber: this.initialSequenceNumber,
@@ -985,13 +999,13 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
985
999
  this.close(error);
986
1000
  }
987
1001
  }
988
- } else if (message.sequenceNumber !== this.lastQueuedSequenceNumber + 1) {
989
- this.pending.push(message);
990
- this.fetchMissingDeltas(reason, message.sequenceNumber);
991
- } else {
1002
+ } else if (message.sequenceNumber === this.lastQueuedSequenceNumber + 1) {
992
1003
  this.lastQueuedSequenceNumber = message.sequenceNumber;
993
1004
  this.previouslyProcessedMessage = message;
994
1005
  this._inbound.push(message);
1006
+ } else {
1007
+ this.pending.push(message);
1008
+ this.fetchMissingDeltas(reason, message.sequenceNumber);
995
1009
  }
996
1010
  }
997
1011
 
@@ -1103,7 +1117,7 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
1103
1117
  /**
1104
1118
  * Retrieves the missing deltas between the given sequence numbers
1105
1119
  */
1106
- private fetchMissingDeltas(reasonArg: string, to?: number) {
1120
+ private fetchMissingDeltas(reasonArg: string, to?: number): void {
1107
1121
  this.fetchMissingDeltasCore(reasonArg, false /* cacheOnly */, to).catch((error) => {
1108
1122
  this.logger.sendErrorEvent({ eventName: "fetchMissingDeltasException" }, error);
1109
1123
  });
@@ -1112,7 +1126,11 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
1112
1126
  /**
1113
1127
  * Retrieves the missing deltas between the given sequence numbers
1114
1128
  */
1115
- private async fetchMissingDeltasCore(reason: string, cacheOnly: boolean, to?: number) {
1129
+ private async fetchMissingDeltasCore(
1130
+ reason: string,
1131
+ cacheOnly: boolean,
1132
+ to?: number,
1133
+ ): Promise<void> {
1116
1134
  // Exit out early if we're already fetching deltas
1117
1135
  if (this.fetchReason !== undefined) {
1118
1136
  return;
@@ -1199,13 +1217,14 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
1199
1217
  // and thus can leverage that to trigger recovery. But this is not going to solve all the problems
1200
1218
  // (the other 50%), and thus these errors below should be looked at even if code below results in
1201
1219
  // recovery.
1220
+ // eslint-disable-next-line unicorn/no-lonely-if -- Docs make more sense like this
1202
1221
  if (this.lastQueuedSequenceNumber < this.lastObservedSeqNumber) {
1203
1222
  this.fetchMissingDeltas("OpsBehind");
1204
1223
  }
1205
1224
  }
1206
1225
  }
1207
1226
 
1208
- private updateLatestKnownOpSeqNumber(seq: number) {
1227
+ private updateLatestKnownOpSeqNumber(seq: number): void {
1209
1228
  if (this.lastObservedSeqNumber < seq) {
1210
1229
  this.lastObservedSeqNumber = seq;
1211
1230
  }