@fluidframework/odsp-driver 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compactSnapshotParser.d.ts +1 -1
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +7 -4
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts +1 -1
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +4 -3
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js.map +1 -1
- package/dist/createNewUtils.d.ts +1 -1
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +1 -0
- package/dist/createNewUtils.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +7 -6
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +57 -31
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +17 -17
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +8 -4
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +2 -2
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +13 -13
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspError.d.ts +3 -1
- package/dist/odspError.d.ts.map +1 -1
- package/dist/odspError.js +14 -5
- package/dist/odspError.js.map +1 -1
- package/dist/odspPublicUtils.d.ts +14 -0
- package/dist/odspPublicUtils.d.ts.map +1 -1
- package/dist/odspPublicUtils.js.map +1 -1
- package/dist/odspSnapshotParser.d.ts +2 -2
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js +7 -4
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspUtils.d.ts +0 -7
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +4 -3
- package/dist/odspUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/compactSnapshotParser.d.ts +1 -1
- package/lib/compactSnapshotParser.d.ts.map +1 -1
- package/lib/compactSnapshotParser.js +7 -4
- package/lib/compactSnapshotParser.js.map +1 -1
- package/lib/compactSnapshotWriter.d.ts +1 -1
- package/lib/compactSnapshotWriter.d.ts.map +1 -1
- package/lib/compactSnapshotWriter.js +4 -3
- package/lib/compactSnapshotWriter.js.map +1 -1
- package/lib/contracts.d.ts +1 -1
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js.map +1 -1
- package/lib/createNewUtils.d.ts +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +1 -0
- package/lib/createNewUtils.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +7 -6
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +58 -33
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js +17 -17
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentService.d.ts.map +1 -1
- package/lib/odspDocumentService.js +9 -5
- package/lib/odspDocumentService.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +2 -2
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +13 -13
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspError.d.ts +3 -1
- package/lib/odspError.d.ts.map +1 -1
- package/lib/odspError.js +14 -5
- package/lib/odspError.js.map +1 -1
- package/lib/odspPublicUtils.d.ts +14 -0
- package/lib/odspPublicUtils.d.ts.map +1 -1
- package/lib/odspPublicUtils.js.map +1 -1
- package/lib/odspSnapshotParser.d.ts +2 -2
- package/lib/odspSnapshotParser.d.ts.map +1 -1
- package/lib/odspSnapshotParser.js +5 -2
- package/lib/odspSnapshotParser.js.map +1 -1
- package/lib/odspUtils.d.ts +0 -7
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +4 -3
- package/lib/odspUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +15 -15
- package/src/compactSnapshotParser.ts +10 -4
- package/src/compactSnapshotWriter.ts +7 -4
- package/src/contracts.ts +1 -1
- package/src/createFile.ts +2 -2
- package/src/createNewUtils.ts +2 -1
- package/src/fetchSnapshot.ts +113 -67
- package/src/index.ts +4 -0
- package/src/odspDocumentDeltaConnection.ts +17 -18
- package/src/odspDocumentService.ts +7 -3
- package/src/odspDocumentStorageManager.ts +18 -15
- package/src/odspError.ts +23 -10
- package/src/odspPublicUtils.ts +17 -0
- package/src/odspSnapshotParser.ts +8 -3
- package/src/odspUtils.ts +4 -11
- package/src/packageVersion.ts +1 -1
|
@@ -128,7 +128,7 @@ class SocketReference extends TypedEventEmitter<ISocketEvents> {
|
|
|
128
128
|
this.isPendingInitialConnection = false;
|
|
129
129
|
|
|
130
130
|
// Explicitly cast error to the specified event args type to ensure type compatibility
|
|
131
|
-
this.emit("server_disconnect", error
|
|
131
|
+
this.emit("server_disconnect", error);
|
|
132
132
|
this.closeSocket();
|
|
133
133
|
});
|
|
134
134
|
}
|
|
@@ -460,7 +460,7 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
|
|
|
460
460
|
};
|
|
461
461
|
}
|
|
462
462
|
|
|
463
|
-
this.socketReference!.
|
|
463
|
+
this.socketReference!.on("server_disconnect", this.serverDisconnectHandler);
|
|
464
464
|
|
|
465
465
|
this.socket.on("get_ops_response", (result: IGetOpsResponse) => {
|
|
466
466
|
const messages = result.messages;
|
|
@@ -553,21 +553,20 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
|
|
|
553
553
|
case "nack":
|
|
554
554
|
// per client / document nack handling
|
|
555
555
|
super.addTrackedListener(event, (clientIdOrDocumentId: string, nacks: INack[]) => {
|
|
556
|
-
|
|
556
|
+
const handle = clientIdOrDocumentId.length === 0 ||
|
|
557
557
|
clientIdOrDocumentId === this.documentId ||
|
|
558
|
-
(
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
558
|
+
(clientIdOrDocumentId === this.clientId);
|
|
559
|
+
const { code, type, message, retryAfter } = nacks[0]?.content ?? {};
|
|
560
|
+
this.logger.sendTelemetryEvent({
|
|
561
|
+
eventName: "ServerNack",
|
|
562
|
+
code,
|
|
563
|
+
type,
|
|
564
|
+
message,
|
|
565
|
+
retryAfterSeconds: retryAfter,
|
|
566
|
+
clientId: this.clientId,
|
|
567
|
+
handle,
|
|
568
|
+
});
|
|
569
|
+
if (handle) {
|
|
571
570
|
this.emit("nack", clientIdOrDocumentId, nacks);
|
|
572
571
|
}
|
|
573
572
|
});
|
|
@@ -585,9 +584,9 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
|
|
|
585
584
|
protected disconnect(socketProtocolError: boolean, reason: IAnyDriverError) {
|
|
586
585
|
const socket = this.socketReference;
|
|
587
586
|
assert(socket !== undefined, 0x0a2 /* "reentrancy not supported!" */);
|
|
588
|
-
this.socketReference = undefined;
|
|
589
587
|
|
|
590
|
-
this.
|
|
588
|
+
this.socketReference?.off("server_disconnect", this.serverDisconnectHandler);
|
|
589
|
+
this.socketReference = undefined;
|
|
591
590
|
|
|
592
591
|
if (!socketProtocolError && this.hasDetails) {
|
|
593
592
|
// tell the server we are disconnecting this client from the document
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
IDocumentServicePolicies,
|
|
22
22
|
DriverErrorType,
|
|
23
23
|
} from "@fluidframework/driver-definitions";
|
|
24
|
-
import { DeltaStreamConnectionForbiddenError, NonRetryableError } from "@fluidframework/driver-utils";
|
|
24
|
+
import { canRetryOnError, DeltaStreamConnectionForbiddenError, NonRetryableError } from "@fluidframework/driver-utils";
|
|
25
25
|
import { IFacetCodes } from "@fluidframework/odsp-doclib-utils";
|
|
26
26
|
import {
|
|
27
27
|
IClient,
|
|
@@ -415,12 +415,16 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
415
415
|
if (response.refreshAfterDeltaMs > 0) {
|
|
416
416
|
this.scheduleJoinSessionRefresh(response.refreshAfterDeltaMs)
|
|
417
417
|
.catch((error) => {
|
|
418
|
-
|
|
418
|
+
const canRetry = canRetryOnError(error);
|
|
419
|
+
// Only record error event in case it is non retriable.
|
|
420
|
+
if (!canRetry) {
|
|
421
|
+
this.mc.logger.sendErrorEvent({
|
|
419
422
|
eventName: "JoinSessionRefreshError",
|
|
420
423
|
details: JSON.stringify(props),
|
|
421
424
|
},
|
|
422
425
|
error,
|
|
423
|
-
|
|
426
|
+
);
|
|
427
|
+
}
|
|
424
428
|
});
|
|
425
429
|
} else {
|
|
426
430
|
// Logging just for informational purposes to help with debugging as this is a new feature.
|
|
@@ -38,8 +38,8 @@ import { IOdspCache } from "./odspCache";
|
|
|
38
38
|
import {
|
|
39
39
|
createCacheSnapshotKey,
|
|
40
40
|
getWithRetryForTokenRefresh,
|
|
41
|
-
ISnapshotContents,
|
|
42
41
|
} from "./odspUtils";
|
|
42
|
+
import { ISnapshotContents } from "./odspPublicUtils";
|
|
43
43
|
import { defaultCacheExpiryTimeoutMs, EpochTracker } from "./epochTracker";
|
|
44
44
|
import { OdspSummaryUploadManager } from "./odspSummaryUploadManager";
|
|
45
45
|
import { FlushResult } from "./odspDocumentDeltaConnection";
|
|
@@ -275,7 +275,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
275
275
|
method: "POST",
|
|
276
276
|
},
|
|
277
277
|
"createBlob",
|
|
278
|
-
|
|
278
|
+
));
|
|
279
279
|
event.end({
|
|
280
280
|
blobId: res.content.id,
|
|
281
281
|
...res.propsToLog,
|
|
@@ -343,14 +343,14 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
343
343
|
return this.readBlobCore(blobId);
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
-
public async getSnapshotTree(version?: api.IVersion): Promise<api.ISnapshotTree | null> {
|
|
346
|
+
public async getSnapshotTree(version?: api.IVersion, scenarioName?: string): Promise<api.ISnapshotTree | null> {
|
|
347
347
|
if (!this.snapshotUrl) {
|
|
348
348
|
return null;
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
let id: string;
|
|
352
352
|
if (!version || !version.id) {
|
|
353
|
-
const versions = await this.getVersions(null, 1);
|
|
353
|
+
const versions = await this.getVersions(null, 1, scenarioName);
|
|
354
354
|
if (!versions || versions.length === 0) {
|
|
355
355
|
return null;
|
|
356
356
|
}
|
|
@@ -359,7 +359,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
359
359
|
id = version.id;
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
-
const snapshotTree = await this.readTree(id);
|
|
362
|
+
const snapshotTree = await this.readTree(id, scenarioName);
|
|
363
363
|
if (!snapshotTree) {
|
|
364
364
|
return null;
|
|
365
365
|
}
|
|
@@ -379,7 +379,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
379
379
|
return this.combineProtocolAndAppSnapshotTree(appTree, protocolTree);
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
-
public async getVersions(blobid: string | null, count: number): Promise<api.IVersion[]> {
|
|
382
|
+
public async getVersions(blobid: string | null, count: number, scenarioName?: string): Promise<api.IVersion[]> {
|
|
383
383
|
// Regular load workflow uses blobId === documentID to indicate "latest".
|
|
384
384
|
if (blobid !== this.documentId && blobid) {
|
|
385
385
|
// FluidFetch & FluidDebugger tools use empty sting to query for versions
|
|
@@ -437,14 +437,14 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
return snapshotCachedEntry;
|
|
440
|
-
|
|
440
|
+
});
|
|
441
441
|
|
|
442
442
|
// Based on the concurrentSnapshotFetch policy:
|
|
443
443
|
// Either retrieve both the network and cache snapshots concurrently and pick the first to return,
|
|
444
444
|
// or grab the cache value and then the network value if the cache value returns undefined.
|
|
445
445
|
let method: string;
|
|
446
446
|
if (this.hostPolicy.concurrentSnapshotFetch && !this.hostPolicy.summarizerClient) {
|
|
447
|
-
const networkSnapshotP = this.fetchSnapshot(hostSnapshotOptions);
|
|
447
|
+
const networkSnapshotP = this.fetchSnapshot(hostSnapshotOptions, scenarioName);
|
|
448
448
|
|
|
449
449
|
// Ensure that failures on both paths are ignored initially.
|
|
450
450
|
// I.e. if cache fails for some reason, we will proceed with network result.
|
|
@@ -478,7 +478,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
478
478
|
method = retrievedSnapshot !== undefined ? "cache" : "network";
|
|
479
479
|
|
|
480
480
|
if (retrievedSnapshot === undefined) {
|
|
481
|
-
retrievedSnapshot = await this.fetchSnapshot(hostSnapshotOptions);
|
|
481
|
+
retrievedSnapshot = await this.fetchSnapshot(hostSnapshotOptions, scenarioName);
|
|
482
482
|
}
|
|
483
483
|
}
|
|
484
484
|
if (method === "network") {
|
|
@@ -524,7 +524,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
524
524
|
eventName: "getVersions",
|
|
525
525
|
headers: Object.keys(headers).length !== 0 ? true : undefined,
|
|
526
526
|
},
|
|
527
|
-
async () => this.epochTracker.fetchAndParseAsJSON<IDocumentStorageGetVersionsResponse>(url, { headers }, "versions"),
|
|
527
|
+
async () => this.epochTracker.fetchAndParseAsJSON<IDocumentStorageGetVersionsResponse>(url, { headers }, "versions", undefined, scenarioName),
|
|
528
528
|
);
|
|
529
529
|
const versionsResponse = response.content;
|
|
530
530
|
if (!versionsResponse) {
|
|
@@ -548,8 +548,8 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
548
548
|
});
|
|
549
549
|
}
|
|
550
550
|
|
|
551
|
-
private async fetchSnapshot(hostSnapshotOptions: ISnapshotOptions | undefined) {
|
|
552
|
-
return this.fetchSnapshotCore(hostSnapshotOptions).catch((error) => {
|
|
551
|
+
private async fetchSnapshot(hostSnapshotOptions: ISnapshotOptions | undefined, scenarioName?: string) {
|
|
552
|
+
return this.fetchSnapshotCore(hostSnapshotOptions, scenarioName).catch((error) => {
|
|
553
553
|
// Issue #5895:
|
|
554
554
|
// If we are offline, this error is retryable. But that means that RetriableDocumentStorageService
|
|
555
555
|
// will run in circles calling getSnapshotTree, which would result in OdspDocumentStorageService class
|
|
@@ -562,7 +562,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
562
562
|
});
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
-
private async fetchSnapshotCore(hostSnapshotOptions: ISnapshotOptions | undefined) {
|
|
565
|
+
private async fetchSnapshotCore(hostSnapshotOptions: ISnapshotOptions | undefined, scenarioName?: string) {
|
|
566
566
|
const snapshotOptions: ISnapshotOptions = {
|
|
567
567
|
mds: this.maxSnapshotSizeLimit,
|
|
568
568
|
...hostSnapshotOptions,
|
|
@@ -589,6 +589,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
589
589
|
this.snapshotFormatFetchType,
|
|
590
590
|
controller,
|
|
591
591
|
this.epochTracker,
|
|
592
|
+
scenarioName,
|
|
592
593
|
);
|
|
593
594
|
};
|
|
594
595
|
const putInCache = async (valueWithEpoch: IVersionedValueWithEpoch) => {
|
|
@@ -648,7 +649,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
648
649
|
// Enable flushing only if we have single commit summary and this is not the initial summary for an empty file
|
|
649
650
|
if (".protocol" in summary.tree && context.ackHandle !== undefined) {
|
|
650
651
|
let retry = 0;
|
|
651
|
-
for (
|
|
652
|
+
for (; ;) {
|
|
652
653
|
const result = await this.flushCallback();
|
|
653
654
|
const seq = result.lastPersistedSequenceNumber;
|
|
654
655
|
if (seq !== undefined && seq >= context.referenceSequenceNumber) {
|
|
@@ -720,7 +721,7 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
720
721
|
}
|
|
721
722
|
}
|
|
722
723
|
|
|
723
|
-
private async readTree(id: string): Promise<api.ISnapshotTree | null> {
|
|
724
|
+
private async readTree(id: string, scenarioName?: string): Promise<api.ISnapshotTree | null> {
|
|
724
725
|
if (!this.snapshotUrl) {
|
|
725
726
|
return null;
|
|
726
727
|
}
|
|
@@ -733,6 +734,8 @@ export class OdspDocumentStorageService implements IDocumentStorageService {
|
|
|
733
734
|
url,
|
|
734
735
|
fetchOptions,
|
|
735
736
|
"snapshotTree",
|
|
737
|
+
undefined,
|
|
738
|
+
scenarioName,
|
|
736
739
|
);
|
|
737
740
|
};
|
|
738
741
|
const snapshot = await fetchSnapshot(
|
package/src/odspError.ts
CHANGED
|
@@ -4,20 +4,33 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { createOdspNetworkError } from "@fluidframework/odsp-doclib-utils";
|
|
7
|
+
import { DriverErrorType } from "@fluidframework/driver-definitions";
|
|
8
|
+
import { NonRetryableError } from "@fluidframework/driver-utils";
|
|
9
|
+
import { OdspError } from "@fluidframework/odsp-driver-definitions";
|
|
10
|
+
import { IFluidErrorBase } from "@fluidframework/telemetry-utils";
|
|
7
11
|
import { IOdspSocketError } from "./contracts";
|
|
12
|
+
import { pkgVersion as driverVersion } from "./packageVersion";
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Returns network error based on error object from ODSP socket (IOdspSocketError)
|
|
11
16
|
*/
|
|
12
|
-
export function errorObjectFromSocketError(socketError: IOdspSocketError, handler: string)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
message
|
|
17
|
-
socketError.
|
|
18
|
-
|
|
17
|
+
export function errorObjectFromSocketError(socketError: IOdspSocketError, handler: string):
|
|
18
|
+
IFluidErrorBase & OdspError {
|
|
19
|
+
// Make sure we always return something, and do not throw.
|
|
20
|
+
try {
|
|
21
|
+
// pre-0.58 error message prefix: OdspSocketError
|
|
22
|
+
const message = `ODSP socket error (${handler}): ${socketError.message}`;
|
|
23
|
+
const error = createOdspNetworkError(
|
|
24
|
+
message,
|
|
25
|
+
socketError.code,
|
|
26
|
+
socketError.retryAfter);
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
error.addTelemetryProperties({ odspError: true, relayServiceError: true });
|
|
29
|
+
return error;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return new NonRetryableError(
|
|
32
|
+
"Internal error: errorObjectFromSocketError",
|
|
33
|
+
DriverErrorType.fileNotFoundOrAccessDeniedError,
|
|
34
|
+
{ driverVersion });
|
|
35
|
+
}
|
|
23
36
|
}
|
package/src/odspPublicUtils.ts
CHANGED
|
@@ -4,8 +4,25 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { hashFile, IsoBuffer } from "@fluidframework/common-utils";
|
|
7
|
+
import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
7
8
|
|
|
8
9
|
export async function getHashedDocumentId(driveId: string, itemId: string): Promise<string> {
|
|
9
10
|
const buffer = IsoBuffer.from(`${driveId}_${itemId}`);
|
|
10
11
|
return encodeURIComponent(await hashFile(buffer, "SHA-256", "base64"));
|
|
11
12
|
}
|
|
13
|
+
|
|
14
|
+
export interface ISnapshotContents {
|
|
15
|
+
snapshotTree: ISnapshotTree;
|
|
16
|
+
blobs: Map<string, ArrayBuffer>;
|
|
17
|
+
ops: ISequencedDocumentMessage[];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Sequence number of the snapshot
|
|
21
|
+
*/
|
|
22
|
+
sequenceNumber: number | undefined;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sequence number for the latest op/snapshot for the file in ODSP
|
|
26
|
+
*/
|
|
27
|
+
latestSequenceNumber: number | undefined;
|
|
28
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { assert, stringToBuffer } from "@fluidframework/common-utils";
|
|
7
7
|
import * as api from "@fluidframework/protocol-definitions";
|
|
8
8
|
import { IOdspSnapshot, IOdspSnapshotCommit, ISnapshotTreeEx } from "./contracts";
|
|
9
|
-
import { ISnapshotContents } from "./
|
|
9
|
+
import { ISnapshotContents } from "./odspPublicUtils";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Build a tree hierarchy base on a flat tree
|
|
@@ -51,7 +51,7 @@ function buildHierarchy(flatTree: IOdspSnapshotCommit): api.ISnapshotTree {
|
|
|
51
51
|
* Converts existing IOdspSnapshot to snapshot tree, blob array and ops
|
|
52
52
|
* @param odspSnapshot - snapshot
|
|
53
53
|
*/
|
|
54
|
-
export function
|
|
54
|
+
export function convertOdspSnapshotToSnapshotTreeAndBlobs(
|
|
55
55
|
odspSnapshot: IOdspSnapshot,
|
|
56
56
|
): ISnapshotContents {
|
|
57
57
|
const blobsWithBufferContent = new Map<string, ArrayBuffer>();
|
|
@@ -62,11 +62,16 @@ export function convertOdspSnapshotToSnapsohtTreeAndBlobs(
|
|
|
62
62
|
blobsWithBufferContent.set(blob.id, stringToBuffer(blob.content, blob.encoding ?? "utf8"));
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
|
+
|
|
66
|
+
const sequenceNumber = odspSnapshot?.trees[0].sequenceNumber;
|
|
67
|
+
|
|
65
68
|
const val: ISnapshotContents = {
|
|
66
69
|
blobs: blobsWithBufferContent,
|
|
67
70
|
ops: odspSnapshot.ops?.map((op) => op.op) ?? [],
|
|
68
|
-
sequenceNumber
|
|
71
|
+
sequenceNumber,
|
|
69
72
|
snapshotTree: buildHierarchy(odspSnapshot.trees[0]),
|
|
73
|
+
latestSequenceNumber: (odspSnapshot.ops && odspSnapshot.ops.length > 0) ?
|
|
74
|
+
odspSnapshot.ops[odspSnapshot.ops.length - 1].sequenceNumber : sequenceNumber,
|
|
70
75
|
};
|
|
71
76
|
return val;
|
|
72
77
|
}
|
package/src/odspUtils.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
NetworkErrorBasic,
|
|
14
14
|
} from "@fluidframework/driver-utils";
|
|
15
15
|
import { assert, performance } from "@fluidframework/common-utils";
|
|
16
|
-
import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
17
16
|
import { ChildLogger, PerformanceEvent, wrapError } from "@fluidframework/telemetry-utils";
|
|
18
17
|
import {
|
|
19
18
|
fetchIncorrectResponse,
|
|
@@ -43,13 +42,6 @@ export const getWithRetryForTokenRefreshRepeat = "getWithRetryForTokenRefreshRep
|
|
|
43
42
|
/** Parse the given url and return the origin (host name) */
|
|
44
43
|
export const getOrigin = (url: string) => new URL(url).origin;
|
|
45
44
|
|
|
46
|
-
export interface ISnapshotContents {
|
|
47
|
-
snapshotTree: ISnapshotTree;
|
|
48
|
-
blobs: Map<string, ArrayBuffer>;
|
|
49
|
-
ops: ISequencedDocumentMessage[];
|
|
50
|
-
sequenceNumber: number | undefined;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
45
|
export interface IOdspResponse<T> {
|
|
54
46
|
content: T;
|
|
55
47
|
headers: Map<string, string>;
|
|
@@ -243,7 +235,8 @@ export const createOdspLogger = (logger?: ITelemetryBaseLogger) =>
|
|
|
243
235
|
ChildLogger.create(
|
|
244
236
|
logger,
|
|
245
237
|
"OdspDriver",
|
|
246
|
-
{
|
|
238
|
+
{
|
|
239
|
+
all:
|
|
247
240
|
{
|
|
248
241
|
driverVersion,
|
|
249
242
|
},
|
|
@@ -307,7 +300,7 @@ export function toInstrumentedOdspTokenFetcher(
|
|
|
307
300
|
if (token === null && throwOnNullToken) {
|
|
308
301
|
throw new NonRetryableError(
|
|
309
302
|
// pre-0.58 error message: Token is null for ${name} call
|
|
310
|
-
`The Host-provided token fetcher
|
|
303
|
+
`The Host-provided token fetcher returned null`,
|
|
311
304
|
OdspErrorType.fetchTokenError,
|
|
312
305
|
{ method: name, driverVersion });
|
|
313
306
|
}
|
|
@@ -319,7 +312,7 @@ export function toInstrumentedOdspTokenFetcher(
|
|
|
319
312
|
const tokenError = wrapError(
|
|
320
313
|
error,
|
|
321
314
|
(errorMessage) => new NetworkErrorBasic(
|
|
322
|
-
`The Host-provided token fetcher
|
|
315
|
+
`The Host-provided token fetcher threw an error: ${errorMessage}`,
|
|
323
316
|
OdspErrorType.fetchTokenError,
|
|
324
317
|
typeof rawCanRetry === "boolean" ? rawCanRetry : false /* canRetry */,
|
|
325
318
|
{ method: name, driverVersion }));
|
package/src/packageVersion.ts
CHANGED