@fluidframework/driver-utils 2.81.1 → 2.82.0

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 (216) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/adapters/compression/documentServiceCompressionAdapter.d.ts +2 -2
  3. package/dist/adapters/compression/documentServiceCompressionAdapter.d.ts.map +1 -1
  4. package/dist/adapters/compression/documentServiceCompressionAdapter.js.map +1 -1
  5. package/dist/adapters/compression/documentServiceFactoryCompressionAdapter.d.ts +4 -4
  6. package/dist/adapters/compression/documentServiceFactoryCompressionAdapter.d.ts.map +1 -1
  7. package/dist/adapters/compression/documentServiceFactoryCompressionAdapter.js.map +1 -1
  8. package/dist/adapters/compression/index.d.ts +1 -1
  9. package/dist/adapters/compression/index.d.ts.map +1 -1
  10. package/dist/adapters/compression/index.js.map +1 -1
  11. package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts +2 -2
  12. package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts.map +1 -1
  13. package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js +15 -11
  14. package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js.map +1 -1
  15. package/dist/adapters/index.d.ts +1 -1
  16. package/dist/adapters/index.d.ts.map +1 -1
  17. package/dist/adapters/index.js.map +1 -1
  18. package/dist/adapters/predefinedAdapters.d.ts +3 -3
  19. package/dist/adapters/predefinedAdapters.d.ts.map +1 -1
  20. package/dist/adapters/predefinedAdapters.js +4 -1
  21. package/dist/adapters/predefinedAdapters.js.map +1 -1
  22. package/dist/blob.d.ts +2 -1
  23. package/dist/blob.d.ts.map +1 -1
  24. package/dist/blob.js +3 -1
  25. package/dist/blob.js.map +1 -1
  26. package/dist/buildSnapshotTree.d.ts +1 -1
  27. package/dist/buildSnapshotTree.d.ts.map +1 -1
  28. package/dist/buildSnapshotTree.js.map +1 -1
  29. package/dist/cacheUtils.js +1 -1
  30. package/dist/cacheUtils.js.map +1 -1
  31. package/dist/documentServiceFactoryProxy.d.ts +3 -3
  32. package/dist/documentServiceFactoryProxy.d.ts.map +1 -1
  33. package/dist/documentServiceFactoryProxy.js.map +1 -1
  34. package/dist/documentServiceProxy.d.ts +3 -3
  35. package/dist/documentServiceProxy.d.ts.map +1 -1
  36. package/dist/documentServiceProxy.js.map +1 -1
  37. package/dist/documentStorageServiceProxy.d.ts +2 -2
  38. package/dist/documentStorageServiceProxy.d.ts.map +1 -1
  39. package/dist/documentStorageServiceProxy.js +3 -1
  40. package/dist/documentStorageServiceProxy.js.map +1 -1
  41. package/dist/error.d.ts +2 -2
  42. package/dist/error.d.ts.map +1 -1
  43. package/dist/error.js.map +1 -1
  44. package/dist/index.d.ts +4 -4
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/insecureUrlResolver.d.ts +2 -2
  48. package/dist/insecureUrlResolver.d.ts.map +1 -1
  49. package/dist/insecureUrlResolver.js +4 -4
  50. package/dist/insecureUrlResolver.js.map +1 -1
  51. package/dist/messageRecognition.d.ts +3 -1
  52. package/dist/messageRecognition.d.ts.map +1 -1
  53. package/dist/messageRecognition.js +2 -0
  54. package/dist/messageRecognition.js.map +1 -1
  55. package/dist/network.d.ts +10 -6
  56. package/dist/network.d.ts.map +1 -1
  57. package/dist/network.js +18 -3
  58. package/dist/network.js.map +1 -1
  59. package/dist/networkUtils.d.ts +4 -3
  60. package/dist/networkUtils.d.ts.map +1 -1
  61. package/dist/networkUtils.js +6 -0
  62. package/dist/networkUtils.js.map +1 -1
  63. package/dist/packageVersion.d.ts +1 -1
  64. package/dist/packageVersion.js +1 -1
  65. package/dist/packageVersion.js.map +1 -1
  66. package/dist/parallelRequests.d.ts +8 -4
  67. package/dist/parallelRequests.d.ts.map +1 -1
  68. package/dist/parallelRequests.js +24 -21
  69. package/dist/parallelRequests.js.map +1 -1
  70. package/dist/prefetchDocumentStorageService.d.ts.map +1 -1
  71. package/dist/prefetchDocumentStorageService.js +8 -10
  72. package/dist/prefetchDocumentStorageService.js.map +1 -1
  73. package/dist/protocol/gitHelper.d.ts +1 -1
  74. package/dist/protocol/gitHelper.d.ts.map +1 -1
  75. package/dist/protocol/gitHelper.js +12 -6
  76. package/dist/protocol/gitHelper.js.map +1 -1
  77. package/dist/readAndParse.d.ts +1 -1
  78. package/dist/readAndParse.d.ts.map +1 -1
  79. package/dist/readAndParse.js.map +1 -1
  80. package/dist/runWithRetry.d.ts +4 -2
  81. package/dist/runWithRetry.d.ts.map +1 -1
  82. package/dist/runWithRetry.js +14 -11
  83. package/dist/runWithRetry.js.map +1 -1
  84. package/dist/storageUtils.d.ts +1 -1
  85. package/dist/storageUtils.d.ts.map +1 -1
  86. package/dist/storageUtils.js.map +1 -1
  87. package/dist/summaryForCreateNew.d.ts +2 -2
  88. package/dist/summaryForCreateNew.d.ts.map +1 -1
  89. package/dist/summaryForCreateNew.js.map +1 -1
  90. package/dist/treeConversions.d.ts +2 -2
  91. package/dist/treeConversions.d.ts.map +1 -1
  92. package/dist/treeConversions.js +3 -1
  93. package/dist/treeConversions.js.map +1 -1
  94. package/eslint.config.mts +2 -2
  95. package/lib/adapters/compression/documentServiceCompressionAdapter.d.ts +2 -2
  96. package/lib/adapters/compression/documentServiceCompressionAdapter.d.ts.map +1 -1
  97. package/lib/adapters/compression/documentServiceCompressionAdapter.js.map +1 -1
  98. package/lib/adapters/compression/documentServiceFactoryCompressionAdapter.d.ts +4 -4
  99. package/lib/adapters/compression/documentServiceFactoryCompressionAdapter.d.ts.map +1 -1
  100. package/lib/adapters/compression/documentServiceFactoryCompressionAdapter.js.map +1 -1
  101. package/lib/adapters/compression/index.d.ts +1 -1
  102. package/lib/adapters/compression/index.d.ts.map +1 -1
  103. package/lib/adapters/compression/index.js.map +1 -1
  104. package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts +2 -2
  105. package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts.map +1 -1
  106. package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js +15 -11
  107. package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js.map +1 -1
  108. package/lib/adapters/index.d.ts +1 -1
  109. package/lib/adapters/index.d.ts.map +1 -1
  110. package/lib/adapters/index.js.map +1 -1
  111. package/lib/adapters/predefinedAdapters.d.ts +3 -3
  112. package/lib/adapters/predefinedAdapters.d.ts.map +1 -1
  113. package/lib/adapters/predefinedAdapters.js +4 -1
  114. package/lib/adapters/predefinedAdapters.js.map +1 -1
  115. package/lib/blob.d.ts +2 -1
  116. package/lib/blob.d.ts.map +1 -1
  117. package/lib/blob.js +4 -2
  118. package/lib/blob.js.map +1 -1
  119. package/lib/buildSnapshotTree.d.ts +1 -1
  120. package/lib/buildSnapshotTree.d.ts.map +1 -1
  121. package/lib/buildSnapshotTree.js.map +1 -1
  122. package/lib/cacheUtils.js +1 -1
  123. package/lib/cacheUtils.js.map +1 -1
  124. package/lib/documentServiceFactoryProxy.d.ts +3 -3
  125. package/lib/documentServiceFactoryProxy.d.ts.map +1 -1
  126. package/lib/documentServiceFactoryProxy.js.map +1 -1
  127. package/lib/documentServiceProxy.d.ts +3 -3
  128. package/lib/documentServiceProxy.d.ts.map +1 -1
  129. package/lib/documentServiceProxy.js.map +1 -1
  130. package/lib/documentStorageServiceProxy.d.ts +2 -2
  131. package/lib/documentStorageServiceProxy.d.ts.map +1 -1
  132. package/lib/documentStorageServiceProxy.js +3 -1
  133. package/lib/documentStorageServiceProxy.js.map +1 -1
  134. package/lib/error.d.ts +2 -2
  135. package/lib/error.d.ts.map +1 -1
  136. package/lib/error.js.map +1 -1
  137. package/lib/index.d.ts +4 -4
  138. package/lib/index.d.ts.map +1 -1
  139. package/lib/index.js.map +1 -1
  140. package/lib/insecureUrlResolver.d.ts +2 -2
  141. package/lib/insecureUrlResolver.d.ts.map +1 -1
  142. package/lib/insecureUrlResolver.js +4 -4
  143. package/lib/insecureUrlResolver.js.map +1 -1
  144. package/lib/messageRecognition.d.ts +3 -1
  145. package/lib/messageRecognition.d.ts.map +1 -1
  146. package/lib/messageRecognition.js +2 -0
  147. package/lib/messageRecognition.js.map +1 -1
  148. package/lib/network.d.ts +10 -6
  149. package/lib/network.d.ts.map +1 -1
  150. package/lib/network.js +18 -3
  151. package/lib/network.js.map +1 -1
  152. package/lib/networkUtils.d.ts +4 -3
  153. package/lib/networkUtils.d.ts.map +1 -1
  154. package/lib/networkUtils.js +6 -0
  155. package/lib/networkUtils.js.map +1 -1
  156. package/lib/packageVersion.d.ts +1 -1
  157. package/lib/packageVersion.js +1 -1
  158. package/lib/packageVersion.js.map +1 -1
  159. package/lib/parallelRequests.d.ts +8 -4
  160. package/lib/parallelRequests.d.ts.map +1 -1
  161. package/lib/parallelRequests.js +24 -21
  162. package/lib/parallelRequests.js.map +1 -1
  163. package/lib/prefetchDocumentStorageService.d.ts.map +1 -1
  164. package/lib/prefetchDocumentStorageService.js +8 -10
  165. package/lib/prefetchDocumentStorageService.js.map +1 -1
  166. package/lib/protocol/gitHelper.d.ts +1 -1
  167. package/lib/protocol/gitHelper.d.ts.map +1 -1
  168. package/lib/protocol/gitHelper.js +12 -6
  169. package/lib/protocol/gitHelper.js.map +1 -1
  170. package/lib/readAndParse.d.ts +1 -1
  171. package/lib/readAndParse.d.ts.map +1 -1
  172. package/lib/readAndParse.js.map +1 -1
  173. package/lib/runWithRetry.d.ts +4 -2
  174. package/lib/runWithRetry.d.ts.map +1 -1
  175. package/lib/runWithRetry.js +15 -12
  176. package/lib/runWithRetry.js.map +1 -1
  177. package/lib/storageUtils.d.ts +1 -1
  178. package/lib/storageUtils.d.ts.map +1 -1
  179. package/lib/storageUtils.js.map +1 -1
  180. package/lib/summaryForCreateNew.d.ts +2 -2
  181. package/lib/summaryForCreateNew.d.ts.map +1 -1
  182. package/lib/summaryForCreateNew.js +1 -1
  183. package/lib/summaryForCreateNew.js.map +1 -1
  184. package/lib/treeConversions.d.ts +2 -2
  185. package/lib/treeConversions.d.ts.map +1 -1
  186. package/lib/treeConversions.js +3 -1
  187. package/lib/treeConversions.js.map +1 -1
  188. package/package.json +10 -9
  189. package/src/adapters/compression/documentServiceCompressionAdapter.ts +2 -2
  190. package/src/adapters/compression/documentServiceFactoryCompressionAdapter.ts +4 -4
  191. package/src/adapters/compression/index.ts +1 -1
  192. package/src/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.ts +25 -21
  193. package/src/adapters/index.ts +1 -1
  194. package/src/adapters/predefinedAdapters.ts +7 -4
  195. package/src/blob.ts +3 -7
  196. package/src/buildSnapshotTree.ts +6 -6
  197. package/src/cacheUtils.ts +1 -1
  198. package/src/documentServiceFactoryProxy.ts +3 -3
  199. package/src/documentServiceProxy.ts +3 -3
  200. package/src/documentStorageServiceProxy.ts +4 -2
  201. package/src/error.ts +2 -2
  202. package/src/index.ts +4 -4
  203. package/src/insecureUrlResolver.ts +7 -7
  204. package/src/messageRecognition.ts +4 -2
  205. package/src/network.ts +26 -12
  206. package/src/networkUtils.ts +12 -4
  207. package/src/packageVersion.ts +1 -1
  208. package/src/parallelRequests.ts +33 -30
  209. package/src/prefetchDocumentStorageService.ts +10 -10
  210. package/src/protocol/gitHelper.ts +15 -9
  211. package/src/readAndParse.ts +1 -1
  212. package/src/runWithRetry.ts +20 -14
  213. package/src/storageUtils.ts +1 -1
  214. package/src/summaryForCreateNew.ts +5 -1
  215. package/src/treeConversions.ts +5 -3
  216. package/biome.jsonc +0 -4
@@ -6,13 +6,13 @@
6
6
  import { type Buffer, IsoBuffer } from "@fluid-internal/client-utils";
7
7
  import { assert } from "@fluidframework/core-utils/internal";
8
8
  import {
9
- ISummaryBlob,
10
- ISummaryHandle,
11
- ISummaryTree,
12
- SummaryObject,
9
+ type ISummaryBlob,
10
+ type ISummaryHandle,
11
+ type ISummaryTree,
12
+ type SummaryObject,
13
13
  SummaryType,
14
14
  } from "@fluidframework/driver-definitions";
15
- import {
15
+ import type {
16
16
  IDocumentStorageService,
17
17
  ISummaryContext,
18
18
  ISnapshotTree,
@@ -74,10 +74,10 @@ export class DocumentStorageServiceCompressionAdapter extends DocumentStorageSer
74
74
  * @param blob - The maybe compressed blob.
75
75
  */
76
76
  private static readAlgorithmFromBlob(blob: ArrayBufferLike): number {
77
- return !this.hasPrefix(blob)
78
- ? SummaryCompressionAlgorithm.None
79
- : // eslint-disable-next-line no-bitwise
80
- IsoBuffer.from(blob)[0] & 0x0f;
77
+ return this.hasPrefix(blob)
78
+ ? // eslint-disable-next-line no-bitwise
79
+ IsoBuffer.from(blob)[0] & 0x0f
80
+ : SummaryCompressionAlgorithm.None;
81
81
  }
82
82
 
83
83
  /**
@@ -202,7 +202,7 @@ export class DocumentStorageServiceCompressionAdapter extends DocumentStorageSer
202
202
  } else if (algorithm === SummaryCompressionAlgorithm.None) {
203
203
  maybeCompressed = file;
204
204
  } else if (algorithm === SummaryCompressionAlgorithm.LZ4) {
205
- const compressed = compress(file) as ArrayBufferLike;
205
+ const compressed = compress(file as Uint8Array) as ArrayBufferLike;
206
206
  maybeCompressed = compressed;
207
207
  } else {
208
208
  throw new Error(`Unknown Algorithm ${config.algorithm}`);
@@ -221,8 +221,9 @@ export class DocumentStorageServiceCompressionAdapter extends DocumentStorageSer
221
221
  */
222
222
  private static decodeBlob(file: ArrayBufferLike): ArrayBufferLike {
223
223
  let decompressed: ArrayBufferLike;
224
- let originalBlob;
225
- let algorithm;
224
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: use a real type
225
+ let originalBlob: any;
226
+ let algorithm: SummaryCompressionAlgorithm;
226
227
  if (this.hasPrefix(file)) {
227
228
  algorithm = DocumentStorageServiceCompressionAdapter.readAlgorithmFromBlob(file);
228
229
  originalBlob = this.removePrefixFromBlobIfPresent(file);
@@ -231,8 +232,10 @@ export class DocumentStorageServiceCompressionAdapter extends DocumentStorageSer
231
232
  originalBlob = file;
232
233
  }
233
234
  if (algorithm === SummaryCompressionAlgorithm.None) {
235
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
234
236
  decompressed = originalBlob;
235
237
  } else if (algorithm === SummaryCompressionAlgorithm.LZ4) {
238
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment
236
239
  decompressed = decompress(originalBlob) as ArrayBufferLike;
237
240
  } else {
238
241
  throw new Error(`Unknown Algorithm ${algorithm}`);
@@ -267,12 +270,13 @@ export class DocumentStorageServiceCompressionAdapter extends DocumentStorageSer
267
270
  }
268
271
  let clone: object | undefined;
269
272
  for (const key of Object.keys(input)) {
270
- const value = input[key];
273
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
274
+ const value: SummaryObject = input[key];
271
275
 
272
276
  if (Boolean(value) && typeof value === "object") {
273
277
  const replaced = this.recursivelyReplace(
274
278
  isEncode,
275
- value as SummaryObject,
279
+ value,
276
280
  encoder,
277
281
  decoder,
278
282
  config,
@@ -396,13 +400,13 @@ export class DocumentStorageServiceCompressionAdapter extends DocumentStorageSer
396
400
  */
397
401
  public override async readBlob(id: string): Promise<ArrayBufferLike> {
398
402
  const originalBlob = await super.readBlob(id);
399
- if (!this._isCompressionEnabled) {
400
- return originalBlob;
401
- } else {
403
+ if (this._isCompressionEnabled) {
402
404
  const decompressedBlob =
403
405
  DocumentStorageServiceCompressionAdapter.decodeBlob(originalBlob);
404
406
  // console.log(`Miso summary-blob Blob read END : ${id} ${decompressedBlob.byteLength}`);
405
407
  return decompressedBlob;
408
+ } else {
409
+ return originalBlob;
406
410
  }
407
411
  }
408
412
 
@@ -451,14 +455,14 @@ export class DocumentStorageServiceCompressionAdapter extends DocumentStorageSer
451
455
  */
452
456
  public override async downloadSummary(id: ISummaryHandle): Promise<ISummaryTree> {
453
457
  const summary = await super.downloadSummary(id);
454
- return !this._isCompressionEnabled
455
- ? summary
456
- : (DocumentStorageServiceCompressionAdapter.recursivelyReplace(
458
+ return this._isCompressionEnabled
459
+ ? (DocumentStorageServiceCompressionAdapter.recursivelyReplace(
457
460
  false,
458
461
  summary,
459
462
  DocumentStorageServiceCompressionAdapter.blobEncoder,
460
463
  DocumentStorageServiceCompressionAdapter.blobDecoder,
461
464
  this._config,
462
- ) as ISummaryTree);
465
+ ) as ISummaryTree)
466
+ : summary;
463
467
  }
464
468
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  export {
7
7
  SummaryCompressionAlgorithm,
8
- ICompressionStorageConfig,
8
+ type ICompressionStorageConfig,
9
9
  DefaultCompressionStorageConfig,
10
10
  blobHeadersBlobName,
11
11
  } from "./compression/index.js";
@@ -4,12 +4,12 @@
4
4
  */
5
5
 
6
6
  import { assert } from "@fluidframework/core-utils/internal";
7
- import { IDocumentServiceFactory } from "@fluidframework/driver-definitions/internal";
7
+ import type { IDocumentServiceFactory } from "@fluidframework/driver-definitions/internal";
8
8
 
9
9
  import {
10
10
  DefaultCompressionStorageConfig,
11
11
  DocumentServiceFactoryCompressionAdapter,
12
- ICompressionStorageConfig,
12
+ type ICompressionStorageConfig,
13
13
  } from "./compression/index.js";
14
14
 
15
15
  /**
@@ -67,9 +67,12 @@ function applyStorageCompressionInternal(
67
67
  * This method checks whether given objects contains
68
68
  * a properties expected for the interface ICompressionStorageConfig.
69
69
  */
70
- export function isCompressionConfig(config: any): config is ICompressionStorageConfig {
70
+ export function isCompressionConfig(config: unknown): config is ICompressionStorageConfig {
71
71
  return (
72
72
  config !== undefined &&
73
- (config.algorithm !== undefined || config.minSizeToCompress !== undefined)
73
+ typeof config === "object" &&
74
+ config !== null &&
75
+ ((config as Partial<ICompressionStorageConfig>).algorithm !== undefined ||
76
+ (config as Partial<ICompressionStorageConfig>).minSizeToCompress !== undefined)
74
77
  );
75
78
  }
package/src/blob.ts CHANGED
@@ -3,13 +3,8 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import {
7
- FileMode,
8
- IAttachment,
9
- IBlob,
10
- ITree,
11
- TreeEntry,
12
- } from "@fluidframework/driver-definitions/internal";
6
+ import type { IAttachment, IBlob, ITree } from "@fluidframework/driver-definitions/internal";
7
+ import { FileMode, TreeEntry } from "@fluidframework/driver-definitions/internal";
13
8
 
14
9
  /**
15
10
  * Basic implementation of a blob ITreeEntry
@@ -29,6 +24,7 @@ export class BlobTreeEntry {
29
24
  constructor(
30
25
  public readonly path: string,
31
26
  contents: string,
27
+ // eslint-disable-next-line unicorn/text-encoding-identifier-case
32
28
  encoding: "utf-8" | "base64" = "utf-8",
33
29
  ) {
34
30
  this.value = { contents, encoding };
@@ -7,10 +7,10 @@ import { stringToBuffer } from "@fluid-internal/client-utils";
7
7
  import { assert } from "@fluidframework/core-utils/internal";
8
8
  import {
9
9
  FileMode,
10
- IGitTree,
11
- IGitTreeEntry,
12
- ISnapshotTree,
13
- ITreeEntry,
10
+ type IGitTree,
11
+ type IGitTreeEntry,
12
+ type ISnapshotTree,
13
+ type ITreeEntry,
14
14
  TreeEntry,
15
15
  } from "@fluidframework/driver-definitions/internal";
16
16
  import { v4 as uuid } from "uuid";
@@ -33,7 +33,7 @@ function flattenCore(
33
33
  blobMap.set(id, buffer);
34
34
 
35
35
  const entry: IGitTreeEntry = {
36
- mode: FileMode[treeEntry.mode],
36
+ mode: FileMode[treeEntry.mode] as string,
37
37
  path: subPath,
38
38
  sha: id,
39
39
  size: 0,
@@ -48,7 +48,7 @@ function flattenCore(
48
48
  );
49
49
  const t = treeEntry.value;
50
50
  const entry: IGitTreeEntry = {
51
- mode: FileMode[treeEntry.mode],
51
+ mode: FileMode[treeEntry.mode] as string,
52
52
  path: subPath,
53
53
  sha: "",
54
54
  size: -1,
package/src/cacheUtils.ts CHANGED
@@ -22,6 +22,6 @@ export const maximumCacheDurationMs: FiveDaysMs = 432_000_000; // 5 days in ms
22
22
  * @internal
23
23
  */
24
24
  export function getKeyForCacheEntry(entry: ICacheEntry): string {
25
- const version = entry.file.fileVersion !== undefined ? `_${entry.file.fileVersion}` : "";
25
+ const version = entry.file.fileVersion === undefined ? "" : `_${entry.file.fileVersion}`;
26
26
  return `${entry.file.docId}${version}_${entry.type}_${entry.key}`;
27
27
  }
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import type { ILayerCompatDetails } from "@fluid-internal/client-utils";
7
- import { ITelemetryBaseLogger, type FluidObject } from "@fluidframework/core-interfaces";
8
- import { ISummaryTree } from "@fluidframework/driver-definitions";
9
- import {
7
+ import type { ITelemetryBaseLogger, FluidObject } from "@fluidframework/core-interfaces";
8
+ import type { ISummaryTree } from "@fluidframework/driver-definitions";
9
+ import type {
10
10
  IDocumentService,
11
11
  IDocumentServiceFactory,
12
12
  IResolvedUrl,
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
- import { IClient } from "@fluidframework/driver-definitions";
8
- import {
7
+ import type { IClient } from "@fluidframework/driver-definitions";
8
+ import type {
9
9
  IDocumentDeltaConnection,
10
10
  IDocumentDeltaStorageService,
11
11
  IDocumentService,
@@ -43,7 +43,7 @@ export abstract class DocumentServiceProxy
43
43
  return this._service.connectToDeltaStream(client);
44
44
  }
45
45
 
46
- public dispose(error?: any): void {
46
+ public dispose(error?: unknown): void {
47
47
  this._service.dispose(error);
48
48
  }
49
49
 
@@ -3,8 +3,8 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
7
- import {
6
+ import type { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
7
+ import type {
8
8
  FetchSource,
9
9
  IDocumentStorageService,
10
10
  IDocumentStorageServicePolicies,
@@ -36,6 +36,7 @@ export class DocumentStorageServiceProxy implements IDocumentStorageService {
36
36
  public async getSnapshotTree(
37
37
  version?: IVersion,
38
38
  scenarioName?: string,
39
+ // eslint-disable-next-line @rushstack/no-new-null
39
40
  ): Promise<ISnapshotTree | null> {
40
41
  return this.internalStorageService.getSnapshotTree(version, scenarioName);
41
42
  }
@@ -50,6 +51,7 @@ export class DocumentStorageServiceProxy implements IDocumentStorageService {
50
51
  }
51
52
 
52
53
  public async getVersions(
54
+ // eslint-disable-next-line @rushstack/no-new-null
53
55
  versionId: string | null,
54
56
  count: number,
55
57
  scenarioName?: string,
package/src/error.ts CHANGED
@@ -5,9 +5,9 @@
5
5
 
6
6
  import {
7
7
  DriverErrorTypes,
8
- IDriverErrorBase,
8
+ type IDriverErrorBase,
9
9
  } from "@fluidframework/driver-definitions/internal";
10
- import { IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils/internal";
10
+ import { type IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils/internal";
11
11
 
12
12
  /**
13
13
  * Error indicating an API is being used improperly resulting in an invalid operation.
package/src/index.ts CHANGED
@@ -18,7 +18,7 @@ export {
18
18
  createGenericNetworkError,
19
19
  createWriteError,
20
20
  DeltaStreamConnectionForbiddenError,
21
- DriverErrorTelemetryProps,
21
+ type DriverErrorTelemetryProps,
22
22
  FluidInvalidSchemaError,
23
23
  GenericNetworkError,
24
24
  getRetryDelayFromError,
@@ -43,9 +43,9 @@ export {
43
43
  export { PrefetchDocumentStorageService } from "./prefetchDocumentStorageService.js";
44
44
  export { RateLimiter } from "./rateLimiter.js";
45
45
  export { readAndParse } from "./readAndParse.js";
46
- export { calculateMaxWaitTime, IProgress, runWithRetry } from "./runWithRetry.js";
46
+ export { calculateMaxWaitTime, type IProgress, runWithRetry } from "./runWithRetry.js";
47
47
  export {
48
- CombinedAppAndProtocolSummary,
48
+ type CombinedAppAndProtocolSummary,
49
49
  getDocAttributesFromProtocolSummary,
50
50
  getQuorumValuesFromProtocolSummary,
51
51
  isCombinedAppAndProtocolSummary,
@@ -53,7 +53,7 @@ export {
53
53
  export { convertSummaryTreeToSnapshotITree } from "./treeConversions.js";
54
54
  export {
55
55
  applyStorageCompression,
56
- ICompressionStorageConfig,
56
+ type ICompressionStorageConfig,
57
57
  SummaryCompressionAlgorithm,
58
58
  blobHeadersBlobName,
59
59
  } from "./adapters/index.js";
@@ -3,12 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { IRequest } from "@fluidframework/core-interfaces";
6
+ import type { IRequest } from "@fluidframework/core-interfaces";
7
7
  import { assert } from "@fluidframework/core-utils/internal";
8
8
  import {
9
9
  DriverHeader,
10
- IResolvedUrl,
11
- IUrlResolver,
10
+ type IResolvedUrl,
11
+ type IUrlResolver,
12
12
  } from "@fluidframework/driver-definitions/internal";
13
13
 
14
14
  /**
@@ -51,11 +51,11 @@ export class InsecureUrlResolver implements IUrlResolver {
51
51
  // If hosts match then we use the local tenant information. Otherwise we make a REST call out to the hosting
52
52
  // service using our bearer token.
53
53
  if (this.isForNodeTest) {
54
- const [, documentId, tmpRelativePath] = parsedUrl.pathname.substr(1).split("/");
54
+ const [, documentId, tmpRelativePath] = parsedUrl.pathname.slice(1).split("/");
55
55
  const relativePath = tmpRelativePath ?? "";
56
56
  return this.resolveHelper(documentId, relativePath, parsedUrl.search);
57
57
  } else if (parsedUrl.host === window.location.host) {
58
- const fullPath = parsedUrl.pathname.substr(1);
58
+ const fullPath = parsedUrl.pathname.slice(1);
59
59
  const documentId = fullPath.split("/")[0];
60
60
  const documentRelativePath = fullPath.slice(documentId.length);
61
61
  return this.resolveHelper(documentId, documentRelativePath);
@@ -142,13 +142,13 @@ export class InsecureUrlResolver implements IUrlResolver {
142
142
  relativeUrl: string,
143
143
  ): Promise<string> {
144
144
  const parsedUrl = new URL(resolvedUrl.url);
145
- const [, , documentId] = parsedUrl.pathname?.split("/") ?? [];
145
+ const documentId = (parsedUrl.pathname?.split("/") ?? [])[2];
146
146
 
147
147
  assert(!!documentId, 0x273 /* "Invalid document id from parsed URL" */);
148
148
 
149
149
  let url = relativeUrl;
150
150
  if (url.startsWith("/")) {
151
- url = url.substr(1);
151
+ url = url.slice(1);
152
152
  }
153
153
 
154
154
  return `${this.hostUrl}/${encodeURIComponent(this.tenantId)}/${encodeURIComponent(
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import {
7
- ISequencedDocumentMessage,
8
- IDocumentMessage,
7
+ type ISequencedDocumentMessage,
8
+ type IDocumentMessage,
9
9
  MessageType,
10
10
  } from "@fluidframework/driver-definitions/internal";
11
11
 
@@ -20,6 +20,8 @@ export function isRuntimeMessage(message: { type: string }): boolean {
20
20
  }
21
21
 
22
22
  /**
23
+ * Whether the message can be coalesced by the relay service.
24
+ *
23
25
  * @privateRemarks ADO #1385: To be moved to packages/protocol-base/src/protocol.ts
24
26
  * @internal
25
27
  */
package/src/network.ts CHANGED
@@ -3,16 +3,16 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
6
+ import type { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
7
7
  import {
8
- IAuthorizationError,
9
- ILocationRedirectionError,
10
- IResolvedUrl,
11
- IThrottlingWarning,
12
8
  DriverErrorTypes,
13
- IDriverErrorBase,
9
+ type IAuthorizationError,
10
+ type ILocationRedirectionError,
11
+ type IResolvedUrl,
12
+ type IThrottlingWarning,
13
+ type IDriverErrorBase,
14
14
  } from "@fluidframework/driver-definitions/internal";
15
- import { IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils/internal";
15
+ import { type IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils/internal";
16
16
 
17
17
  /**
18
18
  * @internal
@@ -226,6 +226,8 @@ export class ThrottlingError
226
226
  }
227
227
 
228
228
  /**
229
+ * Creates a non-retryable write error.
230
+ *
229
231
  * @internal
230
232
  */
231
233
  export const createWriteError = (
@@ -235,6 +237,8 @@ export const createWriteError = (
235
237
  new NonRetryableError(message, DriverErrorTypes.writeError, props);
236
238
 
237
239
  /**
240
+ * Creates a generic network error, either throttling or non-throttling based on the provided retry information.
241
+ *
238
242
  * @internal
239
243
  */
240
244
  export function createGenericNetworkError(
@@ -254,18 +258,28 @@ export function createGenericNetworkError(
254
258
  * @param error - The error to inspect for ability to retry
255
259
  * @internal
256
260
  */
257
- export const canRetryOnError = (error: any): boolean => error?.canRetry === true;
261
+ export const canRetryOnError = (error: unknown): boolean =>
262
+ typeof error === "object" &&
263
+ error !== null &&
264
+ (error as { canRetry?: boolean }).canRetry === true;
258
265
 
259
266
  /**
260
267
  * Check retryAfterSeconds property on error
261
268
  * @internal
262
269
  */
263
- export const getRetryDelaySecondsFromError = (error: any): number | undefined =>
264
- error?.retryAfterSeconds as number | undefined;
270
+ export const getRetryDelaySecondsFromError = (error: unknown): number | undefined => {
271
+ if (typeof error === "object" && error !== null) {
272
+ const retryAfterSeconds = (error as { retryAfterSeconds?: unknown }).retryAfterSeconds;
273
+ return typeof retryAfterSeconds === "number" ? retryAfterSeconds : undefined;
274
+ }
275
+ return undefined;
276
+ };
265
277
 
266
278
  /**
267
279
  * Check retryAfterSeconds property on error and convert to ms
268
280
  * @internal
269
281
  */
270
- export const getRetryDelayFromError = (error: any): number | undefined =>
271
- error?.retryAfterSeconds !== undefined ? error.retryAfterSeconds * 1000 : undefined;
282
+ export const getRetryDelayFromError = (error: unknown): number | undefined => {
283
+ const retryAfterSeconds = getRetryDelaySecondsFromError(error);
284
+ return retryAfterSeconds === undefined ? undefined : retryAfterSeconds * 1000;
285
+ };
@@ -3,29 +3,37 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import type { ITelemetryErrorEventExt } from "@fluidframework/telemetry-utils/internal";
7
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
6
+ import type {
7
+ ITelemetryErrorEventExt,
8
+ ITelemetryLoggerExt,
9
+ } from "@fluidframework/telemetry-utils/internal";
8
10
 
9
11
  import { OnlineStatus, canRetryOnError, isOnline } from "./network.js";
10
12
 
11
13
  /**
14
+ * Logs a network failure with additional context about online status and retry capability for the provided event.
15
+ *
12
16
  * @internal
13
17
  */
14
18
  export function logNetworkFailure(
15
19
  logger: ITelemetryLoggerExt,
16
20
  event: ITelemetryErrorEventExt,
17
- error?: any,
21
+ error?: unknown,
18
22
  ): void {
19
23
  const newEvent = { ...event };
20
24
 
21
- const errorOnlineProp = error?.online;
25
+ // TODO: better typing
26
+ const errorOnlineProp = (error as { online?: unknown })?.online;
22
27
  newEvent.online =
23
28
  typeof errorOnlineProp === "string" ? errorOnlineProp : OnlineStatus[isOnline()];
24
29
 
25
30
  if (typeof navigator === "object" && navigator !== null) {
31
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any -- TODO: use a real type
26
32
  const nav = navigator as any;
33
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
27
34
  const connection = nav.connection ?? nav.mozConnection ?? nav.webkitConnection;
28
35
  if (connection !== null && typeof connection === "object") {
36
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
29
37
  newEvent.connectionType = connection.type;
30
38
  }
31
39
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/driver-utils";
9
- export const pkgVersion = "2.81.1";
9
+ export const pkgVersion = "2.82.0";
@@ -4,16 +4,16 @@
4
4
  */
5
5
 
6
6
  import { performanceNow } from "@fluid-internal/client-utils";
7
- import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
7
+ import type { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
8
8
  import { assert, Deferred } from "@fluidframework/core-utils/internal";
9
- import {
9
+ import type {
10
10
  IDeltasFetchResult,
11
11
  IStream,
12
12
  IStreamResult,
13
13
  ISequencedDocumentMessage,
14
14
  } from "@fluidframework/driver-definitions/internal";
15
15
  import {
16
- ITelemetryLoggerExt,
16
+ type ITelemetryLoggerExt,
17
17
  PerformanceEvent,
18
18
  } from "@fluidframework/telemetry-utils/internal";
19
19
 
@@ -164,10 +164,8 @@ export class ParallelRequests<T> {
164
164
  }
165
165
 
166
166
  const from = this.latestRequested;
167
- if (this.to !== undefined) {
168
- if (this.to <= from) {
169
- return undefined;
170
- }
167
+ if (this.to !== undefined && this.to <= from) {
168
+ return undefined;
171
169
  }
172
170
 
173
171
  // this.latestRequested
@@ -237,7 +235,7 @@ export class ParallelRequests<T> {
237
235
  // If it pops into our view a lot, we would need to reconsider how we approach it.
238
236
  // Note that this is not visible to user other than potentially not hitting 100% of
239
237
  // what we can in perf domain.
240
- if (payload.length !== 0) {
238
+ if (payload.length > 0) {
241
239
  this.logger.sendErrorEvent({
242
240
  eventName: "ParallelRequests_GotExtra",
243
241
  from,
@@ -255,7 +253,25 @@ export class ParallelRequests<T> {
255
253
  const length = payload.length;
256
254
  let fullChunk = requestedLength <= length; // we can possible get more than we asked.
257
255
 
258
- if (length !== 0) {
256
+ if (length === 0) {
257
+ // 1. empty (partial) chunks should not be returned by various caching / adapter layers -
258
+ // they should fall back to next layer. This might be important invariant to hold to ensure
259
+ // that we are less likely have bugs where such layer would keep returning empty partial
260
+ // result on each call.
261
+ // 2. Current invariant is that callback does retries until it gets something,
262
+ // with the goal of failing if zero data is retrieved in given amount of time.
263
+ // This is very specific property of storage / ops, so this logic is not here, but given only
264
+ // one user of this class, we assert that to catch issues earlier.
265
+ // These invariant can be relaxed if needed.
266
+ assert(
267
+ !partial,
268
+ 0x10f /* "empty/partial chunks should not be returned by caching" */,
269
+ );
270
+ assert(
271
+ !this.knewTo,
272
+ 0x110 /* "callback should retry until valid fetch before it learns new boundary" */,
273
+ );
274
+ } else {
259
275
  // We can get more than we asked for!
260
276
  // This can screw up logic in dispatch!
261
277
  // So push only batch size, and keep the rest for later - if conditions are favorable, we
@@ -274,24 +290,6 @@ export class ParallelRequests<T> {
274
290
  const data = payload.splice(0, requestedLength);
275
291
  this.results.set(from, data);
276
292
  from += data.length;
277
- } else {
278
- // 1. empty (partial) chunks should not be returned by various caching / adapter layers -
279
- // they should fall back to next layer. This might be important invariant to hold to ensure
280
- // that we are less likely have bugs where such layer would keep returning empty partial
281
- // result on each call.
282
- // 2. Current invariant is that callback does retries until it gets something,
283
- // with the goal of failing if zero data is retrieved in given amount of time.
284
- // This is very specific property of storage / ops, so this logic is not here, but given only
285
- // one user of this class, we assert that to catch issues earlier.
286
- // These invariant can be relaxed if needed.
287
- assert(
288
- !partial,
289
- 0x10f /* "empty/partial chunks should not be returned by caching" */,
290
- );
291
- assert(
292
- !this.knewTo,
293
- 0x110 /* "callback should retry until valid fetch before it learns new boundary" */,
294
- );
295
293
  }
296
294
 
297
295
  if (!partial && !fullChunk) {
@@ -319,7 +317,7 @@ export class ParallelRequests<T> {
319
317
  if (to === this.latestRequested) {
320
318
  // we can go after full chunk at the end if we received partial chunk, or more than asked
321
319
  // Also if we got more than we asked to, we can actually use those ops!
322
- while (payload.length !== 0) {
320
+ while (payload.length > 0) {
323
321
  const data = payload.splice(0, requestedLength);
324
322
  this.results.set(from, data);
325
323
  from += data.length;
@@ -358,7 +356,7 @@ export class Queue<T> implements IStream<T> {
358
356
  this.pushCore(Promise.resolve({ done: false, value }));
359
357
  }
360
358
 
361
- public pushError(error: any): void {
359
+ public pushError(error: unknown): void {
362
360
  // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
363
361
  this.pushCore(Promise.reject(error));
364
362
  this.done = true;
@@ -445,7 +443,7 @@ async function getSingleOpBatch(
445
443
 
446
444
  // If we got messages back, return them. Return regardless of whether we got messages back if we didn't
447
445
  // specify a "to", since we don't have an expectation of how many to receive.
448
- if (messages.length !== 0 || !strongTo) {
446
+ if (messages.length > 0 || !strongTo) {
449
447
  // Report this event if we waited to fetch ops due to being offline or throttling.
450
448
  telemetryEvent?.end({
451
449
  duration: totalRetryAfterTime,
@@ -670,6 +668,8 @@ export const emptyMessageStream: IStream<ISequencedDocumentMessage[]> = {
670
668
  };
671
669
 
672
670
  /**
671
+ * Creates a stream from the provided promise of messages.
672
+ *
673
673
  * @internal
674
674
  */
675
675
  export function streamFromMessages(
@@ -682,6 +682,7 @@ export function streamFromMessages(
682
682
  return { done: true };
683
683
  }
684
684
  const value = await messages;
685
+ // eslint-disable-next-line require-atomic-updates
685
686
  messages = undefined;
686
687
  return value.length === 0 ? { done: true } : { done: false, value };
687
688
  },
@@ -689,6 +690,8 @@ export function streamFromMessages(
689
690
  }
690
691
 
691
692
  /**
693
+ * Wraps the provided stream to observe values as they are read.
694
+ *
692
695
  * @internal
693
696
  */
694
697
  export function streamObserver<T>(