@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.
Files changed (122) hide show
  1. package/dist/compactSnapshotParser.d.ts +1 -1
  2. package/dist/compactSnapshotParser.d.ts.map +1 -1
  3. package/dist/compactSnapshotParser.js +7 -4
  4. package/dist/compactSnapshotParser.js.map +1 -1
  5. package/dist/compactSnapshotWriter.d.ts +1 -1
  6. package/dist/compactSnapshotWriter.d.ts.map +1 -1
  7. package/dist/compactSnapshotWriter.js +4 -3
  8. package/dist/compactSnapshotWriter.js.map +1 -1
  9. package/dist/contracts.d.ts +1 -1
  10. package/dist/contracts.d.ts.map +1 -1
  11. package/dist/contracts.js.map +1 -1
  12. package/dist/createFile.d.ts.map +1 -1
  13. package/dist/createFile.js.map +1 -1
  14. package/dist/createNewUtils.d.ts +1 -1
  15. package/dist/createNewUtils.d.ts.map +1 -1
  16. package/dist/createNewUtils.js +1 -0
  17. package/dist/createNewUtils.js.map +1 -1
  18. package/dist/fetchSnapshot.d.ts +7 -6
  19. package/dist/fetchSnapshot.d.ts.map +1 -1
  20. package/dist/fetchSnapshot.js +57 -31
  21. package/dist/fetchSnapshot.js.map +1 -1
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +3 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  27. package/dist/odspDocumentDeltaConnection.js +17 -17
  28. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  29. package/dist/odspDocumentService.d.ts.map +1 -1
  30. package/dist/odspDocumentService.js +8 -4
  31. package/dist/odspDocumentService.js.map +1 -1
  32. package/dist/odspDocumentStorageManager.d.ts +2 -2
  33. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  34. package/dist/odspDocumentStorageManager.js +13 -13
  35. package/dist/odspDocumentStorageManager.js.map +1 -1
  36. package/dist/odspError.d.ts +3 -1
  37. package/dist/odspError.d.ts.map +1 -1
  38. package/dist/odspError.js +14 -5
  39. package/dist/odspError.js.map +1 -1
  40. package/dist/odspPublicUtils.d.ts +14 -0
  41. package/dist/odspPublicUtils.d.ts.map +1 -1
  42. package/dist/odspPublicUtils.js.map +1 -1
  43. package/dist/odspSnapshotParser.d.ts +2 -2
  44. package/dist/odspSnapshotParser.d.ts.map +1 -1
  45. package/dist/odspSnapshotParser.js +7 -4
  46. package/dist/odspSnapshotParser.js.map +1 -1
  47. package/dist/odspUtils.d.ts +0 -7
  48. package/dist/odspUtils.d.ts.map +1 -1
  49. package/dist/odspUtils.js +4 -3
  50. package/dist/odspUtils.js.map +1 -1
  51. package/dist/packageVersion.d.ts +1 -1
  52. package/dist/packageVersion.js +1 -1
  53. package/dist/packageVersion.js.map +1 -1
  54. package/lib/compactSnapshotParser.d.ts +1 -1
  55. package/lib/compactSnapshotParser.d.ts.map +1 -1
  56. package/lib/compactSnapshotParser.js +7 -4
  57. package/lib/compactSnapshotParser.js.map +1 -1
  58. package/lib/compactSnapshotWriter.d.ts +1 -1
  59. package/lib/compactSnapshotWriter.d.ts.map +1 -1
  60. package/lib/compactSnapshotWriter.js +4 -3
  61. package/lib/compactSnapshotWriter.js.map +1 -1
  62. package/lib/contracts.d.ts +1 -1
  63. package/lib/contracts.d.ts.map +1 -1
  64. package/lib/contracts.js.map +1 -1
  65. package/lib/createFile.d.ts.map +1 -1
  66. package/lib/createFile.js.map +1 -1
  67. package/lib/createNewUtils.d.ts +1 -1
  68. package/lib/createNewUtils.d.ts.map +1 -1
  69. package/lib/createNewUtils.js +1 -0
  70. package/lib/createNewUtils.js.map +1 -1
  71. package/lib/fetchSnapshot.d.ts +7 -6
  72. package/lib/fetchSnapshot.d.ts.map +1 -1
  73. package/lib/fetchSnapshot.js +58 -33
  74. package/lib/fetchSnapshot.js.map +1 -1
  75. package/lib/index.d.ts +2 -0
  76. package/lib/index.d.ts.map +1 -1
  77. package/lib/index.js +3 -0
  78. package/lib/index.js.map +1 -1
  79. package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
  80. package/lib/odspDocumentDeltaConnection.js +17 -17
  81. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  82. package/lib/odspDocumentService.d.ts.map +1 -1
  83. package/lib/odspDocumentService.js +9 -5
  84. package/lib/odspDocumentService.js.map +1 -1
  85. package/lib/odspDocumentStorageManager.d.ts +2 -2
  86. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  87. package/lib/odspDocumentStorageManager.js +13 -13
  88. package/lib/odspDocumentStorageManager.js.map +1 -1
  89. package/lib/odspError.d.ts +3 -1
  90. package/lib/odspError.d.ts.map +1 -1
  91. package/lib/odspError.js +14 -5
  92. package/lib/odspError.js.map +1 -1
  93. package/lib/odspPublicUtils.d.ts +14 -0
  94. package/lib/odspPublicUtils.d.ts.map +1 -1
  95. package/lib/odspPublicUtils.js.map +1 -1
  96. package/lib/odspSnapshotParser.d.ts +2 -2
  97. package/lib/odspSnapshotParser.d.ts.map +1 -1
  98. package/lib/odspSnapshotParser.js +5 -2
  99. package/lib/odspSnapshotParser.js.map +1 -1
  100. package/lib/odspUtils.d.ts +0 -7
  101. package/lib/odspUtils.d.ts.map +1 -1
  102. package/lib/odspUtils.js +4 -3
  103. package/lib/odspUtils.js.map +1 -1
  104. package/lib/packageVersion.d.ts +1 -1
  105. package/lib/packageVersion.js +1 -1
  106. package/lib/packageVersion.js.map +1 -1
  107. package/package.json +15 -15
  108. package/src/compactSnapshotParser.ts +10 -4
  109. package/src/compactSnapshotWriter.ts +7 -4
  110. package/src/contracts.ts +1 -1
  111. package/src/createFile.ts +2 -2
  112. package/src/createNewUtils.ts +2 -1
  113. package/src/fetchSnapshot.ts +113 -67
  114. package/src/index.ts +4 -0
  115. package/src/odspDocumentDeltaConnection.ts +17 -18
  116. package/src/odspDocumentService.ts +7 -3
  117. package/src/odspDocumentStorageManager.ts +18 -15
  118. package/src/odspError.ts +23 -10
  119. package/src/odspPublicUtils.ts +17 -0
  120. package/src/odspSnapshotParser.ts +8 -3
  121. package/src/odspUtils.ts +4 -11
  122. 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 as IFluidErrorBase & OdspError);
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!.once("server_disconnect", this.serverDisconnectHandler);
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
- if (clientIdOrDocumentId.length === 0 ||
556
+ const handle = clientIdOrDocumentId.length === 0 ||
557
557
  clientIdOrDocumentId === this.documentId ||
558
- (this.hasDetails && clientIdOrDocumentId === this.clientId)) {
559
- const nackContent = nacks[0]?.content;
560
- if (nackContent !== undefined) {
561
- const { code, type, message, retryAfter } = nackContent;
562
- this.logger.sendTelemetryEvent({
563
- eventName: "ServerNack",
564
- code,
565
- type,
566
- message,
567
- retryAfterSeconds: retryAfter,
568
- clientId: this.clientId,
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.socket.off("server_disconnect", this.serverDisconnectHandler);
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
- this.mc.logger.sendErrorEvent({
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
- // pre-0.58 error message prefix: OdspSocketError
14
- const message = `ODSP socket error (${handler}): ${socketError.message}`;
15
- const error = createOdspNetworkError(
16
- message,
17
- socketError.code,
18
- socketError.retryAfter);
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
- error.addTelemetryProperties({ odspError: true, relayServiceError: true });
21
-
22
- return error;
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
  }
@@ -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 "./odspUtils";
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 convertOdspSnapshotToSnapsohtTreeAndBlobs(
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: odspSnapshot?.trees[0].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
- { all:
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 for ${name} call returned null`,
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 for ${name} call threw an error: ${errorMessage}`,
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 }));
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/odsp-driver";
9
- export const pkgVersion = "1.0.1";
9
+ export const pkgVersion = "1.1.0";