@fluidframework/driver-utils 0.56.0 → 0.57.0-51086
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.
- package/dist/blobAggregationStorage.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/multiDocumentServiceFactory.d.ts.map +1 -1
- package/dist/multiDocumentServiceFactory.js +0 -2
- package/dist/multiDocumentServiceFactory.js.map +1 -1
- package/dist/network.d.ts +31 -9
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js +7 -9
- package/dist/network.js.map +1 -1
- package/dist/networkUtils.d.ts.map +1 -1
- package/dist/networkUtils.js +0 -2
- package/dist/networkUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/parallelRequests.d.ts.map +1 -1
- package/dist/parallelRequests.js +4 -1
- package/dist/parallelRequests.js.map +1 -1
- package/dist/prefetchDocumentStorageService.d.ts.map +1 -1
- package/dist/prefetchDocumentStorageService.js +0 -1
- package/dist/prefetchDocumentStorageService.js.map +1 -1
- package/dist/treeConversions.d.ts +11 -0
- package/dist/treeConversions.d.ts.map +1 -0
- package/dist/treeConversions.js +66 -0
- package/dist/treeConversions.js.map +1 -0
- package/lib/blobAggregationStorage.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/multiDocumentServiceFactory.d.ts.map +1 -1
- package/lib/multiDocumentServiceFactory.js +0 -2
- package/lib/multiDocumentServiceFactory.js.map +1 -1
- package/lib/network.d.ts +31 -9
- package/lib/network.d.ts.map +1 -1
- package/lib/network.js +7 -9
- package/lib/network.js.map +1 -1
- package/lib/networkUtils.d.ts.map +1 -1
- package/lib/networkUtils.js +0 -2
- package/lib/networkUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/parallelRequests.d.ts.map +1 -1
- package/lib/parallelRequests.js +4 -1
- package/lib/parallelRequests.js.map +1 -1
- package/lib/prefetchDocumentStorageService.d.ts.map +1 -1
- package/lib/prefetchDocumentStorageService.js +0 -1
- package/lib/prefetchDocumentStorageService.js.map +1 -1
- package/lib/treeConversions.d.ts +11 -0
- package/lib/treeConversions.d.ts.map +1 -0
- package/lib/treeConversions.js +62 -0
- package/lib/treeConversions.js.map +1 -0
- package/package.json +5 -5
- package/src/blobAggregationStorage.ts +2 -2
- package/src/index.ts +1 -0
- package/src/multiDocumentServiceFactory.ts +0 -2
- package/src/network.ts +35 -18
- package/src/networkUtils.ts +0 -3
- package/src/packageVersion.ts +1 -1
- package/src/parallelRequests.ts +4 -2
- package/src/prefetchDocumentStorageService.ts +0 -1
- 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.
|
|
3
|
+
"version": "0.57.0-51086",
|
|
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": "
|
|
65
|
+
"@fluidframework/telemetry-utils": "0.57.0-51086",
|
|
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.
|
|
72
|
-
"@fluidframework/mocha-test-setup": "
|
|
73
|
-
"@fluidframework/runtime-utils": "
|
|
71
|
+
"@fluidframework/eslint-config-fluid": "^0.26.0-0",
|
|
72
|
+
"@fluidframework/mocha-test-setup": "0.57.0-51086",
|
|
73
|
+
"@fluidframework/runtime-utils": "0.57.0-51086",
|
|
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") ??
|
|
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
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
/**
|
package/src/networkUtils.ts
CHANGED
|
@@ -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
|
}
|
package/src/packageVersion.ts
CHANGED
package/src/parallelRequests.ts
CHANGED
|
@@ -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
|
-
|
|
406
|
-
undefined /* retryAfterSeconds */,
|
|
407
|
+
{ canRetry: false },
|
|
407
408
|
{
|
|
408
409
|
retry,
|
|
410
|
+
driverVersion,
|
|
409
411
|
...props,
|
|
410
412
|
},
|
|
411
413
|
);
|
|
@@ -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
|
+
}
|