@fluidframework/routerlicious-driver 1.4.0-115997 → 2.0.0-dev-rc.1.0.0.224419
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/.eslintrc.js +10 -12
- package/.mocharc.js +12 -0
- package/CHANGELOG.md +156 -0
- package/README.md +39 -1
- package/api-extractor-lint.json +4 -0
- package/api-extractor.json +2 -2
- package/api-report/routerlicious-driver.api.md +108 -0
- package/dist/cache.cjs +30 -0
- package/dist/cache.cjs.map +1 -0
- package/dist/cache.d.ts +7 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/{definitions.js → contracts.cjs} +1 -1
- package/dist/contracts.cjs.map +1 -0
- package/dist/contracts.d.ts +42 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/{createNewUtils.js → createNewUtils.cjs} +7 -5
- package/dist/createNewUtils.cjs.map +1 -0
- package/dist/createNewUtils.d.ts +1 -1
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/{defaultTokenProvider.js → defaultTokenProvider.cjs} +2 -1
- package/dist/defaultTokenProvider.cjs.map +1 -0
- package/dist/defaultTokenProvider.d.ts +1 -0
- package/dist/defaultTokenProvider.d.ts.map +1 -1
- package/dist/definitions.cjs +7 -0
- package/dist/definitions.cjs.map +1 -0
- package/dist/definitions.d.ts.map +1 -1
- package/dist/deltaStorageService.cjs +122 -0
- package/dist/deltaStorageService.cjs.map +1 -0
- package/dist/deltaStorageService.d.ts +7 -6
- package/dist/deltaStorageService.d.ts.map +1 -1
- package/dist/{documentDeltaConnection.js → documentDeltaConnection.cjs} +8 -13
- package/dist/documentDeltaConnection.cjs.map +1 -0
- package/dist/documentDeltaConnection.d.ts +3 -4
- package/dist/documentDeltaConnection.d.ts.map +1 -1
- package/dist/{documentService.js → documentService.cjs} +61 -64
- package/dist/documentService.cjs.map +1 -0
- package/dist/documentService.d.ts +12 -4
- package/dist/documentService.d.ts.map +1 -1
- package/dist/{documentServiceFactory.js → documentServiceFactory.cjs} +87 -33
- package/dist/documentServiceFactory.cjs.map +1 -0
- package/dist/documentServiceFactory.d.ts +5 -3
- package/dist/documentServiceFactory.d.ts.map +1 -1
- package/dist/{documentStorageService.js → documentStorageService.cjs} +18 -16
- package/dist/documentStorageService.cjs.map +1 -0
- package/dist/documentStorageService.d.ts +4 -3
- package/dist/documentStorageService.d.ts.map +1 -1
- package/dist/errorUtils.cjs +87 -0
- package/dist/errorUtils.cjs.map +1 -0
- package/dist/errorUtils.d.ts +56 -10
- package/dist/errorUtils.d.ts.map +1 -1
- package/dist/gitManager.cjs +46 -0
- package/dist/gitManager.cjs.map +1 -0
- package/dist/gitManager.d.ts +27 -0
- package/dist/gitManager.d.ts.map +1 -0
- package/dist/historian.cjs +72 -0
- package/dist/historian.cjs.map +1 -0
- package/dist/historian.d.ts +34 -0
- package/dist/historian.d.ts.map +1 -0
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +5 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/mapWithExpiration.cjs +105 -0
- package/dist/mapWithExpiration.cjs.map +1 -0
- package/dist/mapWithExpiration.d.ts +34 -0
- package/dist/mapWithExpiration.d.ts.map +1 -0
- package/dist/{nullBlobStorageService.js → nullBlobStorageService.cjs} +5 -5
- package/dist/nullBlobStorageService.cjs.map +1 -0
- package/dist/nullBlobStorageService.d.ts.map +1 -1
- package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
- package/dist/packageVersion.cjs.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/{policies.js → policies.cjs} +1 -1
- package/dist/policies.cjs.map +1 -0
- package/dist/policies.d.ts +22 -9
- package/dist/policies.d.ts.map +1 -1
- package/dist/r11sSnapshotParser.cjs +73 -0
- package/dist/r11sSnapshotParser.cjs.map +1 -0
- package/dist/r11sSnapshotParser.d.ts +14 -0
- package/dist/r11sSnapshotParser.d.ts.map +1 -0
- package/dist/restWrapper.cjs +249 -0
- package/dist/restWrapper.cjs.map +1 -0
- package/dist/restWrapper.d.ts +32 -12
- package/dist/restWrapper.d.ts.map +1 -1
- package/dist/restWrapperBase.cjs +89 -0
- package/dist/restWrapperBase.cjs.map +1 -0
- package/dist/restWrapperBase.d.ts +26 -0
- package/dist/restWrapperBase.d.ts.map +1 -0
- package/dist/retriableGitManager.cjs +40 -0
- package/dist/retriableGitManager.cjs.map +1 -0
- package/dist/retriableGitManager.d.ts +13 -23
- package/dist/retriableGitManager.d.ts.map +1 -1
- package/dist/routerlicious-driver-alpha.d.ts +92 -0
- package/dist/routerlicious-driver-beta.d.ts +98 -0
- package/dist/routerlicious-driver-public.d.ts +98 -0
- package/dist/routerlicious-driver-untrimmed.d.ts +261 -0
- package/dist/{shreddedSummaryDocumentStorageService.js → shreddedSummaryDocumentStorageService.cjs} +41 -34
- package/dist/shreddedSummaryDocumentStorageService.cjs.map +1 -0
- package/dist/shreddedSummaryDocumentStorageService.d.ts +6 -5
- package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/storageContracts.cjs +7 -0
- package/dist/storageContracts.cjs.map +1 -0
- package/dist/storageContracts.d.ts +45 -0
- package/dist/storageContracts.d.ts.map +1 -0
- package/dist/summaryTreeUploadManager.cjs +110 -0
- package/dist/summaryTreeUploadManager.cjs.map +1 -0
- package/dist/summaryTreeUploadManager.d.ts +23 -0
- package/dist/summaryTreeUploadManager.d.ts.map +1 -0
- package/dist/{tokens.js → tokens.cjs} +1 -1
- package/dist/tokens.cjs.map +1 -0
- package/dist/tokens.d.ts +34 -5
- package/dist/tokens.d.ts.map +1 -1
- package/dist/treeUtils.cjs +107 -0
- package/dist/treeUtils.cjs.map +1 -0
- package/dist/treeUtils.d.ts +58 -0
- package/dist/treeUtils.d.ts.map +1 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/{urlUtils.js → urlUtils.cjs} +21 -25
- package/dist/urlUtils.cjs.map +1 -0
- package/dist/urlUtils.d.ts +2 -2
- package/dist/urlUtils.d.ts.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.cjs +253 -0
- package/dist/wholeSummaryDocumentStorageService.cjs.map +1 -0
- package/dist/wholeSummaryDocumentStorageService.d.ts +10 -8
- package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/wholeSummaryUploadManager.cjs +37 -0
- package/dist/wholeSummaryUploadManager.cjs.map +1 -0
- package/dist/wholeSummaryUploadManager.d.ts +16 -0
- package/dist/wholeSummaryUploadManager.d.ts.map +1 -0
- package/lib/{cache.d.ts → cache.d.mts} +7 -0
- package/lib/cache.d.mts.map +1 -0
- package/lib/cache.mjs +25 -0
- package/lib/cache.mjs.map +1 -0
- package/lib/contracts.d.mts +42 -0
- package/lib/contracts.d.mts.map +1 -0
- package/lib/{definitions.js → contracts.mjs} +1 -1
- package/lib/contracts.mjs.map +1 -0
- package/lib/{createNewUtils.d.ts → createNewUtils.d.mts} +1 -1
- package/lib/{createNewUtils.d.ts.map → createNewUtils.d.mts.map} +1 -1
- package/lib/{createNewUtils.js → createNewUtils.mjs} +7 -5
- package/lib/createNewUtils.mjs.map +1 -0
- package/lib/{defaultTokenProvider.d.ts → defaultTokenProvider.d.mts} +2 -1
- package/lib/defaultTokenProvider.d.mts.map +1 -0
- package/lib/{defaultTokenProvider.js → defaultTokenProvider.mjs} +2 -1
- package/lib/defaultTokenProvider.mjs.map +1 -0
- package/lib/definitions.d.mts.map +1 -0
- package/lib/definitions.mjs +6 -0
- package/{dist/definitions.js.map → lib/definitions.mjs.map} +1 -1
- package/lib/{deltaStorageService.d.ts → deltaStorageService.d.mts} +8 -7
- package/lib/deltaStorageService.d.mts.map +1 -0
- package/lib/deltaStorageService.mjs +117 -0
- package/lib/deltaStorageService.mjs.map +1 -0
- package/lib/{documentDeltaConnection.d.ts → documentDeltaConnection.d.mts} +3 -4
- package/lib/documentDeltaConnection.d.mts.map +1 -0
- package/lib/{documentDeltaConnection.js → documentDeltaConnection.mjs} +8 -13
- package/lib/documentDeltaConnection.mjs.map +1 -0
- package/lib/{documentService.d.ts → documentService.d.mts} +16 -8
- package/lib/documentService.d.mts.map +1 -0
- package/lib/{documentService.js → documentService.mjs} +60 -44
- package/lib/documentService.mjs.map +1 -0
- package/lib/{documentServiceFactory.d.ts → documentServiceFactory.d.mts} +7 -5
- package/lib/documentServiceFactory.d.mts.map +1 -0
- package/lib/{documentServiceFactory.js → documentServiceFactory.mjs} +88 -34
- package/lib/documentServiceFactory.mjs.map +1 -0
- package/lib/{documentStorageService.d.ts → documentStorageService.d.mts} +7 -6
- package/lib/documentStorageService.d.mts.map +1 -0
- package/lib/{documentStorageService.js → documentStorageService.mjs} +19 -17
- package/lib/documentStorageService.mjs.map +1 -0
- package/lib/errorUtils.d.mts +93 -0
- package/lib/errorUtils.d.mts.map +1 -0
- package/lib/errorUtils.mjs +81 -0
- package/lib/errorUtils.mjs.map +1 -0
- package/lib/gitManager.d.mts +27 -0
- package/lib/gitManager.d.mts.map +1 -0
- package/lib/gitManager.mjs +42 -0
- package/lib/gitManager.mjs.map +1 -0
- package/lib/historian.d.mts +34 -0
- package/lib/historian.d.mts.map +1 -0
- package/lib/historian.mjs +67 -0
- package/lib/historian.mjs.map +1 -0
- package/lib/index.d.mts +10 -0
- package/lib/index.d.mts.map +1 -0
- package/lib/index.mjs +8 -0
- package/lib/index.mjs.map +1 -0
- package/lib/mapWithExpiration.d.mts +34 -0
- package/lib/mapWithExpiration.d.mts.map +1 -0
- package/lib/mapWithExpiration.mjs +101 -0
- package/lib/mapWithExpiration.mjs.map +1 -0
- package/lib/nullBlobStorageService.d.mts.map +1 -0
- package/lib/{nullBlobStorageService.js → nullBlobStorageService.mjs} +5 -5
- package/lib/nullBlobStorageService.mjs.map +1 -0
- package/lib/{packageVersion.d.ts → packageVersion.d.mts} +1 -1
- package/lib/{packageVersion.d.ts.map → packageVersion.d.mts.map} +1 -1
- package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
- package/lib/packageVersion.mjs.map +1 -0
- package/lib/{policies.d.ts → policies.d.mts} +22 -9
- package/lib/policies.d.mts.map +1 -0
- package/lib/{policies.js → policies.mjs} +1 -1
- package/lib/policies.mjs.map +1 -0
- package/lib/r11sSnapshotParser.d.mts +14 -0
- package/lib/r11sSnapshotParser.d.mts.map +1 -0
- package/lib/r11sSnapshotParser.mjs +69 -0
- package/lib/r11sSnapshotParser.mjs.map +1 -0
- package/lib/restWrapper.d.mts +53 -0
- package/lib/restWrapper.d.mts.map +1 -0
- package/lib/restWrapper.mjs +236 -0
- package/lib/restWrapper.mjs.map +1 -0
- package/lib/restWrapperBase.d.mts +26 -0
- package/lib/restWrapperBase.d.mts.map +1 -0
- package/lib/restWrapperBase.mjs +84 -0
- package/lib/restWrapperBase.mjs.map +1 -0
- package/lib/retriableGitManager.d.mts +24 -0
- package/lib/retriableGitManager.d.mts.map +1 -0
- package/lib/retriableGitManager.mjs +36 -0
- package/lib/retriableGitManager.mjs.map +1 -0
- package/lib/routerlicious-driver-alpha.d.mts +92 -0
- package/lib/routerlicious-driver-beta.d.mts +98 -0
- package/lib/routerlicious-driver-public.d.mts +98 -0
- package/lib/routerlicious-driver-untrimmed.d.mts +261 -0
- package/lib/{shreddedSummaryDocumentStorageService.d.ts → shreddedSummaryDocumentStorageService.d.mts} +9 -8
- package/lib/shreddedSummaryDocumentStorageService.d.mts.map +1 -0
- package/lib/{shreddedSummaryDocumentStorageService.js → shreddedSummaryDocumentStorageService.mjs} +41 -34
- package/lib/shreddedSummaryDocumentStorageService.mjs.map +1 -0
- package/lib/storageContracts.d.mts +45 -0
- package/lib/storageContracts.d.mts.map +1 -0
- package/lib/storageContracts.mjs +6 -0
- package/lib/storageContracts.mjs.map +1 -0
- package/lib/summaryTreeUploadManager.d.mts +23 -0
- package/lib/summaryTreeUploadManager.d.mts.map +1 -0
- package/lib/summaryTreeUploadManager.mjs +106 -0
- package/lib/summaryTreeUploadManager.mjs.map +1 -0
- package/lib/{tokens.d.ts → tokens.d.mts} +34 -5
- package/lib/tokens.d.mts.map +1 -0
- package/lib/{tokens.js → tokens.mjs} +1 -1
- package/lib/tokens.mjs.map +1 -0
- package/lib/treeUtils.d.mts +58 -0
- package/lib/treeUtils.d.mts.map +1 -0
- package/lib/treeUtils.mjs +100 -0
- package/lib/treeUtils.mjs.map +1 -0
- package/lib/{urlUtils.d.ts → urlUtils.d.mts} +2 -2
- package/lib/urlUtils.d.mts.map +1 -0
- package/lib/urlUtils.mjs +38 -0
- package/lib/urlUtils.mjs.map +1 -0
- package/lib/{wholeSummaryDocumentStorageService.d.ts → wholeSummaryDocumentStorageService.d.mts} +12 -10
- package/lib/wholeSummaryDocumentStorageService.d.mts.map +1 -0
- package/lib/wholeSummaryDocumentStorageService.mjs +249 -0
- package/lib/wholeSummaryDocumentStorageService.mjs.map +1 -0
- package/lib/wholeSummaryUploadManager.d.mts +16 -0
- package/lib/wholeSummaryUploadManager.d.mts.map +1 -0
- package/lib/wholeSummaryUploadManager.mjs +33 -0
- package/lib/wholeSummaryUploadManager.mjs.map +1 -0
- package/package.json +104 -68
- package/prettier.config.cjs +8 -0
- package/src/cache.ts +25 -9
- package/src/contracts.ts +60 -0
- package/src/createNewUtils.ts +26 -24
- package/src/defaultTokenProvider.ts +14 -15
- package/src/definitions.ts +2 -2
- package/src/deltaStorageService.ts +145 -91
- package/src/documentDeltaConnection.ts +54 -52
- package/src/documentService.ts +272 -242
- package/src/documentServiceFactory.ts +338 -237
- package/src/documentStorageService.ts +92 -84
- package/src/errorUtils.ts +117 -79
- package/src/gitManager.ts +67 -0
- package/src/historian.ts +121 -0
- package/src/index.ts +15 -8
- package/src/mapWithExpiration.ts +124 -0
- package/src/nullBlobStorageService.ts +24 -21
- package/src/packageVersion.ts +1 -1
- package/src/policies.ts +51 -38
- package/src/r11sSnapshotParser.ts +82 -0
- package/src/restWrapper.ts +400 -216
- package/src/restWrapperBase.ts +146 -0
- package/src/retriableGitManager.ts +76 -153
- package/src/shreddedSummaryDocumentStorageService.ts +214 -195
- package/src/storageContracts.ts +63 -0
- package/src/summaryTreeUploadManager.ts +155 -0
- package/src/tokens.ts +74 -39
- package/src/treeUtils.ts +138 -0
- package/src/urlUtils.ts +27 -28
- package/src/wholeSummaryDocumentStorageService.ts +352 -252
- package/src/wholeSummaryUploadManager.ts +64 -0
- package/tsc-multi.test.json +4 -0
- package/tsconfig.json +10 -13
- package/dist/cache.js +0 -20
- package/dist/cache.js.map +0 -1
- package/dist/createNewUtils.js.map +0 -1
- package/dist/defaultTokenProvider.js.map +0 -1
- package/dist/deltaStorageService.js +0 -82
- package/dist/deltaStorageService.js.map +0 -1
- package/dist/documentDeltaConnection.js.map +0 -1
- package/dist/documentService.js.map +0 -1
- package/dist/documentServiceFactory.js.map +0 -1
- package/dist/documentStorageService.js.map +0 -1
- package/dist/errorUtils.js +0 -56
- package/dist/errorUtils.js.map +0 -1
- package/dist/index.js +0 -25
- package/dist/index.js.map +0 -1
- package/dist/nullBlobStorageService.js.map +0 -1
- package/dist/packageVersion.js.map +0 -1
- package/dist/policies.js.map +0 -1
- package/dist/restWrapper.js +0 -153
- package/dist/restWrapper.js.map +0 -1
- package/dist/retriableGitManager.js +0 -76
- package/dist/retriableGitManager.js.map +0 -1
- package/dist/shreddedSummaryDocumentStorageService.js.map +0 -1
- package/dist/tokens.js.map +0 -1
- package/dist/urlUtils.js.map +0 -1
- package/dist/wholeSummaryDocumentStorageService.js +0 -191
- package/dist/wholeSummaryDocumentStorageService.js.map +0 -1
- package/lib/cache.d.ts.map +0 -1
- package/lib/cache.js +0 -16
- package/lib/cache.js.map +0 -1
- package/lib/createNewUtils.js.map +0 -1
- package/lib/defaultTokenProvider.d.ts.map +0 -1
- package/lib/defaultTokenProvider.js.map +0 -1
- package/lib/definitions.d.ts.map +0 -1
- package/lib/definitions.js.map +0 -1
- package/lib/deltaStorageService.d.ts.map +0 -1
- package/lib/deltaStorageService.js +0 -77
- package/lib/deltaStorageService.js.map +0 -1
- package/lib/documentDeltaConnection.d.ts.map +0 -1
- package/lib/documentDeltaConnection.js.map +0 -1
- package/lib/documentService.d.ts.map +0 -1
- package/lib/documentService.js.map +0 -1
- package/lib/documentServiceFactory.d.ts.map +0 -1
- package/lib/documentServiceFactory.js.map +0 -1
- package/lib/documentStorageService.d.ts.map +0 -1
- package/lib/documentStorageService.js.map +0 -1
- package/lib/errorUtils.d.ts +0 -47
- package/lib/errorUtils.d.ts.map +0 -1
- package/lib/errorUtils.js +0 -50
- package/lib/errorUtils.js.map +0 -1
- package/lib/index.d.ts +0 -13
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -13
- package/lib/index.js.map +0 -1
- package/lib/nullBlobStorageService.d.ts.map +0 -1
- package/lib/nullBlobStorageService.js.map +0 -1
- package/lib/packageVersion.js.map +0 -1
- package/lib/policies.d.ts.map +0 -1
- package/lib/policies.js.map +0 -1
- package/lib/restWrapper.d.ts +0 -33
- package/lib/restWrapper.d.ts.map +0 -1
- package/lib/restWrapper.js +0 -144
- package/lib/restWrapper.js.map +0 -1
- package/lib/retriableGitManager.d.ts +0 -34
- package/lib/retriableGitManager.d.ts.map +0 -1
- package/lib/retriableGitManager.js +0 -72
- package/lib/retriableGitManager.js.map +0 -1
- package/lib/shreddedSummaryDocumentStorageService.d.ts.map +0 -1
- package/lib/shreddedSummaryDocumentStorageService.js.map +0 -1
- package/lib/tokens.d.ts.map +0 -1
- package/lib/tokens.js.map +0 -1
- package/lib/urlUtils.d.ts.map +0 -1
- package/lib/urlUtils.js +0 -42
- package/lib/urlUtils.js.map +0 -1
- package/lib/wholeSummaryDocumentStorageService.d.ts.map +0 -1
- package/lib/wholeSummaryDocumentStorageService.js +0 -187
- package/lib/wholeSummaryDocumentStorageService.js.map +0 -1
- package/tsconfig.esnext.json +0 -7
- /package/lib/{definitions.d.ts → definitions.d.mts} +0 -0
- /package/lib/{nullBlobStorageService.d.ts → nullBlobStorageService.d.mts} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { assert } from "@fluidframework/core-utils";
|
|
6
|
+
/**
|
|
7
|
+
* An extension of Map that expires (deletes) entries after a period of inactivity.
|
|
8
|
+
* The policy is based on the last time a key was written to.
|
|
9
|
+
*/
|
|
10
|
+
export class MapWithExpiration extends Map {
|
|
11
|
+
constructor(expiryMs) {
|
|
12
|
+
super();
|
|
13
|
+
this.expiryMs = expiryMs;
|
|
14
|
+
/** Timestamps (as epoch ms numbers) of when each key was last refreshed */
|
|
15
|
+
this.lastRefreshedTimes = new Map();
|
|
16
|
+
}
|
|
17
|
+
refresh(key) {
|
|
18
|
+
this.lastRefreshedTimes.set(key, new Date().valueOf());
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if the key is present and expired, false if it's not expired, and undefined if it's not found
|
|
22
|
+
* If cleanUp is passed as true, then delete any expired entry before returning.
|
|
23
|
+
*/
|
|
24
|
+
checkExpiry(key, cleanUp = false) {
|
|
25
|
+
const refreshTime = this.lastRefreshedTimes.get(key);
|
|
26
|
+
assert((refreshTime !== undefined) === super.has(key), 0x50c /* freshness map out of sync */);
|
|
27
|
+
if (refreshTime === undefined) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const expired = new Date().valueOf() - refreshTime >= this.expiryMs;
|
|
31
|
+
if (expired && cleanUp) {
|
|
32
|
+
this.delete(key);
|
|
33
|
+
}
|
|
34
|
+
return expired;
|
|
35
|
+
}
|
|
36
|
+
clearExpiredEntries() {
|
|
37
|
+
// forEach clears out any expired entries
|
|
38
|
+
this.forEach(() => { });
|
|
39
|
+
}
|
|
40
|
+
get size() {
|
|
41
|
+
this.clearExpiredEntries();
|
|
42
|
+
return super.size;
|
|
43
|
+
}
|
|
44
|
+
has(key) {
|
|
45
|
+
this.checkExpiry(key, true /* cleanUp */);
|
|
46
|
+
return super.has(key);
|
|
47
|
+
}
|
|
48
|
+
get(key) {
|
|
49
|
+
this.checkExpiry(key, true /* cleanUp */);
|
|
50
|
+
return super.get(key);
|
|
51
|
+
}
|
|
52
|
+
set(key, value) {
|
|
53
|
+
// Sliding window expiration policy (on write)
|
|
54
|
+
this.refresh(key);
|
|
55
|
+
return super.set(key, value);
|
|
56
|
+
}
|
|
57
|
+
delete(key) {
|
|
58
|
+
this.lastRefreshedTimes.delete(key);
|
|
59
|
+
return super.delete(key);
|
|
60
|
+
}
|
|
61
|
+
clear() {
|
|
62
|
+
this.lastRefreshedTimes.clear();
|
|
63
|
+
super.clear();
|
|
64
|
+
}
|
|
65
|
+
forEach(callbackfn, thisArg) {
|
|
66
|
+
const expiredKeys = [];
|
|
67
|
+
super.forEach((v, k, m) => {
|
|
68
|
+
if (this.checkExpiry(k) === true) {
|
|
69
|
+
expiredKeys.push(k);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
callbackfn.bind(thisArg)(v, k, m);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
// Clean up keys we know are expired now that we're done iterating
|
|
76
|
+
expiredKeys.forEach((key) => {
|
|
77
|
+
this.delete(key);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
entries() {
|
|
81
|
+
this.clearExpiredEntries();
|
|
82
|
+
return super.entries();
|
|
83
|
+
}
|
|
84
|
+
keys() {
|
|
85
|
+
this.clearExpiredEntries();
|
|
86
|
+
return super.keys();
|
|
87
|
+
}
|
|
88
|
+
values() {
|
|
89
|
+
this.clearExpiredEntries();
|
|
90
|
+
return super.values();
|
|
91
|
+
}
|
|
92
|
+
[Symbol.iterator]() {
|
|
93
|
+
this.clearExpiredEntries();
|
|
94
|
+
return super[Symbol.iterator]();
|
|
95
|
+
}
|
|
96
|
+
valueOf() {
|
|
97
|
+
this.clearExpiredEntries();
|
|
98
|
+
return super.valueOf();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=mapWithExpiration.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapWithExpiration.mjs","sourceRoot":"","sources":["../src/mapWithExpiration.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 { assert } from \"@fluidframework/core-utils\";\n\n/**\n * An extension of Map that expires (deletes) entries after a period of inactivity.\n * The policy is based on the last time a key was written to.\n */\nexport class MapWithExpiration<TKey = any, TValue = any> extends Map<TKey, TValue> {\n\t/** Timestamps (as epoch ms numbers) of when each key was last refreshed */\n\tprivate readonly lastRefreshedTimes = new Map<TKey, number>();\n\n\tconstructor(private readonly expiryMs: number) {\n\t\tsuper();\n\t}\n\n\tprivate refresh(key: TKey): void {\n\t\tthis.lastRefreshedTimes.set(key, new Date().valueOf());\n\t}\n\n\t/**\n\t * Returns true if the key is present and expired, false if it's not expired, and undefined if it's not found\n\t * If cleanUp is passed as true, then delete any expired entry before returning.\n\t */\n\tprivate checkExpiry(key: TKey, cleanUp: boolean = false): boolean | undefined {\n\t\tconst refreshTime = this.lastRefreshedTimes.get(key);\n\t\tassert(\n\t\t\t(refreshTime !== undefined) === super.has(key),\n\t\t\t0x50c /* freshness map out of sync */,\n\t\t);\n\n\t\tif (refreshTime === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst expired = new Date().valueOf() - refreshTime >= this.expiryMs;\n\t\tif (expired && cleanUp) {\n\t\t\tthis.delete(key);\n\t\t}\n\t\treturn expired;\n\t}\n\n\tprivate clearExpiredEntries() {\n\t\t// forEach clears out any expired entries\n\t\tthis.forEach(() => {});\n\t}\n\n\tget size(): number {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.size;\n\t}\n\n\thas(key: TKey): boolean {\n\t\tthis.checkExpiry(key, true /* cleanUp */);\n\t\treturn super.has(key);\n\t}\n\n\tget(key: TKey): TValue | undefined {\n\t\tthis.checkExpiry(key, true /* cleanUp */);\n\t\treturn super.get(key);\n\t}\n\n\tset(key: TKey, value: TValue): this {\n\t\t// Sliding window expiration policy (on write)\n\t\tthis.refresh(key);\n\t\treturn super.set(key, value);\n\t}\n\n\tdelete(key: TKey): boolean {\n\t\tthis.lastRefreshedTimes.delete(key);\n\t\treturn super.delete(key);\n\t}\n\n\tclear(): void {\n\t\tthis.lastRefreshedTimes.clear();\n\t\tsuper.clear();\n\t}\n\n\tforEach(\n\t\tcallbackfn: (value: TValue, key: TKey, map: Map<TKey, TValue>) => void,\n\t\tthisArg?: any,\n\t): void {\n\t\tconst expiredKeys: TKey[] = [];\n\t\tsuper.forEach(\n\t\t\t(v, k, m) => {\n\t\t\t\tif (this.checkExpiry(k) === true) {\n\t\t\t\t\texpiredKeys.push(k);\n\t\t\t\t} else {\n\t\t\t\t\tcallbackfn.bind(thisArg)(v, k, m);\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Note we don't pass thisArg here, since we bind it directly to callbackFn and don't need it otherwise\n\t\t);\n\n\t\t// Clean up keys we know are expired now that we're done iterating\n\t\texpiredKeys.forEach((key: TKey) => {\n\t\t\tthis.delete(key);\n\t\t});\n\t}\n\n\tentries(): IterableIterator<[TKey, TValue]> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.entries();\n\t}\n\tkeys(): IterableIterator<TKey> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.keys();\n\t}\n\tvalues(): IterableIterator<TValue> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.values();\n\t}\n\t[Symbol.iterator](): IterableIterator<[TKey, TValue]> {\n\t\tthis.clearExpiredEntries();\n\t\treturn super[Symbol.iterator]();\n\t}\n\n\tvalueOf() {\n\t\tthis.clearExpiredEntries();\n\t\treturn super.valueOf();\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nullBlobStorageService.d.ts","sourceRoot":"","sources":["../src/nullBlobStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAEI,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,oCAAoC;OACtF,KAAK,GAAG,MAAM,sCAAsC;AAE3D;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,uBAAuB;IACrE,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;IAI1E,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;IAI7E,wBAAwB,CACpC,OAAO,EAAE,GAAG,CAAC,YAAY,EACzB,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IAIL,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAItE,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAGnE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAG/D"}
|
|
@@ -17,16 +17,16 @@ export class NullBlobStorageService {
|
|
|
17
17
|
return [];
|
|
18
18
|
}
|
|
19
19
|
async uploadSummaryWithContext(summary, context) {
|
|
20
|
-
|
|
20
|
+
throw new Error("Invalid operation");
|
|
21
21
|
}
|
|
22
22
|
async downloadSummary(handle) {
|
|
23
|
-
|
|
23
|
+
throw new Error("Invalid operation");
|
|
24
24
|
}
|
|
25
25
|
async createBlob(file) {
|
|
26
|
-
|
|
26
|
+
throw new Error("Null blob storage can not create blob");
|
|
27
27
|
}
|
|
28
28
|
async readBlob(blobId) {
|
|
29
|
-
|
|
29
|
+
throw new Error("Null blob storage can not read blob");
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
//# sourceMappingURL=nullBlobStorageService.
|
|
32
|
+
//# sourceMappingURL=nullBlobStorageService.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nullBlobStorageService.mjs","sourceRoot":"","sources":["../src/nullBlobStorageService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAClC,IAAW,aAAa;QACvB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,OAAsB;QAClD,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,SAAwB,EAAE,KAAa;QAC/D,OAAO,EAAE,CAAC;IACX,CAAC;IAEM,KAAK,CAAC,wBAAwB,CACpC,OAAyB,EACzB,OAAwB;QAExB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,MAA0B;QACtD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,IAAqB;QAC5C,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC1D,CAAC;IACM,KAAK,CAAC,QAAQ,CAAC,MAAc;QACnC,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACxD,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDocumentStorageService, ISummaryContext } from \"@fluidframework/driver-definitions\";\nimport * as api from \"@fluidframework/protocol-definitions\";\n\n/**\n * Document access to underlying storage. It is default implementation of a storage service.\n * Does not read/write anything.\n */\nexport class NullBlobStorageService implements IDocumentStorageService {\n\tpublic get repositoryUrl(): string {\n\t\tthrow new Error(\"Invalid operation\");\n\t}\n\n\tpublic async getSnapshotTree(version?: api.IVersion): Promise<api.ISnapshotTree | null> {\n\t\treturn version ? Promise.reject(new Error(\"Invalid operation\")) : null;\n\t}\n\n\tpublic async getVersions(versionId: string | null, count: number): Promise<api.IVersion[]> {\n\t\treturn [];\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: api.ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\tthrow new Error(\"Invalid operation\");\n\t}\n\n\tpublic async downloadSummary(handle: api.ISummaryHandle): Promise<api.ISummaryTree> {\n\t\tthrow new Error(\"Invalid operation\");\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<api.ICreateBlobResponse> {\n\t\tthrow new Error(\"Null blob storage can not create blob\");\n\t}\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tthrow new Error(\"Null blob storage can not read blob\");\n\t}\n}\n"]}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/routerlicious-driver";
|
|
8
|
-
export declare const pkgVersion = "1.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-dev-rc.1.0.0.224419";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,yCAAyC,CAAC;AAC9D,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,yCAAyC,CAAC;AAC9D,eAAO,MAAM,UAAU,8BAA8B,CAAC"}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export const pkgName = "@fluidframework/routerlicious-driver";
|
|
8
|
-
export const pkgVersion = "1.
|
|
9
|
-
//# sourceMappingURL=packageVersion.
|
|
8
|
+
export const pkgVersion = "2.0.0-dev-rc.1.0.0.224419";
|
|
9
|
+
//# sourceMappingURL=packageVersion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageVersion.mjs","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,sCAAsC,CAAC;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,2BAA2B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/routerlicious-driver\";\nexport const pkgVersion = \"2.0.0-dev-rc.1.0.0.224419\";\n"]}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
5
8
|
export interface IRouterliciousDriverPolicies {
|
|
6
9
|
/**
|
|
7
10
|
* Enable prefetching entire snapshot tree into memory before it is loaded by the runtime.
|
|
@@ -18,14 +21,6 @@ export interface IRouterliciousDriverPolicies {
|
|
|
18
21
|
* Default: 100
|
|
19
22
|
*/
|
|
20
23
|
maxConcurrentOrdererRequests: number;
|
|
21
|
-
/**
|
|
22
|
-
* Give hosts the option to change blob aggregation behavior to suit their needs.
|
|
23
|
-
* Larger number means fewer blob individual requests, but less blob-deduping.
|
|
24
|
-
* Smaller number means more blob individual requests, but more blob-deduping.
|
|
25
|
-
* Setting to `undefined` disables blob aggregration.
|
|
26
|
-
* Default: undefined
|
|
27
|
-
*/
|
|
28
|
-
aggregateBlobsSmallerThanBytes: number | undefined;
|
|
29
24
|
/**
|
|
30
25
|
* Enable uploading entire summary tree as a IWholeSummaryPayload to storage.
|
|
31
26
|
* Default: false
|
|
@@ -35,11 +30,29 @@ export interface IRouterliciousDriverPolicies {
|
|
|
35
30
|
* Enable service endpoint discovery when creating or joining a session.
|
|
36
31
|
* Default: false
|
|
37
32
|
*/
|
|
38
|
-
enableDiscovery
|
|
33
|
+
enableDiscovery: boolean;
|
|
39
34
|
/**
|
|
40
35
|
* Enable using RestLess which avoids CORS preflight requests.
|
|
41
36
|
* Default: true
|
|
42
37
|
*/
|
|
43
38
|
enableRestLess: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Enable internal cache of summaries/snapshots.
|
|
41
|
+
* Reduces Summarizer boot time and reduces server load in E2E tests.
|
|
42
|
+
* Default: true
|
|
43
|
+
*/
|
|
44
|
+
enableInternalSummaryCaching: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Enable downgrading socket connection to long-polling
|
|
47
|
+
* when websocket connection cannot be established.
|
|
48
|
+
* Default: true
|
|
49
|
+
*/
|
|
50
|
+
enableLongPollingDowngrade: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Indicates that the container is ephemeral.
|
|
53
|
+
* Artifacts relates to the container are limited to container lifetime.
|
|
54
|
+
* Default: false
|
|
55
|
+
*/
|
|
56
|
+
isEphemeralContainer: boolean;
|
|
44
57
|
}
|
|
45
58
|
//# sourceMappingURL=policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,4BAA4B,EAAE,MAAM,CAAC;IACrC;;;OAGG;IACH,4BAA4B,EAAE,MAAM,CAAC;IACrC;;;OAGG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,4BAA4B,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,0BAA0B,EAAE,OAAO,CAAC;IACpC;;;;OAIG;IACH,oBAAoB,EAAE,OAAO,CAAC;CAC9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.mjs","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * @internal\n */\nexport interface IRouterliciousDriverPolicies {\n\t/**\n\t * Enable prefetching entire snapshot tree into memory before it is loaded by the runtime.\n\t * Default: true\n\t */\n\tenablePrefetch: boolean;\n\t/**\n\t * Rate limit concurrent storage requests.\n\t * Default: 100\n\t */\n\tmaxConcurrentStorageRequests: number;\n\t/**\n\t * Rate limit concurrent orderer requests.\n\t * Default: 100\n\t */\n\tmaxConcurrentOrdererRequests: number;\n\t/**\n\t * Enable uploading entire summary tree as a IWholeSummaryPayload to storage.\n\t * Default: false\n\t */\n\tenableWholeSummaryUpload: boolean;\n\t/**\n\t * Enable service endpoint discovery when creating or joining a session.\n\t * Default: false\n\t */\n\tenableDiscovery: boolean;\n\t/**\n\t * Enable using RestLess which avoids CORS preflight requests.\n\t * Default: true\n\t */\n\tenableRestLess: boolean;\n\t/**\n\t * Enable internal cache of summaries/snapshots.\n\t * Reduces Summarizer boot time and reduces server load in E2E tests.\n\t * Default: true\n\t */\n\tenableInternalSummaryCaching: boolean;\n\t/**\n\t * Enable downgrading socket connection to long-polling\n\t * when websocket connection cannot be established.\n\t * Default: true\n\t */\n\tenableLongPollingDowngrade: boolean;\n\t/**\n\t * Indicates that the container is ephemeral.\n\t * Artifacts relates to the container are limited to container lifetime.\n\t * Default: false\n\t */\n\tisEphemeralContainer: boolean;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { INormalizedWholeSnapshot, IWholeFlatSnapshot } from "./contracts.mjs";
|
|
6
|
+
/**
|
|
7
|
+
* Converts existing IWholeFlatSnapshot to snapshot tree, blob array, and sequence number.
|
|
8
|
+
*
|
|
9
|
+
* @param flatSnapshot - flat snapshot
|
|
10
|
+
* @param treePrefixToRemove - tree prefix to strip. By default we are stripping ".app" prefix
|
|
11
|
+
* @returns snapshot tree, blob array, and sequence number
|
|
12
|
+
*/
|
|
13
|
+
export declare function convertWholeFlatSnapshotToSnapshotTreeAndBlobs(flatSnapshot: IWholeFlatSnapshot, treePrefixToRemove?: string): INormalizedWholeSnapshot;
|
|
14
|
+
//# sourceMappingURL=r11sSnapshotParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r11sSnapshotParser.d.ts","sourceRoot":"","sources":["../src/r11sSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAII,EAAE,wBAAwB,EAAE,kBAAkB,EAA0B;AA+C/E;;;;;;GAMG;AACH,wBAAgB,8CAA8C,CAC7D,YAAY,EAAE,kBAAkB,EAChC,kBAAkB,GAAE,MAAe,GACjC,wBAAwB,CAiB1B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { stringToBuffer } from "@fluid-internal/client-utils";
|
|
6
|
+
/**
|
|
7
|
+
* Build a tree hierarchy from a flat tree.
|
|
8
|
+
*
|
|
9
|
+
* @param flatTree - a flat tree
|
|
10
|
+
* @param treePrefixToRemove - tree prefix to strip
|
|
11
|
+
* @returns the heirarchical tree
|
|
12
|
+
*/
|
|
13
|
+
function buildHierarchy(flatTree, treePrefixToRemove) {
|
|
14
|
+
const lookup = {};
|
|
15
|
+
// Root tree id will be used to determine which version was downloaded.
|
|
16
|
+
const root = { id: flatTree.id, blobs: {}, trees: {} };
|
|
17
|
+
lookup[""] = root;
|
|
18
|
+
for (const entry of flatTree.entries) {
|
|
19
|
+
// Strip the `treePrefixToRemove` path from tree entries such that they are stored under root.
|
|
20
|
+
const entryPath = entry.path.replace(new RegExp(`^${treePrefixToRemove}/`), "");
|
|
21
|
+
const lastIndex = entryPath.lastIndexOf("/");
|
|
22
|
+
const entryPathDir = entryPath.slice(0, Math.max(0, lastIndex));
|
|
23
|
+
const entryPathBase = entryPath.slice(lastIndex + 1);
|
|
24
|
+
// The flat output is breadth-first so we can assume we see tree nodes prior to their contents
|
|
25
|
+
const node = lookup[entryPathDir];
|
|
26
|
+
// Add in either the blob or tree
|
|
27
|
+
if (entry.type === "tree") {
|
|
28
|
+
const newTree = {
|
|
29
|
+
blobs: {},
|
|
30
|
+
trees: {},
|
|
31
|
+
unreferenced: entry.unreferenced,
|
|
32
|
+
};
|
|
33
|
+
node.trees[decodeURIComponent(entryPathBase)] = newTree;
|
|
34
|
+
lookup[entryPath] = newTree;
|
|
35
|
+
}
|
|
36
|
+
else if (entry.type === "blob") {
|
|
37
|
+
node.blobs[decodeURIComponent(entryPathBase)] = entry.id;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new Error(`Unknown entry type!!`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return root;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Converts existing IWholeFlatSnapshot to snapshot tree, blob array, and sequence number.
|
|
47
|
+
*
|
|
48
|
+
* @param flatSnapshot - flat snapshot
|
|
49
|
+
* @param treePrefixToRemove - tree prefix to strip. By default we are stripping ".app" prefix
|
|
50
|
+
* @returns snapshot tree, blob array, and sequence number
|
|
51
|
+
*/
|
|
52
|
+
export function convertWholeFlatSnapshotToSnapshotTreeAndBlobs(flatSnapshot, treePrefixToRemove = ".app") {
|
|
53
|
+
const blobs = new Map();
|
|
54
|
+
if (flatSnapshot.blobs) {
|
|
55
|
+
flatSnapshot.blobs.forEach((blob) => {
|
|
56
|
+
blobs.set(blob.id, stringToBuffer(blob.content, blob.encoding ?? "utf-8"));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const flatSnapshotTree = flatSnapshot.trees?.[0];
|
|
60
|
+
const sequenceNumber = flatSnapshotTree?.sequenceNumber;
|
|
61
|
+
const snapshotTree = buildHierarchy(flatSnapshotTree, treePrefixToRemove);
|
|
62
|
+
return {
|
|
63
|
+
blobs,
|
|
64
|
+
snapshotTree,
|
|
65
|
+
sequenceNumber,
|
|
66
|
+
id: flatSnapshot.id,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=r11sSnapshotParser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r11sSnapshotParser.mjs","sourceRoot":"","sources":["../src/r11sSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAGI,EAAE,cAAc,EAAE,MAAM,8BAA8B;AAG7D;;;;;;GAMG;AACH,SAAS,cAAc,CACtB,QAAgC,EAChC,kBAA0B;IAE1B,MAAM,MAAM,GAAsC,EAAE,CAAC;IACrD,uEAAuE;IACvE,MAAM,IAAI,GAAkB,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACtE,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAElB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE;QACrC,8FAA8F;QAC9F,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,kBAAkB,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAChF,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAChE,MAAM,aAAa,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QAErD,8FAA8F;QAC9F,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;QAElC,iCAAiC;QACjC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE;YAC1B,MAAM,OAAO,GAAkB;gBAC9B,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,EAAE;gBACT,YAAY,EAAE,KAAK,CAAC,YAAY;aAChC,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,GAAG,OAAO,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC;SAC5B;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE;YACjC,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;SACzD;aAAM;YACN,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;SACxC;KACD;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,8CAA8C,CAC7D,YAAgC,EAChC,qBAA6B,MAAM;IAEnC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,IAAI,YAAY,CAAC,KAAK,EAAE;QACvB,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACnC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;KACH;IACD,MAAM,gBAAgB,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,cAAc,GAAG,gBAAgB,EAAE,cAAc,CAAC;IACxD,MAAM,YAAY,GAAG,cAAc,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAE1E,OAAO;QACN,KAAK;QACL,YAAY;QACZ,cAAc;QACd,EAAE,EAAE,YAAY,CAAC,EAAE;KACnB,CAAC;AACH,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { INormalizedWholeSnapshot, IWholeFlatSnapshot, IWholeFlatSnapshotTree } from \"./contracts\";\n\n/**\n * Build a tree hierarchy from a flat tree.\n *\n * @param flatTree - a flat tree\n * @param treePrefixToRemove - tree prefix to strip\n * @returns the heirarchical tree\n */\nfunction buildHierarchy(\n\tflatTree: IWholeFlatSnapshotTree,\n\ttreePrefixToRemove: string,\n): ISnapshotTree {\n\tconst lookup: { [path: string]: ISnapshotTree } = {};\n\t// Root tree id will be used to determine which version was downloaded.\n\tconst root: ISnapshotTree = { id: flatTree.id, blobs: {}, trees: {} };\n\tlookup[\"\"] = root;\n\n\tfor (const entry of flatTree.entries) {\n\t\t// Strip the `treePrefixToRemove` path from tree entries such that they are stored under root.\n\t\tconst entryPath = entry.path.replace(new RegExp(`^${treePrefixToRemove}/`), \"\");\n\t\tconst lastIndex = entryPath.lastIndexOf(\"/\");\n\t\tconst entryPathDir = entryPath.slice(0, Math.max(0, lastIndex));\n\t\tconst entryPathBase = entryPath.slice(lastIndex + 1);\n\n\t\t// The flat output is breadth-first so we can assume we see tree nodes prior to their contents\n\t\tconst node = lookup[entryPathDir];\n\n\t\t// Add in either the blob or tree\n\t\tif (entry.type === \"tree\") {\n\t\t\tconst newTree: ISnapshotTree = {\n\t\t\t\tblobs: {},\n\t\t\t\ttrees: {},\n\t\t\t\tunreferenced: entry.unreferenced,\n\t\t\t};\n\t\t\tnode.trees[decodeURIComponent(entryPathBase)] = newTree;\n\t\t\tlookup[entryPath] = newTree;\n\t\t} else if (entry.type === \"blob\") {\n\t\t\tnode.blobs[decodeURIComponent(entryPathBase)] = entry.id;\n\t\t} else {\n\t\t\tthrow new Error(`Unknown entry type!!`);\n\t\t}\n\t}\n\n\treturn root;\n}\n\n/**\n * Converts existing IWholeFlatSnapshot to snapshot tree, blob array, and sequence number.\n *\n * @param flatSnapshot - flat snapshot\n * @param treePrefixToRemove - tree prefix to strip. By default we are stripping \".app\" prefix\n * @returns snapshot tree, blob array, and sequence number\n */\nexport function convertWholeFlatSnapshotToSnapshotTreeAndBlobs(\n\tflatSnapshot: IWholeFlatSnapshot,\n\ttreePrefixToRemove: string = \".app\",\n): INormalizedWholeSnapshot {\n\tconst blobs = new Map<string, ArrayBuffer>();\n\tif (flatSnapshot.blobs) {\n\t\tflatSnapshot.blobs.forEach((blob) => {\n\t\t\tblobs.set(blob.id, stringToBuffer(blob.content, blob.encoding ?? \"utf-8\"));\n\t\t});\n\t}\n\tconst flatSnapshotTree = flatSnapshot.trees?.[0];\n\tconst sequenceNumber = flatSnapshotTree?.sequenceNumber;\n\tconst snapshotTree = buildHierarchy(flatSnapshotTree, treePrefixToRemove);\n\n\treturn {\n\t\tblobs,\n\t\tsnapshotTree,\n\t\tsequenceNumber,\n\t\tid: flatSnapshot.id,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { ITelemetryProperties } from "@fluidframework/core-interfaces";
|
|
6
|
+
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
7
|
+
import { RateLimiter } from "@fluidframework/driver-utils";
|
|
8
|
+
import type { AxiosRequestConfig } from "axios";
|
|
9
|
+
import { ITokenProvider, ITokenResponse } from "./tokens.mjs";
|
|
10
|
+
import { QueryStringType, RestWrapper } from "./restWrapperBase.mjs";
|
|
11
|
+
type AuthorizationHeaderGetter = (token: ITokenResponse) => string;
|
|
12
|
+
export type TokenFetcher = (refresh?: boolean) => Promise<ITokenResponse>;
|
|
13
|
+
export interface IR11sResponse<T> {
|
|
14
|
+
content: T;
|
|
15
|
+
headers: Map<string, string>;
|
|
16
|
+
propsToLog: ITelemetryProperties;
|
|
17
|
+
requestUrl: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A utility function to create a Routerlicious response without any additional props as we might not have them always.
|
|
21
|
+
* @param content - Response which is equivalent to content.
|
|
22
|
+
* @returns A Routerlicious response without any extra props.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createR11sResponseFromContent<T>(content: T): IR11sResponse<T>;
|
|
25
|
+
export declare function getPropsToLogFromResponse(headers: {
|
|
26
|
+
get: (id: string) => string | undefined | null;
|
|
27
|
+
}): ITelemetryProperties;
|
|
28
|
+
export declare class RouterliciousRestWrapper extends RestWrapper {
|
|
29
|
+
private readonly rateLimiter;
|
|
30
|
+
private readonly fetchRefreshedToken;
|
|
31
|
+
private readonly getAuthorizationHeader;
|
|
32
|
+
private readonly useRestLess;
|
|
33
|
+
private tokenP?;
|
|
34
|
+
private readonly restLess;
|
|
35
|
+
private token;
|
|
36
|
+
constructor(logger: ITelemetryLoggerExt, rateLimiter: RateLimiter, fetchRefreshedToken: TokenFetcher, getAuthorizationHeader: AuthorizationHeaderGetter, useRestLess: boolean, baseurl?: string, tokenP?: Promise<ITokenResponse> | undefined, defaultQueryString?: QueryStringType);
|
|
37
|
+
protected request<T>(requestConfig: AxiosRequestConfig, statusCode: number, canRetry?: boolean): Promise<IR11sResponse<T>>;
|
|
38
|
+
private generateHeaders;
|
|
39
|
+
getToken(): Promise<ITokenResponse>;
|
|
40
|
+
setToken(token: ITokenResponse): void;
|
|
41
|
+
}
|
|
42
|
+
export declare class RouterliciousStorageRestWrapper extends RouterliciousRestWrapper {
|
|
43
|
+
private constructor();
|
|
44
|
+
static load(tenantId: string, tokenFetcher: TokenFetcher, logger: ITelemetryLoggerExt, rateLimiter: RateLimiter, useRestLess: boolean, baseurl?: string, initialTokenP?: Promise<ITokenResponse>): Promise<RouterliciousStorageRestWrapper>;
|
|
45
|
+
}
|
|
46
|
+
export declare class RouterliciousOrdererRestWrapper extends RouterliciousRestWrapper {
|
|
47
|
+
private constructor();
|
|
48
|
+
static load(tokenFetcher: TokenFetcher, logger: ITelemetryLoggerExt, rateLimiter: RateLimiter, useRestLess: boolean, baseurl?: string, initialTokenP?: Promise<ITokenResponse>): Promise<RouterliciousOrdererRestWrapper>;
|
|
49
|
+
}
|
|
50
|
+
export declare function toInstrumentedR11sOrdererTokenFetcher(tenantId: string, documentId: string | undefined, tokenProvider: ITokenProvider, logger: ITelemetryLoggerExt): TokenFetcher;
|
|
51
|
+
export declare function toInstrumentedR11sStorageTokenFetcher(tenantId: string, documentId: string, tokenProvider: ITokenProvider, logger: ITelemetryLoggerExt): TokenFetcher;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=restWrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restWrapper.d.ts","sourceRoot":"","sources":["../src/restWrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { PerformanceEvent, numberFromString, } from "@fluidframework/telemetry-utils";
|
|
6
|
+
import { assert } from "@fluidframework/core-utils";
|
|
7
|
+
import { fromUtf8ToBase64, performance } from "@fluid-internal/client-utils";
|
|
8
|
+
import { GenericNetworkError, NonRetryableError } from "@fluidframework/driver-utils";
|
|
9
|
+
import { CorrelationIdHeaderName, DriverVersionHeaderName, getAuthorizationTokenFromCredentials, RestLessClient, } from "@fluidframework/server-services-client";
|
|
10
|
+
import fetch from "cross-fetch";
|
|
11
|
+
import safeStringify from "json-stringify-safe";
|
|
12
|
+
import { RouterliciousErrorTypes, throwR11sNetworkError } from "./errorUtils.mjs";
|
|
13
|
+
import { pkgVersion as driverVersion } from "./packageVersion.mjs";
|
|
14
|
+
import { RestWrapper } from "./restWrapperBase.mjs";
|
|
15
|
+
const axiosRequestConfigToFetchRequestConfig = (requestConfig) => {
|
|
16
|
+
const requestInfo = requestConfig.baseURL !== undefined
|
|
17
|
+
? `${requestConfig.baseURL}${requestConfig.url ?? ""}`
|
|
18
|
+
: requestConfig.url ?? "";
|
|
19
|
+
const requestInit = {
|
|
20
|
+
method: requestConfig.method,
|
|
21
|
+
// NOTE: I believe that although the Axios type permits non-string values in the header, here we are
|
|
22
|
+
// guaranteed the requestConfig only has string values in its header.
|
|
23
|
+
headers: requestConfig.headers,
|
|
24
|
+
body: requestConfig.data,
|
|
25
|
+
};
|
|
26
|
+
return [requestInfo, requestInit];
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* A utility function to create a Routerlicious response without any additional props as we might not have them always.
|
|
30
|
+
* @param content - Response which is equivalent to content.
|
|
31
|
+
* @returns A Routerlicious response without any extra props.
|
|
32
|
+
*/
|
|
33
|
+
export function createR11sResponseFromContent(content) {
|
|
34
|
+
return {
|
|
35
|
+
content,
|
|
36
|
+
headers: new Map(),
|
|
37
|
+
propsToLog: {},
|
|
38
|
+
requestUrl: "",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function headersToMap(headers) {
|
|
42
|
+
const newHeaders = new Map();
|
|
43
|
+
for (const [key, value] of headers.entries()) {
|
|
44
|
+
newHeaders.set(key, value);
|
|
45
|
+
}
|
|
46
|
+
return newHeaders;
|
|
47
|
+
}
|
|
48
|
+
export function getPropsToLogFromResponse(headers) {
|
|
49
|
+
// We rename headers so that otel doesn't scrub them away. Otel doesn't allow
|
|
50
|
+
// certain characters in headers including '-'
|
|
51
|
+
const headersToLog = [
|
|
52
|
+
{ headerName: CorrelationIdHeaderName, logName: "requestCorrelationId" },
|
|
53
|
+
{ headerName: "content-encoding", logName: "contentEncoding" },
|
|
54
|
+
{ headerName: "content-type", logName: "contentType" },
|
|
55
|
+
];
|
|
56
|
+
const additionalProps = {
|
|
57
|
+
contentsize: numberFromString(headers.get("content-length")),
|
|
58
|
+
};
|
|
59
|
+
headersToLog.forEach((header) => {
|
|
60
|
+
const headerValue = headers.get(header.headerName);
|
|
61
|
+
if (headerValue !== undefined && headerValue !== null) {
|
|
62
|
+
additionalProps[header.logName] = headerValue;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return additionalProps;
|
|
66
|
+
}
|
|
67
|
+
export class RouterliciousRestWrapper extends RestWrapper {
|
|
68
|
+
constructor(logger, rateLimiter, fetchRefreshedToken, getAuthorizationHeader, useRestLess, baseurl, tokenP, defaultQueryString = {}) {
|
|
69
|
+
super(baseurl, defaultQueryString);
|
|
70
|
+
this.rateLimiter = rateLimiter;
|
|
71
|
+
this.fetchRefreshedToken = fetchRefreshedToken;
|
|
72
|
+
this.getAuthorizationHeader = getAuthorizationHeader;
|
|
73
|
+
this.useRestLess = useRestLess;
|
|
74
|
+
this.tokenP = tokenP;
|
|
75
|
+
this.restLess = new RestLessClient();
|
|
76
|
+
}
|
|
77
|
+
async request(requestConfig, statusCode, canRetry = true) {
|
|
78
|
+
const config = {
|
|
79
|
+
...requestConfig,
|
|
80
|
+
headers: await this.generateHeaders(requestConfig.headers),
|
|
81
|
+
};
|
|
82
|
+
const translatedConfig = this.useRestLess ? this.restLess.translate(config) : config;
|
|
83
|
+
const fetchRequestConfig = axiosRequestConfigToFetchRequestConfig(translatedConfig);
|
|
84
|
+
const res = await this.rateLimiter.schedule(async () => {
|
|
85
|
+
const perfStart = performance.now();
|
|
86
|
+
const result = await fetch(...fetchRequestConfig).catch(async (error) => {
|
|
87
|
+
// Browser Fetch throws a TypeError on network error, `node-fetch` throws a FetchError
|
|
88
|
+
const isNetworkError = ["TypeError", "FetchError"].includes(error?.name);
|
|
89
|
+
const errorMessage = isNetworkError
|
|
90
|
+
? `NetworkError: ${error.message}`
|
|
91
|
+
: safeStringify(error);
|
|
92
|
+
// If a service is temporarily down or a browser resource limit is reached, RestWrapper will throw
|
|
93
|
+
// a network error with no status code (e.g. err:ERR_CONN_REFUSED or err:ERR_FAILED) and
|
|
94
|
+
// the error message will start with NetworkError as defined in restWrapper.ts
|
|
95
|
+
// If there exists a self-signed SSL certificates error, throw a NonRetryableError
|
|
96
|
+
// TODO: instead of relying on string matching, filter error based on the error code like we do for websocket connections
|
|
97
|
+
const err = errorMessage.includes("failed, reason: self signed certificate")
|
|
98
|
+
? new NonRetryableError(errorMessage, RouterliciousErrorTypes.sslCertError, {
|
|
99
|
+
driverVersion,
|
|
100
|
+
})
|
|
101
|
+
: new GenericNetworkError(errorMessage, errorMessage.startsWith("NetworkError"), { driverVersion });
|
|
102
|
+
throw err;
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
response: result,
|
|
106
|
+
duration: performance.now() - perfStart,
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
const response = res.response;
|
|
110
|
+
let start = performance.now();
|
|
111
|
+
const text = await response.text();
|
|
112
|
+
const receiveContentTime = performance.now() - start;
|
|
113
|
+
const bodySize = text.length;
|
|
114
|
+
start = performance.now();
|
|
115
|
+
const responseBody = response.headers.get("content-type")?.includes("application/json")
|
|
116
|
+
? JSON.parse(text)
|
|
117
|
+
: text;
|
|
118
|
+
const parseTime = performance.now() - start;
|
|
119
|
+
// Success
|
|
120
|
+
if (response.ok || response.status === statusCode) {
|
|
121
|
+
const result = responseBody;
|
|
122
|
+
const headers = headersToMap(response.headers);
|
|
123
|
+
return {
|
|
124
|
+
content: result,
|
|
125
|
+
headers,
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
127
|
+
requestUrl: fetchRequestConfig[0].toString(),
|
|
128
|
+
propsToLog: {
|
|
129
|
+
...getPropsToLogFromResponse(headers),
|
|
130
|
+
bodySize,
|
|
131
|
+
receiveContentTime,
|
|
132
|
+
parseTime,
|
|
133
|
+
fetchTime: res.duration,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Failure
|
|
138
|
+
if (response.status === 401 && canRetry) {
|
|
139
|
+
// Refresh Authorization header and retry once
|
|
140
|
+
this.token = await this.fetchRefreshedToken(true /* refreshToken */);
|
|
141
|
+
return this.request(config, statusCode, false);
|
|
142
|
+
}
|
|
143
|
+
if (response.status === 429 && responseBody?.retryAfter > 0) {
|
|
144
|
+
// Retry based on retryAfter[Seconds]
|
|
145
|
+
return new Promise((resolve, reject) => setTimeout(() => {
|
|
146
|
+
this.request(config, statusCode).then(resolve).catch(reject);
|
|
147
|
+
}, responseBody.retryAfter * 1000));
|
|
148
|
+
}
|
|
149
|
+
const responseSummary = responseBody !== undefined
|
|
150
|
+
? typeof responseBody === "string"
|
|
151
|
+
? responseBody
|
|
152
|
+
: safeStringify(responseBody)
|
|
153
|
+
: response.statusText;
|
|
154
|
+
throwR11sNetworkError(`R11s fetch error: ${responseSummary}`, response.status, responseBody?.retryAfter);
|
|
155
|
+
}
|
|
156
|
+
async generateHeaders(requestHeaders) {
|
|
157
|
+
const token = await this.getToken();
|
|
158
|
+
assert(token !== undefined, 0x679 /* token should be present */);
|
|
159
|
+
const headers = {
|
|
160
|
+
...requestHeaders,
|
|
161
|
+
[DriverVersionHeaderName]: driverVersion,
|
|
162
|
+
// NOTE: If this.authorizationHeader is undefined, should "Authorization" be removed entirely?
|
|
163
|
+
Authorization: this.getAuthorizationHeader(token),
|
|
164
|
+
};
|
|
165
|
+
return headers;
|
|
166
|
+
}
|
|
167
|
+
async getToken() {
|
|
168
|
+
if (this.token !== undefined) {
|
|
169
|
+
return this.token;
|
|
170
|
+
}
|
|
171
|
+
const token = await (this.tokenP ?? this.fetchRefreshedToken());
|
|
172
|
+
this.setToken(token);
|
|
173
|
+
this.tokenP = undefined;
|
|
174
|
+
return token;
|
|
175
|
+
}
|
|
176
|
+
setToken(token) {
|
|
177
|
+
this.token = token;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
export class RouterliciousStorageRestWrapper extends RouterliciousRestWrapper {
|
|
181
|
+
constructor(logger, rateLimiter, fetchToken, getAuthorizationHeader, useRestLess, baseurl, initialTokenP, defaultQueryString = {}) {
|
|
182
|
+
super(logger, rateLimiter, fetchToken, getAuthorizationHeader, useRestLess, baseurl, initialTokenP, defaultQueryString);
|
|
183
|
+
}
|
|
184
|
+
static async load(tenantId, tokenFetcher, logger, rateLimiter, useRestLess, baseurl, initialTokenP) {
|
|
185
|
+
const defaultQueryString = {
|
|
186
|
+
token: `${fromUtf8ToBase64(tenantId)}`,
|
|
187
|
+
};
|
|
188
|
+
const getAuthorizationHeader = (token) => {
|
|
189
|
+
const credentials = {
|
|
190
|
+
password: token.jwt,
|
|
191
|
+
user: tenantId,
|
|
192
|
+
};
|
|
193
|
+
return getAuthorizationTokenFromCredentials(credentials);
|
|
194
|
+
};
|
|
195
|
+
const restWrapper = new RouterliciousStorageRestWrapper(logger, rateLimiter, tokenFetcher, getAuthorizationHeader, useRestLess, baseurl, initialTokenP, defaultQueryString);
|
|
196
|
+
return restWrapper;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
export class RouterliciousOrdererRestWrapper extends RouterliciousRestWrapper {
|
|
200
|
+
constructor(logger, rateLimiter, fetchToken, getAuthorizationHeader, useRestLess, baseurl, initialTokenP, defaultQueryString = {}) {
|
|
201
|
+
super(logger, rateLimiter, fetchToken, getAuthorizationHeader, useRestLess, baseurl, initialTokenP, defaultQueryString);
|
|
202
|
+
}
|
|
203
|
+
static async load(tokenFetcher, logger, rateLimiter, useRestLess, baseurl, initialTokenP) {
|
|
204
|
+
const getAuthorizationHeader = (token) => {
|
|
205
|
+
return `Basic ${token.jwt}`;
|
|
206
|
+
};
|
|
207
|
+
const restWrapper = new RouterliciousOrdererRestWrapper(logger, rateLimiter, tokenFetcher, getAuthorizationHeader, useRestLess, baseurl, initialTokenP);
|
|
208
|
+
return restWrapper;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
export function toInstrumentedR11sOrdererTokenFetcher(tenantId, documentId, tokenProvider, logger) {
|
|
212
|
+
const fetchOrdererToken = async (refreshToken) => {
|
|
213
|
+
return PerformanceEvent.timedExecAsync(logger, {
|
|
214
|
+
eventName: "FetchOrdererToken",
|
|
215
|
+
docId: documentId,
|
|
216
|
+
}, async () => {
|
|
217
|
+
const ordererToken = await tokenProvider.fetchOrdererToken(tenantId, documentId, refreshToken);
|
|
218
|
+
return ordererToken;
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
return fetchOrdererToken;
|
|
222
|
+
}
|
|
223
|
+
export function toInstrumentedR11sStorageTokenFetcher(tenantId, documentId, tokenProvider, logger) {
|
|
224
|
+
const fetchStorageToken = async (refreshToken) => {
|
|
225
|
+
return PerformanceEvent.timedExecAsync(logger, {
|
|
226
|
+
eventName: "FetchStorageToken",
|
|
227
|
+
docId: documentId,
|
|
228
|
+
}, async () => {
|
|
229
|
+
// Craft credentials using tenant id and token
|
|
230
|
+
const storageToken = await tokenProvider.fetchStorageToken(tenantId, documentId, refreshToken);
|
|
231
|
+
return storageToken;
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
return fetchStorageToken;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=restWrapper.mjs.map
|