@fluidframework/driver-utils 0.56.7 → 0.57.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 (66) hide show
  1. package/dist/blobAggregationStorage.js.map +1 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/multiDocumentServiceFactory.d.ts.map +1 -1
  7. package/dist/multiDocumentServiceFactory.js +0 -2
  8. package/dist/multiDocumentServiceFactory.js.map +1 -1
  9. package/dist/network.d.ts +31 -9
  10. package/dist/network.d.ts.map +1 -1
  11. package/dist/network.js +7 -9
  12. package/dist/network.js.map +1 -1
  13. package/dist/networkUtils.d.ts.map +1 -1
  14. package/dist/networkUtils.js +0 -2
  15. package/dist/networkUtils.js.map +1 -1
  16. package/dist/packageVersion.d.ts +1 -1
  17. package/dist/packageVersion.js +1 -1
  18. package/dist/packageVersion.js.map +1 -1
  19. package/dist/parallelRequests.d.ts.map +1 -1
  20. package/dist/parallelRequests.js +4 -1
  21. package/dist/parallelRequests.js.map +1 -1
  22. package/dist/prefetchDocumentStorageService.d.ts.map +1 -1
  23. package/dist/prefetchDocumentStorageService.js +0 -1
  24. package/dist/prefetchDocumentStorageService.js.map +1 -1
  25. package/dist/treeConversions.d.ts +11 -0
  26. package/dist/treeConversions.d.ts.map +1 -0
  27. package/dist/treeConversions.js +66 -0
  28. package/dist/treeConversions.js.map +1 -0
  29. package/lib/blobAggregationStorage.js.map +1 -1
  30. package/lib/index.d.ts +1 -0
  31. package/lib/index.d.ts.map +1 -1
  32. package/lib/index.js +1 -0
  33. package/lib/index.js.map +1 -1
  34. package/lib/multiDocumentServiceFactory.d.ts.map +1 -1
  35. package/lib/multiDocumentServiceFactory.js +0 -2
  36. package/lib/multiDocumentServiceFactory.js.map +1 -1
  37. package/lib/network.d.ts +31 -9
  38. package/lib/network.d.ts.map +1 -1
  39. package/lib/network.js +7 -9
  40. package/lib/network.js.map +1 -1
  41. package/lib/networkUtils.d.ts.map +1 -1
  42. package/lib/networkUtils.js +0 -2
  43. package/lib/networkUtils.js.map +1 -1
  44. package/lib/packageVersion.d.ts +1 -1
  45. package/lib/packageVersion.js +1 -1
  46. package/lib/packageVersion.js.map +1 -1
  47. package/lib/parallelRequests.d.ts.map +1 -1
  48. package/lib/parallelRequests.js +4 -1
  49. package/lib/parallelRequests.js.map +1 -1
  50. package/lib/prefetchDocumentStorageService.d.ts.map +1 -1
  51. package/lib/prefetchDocumentStorageService.js +0 -1
  52. package/lib/prefetchDocumentStorageService.js.map +1 -1
  53. package/lib/treeConversions.d.ts +11 -0
  54. package/lib/treeConversions.d.ts.map +1 -0
  55. package/lib/treeConversions.js +62 -0
  56. package/lib/treeConversions.js.map +1 -0
  57. package/package.json +5 -5
  58. package/src/blobAggregationStorage.ts +2 -2
  59. package/src/index.ts +1 -0
  60. package/src/multiDocumentServiceFactory.ts +0 -2
  61. package/src/network.ts +35 -18
  62. package/src/networkUtils.ts +0 -3
  63. package/src/packageVersion.ts +1 -1
  64. package/src/parallelRequests.ts +4 -2
  65. package/src/prefetchDocumentStorageService.ts +0 -1
  66. package/src/treeConversions.ts +86 -0
@@ -0,0 +1,62 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { Uint8ArrayToString, unreachableCase, } from "@fluidframework/common-utils";
6
+ import { AttachmentTreeEntry, BlobTreeEntry, TreeTreeEntry, } from "@fluidframework/protocol-base";
7
+ import { SummaryType, } from "@fluidframework/protocol-definitions";
8
+ /**
9
+ * Converts ISummaryTree to ITree format.
10
+ * @param summaryTree - summary tree in ISummaryTree format
11
+ */
12
+ export function convertSummaryTreeToSnapshotITree(summaryTree) {
13
+ const entries = [];
14
+ const protocolSummary = summaryTree.tree[".protocol"];
15
+ const appSummary = summaryTree.tree[".app"];
16
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
17
+ const adaptSumaryTree = protocolSummary && appSummary;
18
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
19
+ const allSummaryEntries = adaptSumaryTree
20
+ ? [
21
+ ...Object.entries(protocolSummary.tree),
22
+ ...Object.entries(appSummary.tree),
23
+ ]
24
+ : Object.entries(summaryTree.tree);
25
+ for (const [key, value] of allSummaryEntries) {
26
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
27
+ const k = adaptSumaryTree && ["attributes"].includes(key) ? `.${key}` : key;
28
+ switch (value.type) {
29
+ case SummaryType.Blob: {
30
+ let parsedContent;
31
+ let encoding = "utf-8";
32
+ if (typeof value.content === "string") {
33
+ parsedContent = value.content;
34
+ }
35
+ else {
36
+ parsedContent = Uint8ArrayToString(value.content, "base64");
37
+ encoding = "base64";
38
+ }
39
+ entries.push(new BlobTreeEntry(k, parsedContent, encoding));
40
+ break;
41
+ }
42
+ case SummaryType.Tree: {
43
+ entries.push(new TreeTreeEntry(k, convertSummaryTreeToSnapshotITree(value)));
44
+ break;
45
+ }
46
+ case SummaryType.Attachment: {
47
+ entries.push(new AttachmentTreeEntry(k, value.id));
48
+ break;
49
+ }
50
+ case SummaryType.Handle: {
51
+ throw new Error("Should not have Handle type in summary tree");
52
+ }
53
+ default:
54
+ unreachableCase(value, "Unexpected summary tree type");
55
+ }
56
+ }
57
+ return {
58
+ entries,
59
+ unreferenced: summaryTree.unreferenced,
60
+ };
61
+ }
62
+ //# sourceMappingURL=treeConversions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"treeConversions.js","sourceRoot":"","sources":["../src/treeConversions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,kBAAkB,EAClB,eAAe,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,aAAa,GAChB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAIH,WAAW,GACd,MAAM,sCAAsC,CAAC;AAE9C;;;GAGG;AACH,MAAM,UAAU,iCAAiC,CAC7C,WAAyB;IAEzB,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,eAAe,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,CAAiB,CAAC;IACtE,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAiB,CAAC;IAC5D,yEAAyE;IACzE,MAAM,eAAe,GAAG,eAAe,IAAI,UAAU,CAAC;IACtD,yEAAyE;IACzE,MAAM,iBAAiB,GAAG,eAAe;QACrC,CAAC,CAAC;YACI,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;YACvC,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;SACrC;QACH,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAEvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,iBAAiB,EAAE;QAC1C,yEAAyE;QACzE,MAAM,CAAC,GAAG,eAAe,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAC5E,QAAQ,KAAK,CAAC,IAAI,EAAE;YAChB,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC;gBACnB,IAAI,aAAqB,CAAC;gBAC1B,IAAI,QAAQ,GAAuB,OAAO,CAAC;gBAC3C,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE;oBACnC,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC;iBACjC;qBAAM;oBACH,aAAa,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;oBAC5D,QAAQ,GAAG,QAAQ,CAAC;iBACvB;gBACD,OAAO,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;gBAC5D,MAAM;aACT;YAED,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC;gBACnB,OAAO,CAAC,IAAI,CACR,IAAI,aAAa,CACb,CAAC,EACD,iCAAiC,CAAC,KAAK,CAAC,CAC3C,CACJ,CAAC;gBACF,MAAM;aACT;YAED,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC;gBACzB,OAAO,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;gBACnD,MAAM;aACT;YAED,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;aAClE;YAED;gBACI,eAAe,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;SAC9D;KACJ;IACD,OAAO;QACH,OAAO;QACP,YAAY,EAAE,WAAW,CAAC,YAAY;KACzC,CAAC;AACN,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n Uint8ArrayToString,\n unreachableCase,\n} from \"@fluidframework/common-utils\";\nimport {\n AttachmentTreeEntry,\n BlobTreeEntry,\n TreeTreeEntry,\n} from \"@fluidframework/protocol-base\";\nimport {\n ISummaryTree,\n ITree,\n ITreeEntry,\n SummaryType,\n} from \"@fluidframework/protocol-definitions\";\n\n/**\n * Converts ISummaryTree to ITree format.\n * @param summaryTree - summary tree in ISummaryTree format\n */\nexport function convertSummaryTreeToSnapshotITree(\n summaryTree: ISummaryTree,\n): ITree {\n const entries: ITreeEntry[] = [];\n const protocolSummary = summaryTree.tree[\".protocol\"] as ISummaryTree;\n const appSummary = summaryTree.tree[\".app\"] as ISummaryTree;\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n const adaptSumaryTree = protocolSummary && appSummary;\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n const allSummaryEntries = adaptSumaryTree\n ? [\n ...Object.entries(protocolSummary.tree),\n ...Object.entries(appSummary.tree),\n ]\n : Object.entries(summaryTree.tree);\n\n for (const [key, value] of allSummaryEntries) {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n const k = adaptSumaryTree && [\"attributes\"].includes(key) ? `.${key}` : key;\n switch (value.type) {\n case SummaryType.Blob: {\n let parsedContent: string;\n let encoding: \"utf-8\" | \"base64\" = \"utf-8\";\n if (typeof value.content === \"string\") {\n parsedContent = value.content;\n } else {\n parsedContent = Uint8ArrayToString(value.content, \"base64\");\n encoding = \"base64\";\n }\n entries.push(new BlobTreeEntry(k, parsedContent, encoding));\n break;\n }\n\n case SummaryType.Tree: {\n entries.push(\n new TreeTreeEntry(\n k,\n convertSummaryTreeToSnapshotITree(value),\n ),\n );\n break;\n }\n\n case SummaryType.Attachment: {\n entries.push(new AttachmentTreeEntry(k, value.id));\n break;\n }\n\n case SummaryType.Handle: {\n throw new Error(\"Should not have Handle type in summary tree\");\n }\n\n default:\n unreachableCase(value, \"Unexpected summary tree type\");\n }\n }\n return {\n entries,\n unreferenced: summaryTree.unreferenced,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/driver-utils",
3
- "version": "0.56.7",
3
+ "version": "0.57.1",
4
4
  "description": "Collection of utility functions for Fluid drivers",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": "https://github.com/microsoft/FluidFramework",
@@ -62,15 +62,15 @@
62
62
  "@fluidframework/gitresources": "^0.1034.0",
63
63
  "@fluidframework/protocol-base": "^0.1034.0",
64
64
  "@fluidframework/protocol-definitions": "^0.1026.0",
65
- "@fluidframework/telemetry-utils": "^0.56.7",
65
+ "@fluidframework/telemetry-utils": "^0.57.1",
66
66
  "axios": "^0.21.2",
67
67
  "uuid": "^8.3.1"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@fluidframework/build-common": "^0.23.0",
71
- "@fluidframework/eslint-config-fluid": "^0.25.0",
72
- "@fluidframework/mocha-test-setup": "^0.56.7",
73
- "@fluidframework/runtime-utils": "^0.56.7",
71
+ "@fluidframework/eslint-config-fluid": "^0.26.0",
72
+ "@fluidframework/mocha-test-setup": "^0.57.1",
73
+ "@fluidframework/runtime-utils": "^0.57.1",
74
74
  "@microsoft/api-extractor": "^7.16.1",
75
75
  "@rushstack/eslint-config": "^2.5.1",
76
76
  "@types/mocha": "^8.2.2",
@@ -43,7 +43,7 @@ function bufferToString2(blob: ArrayBufferLike, encoding: "utf-8" | "base64"): s
43
43
  * Class responsible for aggregating smaller blobs into one and unpacking it later on.
44
44
  */
45
45
  class BlobAggregator {
46
- private readonly content: [string, string][]= [];
46
+ private readonly content: [string, string][] = [];
47
47
 
48
48
  public addBlob(key: string, content: string) {
49
49
  this.content.push([key, content]);
@@ -172,7 +172,7 @@ export class BlobAggregationStorage extends SnapshotExtractor implements IDocume
172
172
  return storage;
173
173
  }
174
174
  const mc = loggerToMonitoringContext(logger);
175
- const realAllowPackaging = mc.config.getBoolean("FluidAggregateBlobs") ?? allowPacking ?? false;
175
+ const realAllowPackaging = mc.config.getBoolean("FluidAggregateBlobs") ?? allowPacking ?? false;
176
176
 
177
177
  // Always create BlobAggregationStorage even if storage is not asking for packing.
178
178
  // This is mostly to avoid cases where future changes in policy would result in inability to
package/src/index.ts CHANGED
@@ -19,3 +19,4 @@ export * from "./prefetchDocumentStorageService";
19
19
  export * from "./networkUtils";
20
20
  export * from "./rateLimiter";
21
21
  export * from "./runWithRetry";
22
+ export * from "./treeConversions";
@@ -45,7 +45,6 @@ export class MultiDocumentServiceFactory implements IDocumentServiceFactory {
45
45
  async createDocumentService(resolvedUrl: IResolvedUrl, logger?: ITelemetryBaseLogger): Promise<IDocumentService> {
46
46
  ensureFluidResolvedUrl(resolvedUrl);
47
47
  const urlObj = parse(resolvedUrl.url);
48
- // eslint-disable-next-line no-null/no-null
49
48
  if (urlObj.protocol === undefined || urlObj.protocol === null) {
50
49
  throw new Error("No protocol provided");
51
50
  }
@@ -64,7 +63,6 @@ export class MultiDocumentServiceFactory implements IDocumentServiceFactory {
64
63
  ): Promise<IDocumentService> {
65
64
  ensureFluidResolvedUrl(createNewResolvedUrl);
66
65
  const urlObj = parse(createNewResolvedUrl.url);
67
- // eslint-disable-next-line no-null/no-null
68
66
  if (urlObj.protocol === undefined || urlObj.protocol === null) {
69
67
  throw new Error("No protocol provided");
70
68
  }
package/src/network.ts CHANGED
@@ -22,13 +22,31 @@ export enum OnlineStatus {
22
22
  // No solution for node.js (other than resolve dns names / ping specific sites)
23
23
  // Can also use window.addEventListener("online" / "offline")
24
24
  export function isOnline(): OnlineStatus {
25
- // eslint-disable-next-line no-null/no-null
26
25
  if (typeof navigator === "object" && navigator !== null && typeof navigator.onLine === "boolean") {
27
26
  return navigator.onLine ? OnlineStatus.Online : OnlineStatus.Offline;
28
27
  }
29
28
  return OnlineStatus.Unknown;
30
29
  }
31
30
 
31
+ /**
32
+ * Interface describing errors and warnings raised by any driver code.
33
+ * Not expected to be implemented by a class or an object literal, but rather used in place of
34
+ * any or unknown in various function signatures that pass errors around.
35
+ *
36
+ * "Any" in the interface name is a nod to the fact that errorType has lost its type constraint.
37
+ * It will be either DriverErrorType or the specific driver's specialized error type enum,
38
+ * but we can't reference a specific driver's error type enum in this code.
39
+ */
40
+ export interface IAnyDriverError {
41
+ readonly errorType: string;
42
+ readonly message: string;
43
+ canRetry: boolean;
44
+ online?: string;
45
+ }
46
+
47
+ /** Telemetry props with driver-specific required properties */
48
+ export type DriverErrorTelemetryProps = ITelemetryProperties & { driverVersion: string | undefined };
49
+
32
50
  /**
33
51
  * Generic network error class.
34
52
  */
@@ -39,7 +57,7 @@ export class GenericNetworkError extends LoggingError implements IDriverErrorBas
39
57
  readonly fluidErrorCode: string,
40
58
  message: string,
41
59
  readonly canRetry: boolean,
42
- props?: ITelemetryProperties,
60
+ props: DriverErrorTelemetryProps,
43
61
  ) {
44
62
  super(message, props);
45
63
  }
@@ -57,8 +75,8 @@ export class DeltaStreamConnectionForbiddenError extends LoggingError implements
57
75
  readonly errorType: string = DeltaStreamConnectionForbiddenError.errorType;
58
76
  readonly canRetry = false;
59
77
 
60
- constructor(readonly fluidErrorCode: string) {
61
- super(fluidErrorCode, { statusCode: 400 });
78
+ constructor(readonly fluidErrorCode: string, props: DriverErrorTelemetryProps) {
79
+ super(fluidErrorCode, { ...props, statusCode: 400 });
62
80
  }
63
81
  }
64
82
 
@@ -71,7 +89,7 @@ export class AuthorizationError extends LoggingError implements IAuthorizationEr
71
89
  message: string,
72
90
  readonly claims: string | undefined,
73
91
  readonly tenantId: string | undefined,
74
- props?: ITelemetryProperties,
92
+ props: DriverErrorTelemetryProps,
75
93
  ) {
76
94
  // don't log claims or tenantId
77
95
  super(message, props, new Set(["claims", "tenantId"]));
@@ -84,7 +102,7 @@ export class NetworkErrorBasic<T extends string> extends LoggingError implements
84
102
  message: string,
85
103
  readonly errorType: T,
86
104
  readonly canRetry: boolean,
87
- props?: ITelemetryProperties,
105
+ props: DriverErrorTelemetryProps,
88
106
  ) {
89
107
  super(message, props);
90
108
  }
@@ -95,7 +113,7 @@ export class NonRetryableError<T extends string> extends NetworkErrorBasic<T> {
95
113
  fluidErrorCode: string,
96
114
  message: string | undefined,
97
115
  readonly errorType: T,
98
- props?: ITelemetryProperties,
116
+ props: DriverErrorTelemetryProps,
99
117
  ) {
100
118
  super(fluidErrorCode, message ?? fluidErrorCode, errorType, false, props);
101
119
  }
@@ -106,13 +124,12 @@ export class RetryableError<T extends string> extends NetworkErrorBasic<T> {
106
124
  fluidErrorCode: string,
107
125
  message: string | undefined,
108
126
  readonly errorType: T,
109
- props?: ITelemetryProperties,
127
+ props: DriverErrorTelemetryProps,
110
128
  ) {
111
129
  super(fluidErrorCode, message ?? fluidErrorCode, errorType, true, props);
112
130
  }
113
131
  }
114
132
 
115
- //* Check
116
133
  /**
117
134
  * Throttling error class - used to communicate all throttling errors
118
135
  */
@@ -124,26 +141,26 @@ export class ThrottlingError extends LoggingError implements IThrottlingWarning,
124
141
  readonly fluidErrorCode: string,
125
142
  message: string,
126
143
  readonly retryAfterSeconds: number,
127
- props?: ITelemetryProperties,
144
+ props: DriverErrorTelemetryProps,
128
145
  ) {
129
146
  super(message, props);
130
147
  }
131
148
  }
132
149
 
133
- export const createWriteError = (fluidErrorCode: string) =>
134
- new NonRetryableError(fluidErrorCode, undefined, DriverErrorType.writeError);
150
+ export const createWriteError = (fluidErrorCode: string, props: DriverErrorTelemetryProps) =>
151
+ new NonRetryableError(fluidErrorCode, undefined, DriverErrorType.writeError, props);
135
152
 
136
153
  export function createGenericNetworkError(
137
154
  fluidErrorCode: string,
138
155
  message: string | undefined,
139
- canRetry: boolean,
140
- retryAfterMs?: number,
141
- props?: ITelemetryProperties,
156
+ retryInfo: {canRetry: boolean, retryAfterMs?: number },
157
+ props: DriverErrorTelemetryProps,
142
158
  ): ThrottlingError | GenericNetworkError {
143
- if (retryAfterMs !== undefined && canRetry) {
144
- return new ThrottlingError(fluidErrorCode, message ?? fluidErrorCode, retryAfterMs / 1000, props);
159
+ if (retryInfo.retryAfterMs !== undefined && retryInfo.canRetry) {
160
+ return new ThrottlingError(
161
+ fluidErrorCode, message ?? fluidErrorCode, retryInfo.retryAfterMs / 1000, props);
145
162
  }
146
- return new GenericNetworkError(fluidErrorCode, message ?? fluidErrorCode, canRetry, props);
163
+ return new GenericNetworkError(fluidErrorCode, message ?? fluidErrorCode, retryInfo.canRetry, props);
147
164
  }
148
165
 
149
166
  /**
@@ -12,12 +12,9 @@ export function logNetworkFailure(logger: ITelemetryLogger, event: ITelemetryErr
12
12
  if (error?.online !== undefined) {
13
13
  newEvent.online = error.online as string;
14
14
  }
15
-
16
- // eslint-disable-next-line no-null/no-null
17
15
  if (typeof navigator === "object" && navigator !== null) {
18
16
  const nav = navigator as any;
19
17
  const connection = nav.connection ?? nav.mozConnection ?? nav.webkitConnection;
20
- // eslint-disable-next-line no-null/no-null
21
18
  if (connection !== null && typeof connection === "object") {
22
19
  newEvent.connectionType = connection.type;
23
20
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/driver-utils";
9
- export const pkgVersion = "0.56.7";
9
+ export const pkgVersion = "0.57.1";
@@ -9,6 +9,8 @@ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions"
9
9
  import { IDeltasFetchResult, IStream, IStreamResult } from "@fluidframework/driver-definitions";
10
10
  import { getRetryDelayFromError, canRetryOnError, createGenericNetworkError } from "./network";
11
11
  import { waitForConnectedState, logNetworkFailure } from "./networkUtils";
12
+ // For now, this package is versioned and released in unison with the specific drivers
13
+ import { pkgVersion as driverVersion } from "./packageVersion";
12
14
 
13
15
  const MaxFetchDelayInMs = 10000;
14
16
  const MissingFetchDelayInMs = 100;
@@ -402,10 +404,10 @@ async function getSingleOpBatch(
402
404
  throw createGenericNetworkError(
403
405
  "failedToRetrieveOpsFromStorage:TooManyRetries",
404
406
  undefined,
405
- false /* canRetry */,
406
- undefined /* retryAfterSeconds */,
407
+ { canRetry: false },
407
408
  {
408
409
  retry,
410
+ driverVersion,
409
411
  ...props,
410
412
  },
411
413
  );
@@ -2,7 +2,6 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- /* eslint-disable no-null/no-null */
6
5
  import { LoaderCachingPolicy } from "@fluidframework/driver-definitions";
7
6
  import {
8
7
  ISnapshotTree,
@@ -0,0 +1,86 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ Uint8ArrayToString,
8
+ unreachableCase,
9
+ } from "@fluidframework/common-utils";
10
+ import {
11
+ AttachmentTreeEntry,
12
+ BlobTreeEntry,
13
+ TreeTreeEntry,
14
+ } from "@fluidframework/protocol-base";
15
+ import {
16
+ ISummaryTree,
17
+ ITree,
18
+ ITreeEntry,
19
+ SummaryType,
20
+ } from "@fluidframework/protocol-definitions";
21
+
22
+ /**
23
+ * Converts ISummaryTree to ITree format.
24
+ * @param summaryTree - summary tree in ISummaryTree format
25
+ */
26
+ export function convertSummaryTreeToSnapshotITree(
27
+ summaryTree: ISummaryTree,
28
+ ): ITree {
29
+ const entries: ITreeEntry[] = [];
30
+ const protocolSummary = summaryTree.tree[".protocol"] as ISummaryTree;
31
+ const appSummary = summaryTree.tree[".app"] as ISummaryTree;
32
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
33
+ const adaptSumaryTree = protocolSummary && appSummary;
34
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
35
+ const allSummaryEntries = adaptSumaryTree
36
+ ? [
37
+ ...Object.entries(protocolSummary.tree),
38
+ ...Object.entries(appSummary.tree),
39
+ ]
40
+ : Object.entries(summaryTree.tree);
41
+
42
+ for (const [key, value] of allSummaryEntries) {
43
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
44
+ const k = adaptSumaryTree && ["attributes"].includes(key) ? `.${key}` : key;
45
+ switch (value.type) {
46
+ case SummaryType.Blob: {
47
+ let parsedContent: string;
48
+ let encoding: "utf-8" | "base64" = "utf-8";
49
+ if (typeof value.content === "string") {
50
+ parsedContent = value.content;
51
+ } else {
52
+ parsedContent = Uint8ArrayToString(value.content, "base64");
53
+ encoding = "base64";
54
+ }
55
+ entries.push(new BlobTreeEntry(k, parsedContent, encoding));
56
+ break;
57
+ }
58
+
59
+ case SummaryType.Tree: {
60
+ entries.push(
61
+ new TreeTreeEntry(
62
+ k,
63
+ convertSummaryTreeToSnapshotITree(value),
64
+ ),
65
+ );
66
+ break;
67
+ }
68
+
69
+ case SummaryType.Attachment: {
70
+ entries.push(new AttachmentTreeEntry(k, value.id));
71
+ break;
72
+ }
73
+
74
+ case SummaryType.Handle: {
75
+ throw new Error("Should not have Handle type in summary tree");
76
+ }
77
+
78
+ default:
79
+ unreachableCase(value, "Unexpected summary tree type");
80
+ }
81
+ }
82
+ return {
83
+ entries,
84
+ unreferenced: summaryTree.unreferenced,
85
+ };
86
+ }