@fluidframework/odsp-driver 1.2.7 → 2.0.0-dev.1.3.0.96595
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/.mocharc.js +12 -0
- package/README.md +19 -0
- package/dist/ReadBufferUtils.d.ts.map +1 -1
- package/dist/ReadBufferUtils.js +1 -0
- package/dist/ReadBufferUtils.js.map +1 -1
- package/dist/WriteBufferUtils.d.ts +3 -5
- package/dist/WriteBufferUtils.d.ts.map +1 -1
- package/dist/WriteBufferUtils.js +59 -55
- package/dist/WriteBufferUtils.js.map +1 -1
- package/dist/compactSnapshotParser.d.ts +2 -2
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +91 -34
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts +1 -2
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +17 -14
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/contracts.d.ts +1 -18
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/createFile.d.ts +1 -1
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +53 -16
- package/dist/createFile.js.map +1 -1
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +0 -1
- package/dist/createNewUtils.js.map +1 -1
- package/dist/createOdspCreateContainerRequest.d.ts +4 -3
- package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/dist/createOdspCreateContainerRequest.js +6 -3
- package/dist/createOdspCreateContainerRequest.js.map +1 -1
- package/dist/epochTracker.d.ts +1 -0
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +24 -5
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +1 -2
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +22 -27
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts +3 -6
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +22 -33
- package/dist/getFileLink.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js +1 -2
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +3 -2
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +9 -12
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +3 -6
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentService.d.ts +1 -0
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +12 -6
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +29 -6
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +4 -4
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +82 -64
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js +4 -2
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +4 -4
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspFluidFileLink.js +1 -1
- package/dist/odspFluidFileLink.js.map +1 -1
- package/dist/odspLocationRedirection.d.ts +14 -0
- package/dist/odspLocationRedirection.d.ts.map +1 -0
- package/dist/odspLocationRedirection.js +24 -0
- package/dist/odspLocationRedirection.js.map +1 -0
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js +1 -2
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts +6 -3
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +14 -17
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUrlHelper.js +2 -1
- package/dist/odspUrlHelper.js.map +1 -1
- package/dist/odspUtils.d.ts +11 -2
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +32 -5
- package/dist/odspUtils.js.map +1 -1
- package/dist/opsCaching.d.ts.map +1 -1
- package/dist/opsCaching.js +3 -2
- package/dist/opsCaching.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts +6 -4
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +6 -4
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/retryUtils.d.ts.map +1 -1
- package/dist/retryUtils.js +8 -4
- package/dist/retryUtils.js.map +1 -1
- package/dist/zipItDataRepresentationUtils.d.ts +30 -18
- package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/dist/zipItDataRepresentationUtils.js +170 -76
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/lib/ReadBufferUtils.d.ts.map +1 -1
- package/lib/ReadBufferUtils.js +1 -0
- package/lib/ReadBufferUtils.js.map +1 -1
- package/lib/WriteBufferUtils.d.ts +3 -5
- package/lib/WriteBufferUtils.d.ts.map +1 -1
- package/lib/WriteBufferUtils.js +61 -57
- package/lib/WriteBufferUtils.js.map +1 -1
- package/lib/compactSnapshotParser.d.ts +2 -2
- package/lib/compactSnapshotParser.d.ts.map +1 -1
- package/lib/compactSnapshotParser.js +92 -35
- package/lib/compactSnapshotParser.js.map +1 -1
- package/lib/compactSnapshotWriter.d.ts +1 -2
- package/lib/compactSnapshotWriter.d.ts.map +1 -1
- package/lib/compactSnapshotWriter.js +18 -15
- package/lib/compactSnapshotWriter.js.map +1 -1
- package/lib/contracts.d.ts +1 -18
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/createFile.d.ts +1 -1
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +54 -17
- package/lib/createFile.js.map +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +0 -1
- package/lib/createNewUtils.js.map +1 -1
- package/lib/createOdspCreateContainerRequest.d.ts +4 -3
- package/lib/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/lib/createOdspCreateContainerRequest.js +6 -3
- package/lib/createOdspCreateContainerRequest.js.map +1 -1
- package/lib/epochTracker.d.ts +1 -0
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +26 -7
- package/lib/epochTracker.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +1 -2
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +22 -27
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.d.ts +3 -6
- package/lib/getFileLink.d.ts.map +1 -1
- package/lib/getFileLink.js +24 -35
- package/lib/getFileLink.js.map +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -3
- package/lib/index.js.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.js +1 -2
- package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts +3 -2
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +9 -12
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js +3 -6
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentService.d.ts +1 -0
- package/lib/odspDocumentService.d.ts.map +1 -1
- package/lib/odspDocumentService.js +14 -8
- package/lib/odspDocumentService.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +29 -6
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +4 -4
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +83 -65
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/lib/odspDocumentStorageServiceBase.js +4 -2
- package/lib/odspDocumentStorageServiceBase.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js +4 -4
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspFluidFileLink.js +1 -1
- package/lib/odspFluidFileLink.js.map +1 -1
- package/lib/odspLocationRedirection.d.ts +14 -0
- package/lib/odspLocationRedirection.d.ts.map +1 -0
- package/lib/odspLocationRedirection.js +20 -0
- package/lib/odspLocationRedirection.js.map +1 -0
- package/lib/odspSnapshotParser.d.ts.map +1 -1
- package/lib/odspSnapshotParser.js +1 -2
- package/lib/odspSnapshotParser.js.map +1 -1
- package/lib/odspSummaryUploadManager.d.ts +6 -3
- package/lib/odspSummaryUploadManager.d.ts.map +1 -1
- package/lib/odspSummaryUploadManager.js +14 -17
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/odspUrlHelper.js +2 -1
- package/lib/odspUrlHelper.js.map +1 -1
- package/lib/odspUtils.d.ts +11 -2
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +31 -5
- package/lib/odspUtils.js.map +1 -1
- package/lib/opsCaching.d.ts.map +1 -1
- package/lib/opsCaching.js +3 -2
- package/lib/opsCaching.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/prefetchLatestSnapshot.d.ts +6 -4
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +6 -4
- package/lib/prefetchLatestSnapshot.js.map +1 -1
- package/lib/retryUtils.d.ts.map +1 -1
- package/lib/retryUtils.js +9 -5
- package/lib/retryUtils.js.map +1 -1
- package/lib/zipItDataRepresentationUtils.d.ts +30 -18
- package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/lib/zipItDataRepresentationUtils.js +166 -75
- package/lib/zipItDataRepresentationUtils.js.map +1 -1
- package/package.json +33 -20
- package/src/ReadBufferUtils.ts +1 -0
- package/src/WriteBufferUtils.ts +67 -58
- package/src/compactSnapshotParser.ts +102 -40
- package/src/compactSnapshotWriter.ts +25 -17
- package/src/contracts.ts +2 -14
- package/src/createFile.ts +75 -15
- package/src/createNewUtils.ts +2 -4
- package/src/createOdspCreateContainerRequest.ts +7 -4
- package/src/epochTracker.ts +47 -7
- package/src/fetchSnapshot.ts +35 -31
- package/src/getFileLink.ts +26 -39
- package/src/index.ts +1 -3
- package/src/localOdspDriver/localOdspDocumentStorageManager.ts +2 -2
- package/src/odspDeltaStorageService.ts +8 -9
- package/src/odspDocumentDeltaConnection.ts +3 -5
- package/src/odspDocumentService.ts +16 -13
- package/src/odspDocumentServiceFactoryCore.ts +40 -4
- package/src/odspDocumentStorageManager.ts +64 -50
- package/src/odspDocumentStorageServiceBase.ts +4 -2
- package/src/odspDriverUrlResolverForShareLink.ts +2 -5
- package/src/odspFluidFileLink.ts +1 -1
- package/src/odspLocationRedirection.ts +23 -0
- package/src/odspSnapshotParser.ts +3 -4
- package/src/odspSummaryUploadManager.ts +10 -11
- package/src/odspUrlHelper.ts +1 -1
- package/src/odspUtils.ts +40 -7
- package/src/opsCaching.ts +3 -2
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +6 -4
- package/src/retryUtils.ts +8 -5
- package/src/zipItDataRepresentationUtils.ts +198 -75
|
@@ -31,17 +31,18 @@ export class OdspDeltaStorageService {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Retrieves ops from
|
|
34
|
+
* Retrieves ops from storage
|
|
35
35
|
* @param from - inclusive
|
|
36
36
|
* @param to - exclusive
|
|
37
37
|
* @param telemetryProps - properties to add when issuing telemetry events
|
|
38
|
+
* @param scenarioName - reason for fetching ops
|
|
38
39
|
* @returns ops retrieved & info if result was partial (i.e. more is available)
|
|
39
40
|
*/
|
|
40
41
|
public async get(
|
|
41
42
|
from: number,
|
|
42
43
|
to: number,
|
|
43
44
|
telemetryProps: ITelemetryProperties,
|
|
44
|
-
|
|
45
|
+
scenarioName?: string,
|
|
45
46
|
): Promise<IDeltasFetchResult> {
|
|
46
47
|
return getWithRetryForTokenRefresh(async (options) => {
|
|
47
48
|
// Note - this call ends up in getSocketStorageDiscovery() and can refresh token
|
|
@@ -78,16 +79,13 @@ export class OdspDeltaStorageService {
|
|
|
78
79
|
},
|
|
79
80
|
"ops",
|
|
80
81
|
true,
|
|
81
|
-
|
|
82
|
+
scenarioName,
|
|
82
83
|
);
|
|
83
84
|
clearTimeout(timer);
|
|
84
85
|
const deltaStorageResponse = response.content;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
} else {
|
|
89
|
-
messages = deltaStorageResponse.value as ISequencedDocumentMessage[];
|
|
90
|
-
}
|
|
86
|
+
const messages = deltaStorageResponse.value.length > 0 && "op" in deltaStorageResponse.value[0]
|
|
87
|
+
? (deltaStorageResponse.value as ISequencedDeltaOpMessage[]).map((operation) => operation.op)
|
|
88
|
+
: deltaStorageResponse.value as ISequencedDocumentMessage[];
|
|
91
89
|
|
|
92
90
|
this.logger.sendPerformanceEvent({
|
|
93
91
|
eventName: "OpsFetch",
|
|
@@ -99,6 +97,7 @@ export class OdspDeltaStorageService {
|
|
|
99
97
|
from,
|
|
100
98
|
to,
|
|
101
99
|
...telemetryProps,
|
|
100
|
+
reason: scenarioName,
|
|
102
101
|
});
|
|
103
102
|
|
|
104
103
|
// It is assumed that server always returns all the ops that it has in the range that was requested.
|
|
@@ -290,11 +290,9 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
|
|
|
290
290
|
// Note: we suspect the incoming error object is either:
|
|
291
291
|
// - a socketError: add it to the OdspError object for driver to be able to parse it and reason over it.
|
|
292
292
|
// - anything else: let base class handle it
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return super.createErrorObject(handler, error, canRetry);
|
|
297
|
-
}
|
|
293
|
+
return canRetry && Number.isInteger(error?.code) && typeof error?.message === "string"
|
|
294
|
+
? errorObjectFromSocketError(error as IOdspSocketError, handler)
|
|
295
|
+
: super.createErrorObject(handler, error, canRetry);
|
|
298
296
|
}
|
|
299
297
|
|
|
300
298
|
/**
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
7
|
-
import { performance } from "@fluidframework/common-utils";
|
|
7
|
+
import { assert, performance } from "@fluidframework/common-utils";
|
|
8
8
|
import {
|
|
9
9
|
ChildLogger,
|
|
10
10
|
IFluidErrorBase,
|
|
@@ -21,12 +21,7 @@ import {
|
|
|
21
21
|
IDocumentServicePolicies,
|
|
22
22
|
DriverErrorType,
|
|
23
23
|
} from "@fluidframework/driver-definitions";
|
|
24
|
-
import {
|
|
25
|
-
canRetryOnError,
|
|
26
|
-
DeltaStreamConnectionForbiddenError,
|
|
27
|
-
NonRetryableError,
|
|
28
|
-
} from "@fluidframework/driver-utils";
|
|
29
|
-
import { IFacetCodes } from "@fluidframework/odsp-doclib-utils";
|
|
24
|
+
import { canRetryOnError, DeltaStreamConnectionForbiddenError, NonRetryableError } from "@fluidframework/driver-utils";
|
|
30
25
|
import {
|
|
31
26
|
IClient,
|
|
32
27
|
ISequencedDocumentMessage,
|
|
@@ -39,6 +34,7 @@ import {
|
|
|
39
34
|
InstrumentedStorageTokenFetcher,
|
|
40
35
|
OdspErrorType,
|
|
41
36
|
} from "@fluidframework/odsp-driver-definitions";
|
|
37
|
+
import { hasFacetCodes } from "@fluidframework/odsp-doclib-utils";
|
|
42
38
|
import type { io as SocketIOClientStatic } from "socket.io-client";
|
|
43
39
|
import { HostStoragePolicyInternal, ISocketStorageDiscovery } from "./contracts";
|
|
44
40
|
import { IOdspCache } from "./odspCache";
|
|
@@ -113,6 +109,8 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
113
109
|
|
|
114
110
|
private currentConnection?: OdspDocumentDeltaConnection;
|
|
115
111
|
|
|
112
|
+
private relayServiceTenantAndSessionId: string | undefined;
|
|
113
|
+
|
|
116
114
|
/**
|
|
117
115
|
* @param odspResolvedUrl - resolved url identifying document that will be managed by this service instance.
|
|
118
116
|
* @param getStorageToken - function that can provide the storage token. This is is also referred to as
|
|
@@ -178,7 +176,6 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
178
176
|
this.odspResolvedUrl,
|
|
179
177
|
this.getStorageToken,
|
|
180
178
|
this.mc.logger,
|
|
181
|
-
true,
|
|
182
179
|
this.cache,
|
|
183
180
|
this.hostPolicy,
|
|
184
181
|
this.epochTracker,
|
|
@@ -189,6 +186,11 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
189
186
|
}
|
|
190
187
|
throw new Error("Disconnected while uploading summary (attempt to perform flush())");
|
|
191
188
|
},
|
|
189
|
+
() => {
|
|
190
|
+
assert(this.relayServiceTenantAndSessionId !== undefined,
|
|
191
|
+
0x37b /* relayServiceTenantAndSessionId should be present */);
|
|
192
|
+
return this.relayServiceTenantAndSessionId;
|
|
193
|
+
},
|
|
192
194
|
this.mc.config.getNumber("Fluid.Driver.Odsp.snapshotFormatFetchType"),
|
|
193
195
|
);
|
|
194
196
|
}
|
|
@@ -271,7 +273,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
271
273
|
this.socketIoClientFactory().catch(annotateAndRethrowConnectionError("socketIoClientFactory")),
|
|
272
274
|
]);
|
|
273
275
|
|
|
274
|
-
const finalWebsocketToken = websocketToken ?? (websocketEndpoint.socketToken
|
|
276
|
+
const finalWebsocketToken = websocketToken ?? (websocketEndpoint.socketToken ?? null);
|
|
275
277
|
if (finalWebsocketToken === null) {
|
|
276
278
|
throw this.annotateConnectionError(
|
|
277
279
|
new NonRetryableError(
|
|
@@ -344,10 +346,9 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
344
346
|
requestSocketToken: boolean,
|
|
345
347
|
options: TokenFetchOptionsEx,
|
|
346
348
|
) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
for (const code of likelyFacetCodes.facetCodes) {
|
|
349
|
+
const response = await this.joinSessionCore(requestSocketToken, options).catch((e) => {
|
|
350
|
+
if (hasFacetCodes(e) && e.facetCodes !== undefined) {
|
|
351
|
+
for (const code of e.facetCodes) {
|
|
351
352
|
switch (code) {
|
|
352
353
|
case "sessionForbiddenOnPreservedFiles":
|
|
353
354
|
case "sessionForbiddenOnModerationEnabledLibrary":
|
|
@@ -364,6 +365,8 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
364
365
|
}
|
|
365
366
|
throw e;
|
|
366
367
|
});
|
|
368
|
+
this.relayServiceTenantAndSessionId = `${response.tenantId}/${response.id}`;
|
|
369
|
+
return response;
|
|
367
370
|
}
|
|
368
371
|
|
|
369
372
|
private async joinSessionCore(
|
|
@@ -26,6 +26,10 @@ import {
|
|
|
26
26
|
HostStoragePolicy,
|
|
27
27
|
IFileEntry,
|
|
28
28
|
IOdspUrlParts,
|
|
29
|
+
SharingLinkScope,
|
|
30
|
+
SharingLinkRole,
|
|
31
|
+
ShareLinkTypes,
|
|
32
|
+
ISharingLinkKind,
|
|
29
33
|
} from "@fluidframework/odsp-driver-definitions";
|
|
30
34
|
import type { io as SocketIOClientStatic } from "socket.io-client";
|
|
31
35
|
import { v4 as uuid } from "uuid";
|
|
@@ -84,15 +88,13 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
90
|
|
|
91
|
+
const createShareLinkParam = getSharingLinkParams(this.hostPolicy, searchParams);
|
|
87
92
|
const newFileInfo: INewFileInfo = {
|
|
88
93
|
driveId: odspResolvedUrl.driveId,
|
|
89
94
|
siteUrl: odspResolvedUrl.siteUrl,
|
|
90
95
|
filePath,
|
|
91
96
|
filename: odspResolvedUrl.fileName,
|
|
92
|
-
|
|
93
|
-
// so that share link creation with create file can be enabled
|
|
94
|
-
createLinkType: this.hostPolicy.enableShareLinkWithCreate ?
|
|
95
|
-
odspResolvedUrl.shareLinkInfo?.createLink?.type : undefined,
|
|
97
|
+
createLinkType: createShareLinkParam,
|
|
96
98
|
};
|
|
97
99
|
|
|
98
100
|
const odspLogger = createOdspLogger(logger);
|
|
@@ -110,6 +112,10 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
110
112
|
{
|
|
111
113
|
eventName: "CreateNew",
|
|
112
114
|
isWithSummaryUpload: true,
|
|
115
|
+
createShareLinkParam: JSON.stringify(createShareLinkParam),
|
|
116
|
+
enableShareLinkWithCreate: this.hostPolicy.enableShareLinkWithCreate,
|
|
117
|
+
enableSingleRequestForShareLinkWithCreate:
|
|
118
|
+
this.hostPolicy.enableSingleRequestForShareLinkWithCreate,
|
|
113
119
|
},
|
|
114
120
|
async (event) => {
|
|
115
121
|
odspResolvedUrl = await createNewFluidFile(
|
|
@@ -127,6 +133,8 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
127
133
|
this.hostPolicy.cacheCreateNewSummary ?? true,
|
|
128
134
|
!!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,
|
|
129
135
|
odspResolvedUrl.isClpCompliantApp,
|
|
136
|
+
this.hostPolicy.enableSingleRequestForShareLinkWithCreate,
|
|
137
|
+
this.hostPolicy.enableShareLinkWithCreate,
|
|
130
138
|
);
|
|
131
139
|
const docService = this.createDocumentServiceCore(odspResolvedUrl, odspLogger,
|
|
132
140
|
cacheAndTracker, clientIsSummarizer);
|
|
@@ -223,3 +231,31 @@ export class OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
|
|
|
223
231
|
);
|
|
224
232
|
}
|
|
225
233
|
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Extract the sharing link kind from the resolved URL's query paramerters
|
|
237
|
+
*/
|
|
238
|
+
function getSharingLinkParams(
|
|
239
|
+
hostPolicy: HostStoragePolicy,
|
|
240
|
+
searchParams: URLSearchParams,
|
|
241
|
+
): ShareLinkTypes | ISharingLinkKind | undefined {
|
|
242
|
+
// extract request parameters for creation of sharing link (if provided) if the feature is enabled
|
|
243
|
+
let createShareLinkParam: ShareLinkTypes | ISharingLinkKind | undefined;
|
|
244
|
+
if (hostPolicy.enableSingleRequestForShareLinkWithCreate) {
|
|
245
|
+
const createLinkScope = searchParams.get("createLinkScope");
|
|
246
|
+
const createLinkRole = searchParams.get("createLinkRole");
|
|
247
|
+
if (createLinkScope && SharingLinkScope[createLinkScope]) {
|
|
248
|
+
createShareLinkParam = {
|
|
249
|
+
scope: SharingLinkScope[createLinkScope],
|
|
250
|
+
...(createLinkRole && SharingLinkRole[createLinkRole] ?
|
|
251
|
+
{ role: SharingLinkRole[createLinkRole] } : {}),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
} else if (hostPolicy.enableShareLinkWithCreate) {
|
|
255
|
+
const createLinkType = searchParams.get("createLinkType");
|
|
256
|
+
if (createLinkType && ShareLinkTypes[createLinkType]) {
|
|
257
|
+
createShareLinkParam = ShareLinkTypes[createLinkType || ""];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return createShareLinkParam;
|
|
261
|
+
}
|
|
@@ -16,6 +16,7 @@ import * as api from "@fluidframework/protocol-definitions";
|
|
|
16
16
|
import {
|
|
17
17
|
ISummaryContext,
|
|
18
18
|
DriverErrorType,
|
|
19
|
+
FetchSource,
|
|
19
20
|
} from "@fluidframework/driver-definitions";
|
|
20
21
|
import { RateLimiter, NonRetryableError } from "@fluidframework/driver-utils";
|
|
21
22
|
import {
|
|
@@ -87,11 +88,11 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
87
88
|
private readonly odspResolvedUrl: IOdspResolvedUrl,
|
|
88
89
|
private readonly getStorageToken: InstrumentedStorageTokenFetcher,
|
|
89
90
|
private readonly logger: ITelemetryLogger,
|
|
90
|
-
private readonly fetchFullSnapshot: boolean,
|
|
91
91
|
private readonly cache: IOdspCache,
|
|
92
92
|
private readonly hostPolicy: HostStoragePolicyInternal,
|
|
93
93
|
private readonly epochTracker: EpochTracker,
|
|
94
94
|
private readonly flushCallback: () => Promise<FlushResult>,
|
|
95
|
+
private readonly relayServiceTenantAndSessionId: () => string,
|
|
95
96
|
private readonly snapshotFormatFetchType?: SnapshotFormatSupportType,
|
|
96
97
|
) {
|
|
97
98
|
super();
|
|
@@ -107,6 +108,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
107
108
|
logger,
|
|
108
109
|
epochTracker,
|
|
109
110
|
!!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,
|
|
111
|
+
this.relayServiceTenantAndSessionId,
|
|
110
112
|
);
|
|
111
113
|
}
|
|
112
114
|
|
|
@@ -204,7 +206,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
204
206
|
return super.getSnapshotTree(version, scenarioName);
|
|
205
207
|
}
|
|
206
208
|
|
|
207
|
-
public async getVersions(blobid: string | null, count: number, scenarioName?: string): Promise<api.IVersion[]> {
|
|
209
|
+
public async getVersions(blobid: string | null, count: number, scenarioName?: string, fetchSource?: FetchSource): Promise<api.IVersion[]> {
|
|
208
210
|
// Regular load workflow uses blobId === documentID to indicate "latest".
|
|
209
211
|
if (blobid !== this.documentId && blobid) {
|
|
210
212
|
// FluidFetch & FluidDebugger tools use empty sting to query for versions
|
|
@@ -225,19 +227,23 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
// If count is one, we can use the trees/latest API, which returns the latest version and trees in a single request for better performance
|
|
228
|
-
|
|
229
|
-
if (this.firstVersionCall && count === 1 && (blobid === null || blobid === this.documentId)) {
|
|
230
|
+
if (count === 1 && (blobid === null || blobid === this.documentId)) {
|
|
230
231
|
const hostSnapshotOptions = this.hostPolicy.snapshotOptions;
|
|
231
232
|
const odspSnapshotCacheValue: ISnapshotContents = await PerformanceEvent.timedExecAsync(
|
|
232
233
|
this.logger,
|
|
233
|
-
{ eventName: "ObtainSnapshot" },
|
|
234
|
+
{ eventName: "ObtainSnapshot", fetchSource },
|
|
234
235
|
async (event: PerformanceEvent) => {
|
|
235
236
|
const props: GetVersionsTelemetryProps = {};
|
|
236
237
|
let retrievedSnapshot: ISnapshotContents | undefined;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
this.
|
|
238
|
+
|
|
239
|
+
let method: string;
|
|
240
|
+
if (fetchSource === FetchSource.noCache) {
|
|
241
|
+
retrievedSnapshot = await this.fetchSnapshot(hostSnapshotOptions, scenarioName);
|
|
242
|
+
method = "networkOnly";
|
|
243
|
+
} else {
|
|
244
|
+
// Here's the logic to grab the persistent cache snapshot implemented by the host
|
|
245
|
+
// Epoch tracker is responsible for communicating with the persistent cache, handling epochs and cache versions
|
|
246
|
+
const cachedSnapshotP: Promise<ISnapshotContents | undefined> = this.epochTracker.get(createCacheSnapshotKey(this.odspResolvedUrl))
|
|
241
247
|
.then(async (snapshotCachedEntry: ISnapshotCachedEntry) => {
|
|
242
248
|
if (snapshotCachedEntry !== undefined) {
|
|
243
249
|
// If the cached entry does not contain the entry time, then assign it a default of 30 days old.
|
|
@@ -264,46 +270,56 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
264
270
|
return snapshotCachedEntry;
|
|
265
271
|
});
|
|
266
272
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// If cache returned empty or failed -> wait for network (success of failure)
|
|
288
|
-
if (promiseRaceWinner.index === 1) {
|
|
289
|
-
retrievedSnapshot = await cachedSnapshotP;
|
|
290
|
-
method = "cache";
|
|
291
|
-
}
|
|
273
|
+
// Based on the concurrentSnapshotFetch policy:
|
|
274
|
+
// Either retrieve both the network and cache snapshots concurrently and pick the first to return,
|
|
275
|
+
// or grab the cache value and then the network value if the cache value returns undefined.
|
|
276
|
+
// For summarizer which could call this during refreshing of summary parent, always use the cache
|
|
277
|
+
// first. Also for other clients, if it is not critical path which is determined by firstVersionCall,
|
|
278
|
+
// then also check the cache first.
|
|
279
|
+
if (this.firstVersionCall && this.hostPolicy.concurrentSnapshotFetch && !this.hostPolicy.summarizerClient) {
|
|
280
|
+
const networkSnapshotP = this.fetchSnapshot(hostSnapshotOptions, scenarioName);
|
|
281
|
+
|
|
282
|
+
// Ensure that failures on both paths are ignored initially.
|
|
283
|
+
// I.e. if cache fails for some reason, we will proceed with network result.
|
|
284
|
+
// And vice versa - if (for example) client is offline and network request fails first, we
|
|
285
|
+
// do want to attempt to succeed with cached data!
|
|
286
|
+
const promiseRaceWinner = await promiseRaceWithWinner([
|
|
287
|
+
cachedSnapshotP.catch(() => undefined),
|
|
288
|
+
networkSnapshotP.catch(() => undefined),
|
|
289
|
+
]);
|
|
290
|
+
retrievedSnapshot = promiseRaceWinner.value;
|
|
291
|
+
method = promiseRaceWinner.index === 0 ? "cache" : "network";
|
|
292
|
+
|
|
292
293
|
if (retrievedSnapshot === undefined) {
|
|
293
|
-
|
|
294
|
-
|
|
294
|
+
// if network failed -> wait for cache ( then return network failure)
|
|
295
|
+
// If cache returned empty or failed -> wait for network (success of failure)
|
|
296
|
+
if (promiseRaceWinner.index === 1) {
|
|
297
|
+
retrievedSnapshot = await cachedSnapshotP;
|
|
298
|
+
method = "cache";
|
|
299
|
+
}
|
|
300
|
+
if (retrievedSnapshot === undefined) {
|
|
301
|
+
retrievedSnapshot = await networkSnapshotP;
|
|
302
|
+
method = "network";
|
|
303
|
+
}
|
|
295
304
|
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
// while the first caller is awaiting later async code in this block.
|
|
300
|
-
|
|
301
|
-
retrievedSnapshot = await cachedSnapshotP;
|
|
305
|
+
} else {
|
|
306
|
+
// Note: There's a race condition here - another caller may come past the undefined check
|
|
307
|
+
// while the first caller is awaiting later async code in this block.
|
|
302
308
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
309
|
+
retrievedSnapshot = await cachedSnapshotP;
|
|
310
|
+
if (retrievedSnapshot !== undefined) {
|
|
311
|
+
method = "cache";
|
|
312
|
+
} else {
|
|
313
|
+
method = "network";
|
|
314
|
+
const options: ISnapshotOptions = { ...hostSnapshotOptions };
|
|
315
|
+
// Don't fetch the blobs/deltas if it is not the first call. By default server will add
|
|
316
|
+
// blobs and deltas to the response.
|
|
317
|
+
if (!this.firstVersionCall) {
|
|
318
|
+
options.blobs = 0;
|
|
319
|
+
options.deltas = 0;
|
|
320
|
+
}
|
|
321
|
+
retrievedSnapshot = await this.fetchSnapshot(options, scenarioName);
|
|
322
|
+
}
|
|
307
323
|
}
|
|
308
324
|
}
|
|
309
325
|
if (method === "network") {
|
|
@@ -314,10 +330,9 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
314
330
|
},
|
|
315
331
|
);
|
|
316
332
|
|
|
317
|
-
//
|
|
333
|
+
// Don't override ops which were fetched during initial load, since we could still need them.
|
|
334
|
+
const id = this.initializeFromSnapshot(odspSnapshotCacheValue, this.firstVersionCall);
|
|
318
335
|
this.firstVersionCall = false;
|
|
319
|
-
const id = this.initializeFromSnapshot(odspSnapshotCacheValue);
|
|
320
|
-
|
|
321
336
|
return id ? [{ id, treeId: undefined! }] : [];
|
|
322
337
|
}
|
|
323
338
|
|
|
@@ -537,7 +552,6 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
537
552
|
this.snapshotUrl!,
|
|
538
553
|
storageToken,
|
|
539
554
|
id,
|
|
540
|
-
this.fetchFullSnapshot,
|
|
541
555
|
!!this.hostPolicy.sessionOptions?.forceAccessTokenViaAuthorizationHeader,
|
|
542
556
|
this.logger,
|
|
543
557
|
snapshotDownloader,
|
|
@@ -244,7 +244,7 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
244
244
|
return summarySnapshotTree;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
protected initializeFromSnapshot(odspSnapshotCacheValue: ISnapshotContents): string | undefined {
|
|
247
|
+
protected initializeFromSnapshot(odspSnapshotCacheValue: ISnapshotContents, cacheOps: boolean = true): string | undefined {
|
|
248
248
|
this._snapshotSequenceNumber = odspSnapshotCacheValue.sequenceNumber;
|
|
249
249
|
const { snapshotTree, blobs, ops } = odspSnapshotCacheValue;
|
|
250
250
|
|
|
@@ -260,7 +260,9 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
260
260
|
this.initBlobsCache(blobs);
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
if (cacheOps) {
|
|
264
|
+
this.ops = ops;
|
|
265
|
+
}
|
|
264
266
|
return id;
|
|
265
267
|
}
|
|
266
268
|
}
|
|
@@ -136,7 +136,7 @@ export class OdspDriverUrlResolverForShareLink implements IUrlResolver {
|
|
|
136
136
|
// We need to remove the nav param if set by host when setting the sharelink as otherwise the shareLinkId
|
|
137
137
|
// when redeeming the share link during the redeem fallback for trees latest call becomes greater than
|
|
138
138
|
// the eligible length.
|
|
139
|
-
odspResolvedUrl.shareLinkInfo = Object.assign(odspResolvedUrl.shareLinkInfo
|
|
139
|
+
odspResolvedUrl.shareLinkInfo = Object.assign(odspResolvedUrl.shareLinkInfo ?? {},
|
|
140
140
|
{ sharingLinkToRedeem: this.removeNavParam(request.url) });
|
|
141
141
|
}
|
|
142
142
|
if (odspResolvedUrl.itemId) {
|
|
@@ -171,10 +171,7 @@ export class OdspDriverUrlResolverForShareLink implements IUrlResolver {
|
|
|
171
171
|
return cachedLinkPromise;
|
|
172
172
|
}
|
|
173
173
|
const newLinkPromise = getFileLink(
|
|
174
|
-
this.shareLinkFetcherProps.tokenFetcher,
|
|
175
|
-
resolvedUrl,
|
|
176
|
-
this.shareLinkFetcherProps.identityType,
|
|
177
|
-
this.logger,
|
|
174
|
+
this.shareLinkFetcherProps.tokenFetcher, resolvedUrl, this.logger,
|
|
178
175
|
).catch((error) => {
|
|
179
176
|
// This should imply that error is a non-retriable error.
|
|
180
177
|
this.logger.sendErrorEvent({ eventName: "FluidFileUrlError" }, error);
|
package/src/odspFluidFileLink.ts
CHANGED
|
@@ -52,7 +52,7 @@ export function encodeOdspFluidDataStoreLocator(locator: OdspFluidDataStoreLocat
|
|
|
52
52
|
/**
|
|
53
53
|
* Decodes given encoded value representing Fluid data store locator extracted from ODSP Fluid file link
|
|
54
54
|
* @param encodedLocatorValue - encoded Fluid data store locator value which was produced by
|
|
55
|
-
*
|
|
55
|
+
* {@link encodeOdspFluidDataStoreLocator} function
|
|
56
56
|
* @param siteOriginUrl - site origin that will be appended to encoded relative path to form absolute file url
|
|
57
57
|
* @returns object representing Fluid data store location in ODSP terms
|
|
58
58
|
*/
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IFluidResolvedUrl } from "@fluidframework/driver-definitions";
|
|
7
|
+
import { IOdspResolvedUrl } from "@fluidframework/odsp-driver-definitions";
|
|
8
|
+
import { getOdspResolvedUrl } from "./odspUtils";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* It takes a resolved url with old siteUrl and creates a new resolved url with updated site url domain.
|
|
12
|
+
* @param resolvedUrl - Previous odsp resolved url with older site url.
|
|
13
|
+
* @param redirectLocation - Url at which the network call has to be made. It contains new site info.
|
|
14
|
+
* @returns - Resolved url after patching the correct siteUrl.
|
|
15
|
+
*/
|
|
16
|
+
export function patchOdspResolvedUrl(resolvedUrl: IFluidResolvedUrl, redirectLocation: string): IOdspResolvedUrl {
|
|
17
|
+
const odspResolvedUrl = { ...getOdspResolvedUrl(resolvedUrl) };
|
|
18
|
+
// Generate the new SiteUrl from the redirection location.
|
|
19
|
+
const newSiteDomain = new URL(redirectLocation).origin;
|
|
20
|
+
const newSiteUrl = `${newSiteDomain}${new URL(odspResolvedUrl.siteUrl).pathname}`;
|
|
21
|
+
odspResolvedUrl.siteUrl = newSiteUrl;
|
|
22
|
+
return odspResolvedUrl;
|
|
23
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert, stringToBuffer } from "@fluidframework/common-utils";
|
|
7
7
|
import * as api from "@fluidframework/protocol-definitions";
|
|
8
|
-
import { IOdspSnapshot, IOdspSnapshotCommit
|
|
8
|
+
import { IOdspSnapshot, IOdspSnapshotCommit } from "./contracts";
|
|
9
9
|
import { ISnapshotContents } from "./odspPublicUtils";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -18,7 +18,7 @@ import { ISnapshotContents } from "./odspPublicUtils";
|
|
|
18
18
|
function buildHierarchy(flatTree: IOdspSnapshotCommit): api.ISnapshotTree {
|
|
19
19
|
const lookup: { [path: string]: api.ISnapshotTree; } = {};
|
|
20
20
|
// id is required for root tree as it will be used to determine the version we loaded from.
|
|
21
|
-
const root:
|
|
21
|
+
const root: api.ISnapshotTree = { id: flatTree.id, blobs: {}, trees: {} };
|
|
22
22
|
lookup[""] = root;
|
|
23
23
|
|
|
24
24
|
for (const entry of flatTree.entries) {
|
|
@@ -31,10 +31,9 @@ function buildHierarchy(flatTree: IOdspSnapshotCommit): api.ISnapshotTree {
|
|
|
31
31
|
|
|
32
32
|
// Add in either the blob or tree
|
|
33
33
|
if (entry.type === "tree") {
|
|
34
|
-
const newTree:
|
|
34
|
+
const newTree: api.ISnapshotTree = {
|
|
35
35
|
blobs: {},
|
|
36
36
|
trees: {},
|
|
37
|
-
commits: {},
|
|
38
37
|
unreferenced: entry.unreferenced,
|
|
39
38
|
};
|
|
40
39
|
node.trees[decodeURIComponent(entryPathBase)] = newTree;
|
|
@@ -39,6 +39,7 @@ export class OdspSummaryUploadManager {
|
|
|
39
39
|
logger: ITelemetryLogger,
|
|
40
40
|
private readonly epochTracker: EpochTracker,
|
|
41
41
|
private readonly forceAccessTokenViaAuthorizationHeader: boolean,
|
|
42
|
+
private readonly relayServiceTenantAndSessionId: () => string,
|
|
42
43
|
) {
|
|
43
44
|
this.mc = loggerToMonitoringContext(logger);
|
|
44
45
|
}
|
|
@@ -93,9 +94,8 @@ export class OdspSummaryUploadManager {
|
|
|
93
94
|
this.forceAccessTokenViaAuthorizationHeader,
|
|
94
95
|
);
|
|
95
96
|
headers["Content-Type"] = "application/json";
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
97
|
+
headers["If-Match"] = `fluid:sessionid=${
|
|
98
|
+
this.relayServiceTenantAndSessionId()}${parentHandle ? `;containerid=${parentHandle}` : ""}`;
|
|
99
99
|
|
|
100
100
|
const postBody = JSON.stringify(snapshot);
|
|
101
101
|
|
|
@@ -126,8 +126,10 @@ export class OdspSummaryUploadManager {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
|
-
* Following are the goals of this function
|
|
130
|
-
*
|
|
129
|
+
* Following are the goals of this function:
|
|
130
|
+
*
|
|
131
|
+
* a. Converts the summary tree to a snapshot/odsp tree to be uploaded. Always upload full snapshot tree.
|
|
132
|
+
*
|
|
131
133
|
* @param parentHandle - Handle of the last uploaded summary or detach new summary.
|
|
132
134
|
* @param tree - Summary Tree which will be converted to snapshot tree to be uploaded.
|
|
133
135
|
* @param rootNodeName - Root node name of the summary tree.
|
|
@@ -169,19 +171,16 @@ export class OdspSummaryUploadManager {
|
|
|
169
171
|
break;
|
|
170
172
|
}
|
|
171
173
|
case api.SummaryType.Blob: {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
value = typeof summaryObject.content === "string"
|
|
175
|
+
? {
|
|
174
176
|
type: "blob",
|
|
175
177
|
content: summaryObject.content,
|
|
176
178
|
encoding: "utf-8",
|
|
177
|
-
}
|
|
178
|
-
} else {
|
|
179
|
-
value = {
|
|
179
|
+
} : {
|
|
180
180
|
type: "blob",
|
|
181
181
|
content: Uint8ArrayToString(summaryObject.content, "base64"),
|
|
182
182
|
encoding: "base64",
|
|
183
183
|
};
|
|
184
|
-
}
|
|
185
184
|
blobs++;
|
|
186
185
|
break;
|
|
187
186
|
}
|
package/src/odspUrlHelper.ts
CHANGED
|
@@ -69,7 +69,7 @@ export function isOdcUrl(url: string | URL): boolean {
|
|
|
69
69
|
// Format: /v2.1/drives('ABC123')/items('ABC123!123')
|
|
70
70
|
const odcODataRegex = /\/v2.1\/drives\('[^/]+'\)\/items\('[\da-z]+!\d+'\)/;
|
|
71
71
|
|
|
72
|
-
return !!(odcRegex.exec(path)
|
|
72
|
+
return !!(odcRegex.exec(path) ?? odcODataRegex.exec(path));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/**
|