@fluidframework/driver-utils 2.0.0-dev.5.3.2.178189 → 2.0.0-dev.6.4.0.191457
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/CHANGELOG.md +28 -0
- package/README.md +4 -3
- package/dist/adapters/compression/documentServiceFactoryCompressionAdapter.js +4 -1
- package/dist/adapters/compression/documentServiceFactoryCompressionAdapter.js.map +1 -1
- package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts +18 -18
- package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts.map +1 -1
- package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js +34 -33
- package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js.map +1 -1
- package/dist/adapters/predefinedAdapters.d.ts +1 -1
- package/dist/adapters/predefinedAdapters.d.ts.map +1 -1
- package/dist/adapters/predefinedAdapters.js +4 -4
- package/dist/adapters/predefinedAdapters.js.map +1 -1
- package/dist/buildSnapshotTree.d.ts.map +1 -1
- package/dist/buildSnapshotTree.js +5 -4
- package/dist/buildSnapshotTree.js.map +1 -1
- package/dist/documentStorageServiceProxy.d.ts.map +1 -1
- package/dist/documentStorageServiceProxy.js +1 -3
- package/dist/documentStorageServiceProxy.js.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +2 -0
- package/dist/error.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/insecureUrlResolver.js +4 -6
- package/dist/insecureUrlResolver.js.map +1 -1
- package/dist/network.d.ts +1 -1
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js +11 -5
- package/dist/network.js.map +1 -1
- package/dist/networkUtils.js +3 -4
- package/dist/networkUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/parallelRequests.d.ts +2 -2
- package/dist/parallelRequests.d.ts.map +1 -1
- package/dist/parallelRequests.js +63 -45
- package/dist/parallelRequests.js.map +1 -1
- package/dist/prefetchDocumentStorageService.js +1 -1
- package/dist/prefetchDocumentStorageService.js.map +1 -1
- package/dist/rateLimiter.js +2 -2
- package/dist/rateLimiter.js.map +1 -1
- package/dist/readAndParse.js +2 -2
- package/dist/readAndParse.js.map +1 -1
- package/dist/runWithRetry.d.ts +8 -0
- package/dist/runWithRetry.d.ts.map +1 -1
- package/dist/runWithRetry.js +37 -13
- package/dist/runWithRetry.js.map +1 -1
- package/dist/summaryForCreateNew.d.ts +0 -9
- package/dist/summaryForCreateNew.d.ts.map +1 -1
- package/dist/summaryForCreateNew.js +4 -27
- package/dist/summaryForCreateNew.js.map +1 -1
- package/dist/treeConversions.d.ts.map +1 -1
- package/dist/treeConversions.js +4 -3
- package/dist/treeConversions.js.map +1 -1
- package/lib/adapters/compression/documentServiceFactoryCompressionAdapter.js +4 -1
- package/lib/adapters/compression/documentServiceFactoryCompressionAdapter.js.map +1 -1
- package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts +18 -18
- package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.d.ts.map +1 -1
- package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js +22 -21
- package/lib/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js.map +1 -1
- package/lib/adapters/predefinedAdapters.d.ts +1 -1
- package/lib/adapters/predefinedAdapters.d.ts.map +1 -1
- package/lib/adapters/predefinedAdapters.js +3 -3
- package/lib/adapters/predefinedAdapters.js.map +1 -1
- package/lib/buildSnapshotTree.d.ts.map +1 -1
- package/lib/buildSnapshotTree.js +4 -3
- package/lib/buildSnapshotTree.js.map +1 -1
- package/lib/documentStorageServiceProxy.d.ts.map +1 -1
- package/lib/documentStorageServiceProxy.js +1 -3
- package/lib/documentStorageServiceProxy.js.map +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +2 -0
- package/lib/error.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/insecureUrlResolver.js +3 -5
- package/lib/insecureUrlResolver.js.map +1 -1
- package/lib/network.d.ts +1 -1
- package/lib/network.d.ts.map +1 -1
- package/lib/network.js +14 -6
- package/lib/network.js.map +1 -1
- package/lib/networkUtils.js +3 -4
- package/lib/networkUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/parallelRequests.d.ts +2 -2
- package/lib/parallelRequests.d.ts.map +1 -1
- package/lib/parallelRequests.js +33 -15
- package/lib/parallelRequests.js.map +1 -1
- package/lib/prefetchDocumentStorageService.js +1 -1
- package/lib/prefetchDocumentStorageService.js.map +1 -1
- package/lib/rateLimiter.js +1 -1
- package/lib/rateLimiter.js.map +1 -1
- package/lib/readAndParse.js +1 -1
- package/lib/readAndParse.js.map +1 -1
- package/lib/runWithRetry.d.ts +8 -0
- package/lib/runWithRetry.d.ts.map +1 -1
- package/lib/runWithRetry.js +30 -7
- package/lib/runWithRetry.js.map +1 -1
- package/lib/summaryForCreateNew.d.ts +0 -9
- package/lib/summaryForCreateNew.d.ts.map +1 -1
- package/lib/summaryForCreateNew.js +3 -25
- package/lib/summaryForCreateNew.js.map +1 -1
- package/lib/treeConversions.d.ts.map +1 -1
- package/lib/treeConversions.js +2 -1
- package/lib/treeConversions.js.map +1 -1
- package/package.json +21 -22
- package/src/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.ts +20 -19
- package/src/adapters/predefinedAdapters.ts +5 -3
- package/src/buildSnapshotTree.ts +4 -3
- package/src/documentStorageServiceProxy.ts +0 -1
- package/src/error.ts +2 -0
- package/src/index.ts +1 -2
- package/src/insecureUrlResolver.ts +1 -1
- package/src/network.ts +9 -1
- package/src/packageVersion.ts +1 -1
- package/src/parallelRequests.ts +5 -4
- package/src/rateLimiter.ts +1 -1
- package/src/readAndParse.ts +1 -1
- package/src/runWithRetry.ts +32 -7
- package/src/summaryForCreateNew.ts +0 -31
- package/src/treeConversions.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @fluidframework/driver-utils
|
|
2
2
|
|
|
3
|
+
## 2.0.0-internal.6.3.0
|
|
4
|
+
|
|
5
|
+
Dependency updates only.
|
|
6
|
+
|
|
7
|
+
## 2.0.0-internal.6.2.0
|
|
8
|
+
|
|
9
|
+
Dependency updates only.
|
|
10
|
+
|
|
11
|
+
## 2.0.0-internal.6.1.0
|
|
12
|
+
|
|
13
|
+
Dependency updates only.
|
|
14
|
+
|
|
15
|
+
## 2.0.0-internal.6.0.0
|
|
16
|
+
|
|
17
|
+
### Major Changes
|
|
18
|
+
|
|
19
|
+
- combineAppAndProtocolSummary removed from driver-utils [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
|
|
20
|
+
|
|
21
|
+
combineAppAndProtocolSummary was deprecated in 2.0.0-internal.3.4.0 and has now been removed.
|
|
22
|
+
|
|
23
|
+
- Upgraded typescript transpilation target to ES2020 [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
|
|
24
|
+
|
|
25
|
+
Upgraded typescript transpilation target to ES2020. This is done in order to decrease the bundle sizes of Fluid Framework packages. This has provided size improvements across the board for ex. Loader, Driver, Runtime etc. Reduced bundle sizes helps to load lesser code in apps and hence also helps to improve the perf.If any app wants to target any older versions of browsers with which this target version is not compatible, then they can use packages like babel to transpile to a older target.
|
|
26
|
+
|
|
27
|
+
## 2.0.0-internal.5.4.0
|
|
28
|
+
|
|
29
|
+
Dependency updates only.
|
|
30
|
+
|
|
3
31
|
## 2.0.0-internal.5.3.0
|
|
4
32
|
|
|
5
33
|
Dependency updates only.
|
package/README.md
CHANGED
|
@@ -13,9 +13,10 @@ When taking a dependency on a Fluid Framework library, we recommend using a `^`
|
|
|
13
13
|
While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
|
|
14
14
|
library consumers should always prefer `^`.
|
|
15
15
|
|
|
16
|
-
Note that when depending on a library version of the form 2.0.0-internal.x.y.z
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
Note that when depending on a library version of the form `2.0.0-internal.x.y.z`, called the Fluid internal version scheme,
|
|
17
|
+
you must use a `>= <` dependency range (such as `>=2.0.0-internal.x.y.z <2.0.0-internal.w.0.0` where `w` is `x+1`).
|
|
18
|
+
Standard `^` and `~` ranges will not work as expected.
|
|
19
|
+
See the [@fluid-tools/version-tools](https://github.com/microsoft/FluidFramework/blob/main/build-tools/packages/version-tools/README.md)
|
|
19
20
|
package for more information including tools to convert between version schemes.
|
|
20
21
|
|
|
21
22
|
## Installation
|
|
@@ -20,7 +20,10 @@ class DocumentServiceFactoryCompressionAdapter extends documentServiceFactoryPro
|
|
|
20
20
|
// of the hack at packages/drivers/routerlicious-driver/src/createNewUtils.ts
|
|
21
21
|
// where the binary blob is converted to a string using UTF-8 encoding
|
|
22
22
|
// which is producing incorrect results for compressed data.
|
|
23
|
-
const configForInitial =
|
|
23
|
+
const configForInitial = {
|
|
24
|
+
...this._config,
|
|
25
|
+
minSizeToCompress: Number.POSITIVE_INFINITY,
|
|
26
|
+
};
|
|
24
27
|
const newAppSumary = summaryblob_1.DocumentStorageServiceCompressionAdapter.compressSummary(createNewSummary.tree[".app"], configForInitial);
|
|
25
28
|
createNewSummary.tree[".app"] = newAppSumary;
|
|
26
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentServiceFactoryCompressionAdapter.js","sourceRoot":"","sources":["../../../src/adapters/compression/documentServiceFactoryCompressionAdapter.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,mFAAgF;AAEhF,+CAAgI;AAChI,2FAAwF;AAExF,MAAa,wCAAyC,SAAQ,yDAA2B;IACxF,YACC,cAAuC,EACtB,OAAkC;QAEnD,KAAK,CAAC,cAAc,CAAC,CAAC;QAFL,YAAO,GAAP,OAAO,CAA2B;IAGpD,CAAC;IAEM,KAAK,CAAC,eAAe,CAC3B,gBAA0C,EAC1C,oBAAkC,EAClC,MAA6B,EAC7B,kBAA4B;QAE5B,IAAI,gBAAgB,KAAK,SAAS,EAAE;YACnC,gFAAgF;YAChF,oEAAoE;YACpE,6EAA6E;YAC7E,sEAAsE;YACtE,4DAA4D;YAC5D,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"documentServiceFactoryCompressionAdapter.js","sourceRoot":"","sources":["../../../src/adapters/compression/documentServiceFactoryCompressionAdapter.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,mFAAgF;AAEhF,+CAAgI;AAChI,2FAAwF;AAExF,MAAa,wCAAyC,SAAQ,yDAA2B;IACxF,YACC,cAAuC,EACtB,OAAkC;QAEnD,KAAK,CAAC,cAAc,CAAC,CAAC;QAFL,YAAO,GAAP,OAAO,CAA2B;IAGpD,CAAC;IAEM,KAAK,CAAC,eAAe,CAC3B,gBAA0C,EAC1C,oBAAkC,EAClC,MAA6B,EAC7B,kBAA4B;QAE5B,IAAI,gBAAgB,KAAK,SAAS,EAAE;YACnC,gFAAgF;YAChF,oEAAoE;YACpE,6EAA6E;YAC7E,sEAAsE;YACtE,4DAA4D;YAC5D,MAAM,gBAAgB,GAAG;gBACxB,GAAG,IAAI,CAAC,OAAO;gBACf,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;aAC3C,CAAC;YACF,MAAM,YAAY,GACjB,sDAAmD,CAAC,eAAe,CAClE,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAiB,EAC7C,gBAAgB,CAChB,CAAC;YACH,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC;SAC7C;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CACxD,gBAAgB,EAChB,oBAAoB,EACpB,MAAM,EACN,kBAAkB,CAClB,CAAC;QACF,OAAO,IAAI,qEAAiC,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACrE,CAAC;IAEM,KAAK,CAAC,qBAAqB,CAAC,WAAyB;QAC3D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAC7E,OAAO,IAAI,qEAAiC,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACrE,CAAC;CACD;AA5CD,4FA4CC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\tIResolvedUrl,\n} from \"@fluidframework/driver-definitions\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport { DocumentServiceFactoryProxy } from \"../../documentServiceFactoryProxy\";\nimport { ICompressionStorageConfig } from \"..\";\nimport { DocumentStorageServiceCompressionAdapter as DocumentStorageServiceSummaryBlobCompressionAdapter } from \"./summaryblob\";\nimport { DocumentServiceCompressionAdapter } from \"./documentServiceCompressionAdapter\";\n\nexport class DocumentServiceFactoryCompressionAdapter extends DocumentServiceFactoryProxy {\n\tconstructor(\n\t\tserviceFactory: IDocumentServiceFactory,\n\t\tprivate readonly _config: ICompressionStorageConfig,\n\t) {\n\t\tsuper(serviceFactory);\n\t}\n\n\tpublic async createContainer(\n\t\tcreateNewSummary: ISummaryTree | undefined,\n\t\tcreateNewResolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\tif (createNewSummary !== undefined) {\n\t\t\t// TODO : this is a hack to make sure that the initial summary is not compressed\n\t\t\t// We must prevent the initial summary from being compressed because\n\t\t\t// of the hack at packages/drivers/routerlicious-driver/src/createNewUtils.ts\n\t\t\t// where the binary blob is converted to a string using UTF-8 encoding\n\t\t\t// which is producing incorrect results for compressed data.\n\t\t\tconst configForInitial = {\n\t\t\t\t...this._config,\n\t\t\t\tminSizeToCompress: Number.POSITIVE_INFINITY,\n\t\t\t};\n\t\t\tconst newAppSumary =\n\t\t\t\tDocumentStorageServiceSummaryBlobCompressionAdapter.compressSummary(\n\t\t\t\t\tcreateNewSummary.tree[\".app\"] as ISummaryTree,\n\t\t\t\t\tconfigForInitial,\n\t\t\t\t);\n\t\t\tcreateNewSummary.tree[\".app\"] = newAppSumary;\n\t\t}\n\t\tconst service = await this.serviceFactory.createContainer(\n\t\t\tcreateNewSummary,\n\t\t\tcreateNewResolvedUrl,\n\t\t\tlogger,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t\treturn new DocumentServiceCompressionAdapter(service, this._config);\n\t}\n\n\tpublic async createDocumentService(resolvedUrl: IResolvedUrl): Promise<IDocumentService> {\n\t\tconst service = await this.serviceFactory.createDocumentService(resolvedUrl);\n\t\treturn new DocumentServiceCompressionAdapter(service, this._config);\n\t}\n}\n"]}
|
|
@@ -24,9 +24,9 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
24
24
|
constructor(service: IDocumentStorageService, _config: ICompressionStorageConfig);
|
|
25
25
|
get service(): IDocumentStorageService;
|
|
26
26
|
/**
|
|
27
|
-
* This method returns true if there is a compression markup byte in the blob, otherwise false
|
|
27
|
+
* This method returns `true` if there is a compression markup byte in the blob, otherwise `false`.
|
|
28
28
|
* @param blob - The blob to compress.
|
|
29
|
-
* @returns
|
|
29
|
+
* @returns `true` if there is a compression markup byte in the blob, otherwise `false`.
|
|
30
30
|
*/
|
|
31
31
|
private static hasPrefix;
|
|
32
32
|
/**
|
|
@@ -38,13 +38,13 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
38
38
|
* This method writes the given algorithm to the blob as the first byte.
|
|
39
39
|
* @param blob - The blob to write the algorithm to.
|
|
40
40
|
* @param algorithm - The algorithm to write.
|
|
41
|
-
* @returns
|
|
41
|
+
* @returns The blob with the algorithm as the first byte.
|
|
42
42
|
*/
|
|
43
43
|
private static writeAlgorithmToBlob;
|
|
44
44
|
/**
|
|
45
45
|
* This method removes the algorithm markup prefix from the blob (1 byte)
|
|
46
46
|
* @param blob - The blob to remove the prefix from.
|
|
47
|
-
* @returns
|
|
47
|
+
* @returns The blob without the prefix.
|
|
48
48
|
*/
|
|
49
49
|
private static removePrefixFromBlobIfPresent;
|
|
50
50
|
/**
|
|
@@ -52,7 +52,7 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
52
52
|
* it is just returned as is. If the parameter is string, it is converted to Uint8Array using
|
|
53
53
|
* TextEncoder.
|
|
54
54
|
* @param input - The input to convert to Uint8Array.
|
|
55
|
-
* @returns
|
|
55
|
+
* @returns The Uint8Array representation of the input.
|
|
56
56
|
*/
|
|
57
57
|
private static toBinaryArray;
|
|
58
58
|
/**
|
|
@@ -60,26 +60,26 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
60
60
|
* containing the compression algorithm.
|
|
61
61
|
* @param input - The summary object to encode.
|
|
62
62
|
* @param config - The config containing the compression algorithm.
|
|
63
|
-
* @returns
|
|
63
|
+
* @returns The summary object with the encoded blob.
|
|
64
64
|
*/
|
|
65
65
|
private static readonly blobEncoder;
|
|
66
66
|
/**
|
|
67
67
|
* This method decodes the blob inside the given summary object of the SummaryType.Blob type.
|
|
68
68
|
* @param input - The summary object to decode.
|
|
69
|
-
* @returns
|
|
69
|
+
* @returns The summary object with the decoded blob.
|
|
70
70
|
*/
|
|
71
71
|
private static readonly blobDecoder;
|
|
72
72
|
/**
|
|
73
73
|
* This method encodes the given blob according to the given config.
|
|
74
74
|
* @param file - The blob to encode.
|
|
75
75
|
* @param config - The config to use for encoding.
|
|
76
|
-
* @returns
|
|
76
|
+
* @returns The encoded blob.
|
|
77
77
|
*/
|
|
78
78
|
private static encodeBlob;
|
|
79
79
|
/**
|
|
80
80
|
* This method decodes the given blob.
|
|
81
81
|
* @param file - The blob to decode.
|
|
82
|
-
* @returns
|
|
82
|
+
* @returns The decoded blob.
|
|
83
83
|
*/
|
|
84
84
|
private static decodeBlob;
|
|
85
85
|
/**
|
|
@@ -91,7 +91,7 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
91
91
|
* @param decoder - The decoder function to use.
|
|
92
92
|
* @param config - The config to use for encoding.
|
|
93
93
|
* @param context - The summary context.
|
|
94
|
-
* @returns
|
|
94
|
+
* @returns The summary object with the encoded/decoded blob.
|
|
95
95
|
*/
|
|
96
96
|
private static recursivelyReplace;
|
|
97
97
|
/**
|
|
@@ -99,14 +99,14 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
99
99
|
* it returns the summary tree containing that blob.
|
|
100
100
|
*
|
|
101
101
|
* @param summary - The summary tree to traverse.
|
|
102
|
-
* @returns
|
|
102
|
+
* @returns The summary tree containing the metadata blob.
|
|
103
103
|
*/
|
|
104
104
|
private static findMetadataHolderSummary;
|
|
105
105
|
/**
|
|
106
106
|
* This method obtains the summary tree containing the metadata blob. It returns the content
|
|
107
107
|
* of the tree atribute.
|
|
108
108
|
* @param summary - The summary tree to traverse.
|
|
109
|
-
* @returns
|
|
109
|
+
* @returns The content of the tree attribute of the summary tree containing the metadata blob.
|
|
110
110
|
*/
|
|
111
111
|
private static getMetadataHolderTree;
|
|
112
112
|
/**
|
|
@@ -119,20 +119,20 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
119
119
|
* it checks, if the SummaryTree holder of that object also contains the compression markup blob. If it is found,
|
|
120
120
|
* it returns true, otherwise false.
|
|
121
121
|
* @param snapshot - The snapshot tree to traverse.
|
|
122
|
-
* @returns
|
|
122
|
+
* @returns True if the compression markup blob is found, otherwise false.
|
|
123
123
|
*/
|
|
124
124
|
private static hasCompressionMarkup;
|
|
125
125
|
/**
|
|
126
126
|
* This method performs compression of the blobs in the summary tree.
|
|
127
127
|
* @param summary - The summary tree to compress.
|
|
128
128
|
* @param config - The compression config.
|
|
129
|
-
* @returns
|
|
129
|
+
* @returns The compressed summary tree.
|
|
130
130
|
*/
|
|
131
131
|
static compressSummary(summary: ISummaryTree, config: ICompressionStorageConfig): ISummaryTree;
|
|
132
132
|
/**
|
|
133
133
|
* This method read blob from the storage and decompresses it if it is compressed.
|
|
134
134
|
* @param id - The id of the blob to read.
|
|
135
|
-
* @returns
|
|
135
|
+
* @returns The decompressed blob.
|
|
136
136
|
*/
|
|
137
137
|
readBlob(id: string): Promise<ArrayBufferLike>;
|
|
138
138
|
/**
|
|
@@ -141,20 +141,20 @@ export declare class DocumentStorageServiceCompressionAdapter extends DocumentSt
|
|
|
141
141
|
* algorithm byte prefix and store them.
|
|
142
142
|
* @param version - The version of the snapshot tree to load.
|
|
143
143
|
* @param scenarioName - The scenario name of the snapshot tree to load.
|
|
144
|
-
* @returns
|
|
144
|
+
* @returns The snapshot tree.
|
|
145
145
|
*/
|
|
146
146
|
getSnapshotTree(version?: IVersion | undefined, scenarioName?: string | undefined): Promise<ISnapshotTree | null>;
|
|
147
147
|
/**
|
|
148
148
|
* This method uploads the summary to the storage. It performs compression of the blobs in the summary tree.
|
|
149
149
|
* @param summary - The summary tree to upload.
|
|
150
150
|
* @param context - The summary context.
|
|
151
|
-
* @returns
|
|
151
|
+
* @returns The ID of the uploaded summary.
|
|
152
152
|
*/
|
|
153
153
|
uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string>;
|
|
154
154
|
/**
|
|
155
155
|
* This method downloads the summary from the storage and then applies decompression on the compressed blobs.
|
|
156
156
|
* @param id - The ID of the summary to be downloaded
|
|
157
|
-
* @returns
|
|
157
|
+
* @returns The summary with decompressed blobs
|
|
158
158
|
*/
|
|
159
159
|
downloadSummary(id: ISummaryHandle): Promise<ISummaryTree>;
|
|
160
160
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentStorageServiceSummaryBlobCompressionAdapter.d.ts","sourceRoot":"","sources":["../../../../src/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"documentStorageServiceSummaryBlobCompressionAdapter.d.ts","sourceRoot":"","sources":["../../../../src/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC9F,OAAO,EACN,aAAa,EAEb,cAAc,EACd,YAAY,EACZ,QAAQ,EAGR,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAA+B,MAAM,KAAK,CAAC;AAE7E,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAG3D;;;;;;;;;;GAUG;AACH,qBAAa,wCAAyC,SAAQ,2BAA2B;IAKvF,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJzB,OAAO,CAAC,qBAAqB,CAAkB;gBAG9C,OAAO,EAAE,uBAAuB,EACf,OAAO,EAAE,yBAAyB;IAKpD,IAAW,OAAO,IAAI,uBAAuB,CAE5C;IAED;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAMxB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAOpC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAmBnC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAK5C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAI5B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAoBjC;IAEF;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAgBjC;IAEF;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAwBzB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAqBzB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAoCjC;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAkBxC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAOpC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IASnC;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAsBnC;;;;;OAKG;WACW,eAAe,CAC5B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,yBAAyB,GAC/B,YAAY;IAaf;;;;OAIG;IACmB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAYpE;;;;;;;OAOG;IACmB,eAAe,CACpC,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,EAC9B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAE/B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAShC;;;;;OAKG;IACmB,wBAAwB,CAC7C,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IAQlB;;;;OAIG;IACmB,eAAe,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;CAYhF"}
|
package/dist/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.DocumentStorageServiceCompressionAdapter = exports.blobHeadersBlobName = void 0;
|
|
8
|
-
const
|
|
8
|
+
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
9
10
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
10
11
|
const lz4js_1 = require("lz4js");
|
|
11
12
|
const documentStorageServiceProxy_1 = require("../../../documentStorageServiceProxy");
|
|
@@ -33,12 +34,12 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
33
34
|
return this.internalStorageService;
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
|
-
* This method returns true if there is a compression markup byte in the blob, otherwise false
|
|
37
|
+
* This method returns `true` if there is a compression markup byte in the blob, otherwise `false`.
|
|
37
38
|
* @param blob - The blob to compress.
|
|
38
|
-
* @returns
|
|
39
|
+
* @returns `true` if there is a compression markup byte in the blob, otherwise `false`.
|
|
39
40
|
*/
|
|
40
41
|
static hasPrefix(blob) {
|
|
41
|
-
const firstByte =
|
|
42
|
+
const firstByte = client_utils_1.IsoBuffer.from(blob)[0];
|
|
42
43
|
// eslint-disable-next-line no-bitwise
|
|
43
44
|
return (firstByte & 0xf0) === 0xb0;
|
|
44
45
|
}
|
|
@@ -50,23 +51,23 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
50
51
|
return !this.hasPrefix(blob)
|
|
51
52
|
? __1.SummaryCompressionAlgorithm.None
|
|
52
53
|
: // eslint-disable-next-line no-bitwise
|
|
53
|
-
|
|
54
|
+
client_utils_1.IsoBuffer.from(blob)[0] & 0x0f;
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
57
|
* This method writes the given algorithm to the blob as the first byte.
|
|
57
58
|
* @param blob - The blob to write the algorithm to.
|
|
58
59
|
* @param algorithm - The algorithm to write.
|
|
59
|
-
* @returns
|
|
60
|
+
* @returns The blob with the algorithm as the first byte.
|
|
60
61
|
*/
|
|
61
62
|
static writeAlgorithmToBlob(blob, algorithm) {
|
|
62
63
|
if (algorithm === __1.SummaryCompressionAlgorithm.None) {
|
|
63
|
-
const firstByte =
|
|
64
|
+
const firstByte = client_utils_1.IsoBuffer.from(blob)[0];
|
|
64
65
|
// eslint-disable-next-line no-bitwise
|
|
65
66
|
if ((firstByte & 0xf0) !== 0xb0) {
|
|
66
67
|
return blob;
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
|
-
(0,
|
|
70
|
+
(0, core_utils_1.assert)(algorithm < 0x10, 0x6f5 /* Algorithm should be less than 0x10 */);
|
|
70
71
|
const blobView = new Uint8Array(blob);
|
|
71
72
|
const blobLength = blobView.length;
|
|
72
73
|
const newBlob = new Uint8Array(blobLength + 1);
|
|
@@ -74,23 +75,23 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
74
75
|
const prefix = 0xb0 | algorithm;
|
|
75
76
|
newBlob[0] = prefix;
|
|
76
77
|
newBlob.set(blobView, 1);
|
|
77
|
-
return
|
|
78
|
+
return client_utils_1.IsoBuffer.from(newBlob);
|
|
78
79
|
}
|
|
79
80
|
/**
|
|
80
81
|
* This method removes the algorithm markup prefix from the blob (1 byte)
|
|
81
82
|
* @param blob - The blob to remove the prefix from.
|
|
82
|
-
* @returns
|
|
83
|
+
* @returns The blob without the prefix.
|
|
83
84
|
*/
|
|
84
85
|
static removePrefixFromBlobIfPresent(blob) {
|
|
85
86
|
const blobView = new Uint8Array(blob);
|
|
86
|
-
return this.hasPrefix(blob) ?
|
|
87
|
+
return this.hasPrefix(blob) ? client_utils_1.IsoBuffer.from(blobView.subarray(1)) : blob;
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
90
|
* This method converts the given argument to Uint8Array. If the parameter is already Uint8Array,
|
|
90
91
|
* it is just returned as is. If the parameter is string, it is converted to Uint8Array using
|
|
91
92
|
* TextEncoder.
|
|
92
93
|
* @param input - The input to convert to Uint8Array.
|
|
93
|
-
* @returns
|
|
94
|
+
* @returns The Uint8Array representation of the input.
|
|
94
95
|
*/
|
|
95
96
|
static toBinaryArray(input) {
|
|
96
97
|
return typeof input === "string" ? new TextEncoder().encode(input) : input;
|
|
@@ -99,7 +100,7 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
99
100
|
* This method encodes the given blob according to the given config.
|
|
100
101
|
* @param file - The blob to encode.
|
|
101
102
|
* @param config - The config to use for encoding.
|
|
102
|
-
* @returns
|
|
103
|
+
* @returns The encoded blob.
|
|
103
104
|
*/
|
|
104
105
|
static encodeBlob(file, config) {
|
|
105
106
|
let maybeCompressed;
|
|
@@ -124,7 +125,7 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
124
125
|
/**
|
|
125
126
|
* This method decodes the given blob.
|
|
126
127
|
* @param file - The blob to decode.
|
|
127
|
-
* @returns
|
|
128
|
+
* @returns The decoded blob.
|
|
128
129
|
*/
|
|
129
130
|
static decodeBlob(file) {
|
|
130
131
|
let decompressed;
|
|
@@ -158,10 +159,10 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
158
159
|
* @param decoder - The decoder function to use.
|
|
159
160
|
* @param config - The config to use for encoding.
|
|
160
161
|
* @param context - The summary context.
|
|
161
|
-
* @returns
|
|
162
|
+
* @returns The summary object with the encoded/decoded blob.
|
|
162
163
|
*/
|
|
163
164
|
static recursivelyReplace(isEncode, input, encoder, decoder, config, context) {
|
|
164
|
-
(0,
|
|
165
|
+
(0, core_utils_1.assert)(typeof input === "object", 0x6f6 /* input must be a non-null object */);
|
|
165
166
|
const maybeReplaced = isEncode ? encoder(input, config) : decoder(input);
|
|
166
167
|
if (maybeReplaced !== input) {
|
|
167
168
|
return maybeReplaced;
|
|
@@ -172,22 +173,22 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
172
173
|
if (Boolean(value) && typeof value === "object") {
|
|
173
174
|
const replaced = this.recursivelyReplace(isEncode, value, encoder, decoder, config, context);
|
|
174
175
|
if (replaced !== value) {
|
|
175
|
-
clone = clone
|
|
176
|
+
clone = clone ?? (Array.isArray(input) ? [...input] : { ...input });
|
|
176
177
|
clone[key] = replaced;
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
|
-
return (clone
|
|
181
|
+
return (clone ?? input);
|
|
181
182
|
}
|
|
182
183
|
/**
|
|
183
184
|
* This method traverses the SummaryTree recursively. If it finds the ISummaryBlob object with the key '.metadata',
|
|
184
185
|
* it returns the summary tree containing that blob.
|
|
185
186
|
*
|
|
186
187
|
* @param summary - The summary tree to traverse.
|
|
187
|
-
* @returns
|
|
188
|
+
* @returns The summary tree containing the metadata blob.
|
|
188
189
|
*/
|
|
189
190
|
static findMetadataHolderSummary(summary) {
|
|
190
|
-
(0,
|
|
191
|
+
(0, core_utils_1.assert)(typeof summary === "object", 0x6f7 /* summary must be a non-null object */);
|
|
191
192
|
for (const key of Object.keys(summary.tree)) {
|
|
192
193
|
const value = summary.tree[key];
|
|
193
194
|
if (Boolean(value) && value.type === protocol_definitions_1.SummaryType.Tree) {
|
|
@@ -206,11 +207,11 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
206
207
|
* This method obtains the summary tree containing the metadata blob. It returns the content
|
|
207
208
|
* of the tree atribute.
|
|
208
209
|
* @param summary - The summary tree to traverse.
|
|
209
|
-
* @returns
|
|
210
|
+
* @returns The content of the tree attribute of the summary tree containing the metadata blob.
|
|
210
211
|
*/
|
|
211
212
|
static getMetadataHolderTree(summary) {
|
|
212
213
|
const metadataHolder = this.findMetadataHolderSummary(summary);
|
|
213
|
-
(0,
|
|
214
|
+
(0, core_utils_1.assert)(metadataHolder !== undefined, 0x6f8 /* metadataHolder must be a non-null object */);
|
|
214
215
|
const metadataHolderTree = metadataHolder.tree;
|
|
215
216
|
return metadataHolderTree;
|
|
216
217
|
}
|
|
@@ -230,10 +231,10 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
230
231
|
* it checks, if the SummaryTree holder of that object also contains the compression markup blob. If it is found,
|
|
231
232
|
* it returns true, otherwise false.
|
|
232
233
|
* @param snapshot - The snapshot tree to traverse.
|
|
233
|
-
* @returns
|
|
234
|
+
* @returns True if the compression markup blob is found, otherwise false.
|
|
234
235
|
*/
|
|
235
236
|
static hasCompressionMarkup(snapshot) {
|
|
236
|
-
(0,
|
|
237
|
+
(0, core_utils_1.assert)(typeof snapshot === "object", 0x6f9 /* snapshot must be a non-null object */);
|
|
237
238
|
for (const key of Object.keys(snapshot.blobs)) {
|
|
238
239
|
if (key === metadataBlobName) {
|
|
239
240
|
const value = snapshot.blobs[exports.blobHeadersBlobName];
|
|
@@ -257,7 +258,7 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
257
258
|
* This method performs compression of the blobs in the summary tree.
|
|
258
259
|
* @param summary - The summary tree to compress.
|
|
259
260
|
* @param config - The compression config.
|
|
260
|
-
* @returns
|
|
261
|
+
* @returns The compressed summary tree.
|
|
261
262
|
*/
|
|
262
263
|
static compressSummary(summary, config) {
|
|
263
264
|
this.putCompressionMarkup(summary);
|
|
@@ -268,7 +269,7 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
268
269
|
/**
|
|
269
270
|
* This method read blob from the storage and decompresses it if it is compressed.
|
|
270
271
|
* @param id - The id of the blob to read.
|
|
271
|
-
* @returns
|
|
272
|
+
* @returns The decompressed blob.
|
|
272
273
|
*/
|
|
273
274
|
async readBlob(id) {
|
|
274
275
|
const originalBlob = await super.readBlob(id);
|
|
@@ -287,7 +288,7 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
287
288
|
* algorithm byte prefix and store them.
|
|
288
289
|
* @param version - The version of the snapshot tree to load.
|
|
289
290
|
* @param scenarioName - The scenario name of the snapshot tree to load.
|
|
290
|
-
* @returns
|
|
291
|
+
* @returns The snapshot tree.
|
|
291
292
|
*/
|
|
292
293
|
async getSnapshotTree(version, scenarioName) {
|
|
293
294
|
const snapshotTree = await super.getSnapshotTree(version, scenarioName);
|
|
@@ -301,7 +302,7 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
301
302
|
* This method uploads the summary to the storage. It performs compression of the blobs in the summary tree.
|
|
302
303
|
* @param summary - The summary tree to upload.
|
|
303
304
|
* @param context - The summary context.
|
|
304
|
-
* @returns
|
|
305
|
+
* @returns The ID of the uploaded summary.
|
|
305
306
|
*/
|
|
306
307
|
async uploadSummaryWithContext(summary, context) {
|
|
307
308
|
const prep = DocumentStorageServiceCompressionAdapter.compressSummary(summary, this._config);
|
|
@@ -310,7 +311,7 @@ class DocumentStorageServiceCompressionAdapter extends documentStorageServicePro
|
|
|
310
311
|
/**
|
|
311
312
|
* This method downloads the summary from the storage and then applies decompression on the compressed blobs.
|
|
312
313
|
* @param id - The ID of the summary to be downloaded
|
|
313
|
-
* @returns
|
|
314
|
+
* @returns The summary with decompressed blobs
|
|
314
315
|
*/
|
|
315
316
|
async downloadSummary(id) {
|
|
316
317
|
const summary = await super.downloadSummary(id);
|
|
@@ -325,7 +326,7 @@ exports.DocumentStorageServiceCompressionAdapter = DocumentStorageServiceCompres
|
|
|
325
326
|
* containing the compression algorithm.
|
|
326
327
|
* @param input - The summary object to encode.
|
|
327
328
|
* @param config - The config containing the compression algorithm.
|
|
328
|
-
* @returns
|
|
329
|
+
* @returns The summary object with the encoded blob.
|
|
329
330
|
*/
|
|
330
331
|
DocumentStorageServiceCompressionAdapter.blobEncoder = (input, config) => {
|
|
331
332
|
if (input.type === protocol_definitions_1.SummaryType.Blob) {
|
|
@@ -334,7 +335,7 @@ DocumentStorageServiceCompressionAdapter.blobEncoder = (input, config) => {
|
|
|
334
335
|
const processed = DocumentStorageServiceCompressionAdapter.encodeBlob(original, config);
|
|
335
336
|
const newSummaryBlob = {
|
|
336
337
|
type: protocol_definitions_1.SummaryType.Blob,
|
|
337
|
-
content:
|
|
338
|
+
content: client_utils_1.IsoBuffer.from(processed),
|
|
338
339
|
};
|
|
339
340
|
return newSummaryBlob;
|
|
340
341
|
}
|
|
@@ -345,7 +346,7 @@ DocumentStorageServiceCompressionAdapter.blobEncoder = (input, config) => {
|
|
|
345
346
|
/**
|
|
346
347
|
* This method decodes the blob inside the given summary object of the SummaryType.Blob type.
|
|
347
348
|
* @param input - The summary object to decode.
|
|
348
|
-
* @returns
|
|
349
|
+
* @returns The summary object with the decoded blob.
|
|
349
350
|
*/
|
|
350
351
|
DocumentStorageServiceCompressionAdapter.blobDecoder = (input) => {
|
|
351
352
|
if (input.type === protocol_definitions_1.SummaryType.Blob) {
|
|
@@ -354,7 +355,7 @@ DocumentStorageServiceCompressionAdapter.blobDecoder = (input) => {
|
|
|
354
355
|
const processed = DocumentStorageServiceCompressionAdapter.decodeBlob(original);
|
|
355
356
|
const newSummaryBlob = {
|
|
356
357
|
type: protocol_definitions_1.SummaryType.Blob,
|
|
357
|
-
content:
|
|
358
|
+
content: client_utils_1.IsoBuffer.from(processed),
|
|
358
359
|
};
|
|
359
360
|
return newSummaryBlob;
|
|
360
361
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentStorageServiceSummaryBlobCompressionAdapter.js","sourceRoot":"","sources":["../../../../src/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IsoBuffer, assert } from \"@fluidframework/common-utils\";\nimport { IDocumentStorageService, ISummaryContext } from \"@fluidframework/driver-definitions\";\nimport {\n\tISnapshotTree,\n\tISummaryBlob,\n\tISummaryHandle,\n\tISummaryTree,\n\tIVersion,\n\tSummaryObject,\n\tSummaryType,\n} from \"@fluidframework/protocol-definitions\";\nimport { compress, decompress } from \"lz4js\";\nimport { DocumentStorageServiceProxy } from \"../../../documentStorageServiceProxy\";\nimport { ICompressionStorageConfig, SummaryCompressionAlgorithm } from \"../\";\n\nexport const blobHeadersBlobName = \".metadata.blobHeaders\";\nconst metadataBlobName = \".metadata\";\n\n/**\n * This class is a proxy for the IDocumentStorageService that compresses and decompresses blobs in the summary.\n * The identification of the compressed blobs is done by adding a compression markup blob to the summary.\n * Even if the markup blob is present, it does not mean that all blobs are compressed. The blob,\n * which is compressed also contain the compression algorithm enumerated value from the\n * SummaryCompressionAlgorithm enumeration in the first byte . If the blob is not\n * commpressed, it contains the first byte equals to SummaryCompressionAlgorithm.None .\n * In case, the markup blob is present, it is expected that the first byte of the markup blob\n * will contain the info about the compression. If the first byte is not present, it is assumed\n * that the compression is not enabled and no first prefix byte is present in the blobs.\n */\nexport class DocumentStorageServiceCompressionAdapter extends DocumentStorageServiceProxy {\n\tprivate _isCompressionEnabled: boolean = false;\n\n\tconstructor(\n\t\tservice: IDocumentStorageService,\n\t\tprivate readonly _config: ICompressionStorageConfig,\n\t) {\n\t\tsuper(service);\n\t}\n\n\tpublic get service(): IDocumentStorageService {\n\t\treturn this.internalStorageService;\n\t}\n\n\t/**\n\t * This method returns true if there is a compression markup byte in the blob, otherwise false.\n\t * @param blob - The blob to compress.\n\t * @returns - True if there is a compression markup byte in the blob, otherwise false.\n\t */\n\tprivate static hasPrefix(blob: ArrayBufferLike): boolean {\n\t\tconst firstByte = IsoBuffer.from(blob)[0];\n\t\t// eslint-disable-next-line no-bitwise\n\t\treturn (firstByte & 0xf0) === 0xb0;\n\t}\n\n\t/**\n\t * This method reads the first byte from the given blob and maps that byte to the compression algorithm.\n\t * @param blob - The maybe compressed blob.\n\t */\n\tprivate static readAlgorithmFromBlob(blob: ArrayBufferLike): number {\n\t\treturn !this.hasPrefix(blob)\n\t\t\t? SummaryCompressionAlgorithm.None\n\t\t\t: // eslint-disable-next-line no-bitwise\n\t\t\t IsoBuffer.from(blob)[0] & 0x0f;\n\t}\n\n\t/**\n\t * This method writes the given algorithm to the blob as the first byte.\n\t * @param blob - The blob to write the algorithm to.\n\t * @param algorithm - The algorithm to write.\n\t * @returns - The blob with the algorithm as the first byte.\n\t */\n\tprivate static writeAlgorithmToBlob(blob: ArrayBufferLike, algorithm: number): ArrayBufferLike {\n\t\tif (algorithm === SummaryCompressionAlgorithm.None) {\n\t\t\tconst firstByte = IsoBuffer.from(blob)[0];\n\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\tif ((firstByte & 0xf0) !== 0xb0) {\n\t\t\t\treturn blob;\n\t\t\t}\n\t\t}\n\t\tassert(algorithm < 0x10, 0x6f5 /* Algorithm should be less than 0x10 */);\n\t\tconst blobView = new Uint8Array(blob);\n\t\tconst blobLength = blobView.length;\n\t\tconst newBlob = new Uint8Array(blobLength + 1);\n\t\t// eslint-disable-next-line no-bitwise\n\t\tconst prefix = 0xb0 | algorithm;\n\t\tnewBlob[0] = prefix;\n\t\tnewBlob.set(blobView, 1);\n\t\treturn IsoBuffer.from(newBlob);\n\t}\n\n\t/**\n\t * This method removes the algorithm markup prefix from the blob (1 byte)\n\t * @param blob - The blob to remove the prefix from.\n\t * @returns - The blob without the prefix.\n\t */\n\tprivate static removePrefixFromBlobIfPresent(blob: ArrayBufferLike): ArrayBufferLike {\n\t\tconst blobView = new Uint8Array(blob);\n\t\treturn this.hasPrefix(blob) ? IsoBuffer.from(blobView.subarray(1)) : blob;\n\t}\n\n\t/**\n\t * This method converts the given argument to Uint8Array. If the parameter is already Uint8Array,\n\t * it is just returned as is. If the parameter is string, it is converted to Uint8Array using\n\t * TextEncoder.\n\t * @param input - The input to convert to Uint8Array.\n\t * @returns - The Uint8Array representation of the input.\n\t */\n\tprivate static toBinaryArray(input: string | Uint8Array): Uint8Array {\n\t\treturn typeof input === \"string\" ? new TextEncoder().encode(input) : input;\n\t}\n\n\t/**\n\t * This method encodes the blob inside the given summary object of the SummaryType.Blob type using the given config\n\t * containing the compression algorithm.\n\t * @param input - The summary object to encode.\n\t * @param config - The config containing the compression algorithm.\n\t * @returns - The summary object with the encoded blob.\n\t */\n\tprivate static readonly blobEncoder = (\n\t\tinput: SummaryObject,\n\t\tconfig: ICompressionStorageConfig,\n\t): SummaryObject => {\n\t\tif (input.type === SummaryType.Blob) {\n\t\t\tconst summaryBlob: ISummaryBlob = input;\n\t\t\tconst original: ArrayBufferLike =\n\t\t\t\tDocumentStorageServiceCompressionAdapter.toBinaryArray(summaryBlob.content);\n\t\t\tconst processed: ArrayBufferLike = DocumentStorageServiceCompressionAdapter.encodeBlob(\n\t\t\t\toriginal,\n\t\t\t\tconfig,\n\t\t\t);\n\t\t\tconst newSummaryBlob = {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: IsoBuffer.from(processed),\n\t\t\t};\n\t\t\treturn newSummaryBlob;\n\t\t} else {\n\t\t\treturn input;\n\t\t}\n\t};\n\n\t/**\n\t * This method decodes the blob inside the given summary object of the SummaryType.Blob type.\n\t * @param input - The summary object to decode.\n\t * @returns - The summary object with the decoded blob.\n\t */\n\tprivate static readonly blobDecoder = (input: SummaryObject): SummaryObject => {\n\t\tif (input.type === SummaryType.Blob) {\n\t\t\tconst summaryBlob: ISummaryBlob = input;\n\t\t\tconst original: Uint8Array = DocumentStorageServiceCompressionAdapter.toBinaryArray(\n\t\t\t\tsummaryBlob.content,\n\t\t\t);\n\t\t\tconst processed: ArrayBufferLike =\n\t\t\t\tDocumentStorageServiceCompressionAdapter.decodeBlob(original);\n\t\t\tconst newSummaryBlob = {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: IsoBuffer.from(processed),\n\t\t\t};\n\t\t\treturn newSummaryBlob;\n\t\t} else {\n\t\t\treturn input;\n\t\t}\n\t};\n\n\t/**\n\t * This method encodes the given blob according to the given config.\n\t * @param file - The blob to encode.\n\t * @param config - The config to use for encoding.\n\t * @returns - The encoded blob.\n\t */\n\tprivate static encodeBlob(\n\t\tfile: ArrayBufferLike,\n\t\tconfig: ICompressionStorageConfig,\n\t): ArrayBufferLike {\n\t\tlet maybeCompressed: ArrayBufferLike;\n\t\tlet algorithm = config.algorithm;\n\t\tif (new Uint8Array(file).length < config.minSizeToCompress) {\n\t\t\tmaybeCompressed = file;\n\t\t\talgorithm = SummaryCompressionAlgorithm.None;\n\t\t} else if (algorithm === SummaryCompressionAlgorithm.None) {\n\t\t\tmaybeCompressed = file;\n\t\t} else if (algorithm === SummaryCompressionAlgorithm.LZ4) {\n\t\t\tconst compressed = compress(file) as ArrayBufferLike;\n\t\t\tmaybeCompressed = compressed;\n\t\t} else {\n\t\t\tthrow new Error(`Unknown Algorithm ${config.algorithm}`);\n\t\t}\n\t\tmaybeCompressed = DocumentStorageServiceCompressionAdapter.writeAlgorithmToBlob(\n\t\t\tmaybeCompressed,\n\t\t\talgorithm,\n\t\t);\n\t\treturn maybeCompressed;\n\t}\n\n\t/**\n\t * This method decodes the given blob.\n\t * @param file - The blob to decode.\n\t * @returns - The decoded blob.\n\t */\n\tprivate static decodeBlob(file: ArrayBufferLike): ArrayBufferLike {\n\t\tlet decompressed: ArrayBufferLike;\n\t\tlet originalBlob;\n\t\tlet algorithm;\n\t\tif (this.hasPrefix(file)) {\n\t\t\talgorithm = DocumentStorageServiceCompressionAdapter.readAlgorithmFromBlob(file);\n\t\t\toriginalBlob = this.removePrefixFromBlobIfPresent(file);\n\t\t} else {\n\t\t\talgorithm = SummaryCompressionAlgorithm.None;\n\t\t\toriginalBlob = file;\n\t\t}\n\t\tif (algorithm === SummaryCompressionAlgorithm.None) {\n\t\t\tdecompressed = originalBlob;\n\t\t} else if (algorithm === SummaryCompressionAlgorithm.LZ4) {\n\t\t\tdecompressed = decompress(originalBlob) as ArrayBufferLike;\n\t\t} else {\n\t\t\tthrow new Error(`Unknown Algorithm ${algorithm}`);\n\t\t}\n\t\treturn decompressed;\n\t}\n\n\t/**\n\t * This method traverses the SummaryObject recursively. If it finds the ISummaryBlob object,\n\t * it applies encoding/decoding on it according to the given isEncode flag.\n\t * @param isEncode - True if the encoding should be applied, false if the decoding should be applied.\n\t * @param input - The summary object to traverse.\n\t * @param encoder - The encoder function to use.\n\t * @param decoder - The decoder function to use.\n\t * @param config - The config to use for encoding.\n\t * @param context - The summary context.\n\t * @returns - The summary object with the encoded/decoded blob.\n\t */\n\tprivate static recursivelyReplace(\n\t\tisEncode: boolean,\n\t\tinput: SummaryObject,\n\t\tencoder: (input: SummaryObject, config: ICompressionStorageConfig) => SummaryObject,\n\t\tdecoder: (input: SummaryObject) => SummaryObject,\n\t\tconfig: ICompressionStorageConfig,\n\t\tcontext?: ISummaryContext,\n\t): SummaryObject {\n\t\tassert(typeof input === \"object\", 0x6f6 /* input must be a non-null object */);\n\t\tconst maybeReplaced = isEncode ? encoder(input, config) : decoder(input);\n\n\t\tif (maybeReplaced !== input) {\n\t\t\treturn maybeReplaced;\n\t\t}\n\t\tlet clone: object | undefined;\n\t\tfor (const key of Object.keys(input)) {\n\t\t\tconst value = input[key];\n\n\t\t\tif (Boolean(value) && typeof value === \"object\") {\n\t\t\t\tconst replaced = this.recursivelyReplace(\n\t\t\t\t\tisEncode,\n\t\t\t\t\tvalue as SummaryObject,\n\t\t\t\t\tencoder,\n\t\t\t\t\tdecoder,\n\t\t\t\t\tconfig,\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t\tif (replaced !== value) {\n\t\t\t\t\tclone = clone ?? (Array.isArray(input) ? [...input] : { ...input });\n\t\t\t\t\tclone[key] = replaced;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn (clone ?? input) as SummaryObject;\n\t}\n\n\t/**\n\t * This method traverses the SummaryTree recursively. If it finds the ISummaryBlob object with the key '.metadata',\n\t * it returns the summary tree containing that blob.\n\t *\n\t * @param summary - The summary tree to traverse.\n\t * @returns - The summary tree containing the metadata blob.\n\t */\n\tprivate static findMetadataHolderSummary(summary: ISummaryTree): ISummaryTree | undefined {\n\t\tassert(typeof summary === \"object\", 0x6f7 /* summary must be a non-null object */);\n\t\tfor (const key of Object.keys(summary.tree)) {\n\t\t\tconst value = summary.tree[key];\n\n\t\t\tif (Boolean(value) && value.type === SummaryType.Tree) {\n\t\t\t\tconst found = this.findMetadataHolderSummary(value);\n\t\t\t\tif (found) {\n\t\t\t\t\treturn found;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Boolean(value) && key === metadataBlobName && value.type === SummaryType.Blob) {\n\t\t\t\treturn summary;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * This method obtains the summary tree containing the metadata blob. It returns the content\n\t * of the tree atribute.\n\t * @param summary - The summary tree to traverse.\n\t * @returns - The content of the tree attribute of the summary tree containing the metadata blob.\n\t */\n\tprivate static getMetadataHolderTree(summary: ISummaryTree) {\n\t\tconst metadataHolder = this.findMetadataHolderSummary(summary);\n\t\tassert(metadataHolder !== undefined, 0x6f8 /* metadataHolder must be a non-null object */);\n\t\tconst metadataHolderTree = metadataHolder.tree;\n\t\treturn metadataHolderTree;\n\t}\n\n\t/**\n\t * This method adds the compression markup blob to the nested summary tree containing the metadata blob.\n\t * @param summary - The top summary tree to put the compression markup blob into.\n\t */\n\tprivate static putCompressionMarkup(summary: ISummaryTree): void {\n\t\tconst metadataHolderTree =\n\t\t\tDocumentStorageServiceCompressionAdapter.getMetadataHolderTree(summary);\n\t\tmetadataHolderTree[blobHeadersBlobName] = {\n\t\t\ttype: 2,\n\t\t\tcontent: \"\",\n\t\t};\n\t}\n\n\t/**\n\t * This method traverses the SnapshotTree recursively. If it finds the ISummaryBlob object with the key '.metadata',\n\t * it checks, if the SummaryTree holder of that object also contains the compression markup blob. If it is found,\n\t * it returns true, otherwise false.\n\t * @param snapshot - The snapshot tree to traverse.\n\t * @returns - True if the compression markup blob is found, otherwise false.\n\t */\n\tprivate static hasCompressionMarkup(snapshot: ISnapshotTree): boolean {\n\t\tassert(typeof snapshot === \"object\", 0x6f9 /* snapshot must be a non-null object */);\n\t\tfor (const key of Object.keys(snapshot.blobs)) {\n\t\t\tif (key === metadataBlobName) {\n\t\t\t\tconst value = snapshot.blobs[blobHeadersBlobName];\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const key of Object.keys(snapshot.trees)) {\n\t\t\tconst value = snapshot[key] as ISnapshotTree;\n\t\t\tif (value !== undefined) {\n\t\t\t\tconst found = this.hasCompressionMarkup(value);\n\t\t\t\tif (found) {\n\t\t\t\t\treturn found;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * This method performs compression of the blobs in the summary tree.\n\t * @param summary - The summary tree to compress.\n\t * @param config - The compression config.\n\t * @returns - The compressed summary tree.\n\t */\n\tpublic static compressSummary(\n\t\tsummary: ISummaryTree,\n\t\tconfig: ICompressionStorageConfig,\n\t): ISummaryTree {\n\t\tthis.putCompressionMarkup(summary);\n\t\tconst prep = DocumentStorageServiceCompressionAdapter.recursivelyReplace(\n\t\t\ttrue,\n\t\t\tsummary,\n\t\t\tDocumentStorageServiceCompressionAdapter.blobEncoder,\n\t\t\tDocumentStorageServiceCompressionAdapter.blobDecoder,\n\t\t\tconfig,\n\t\t) as ISummaryTree;\n\t\t//\tconsole.log(`Miso summary-blob Summary Upload: ${JSON.stringify(prep).length}`);\n\t\treturn prep;\n\t}\n\n\t/**\n\t * This method read blob from the storage and decompresses it if it is compressed.\n\t * @param id - The id of the blob to read.\n\t * @returns - The decompressed blob.\n\t */\n\tpublic override async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\tconst originalBlob = await super.readBlob(id);\n\t\tif (!this._isCompressionEnabled) {\n\t\t\treturn originalBlob;\n\t\t} else {\n\t\t\tconst decompressedBlob =\n\t\t\t\tDocumentStorageServiceCompressionAdapter.decodeBlob(originalBlob);\n\t\t\t//\t\t\tconsole.log(`Miso summary-blob Blob read END : ${id} ${decompressedBlob.byteLength}`);\n\t\t\treturn decompressedBlob;\n\t\t}\n\t}\n\n\t/**\n\t * This method loads the snapshot tree from the server. It also checks, if the compression markup blob is present\n\t * and setups the compression flag accordingly. It also identifies the blobs that are not compressed and do not contain\n\t * algorithm byte prefix and store them.\n\t * @param version - The version of the snapshot tree to load.\n\t * @param scenarioName - The scenario name of the snapshot tree to load.\n\t * @returns - The snapshot tree.\n\t */\n\tpublic override async getSnapshotTree(\n\t\tversion?: IVersion | undefined,\n\t\tscenarioName?: string | undefined,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): Promise<ISnapshotTree | null> {\n\t\tconst snapshotTree = await super.getSnapshotTree(version, scenarioName);\n\t\tthis._isCompressionEnabled =\n\t\t\tsnapshotTree !== undefined &&\n\t\t\tsnapshotTree !== null &&\n\t\t\tDocumentStorageServiceCompressionAdapter.hasCompressionMarkup(snapshotTree);\n\t\treturn snapshotTree;\n\t}\n\n\t/**\n\t * This method uploads the summary to the storage. It performs compression of the blobs in the summary tree.\n\t * @param summary - The summary tree to upload.\n\t * @param context - The summary context.\n\t * @returns - The ID of the uploaded summary.\n\t */\n\tpublic override async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\tconst prep = DocumentStorageServiceCompressionAdapter.compressSummary(\n\t\t\tsummary,\n\t\t\tthis._config,\n\t\t);\n\t\treturn super.uploadSummaryWithContext(prep, context);\n\t}\n\n\t/**\n\t * This method downloads the summary from the storage and then applies decompression on the compressed blobs.\n\t * @param id - The ID of the summary to be downloaded\n\t * @returns - The summary with decompressed blobs\n\t */\n\tpublic override async downloadSummary(id: ISummaryHandle): Promise<ISummaryTree> {\n\t\tconst summary = await super.downloadSummary(id);\n\t\treturn !this._isCompressionEnabled\n\t\t\t? summary\n\t\t\t: (DocumentStorageServiceCompressionAdapter.recursivelyReplace(\n\t\t\t\t\tfalse,\n\t\t\t\t\tsummary,\n\t\t\t\t\tDocumentStorageServiceCompressionAdapter.blobEncoder,\n\t\t\t\t\tDocumentStorageServiceCompressionAdapter.blobDecoder,\n\t\t\t\t\tthis._config,\n\t\t\t ) as ISummaryTree);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentStorageServiceSummaryBlobCompressionAdapter.js","sourceRoot":"","sources":["../../../../src/adapters/compression/summaryblob/documentStorageServiceSummaryBlobCompressionAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IsoBuffer } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IDocumentStorageService, ISummaryContext } from \"@fluidframework/driver-definitions\";\nimport {\n\tISnapshotTree,\n\tISummaryBlob,\n\tISummaryHandle,\n\tISummaryTree,\n\tIVersion,\n\tSummaryObject,\n\tSummaryType,\n} from \"@fluidframework/protocol-definitions\";\nimport { compress, decompress } from \"lz4js\";\nimport { DocumentStorageServiceProxy } from \"../../../documentStorageServiceProxy\";\nimport { ICompressionStorageConfig, SummaryCompressionAlgorithm } from \"../\";\n\nexport const blobHeadersBlobName = \".metadata.blobHeaders\";\nconst metadataBlobName = \".metadata\";\n\n/**\n * This class is a proxy for the IDocumentStorageService that compresses and decompresses blobs in the summary.\n * The identification of the compressed blobs is done by adding a compression markup blob to the summary.\n * Even if the markup blob is present, it does not mean that all blobs are compressed. The blob,\n * which is compressed also contain the compression algorithm enumerated value from the\n * SummaryCompressionAlgorithm enumeration in the first byte . If the blob is not\n * commpressed, it contains the first byte equals to SummaryCompressionAlgorithm.None .\n * In case, the markup blob is present, it is expected that the first byte of the markup blob\n * will contain the info about the compression. If the first byte is not present, it is assumed\n * that the compression is not enabled and no first prefix byte is present in the blobs.\n */\nexport class DocumentStorageServiceCompressionAdapter extends DocumentStorageServiceProxy {\n\tprivate _isCompressionEnabled: boolean = false;\n\n\tconstructor(\n\t\tservice: IDocumentStorageService,\n\t\tprivate readonly _config: ICompressionStorageConfig,\n\t) {\n\t\tsuper(service);\n\t}\n\n\tpublic get service(): IDocumentStorageService {\n\t\treturn this.internalStorageService;\n\t}\n\n\t/**\n\t * This method returns `true` if there is a compression markup byte in the blob, otherwise `false`.\n\t * @param blob - The blob to compress.\n\t * @returns `true` if there is a compression markup byte in the blob, otherwise `false`.\n\t */\n\tprivate static hasPrefix(blob: ArrayBufferLike): boolean {\n\t\tconst firstByte = IsoBuffer.from(blob)[0];\n\t\t// eslint-disable-next-line no-bitwise\n\t\treturn (firstByte & 0xf0) === 0xb0;\n\t}\n\n\t/**\n\t * This method reads the first byte from the given blob and maps that byte to the compression algorithm.\n\t * @param blob - The maybe compressed blob.\n\t */\n\tprivate static readAlgorithmFromBlob(blob: ArrayBufferLike): number {\n\t\treturn !this.hasPrefix(blob)\n\t\t\t? SummaryCompressionAlgorithm.None\n\t\t\t: // eslint-disable-next-line no-bitwise\n\t\t\t IsoBuffer.from(blob)[0] & 0x0f;\n\t}\n\n\t/**\n\t * This method writes the given algorithm to the blob as the first byte.\n\t * @param blob - The blob to write the algorithm to.\n\t * @param algorithm - The algorithm to write.\n\t * @returns The blob with the algorithm as the first byte.\n\t */\n\tprivate static writeAlgorithmToBlob(blob: ArrayBufferLike, algorithm: number): ArrayBufferLike {\n\t\tif (algorithm === SummaryCompressionAlgorithm.None) {\n\t\t\tconst firstByte = IsoBuffer.from(blob)[0];\n\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\tif ((firstByte & 0xf0) !== 0xb0) {\n\t\t\t\treturn blob;\n\t\t\t}\n\t\t}\n\t\tassert(algorithm < 0x10, 0x6f5 /* Algorithm should be less than 0x10 */);\n\t\tconst blobView = new Uint8Array(blob);\n\t\tconst blobLength = blobView.length;\n\t\tconst newBlob = new Uint8Array(blobLength + 1);\n\t\t// eslint-disable-next-line no-bitwise\n\t\tconst prefix = 0xb0 | algorithm;\n\t\tnewBlob[0] = prefix;\n\t\tnewBlob.set(blobView, 1);\n\t\treturn IsoBuffer.from(newBlob);\n\t}\n\n\t/**\n\t * This method removes the algorithm markup prefix from the blob (1 byte)\n\t * @param blob - The blob to remove the prefix from.\n\t * @returns The blob without the prefix.\n\t */\n\tprivate static removePrefixFromBlobIfPresent(blob: ArrayBufferLike): ArrayBufferLike {\n\t\tconst blobView = new Uint8Array(blob);\n\t\treturn this.hasPrefix(blob) ? IsoBuffer.from(blobView.subarray(1)) : blob;\n\t}\n\n\t/**\n\t * This method converts the given argument to Uint8Array. If the parameter is already Uint8Array,\n\t * it is just returned as is. If the parameter is string, it is converted to Uint8Array using\n\t * TextEncoder.\n\t * @param input - The input to convert to Uint8Array.\n\t * @returns The Uint8Array representation of the input.\n\t */\n\tprivate static toBinaryArray(input: string | Uint8Array): Uint8Array {\n\t\treturn typeof input === \"string\" ? new TextEncoder().encode(input) : input;\n\t}\n\n\t/**\n\t * This method encodes the blob inside the given summary object of the SummaryType.Blob type using the given config\n\t * containing the compression algorithm.\n\t * @param input - The summary object to encode.\n\t * @param config - The config containing the compression algorithm.\n\t * @returns The summary object with the encoded blob.\n\t */\n\tprivate static readonly blobEncoder = (\n\t\tinput: SummaryObject,\n\t\tconfig: ICompressionStorageConfig,\n\t): SummaryObject => {\n\t\tif (input.type === SummaryType.Blob) {\n\t\t\tconst summaryBlob: ISummaryBlob = input;\n\t\t\tconst original: ArrayBufferLike =\n\t\t\t\tDocumentStorageServiceCompressionAdapter.toBinaryArray(summaryBlob.content);\n\t\t\tconst processed: ArrayBufferLike = DocumentStorageServiceCompressionAdapter.encodeBlob(\n\t\t\t\toriginal,\n\t\t\t\tconfig,\n\t\t\t);\n\t\t\tconst newSummaryBlob = {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: IsoBuffer.from(processed),\n\t\t\t};\n\t\t\treturn newSummaryBlob;\n\t\t} else {\n\t\t\treturn input;\n\t\t}\n\t};\n\n\t/**\n\t * This method decodes the blob inside the given summary object of the SummaryType.Blob type.\n\t * @param input - The summary object to decode.\n\t * @returns The summary object with the decoded blob.\n\t */\n\tprivate static readonly blobDecoder = (input: SummaryObject): SummaryObject => {\n\t\tif (input.type === SummaryType.Blob) {\n\t\t\tconst summaryBlob: ISummaryBlob = input;\n\t\t\tconst original: Uint8Array = DocumentStorageServiceCompressionAdapter.toBinaryArray(\n\t\t\t\tsummaryBlob.content,\n\t\t\t);\n\t\t\tconst processed: ArrayBufferLike =\n\t\t\t\tDocumentStorageServiceCompressionAdapter.decodeBlob(original);\n\t\t\tconst newSummaryBlob = {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: IsoBuffer.from(processed),\n\t\t\t};\n\t\t\treturn newSummaryBlob;\n\t\t} else {\n\t\t\treturn input;\n\t\t}\n\t};\n\n\t/**\n\t * This method encodes the given blob according to the given config.\n\t * @param file - The blob to encode.\n\t * @param config - The config to use for encoding.\n\t * @returns The encoded blob.\n\t */\n\tprivate static encodeBlob(\n\t\tfile: ArrayBufferLike,\n\t\tconfig: ICompressionStorageConfig,\n\t): ArrayBufferLike {\n\t\tlet maybeCompressed: ArrayBufferLike;\n\t\tlet algorithm = config.algorithm;\n\t\tif (new Uint8Array(file).length < config.minSizeToCompress) {\n\t\t\tmaybeCompressed = file;\n\t\t\talgorithm = SummaryCompressionAlgorithm.None;\n\t\t} else if (algorithm === SummaryCompressionAlgorithm.None) {\n\t\t\tmaybeCompressed = file;\n\t\t} else if (algorithm === SummaryCompressionAlgorithm.LZ4) {\n\t\t\tconst compressed = compress(file) as ArrayBufferLike;\n\t\t\tmaybeCompressed = compressed;\n\t\t} else {\n\t\t\tthrow new Error(`Unknown Algorithm ${config.algorithm}`);\n\t\t}\n\t\tmaybeCompressed = DocumentStorageServiceCompressionAdapter.writeAlgorithmToBlob(\n\t\t\tmaybeCompressed,\n\t\t\talgorithm,\n\t\t);\n\t\treturn maybeCompressed;\n\t}\n\n\t/**\n\t * This method decodes the given blob.\n\t * @param file - The blob to decode.\n\t * @returns The decoded blob.\n\t */\n\tprivate static decodeBlob(file: ArrayBufferLike): ArrayBufferLike {\n\t\tlet decompressed: ArrayBufferLike;\n\t\tlet originalBlob;\n\t\tlet algorithm;\n\t\tif (this.hasPrefix(file)) {\n\t\t\talgorithm = DocumentStorageServiceCompressionAdapter.readAlgorithmFromBlob(file);\n\t\t\toriginalBlob = this.removePrefixFromBlobIfPresent(file);\n\t\t} else {\n\t\t\talgorithm = SummaryCompressionAlgorithm.None;\n\t\t\toriginalBlob = file;\n\t\t}\n\t\tif (algorithm === SummaryCompressionAlgorithm.None) {\n\t\t\tdecompressed = originalBlob;\n\t\t} else if (algorithm === SummaryCompressionAlgorithm.LZ4) {\n\t\t\tdecompressed = decompress(originalBlob) as ArrayBufferLike;\n\t\t} else {\n\t\t\tthrow new Error(`Unknown Algorithm ${algorithm}`);\n\t\t}\n\t\treturn decompressed;\n\t}\n\n\t/**\n\t * This method traverses the SummaryObject recursively. If it finds the ISummaryBlob object,\n\t * it applies encoding/decoding on it according to the given isEncode flag.\n\t * @param isEncode - True if the encoding should be applied, false if the decoding should be applied.\n\t * @param input - The summary object to traverse.\n\t * @param encoder - The encoder function to use.\n\t * @param decoder - The decoder function to use.\n\t * @param config - The config to use for encoding.\n\t * @param context - The summary context.\n\t * @returns The summary object with the encoded/decoded blob.\n\t */\n\tprivate static recursivelyReplace(\n\t\tisEncode: boolean,\n\t\tinput: SummaryObject,\n\t\tencoder: (input: SummaryObject, config: ICompressionStorageConfig) => SummaryObject,\n\t\tdecoder: (input: SummaryObject) => SummaryObject,\n\t\tconfig: ICompressionStorageConfig,\n\t\tcontext?: ISummaryContext,\n\t): SummaryObject {\n\t\tassert(typeof input === \"object\", 0x6f6 /* input must be a non-null object */);\n\t\tconst maybeReplaced = isEncode ? encoder(input, config) : decoder(input);\n\n\t\tif (maybeReplaced !== input) {\n\t\t\treturn maybeReplaced;\n\t\t}\n\t\tlet clone: object | undefined;\n\t\tfor (const key of Object.keys(input)) {\n\t\t\tconst value = input[key];\n\n\t\t\tif (Boolean(value) && typeof value === \"object\") {\n\t\t\t\tconst replaced = this.recursivelyReplace(\n\t\t\t\t\tisEncode,\n\t\t\t\t\tvalue as SummaryObject,\n\t\t\t\t\tencoder,\n\t\t\t\t\tdecoder,\n\t\t\t\t\tconfig,\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t\tif (replaced !== value) {\n\t\t\t\t\tclone = clone ?? (Array.isArray(input) ? [...input] : { ...input });\n\t\t\t\t\tclone[key] = replaced;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn (clone ?? input) as SummaryObject;\n\t}\n\n\t/**\n\t * This method traverses the SummaryTree recursively. If it finds the ISummaryBlob object with the key '.metadata',\n\t * it returns the summary tree containing that blob.\n\t *\n\t * @param summary - The summary tree to traverse.\n\t * @returns The summary tree containing the metadata blob.\n\t */\n\tprivate static findMetadataHolderSummary(summary: ISummaryTree): ISummaryTree | undefined {\n\t\tassert(typeof summary === \"object\", 0x6f7 /* summary must be a non-null object */);\n\t\tfor (const key of Object.keys(summary.tree)) {\n\t\t\tconst value = summary.tree[key];\n\n\t\t\tif (Boolean(value) && value.type === SummaryType.Tree) {\n\t\t\t\tconst found = this.findMetadataHolderSummary(value);\n\t\t\t\tif (found) {\n\t\t\t\t\treturn found;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Boolean(value) && key === metadataBlobName && value.type === SummaryType.Blob) {\n\t\t\t\treturn summary;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * This method obtains the summary tree containing the metadata blob. It returns the content\n\t * of the tree atribute.\n\t * @param summary - The summary tree to traverse.\n\t * @returns The content of the tree attribute of the summary tree containing the metadata blob.\n\t */\n\tprivate static getMetadataHolderTree(summary: ISummaryTree) {\n\t\tconst metadataHolder = this.findMetadataHolderSummary(summary);\n\t\tassert(metadataHolder !== undefined, 0x6f8 /* metadataHolder must be a non-null object */);\n\t\tconst metadataHolderTree = metadataHolder.tree;\n\t\treturn metadataHolderTree;\n\t}\n\n\t/**\n\t * This method adds the compression markup blob to the nested summary tree containing the metadata blob.\n\t * @param summary - The top summary tree to put the compression markup blob into.\n\t */\n\tprivate static putCompressionMarkup(summary: ISummaryTree): void {\n\t\tconst metadataHolderTree =\n\t\t\tDocumentStorageServiceCompressionAdapter.getMetadataHolderTree(summary);\n\t\tmetadataHolderTree[blobHeadersBlobName] = {\n\t\t\ttype: 2,\n\t\t\tcontent: \"\",\n\t\t};\n\t}\n\n\t/**\n\t * This method traverses the SnapshotTree recursively. If it finds the ISummaryBlob object with the key '.metadata',\n\t * it checks, if the SummaryTree holder of that object also contains the compression markup blob. If it is found,\n\t * it returns true, otherwise false.\n\t * @param snapshot - The snapshot tree to traverse.\n\t * @returns True if the compression markup blob is found, otherwise false.\n\t */\n\tprivate static hasCompressionMarkup(snapshot: ISnapshotTree): boolean {\n\t\tassert(typeof snapshot === \"object\", 0x6f9 /* snapshot must be a non-null object */);\n\t\tfor (const key of Object.keys(snapshot.blobs)) {\n\t\t\tif (key === metadataBlobName) {\n\t\t\t\tconst value = snapshot.blobs[blobHeadersBlobName];\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const key of Object.keys(snapshot.trees)) {\n\t\t\tconst value = snapshot[key] as ISnapshotTree;\n\t\t\tif (value !== undefined) {\n\t\t\t\tconst found = this.hasCompressionMarkup(value);\n\t\t\t\tif (found) {\n\t\t\t\t\treturn found;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * This method performs compression of the blobs in the summary tree.\n\t * @param summary - The summary tree to compress.\n\t * @param config - The compression config.\n\t * @returns The compressed summary tree.\n\t */\n\tpublic static compressSummary(\n\t\tsummary: ISummaryTree,\n\t\tconfig: ICompressionStorageConfig,\n\t): ISummaryTree {\n\t\tthis.putCompressionMarkup(summary);\n\t\tconst prep = DocumentStorageServiceCompressionAdapter.recursivelyReplace(\n\t\t\ttrue,\n\t\t\tsummary,\n\t\t\tDocumentStorageServiceCompressionAdapter.blobEncoder,\n\t\t\tDocumentStorageServiceCompressionAdapter.blobDecoder,\n\t\t\tconfig,\n\t\t) as ISummaryTree;\n\t\t//\tconsole.log(`Miso summary-blob Summary Upload: ${JSON.stringify(prep).length}`);\n\t\treturn prep;\n\t}\n\n\t/**\n\t * This method read blob from the storage and decompresses it if it is compressed.\n\t * @param id - The id of the blob to read.\n\t * @returns The decompressed blob.\n\t */\n\tpublic override async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\tconst originalBlob = await super.readBlob(id);\n\t\tif (!this._isCompressionEnabled) {\n\t\t\treturn originalBlob;\n\t\t} else {\n\t\t\tconst decompressedBlob =\n\t\t\t\tDocumentStorageServiceCompressionAdapter.decodeBlob(originalBlob);\n\t\t\t//\t\t\tconsole.log(`Miso summary-blob Blob read END : ${id} ${decompressedBlob.byteLength}`);\n\t\t\treturn decompressedBlob;\n\t\t}\n\t}\n\n\t/**\n\t * This method loads the snapshot tree from the server. It also checks, if the compression markup blob is present\n\t * and setups the compression flag accordingly. It also identifies the blobs that are not compressed and do not contain\n\t * algorithm byte prefix and store them.\n\t * @param version - The version of the snapshot tree to load.\n\t * @param scenarioName - The scenario name of the snapshot tree to load.\n\t * @returns The snapshot tree.\n\t */\n\tpublic override async getSnapshotTree(\n\t\tversion?: IVersion | undefined,\n\t\tscenarioName?: string | undefined,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): Promise<ISnapshotTree | null> {\n\t\tconst snapshotTree = await super.getSnapshotTree(version, scenarioName);\n\t\tthis._isCompressionEnabled =\n\t\t\tsnapshotTree !== undefined &&\n\t\t\tsnapshotTree !== null &&\n\t\t\tDocumentStorageServiceCompressionAdapter.hasCompressionMarkup(snapshotTree);\n\t\treturn snapshotTree;\n\t}\n\n\t/**\n\t * This method uploads the summary to the storage. It performs compression of the blobs in the summary tree.\n\t * @param summary - The summary tree to upload.\n\t * @param context - The summary context.\n\t * @returns The ID of the uploaded summary.\n\t */\n\tpublic override async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\tconst prep = DocumentStorageServiceCompressionAdapter.compressSummary(\n\t\t\tsummary,\n\t\t\tthis._config,\n\t\t);\n\t\treturn super.uploadSummaryWithContext(prep, context);\n\t}\n\n\t/**\n\t * This method downloads the summary from the storage and then applies decompression on the compressed blobs.\n\t * @param id - The ID of the summary to be downloaded\n\t * @returns The summary with decompressed blobs\n\t */\n\tpublic override async downloadSummary(id: ISummaryHandle): Promise<ISummaryTree> {\n\t\tconst summary = await super.downloadSummary(id);\n\t\treturn !this._isCompressionEnabled\n\t\t\t? summary\n\t\t\t: (DocumentStorageServiceCompressionAdapter.recursivelyReplace(\n\t\t\t\t\tfalse,\n\t\t\t\t\tsummary,\n\t\t\t\t\tDocumentStorageServiceCompressionAdapter.blobEncoder,\n\t\t\t\t\tDocumentStorageServiceCompressionAdapter.blobDecoder,\n\t\t\t\t\tthis._config,\n\t\t\t ) as ISummaryTree);\n\t}\n}\n"]}
|
|
@@ -9,7 +9,7 @@ import { ICompressionStorageConfig } from "./compression";
|
|
|
9
9
|
* must be enabled by setting the config to true or by passing a compression config object.
|
|
10
10
|
* @param documentServiceFactory - The document service factory to apply compression to.
|
|
11
11
|
* @param config - The compression configuration.
|
|
12
|
-
* @returns
|
|
12
|
+
* @returns The document service factory possibly with compression applied.
|
|
13
13
|
*/
|
|
14
14
|
export declare function applyStorageCompression(documentServiceFactory: IDocumentServiceFactory, config?: ICompressionStorageConfig | boolean): IDocumentServiceFactory;
|
|
15
15
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predefinedAdapters.d.ts","sourceRoot":"","sources":["../../src/adapters/predefinedAdapters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAEN,yBAAyB,EAEzB,MAAM,eAAe,CAAC;AAEvB;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACtC,sBAAsB,EAAE,uBAAuB,EAC/C,MAAM,CAAC,EAAE,yBAAyB,GAAG,OAAO,GAC1C,uBAAuB,CAgBzB;
|
|
1
|
+
{"version":3,"file":"predefinedAdapters.d.ts","sourceRoot":"","sources":["../../src/adapters/predefinedAdapters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAEN,yBAAyB,EAEzB,MAAM,eAAe,CAAC;AAEvB;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACtC,sBAAsB,EAAE,uBAAuB,EAC/C,MAAM,CAAC,EAAE,yBAAyB,GAAG,OAAO,GAC1C,uBAAuB,CAgBzB;AAwBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,IAAI,yBAAyB,CAKpF"}
|