@fluidframework/routerlicious-driver 0.57.2 → 0.58.1000

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 (72) hide show
  1. package/dist/definitions.d.ts +10 -0
  2. package/dist/definitions.d.ts.map +1 -0
  3. package/dist/definitions.js +7 -0
  4. package/dist/definitions.js.map +1 -0
  5. package/dist/documentService.d.ts +3 -2
  6. package/dist/documentService.d.ts.map +1 -1
  7. package/dist/documentService.js.map +1 -1
  8. package/dist/documentServiceFactory.d.ts.map +1 -1
  9. package/dist/documentServiceFactory.js.map +1 -1
  10. package/dist/documentStorageService.d.ts +2 -1
  11. package/dist/documentStorageService.d.ts.map +1 -1
  12. package/dist/documentStorageService.js.map +1 -1
  13. package/dist/errorUtils.d.ts +2 -2
  14. package/dist/errorUtils.d.ts.map +1 -1
  15. package/dist/errorUtils.js +11 -11
  16. package/dist/errorUtils.js.map +1 -1
  17. package/dist/packageVersion.d.ts +1 -1
  18. package/dist/packageVersion.d.ts.map +1 -1
  19. package/dist/packageVersion.js +1 -1
  20. package/dist/packageVersion.js.map +1 -1
  21. package/dist/restWrapper.d.ts.map +1 -1
  22. package/dist/restWrapper.js +10 -3
  23. package/dist/restWrapper.js.map +1 -1
  24. package/dist/shreddedSummaryDocumentStorageService.d.ts +3 -2
  25. package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  26. package/dist/shreddedSummaryDocumentStorageService.js +3 -3
  27. package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
  28. package/dist/wholeSummaryDocumentStorageService.d.ts +2 -1
  29. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  30. package/dist/wholeSummaryDocumentStorageService.js +16 -13
  31. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  32. package/lib/definitions.d.ts +10 -0
  33. package/lib/definitions.d.ts.map +1 -0
  34. package/lib/definitions.js +6 -0
  35. package/lib/definitions.js.map +1 -0
  36. package/lib/documentService.d.ts +3 -2
  37. package/lib/documentService.d.ts.map +1 -1
  38. package/lib/documentService.js.map +1 -1
  39. package/lib/documentServiceFactory.d.ts.map +1 -1
  40. package/lib/documentServiceFactory.js.map +1 -1
  41. package/lib/documentStorageService.d.ts +2 -1
  42. package/lib/documentStorageService.d.ts.map +1 -1
  43. package/lib/documentStorageService.js.map +1 -1
  44. package/lib/errorUtils.d.ts +2 -2
  45. package/lib/errorUtils.d.ts.map +1 -1
  46. package/lib/errorUtils.js +11 -11
  47. package/lib/errorUtils.js.map +1 -1
  48. package/lib/packageVersion.d.ts +1 -1
  49. package/lib/packageVersion.d.ts.map +1 -1
  50. package/lib/packageVersion.js +1 -1
  51. package/lib/packageVersion.js.map +1 -1
  52. package/lib/restWrapper.d.ts.map +1 -1
  53. package/lib/restWrapper.js +10 -3
  54. package/lib/restWrapper.js.map +1 -1
  55. package/lib/shreddedSummaryDocumentStorageService.d.ts +3 -2
  56. package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  57. package/lib/shreddedSummaryDocumentStorageService.js +3 -3
  58. package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
  59. package/lib/wholeSummaryDocumentStorageService.d.ts +2 -1
  60. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  61. package/lib/wholeSummaryDocumentStorageService.js +16 -13
  62. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  63. package/package.json +13 -13
  64. package/src/definitions.ts +11 -0
  65. package/src/documentService.ts +3 -2
  66. package/src/documentServiceFactory.ts +3 -2
  67. package/src/documentStorageService.ts +3 -2
  68. package/src/errorUtils.ts +7 -11
  69. package/src/packageVersion.ts +1 -1
  70. package/src/restWrapper.ts +13 -9
  71. package/src/shreddedSummaryDocumentStorageService.ts +6 -6
  72. package/src/wholeSummaryDocumentStorageService.ts +20 -16
package/src/errorUtils.ts CHANGED
@@ -48,7 +48,6 @@ export interface IR11sError {
48
48
  export type R11sError = DriverError | IR11sError;
49
49
 
50
50
  export function createR11sNetworkError(
51
- fluidErrorCode: string,
52
51
  errorMessage: string,
53
52
  statusCode?: number,
54
53
  retryAfterMs?: number,
@@ -60,33 +59,31 @@ export function createR11sNetworkError(
60
59
  // a network error with no status code (e.g. err:ERR_CONN_REFUSED or err:ERR_FAILED) and
61
60
  // the error message will start with NetworkError as defined in restWrapper.ts
62
61
  return new GenericNetworkError(
63
- fluidErrorCode, errorMessage, errorMessage.startsWith("NetworkError"), props);
62
+ errorMessage, errorMessage.startsWith("NetworkError"), props);
64
63
  case 401:
65
64
  case 403:
66
65
  return new AuthorizationError(
67
- fluidErrorCode, errorMessage, undefined, undefined, props);
66
+ errorMessage, undefined, undefined, props);
68
67
  case 404:
69
68
  const errorType = R11sErrorType.fileNotFoundOrAccessDeniedError;
70
- return new NonRetryableError(fluidErrorCode, errorMessage, errorType, props);
69
+ return new NonRetryableError(errorMessage, errorType, props);
71
70
  case 429:
72
71
  return createGenericNetworkError(
73
- fluidErrorCode, errorMessage, { canRetry: true, retryAfterMs }, props);
72
+ errorMessage, { canRetry: true, retryAfterMs }, props);
74
73
  case 500:
75
- return new GenericNetworkError(fluidErrorCode, errorMessage, true, props);
74
+ return new GenericNetworkError(errorMessage, true, props);
76
75
  default:
77
76
  const retryInfo = { canRetry: retryAfterMs !== undefined, retryAfterMs };
78
- return createGenericNetworkError(fluidErrorCode, errorMessage, retryInfo, props);
77
+ return createGenericNetworkError(errorMessage, retryInfo, props);
79
78
  }
80
79
  }
81
80
 
82
81
  export function throwR11sNetworkError(
83
- fluidErrorCode: string,
84
82
  errorMessage: string,
85
83
  statusCode?: number,
86
84
  retryAfterMs?: number,
87
85
  ): never {
88
86
  const networkError = createR11sNetworkError(
89
- fluidErrorCode,
90
87
  errorMessage,
91
88
  statusCode,
92
89
  retryAfterMs);
@@ -99,9 +96,8 @@ export function throwR11sNetworkError(
99
96
  * Returns network error based on error object from R11s socket (IR11sSocketError)
100
97
  */
101
98
  export function errorObjectFromSocketError(socketError: IR11sSocketError, handler: string): R11sError {
102
- const message = `R11sSocketError (${handler}): ${socketError.message}`;
99
+ const message = `R11s socket error (${handler}): ${socketError.message}`;
103
100
  return createR11sNetworkError(
104
- "r11sSocketError",
105
101
  message,
106
102
  socketError.code,
107
103
  socketError.retryAfterMs,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/routerlicious-driver";
9
- export const pkgVersion = "0.57.2";
9
+ export const pkgVersion = "0.58.1000";
@@ -16,7 +16,7 @@ import {
16
16
  RequestInfo as FetchRequestInfo,
17
17
  RequestInit as FetchRequestInit,
18
18
  } from "node-fetch";
19
- import type { AxiosRequestConfig } from "axios";
19
+ import type { AxiosRequestConfig, AxiosRequestHeaders } from "axios";
20
20
  import safeStringify from "json-stringify-safe";
21
21
  import { v4 as uuid } from "uuid";
22
22
  import { throwR11sNetworkError } from "./errorUtils";
@@ -37,7 +37,9 @@ const axiosRequestConfigToFetchRequestConfig = (requestConfig: AxiosRequestConfi
37
37
  : requestConfig.url ?? "";
38
38
  const requestInit: RequestInit = {
39
39
  method: requestConfig.method,
40
- headers: requestConfig.headers,
40
+ // NOTE: I believe that although the Axios type permits non-string values in the header, here we are
41
+ // guaranteed the requestConfig only has string values in its header.
42
+ headers: requestConfig.headers as Record<string, string>,
41
43
  body: requestConfig.data,
42
44
  };
43
45
  return [requestInfo, requestInit];
@@ -102,23 +104,25 @@ export class RouterliciousRestWrapper extends RestWrapper {
102
104
  }, responseBody.retryAfter * 1000));
103
105
  }
104
106
 
107
+ const responseSummary = responseBody !== undefined
108
+ ? typeof responseBody === "string" ? responseBody : safeStringify(responseBody)
109
+ : response.statusText;
105
110
  throwR11sNetworkError(
106
- "r11sFetchError",
107
- responseBody !== undefined
108
- ? typeof responseBody === "string" ? responseBody : safeStringify(responseBody)
109
- : response.statusText,
111
+ `R11s fetch error: ${responseSummary}`,
110
112
  response.status,
111
113
  responseBody?.retryAfter,
112
114
  );
113
115
  }
114
116
 
115
- private generateHeaders(requestHeaders?: Record<string, unknown>): Record<string, unknown> {
117
+ private generateHeaders(requestHeaders?: AxiosRequestHeaders | undefined): Record<string, string> {
116
118
  const correlationId = requestHeaders?.["x-correlation-id"] || uuid();
117
119
 
118
120
  return {
119
121
  ...requestHeaders,
120
- "x-correlation-id": correlationId,
121
- "Authorization": this.authorizationHeader,
122
+ // NOTE: Can correlationId actually be number | true?
123
+ "x-correlation-id": correlationId as string,
124
+ // NOTE: If this.authorizationHeader is undefined, should "Authorization" be removed entirely?
125
+ "Authorization": this.authorizationHeader!,
122
126
  };
123
127
  }
124
128
  }
@@ -16,7 +16,6 @@ import {
16
16
  import { buildHierarchy } from "@fluidframework/protocol-base";
17
17
  import {
18
18
  ICreateBlobResponse,
19
- ISnapshotTree,
20
19
  ISnapshotTreeEx,
21
20
  ISummaryHandle,
22
21
  ISummaryTree,
@@ -32,6 +31,7 @@ import { PerformanceEvent } from "@fluidframework/telemetry-utils";
32
31
  import { IRouterliciousDriverPolicies } from "./policies";
33
32
  import { ICache, InMemoryCache } from "./cache";
34
33
  import { RetriableGitManager } from "./retriableGitManager";
34
+ import { ISnapshotTreeVersion } from "./definitions";
35
35
 
36
36
  const isNode = typeof window === "undefined";
37
37
 
@@ -45,7 +45,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
45
45
  // empty strings as values.
46
46
  protected readonly blobsShaCache = new Map<string, string>();
47
47
  private readonly blobCache: ICache<ArrayBufferLike> | undefined;
48
- private readonly snapshotTreeCache: ICache<ISnapshotTreeEx> | undefined;
48
+ private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> | undefined;
49
49
  private readonly summaryUploadManager: ISummaryUploadManager;
50
50
 
51
51
  public get repositoryUrl(): string {
@@ -59,7 +59,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
59
59
  public readonly policies: IDocumentStorageServicePolicies = {},
60
60
  driverPolicies?: IRouterliciousDriverPolicies,
61
61
  blobCache?: ICache<ArrayBufferLike>,
62
- snapshotTreeCache?: ICache<ISnapshotTree>) {
62
+ snapshotTreeCache?: ICache<ISnapshotTreeVersion>) {
63
63
  this.summaryUploadManager = new SummaryTreeUploadManager(
64
64
  new RetriableGitManager(manager, logger),
65
65
  this.blobsShaCache,
@@ -67,7 +67,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
67
67
  );
68
68
  if (driverPolicies?.enableRestLess === true || isNode) {
69
69
  this.blobCache = blobCache ?? new InMemoryCache();
70
- this.snapshotTreeCache = (snapshotTreeCache ?? new InMemoryCache()) as ICache<ISnapshotTreeEx>;
70
+ this.snapshotTreeCache = snapshotTreeCache ?? new InMemoryCache();
71
71
  }
72
72
  }
73
73
 
@@ -102,7 +102,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
102
102
 
103
103
  const cachedSnapshotTree = await this.snapshotTreeCache?.get(requestVersion.treeId);
104
104
  if (cachedSnapshotTree) {
105
- return cachedSnapshotTree;
105
+ return cachedSnapshotTree.snapshotTree as ISnapshotTreeEx;
106
106
  }
107
107
 
108
108
  const rawTree = await PerformanceEvent.timedExecAsync(
@@ -120,7 +120,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
120
120
  },
121
121
  );
122
122
  const tree = buildHierarchy(rawTree, this.blobsShaCache, true);
123
- await this.snapshotTreeCache?.put(tree.id, tree);
123
+ await this.snapshotTreeCache?.put(tree.id, { id: requestVersion.id, snapshotTree: tree });
124
124
  return tree;
125
125
  }
126
126
 
@@ -30,6 +30,7 @@ import {
30
30
  } from "@fluidframework/server-services-client";
31
31
  import { PerformanceEvent } from "@fluidframework/telemetry-utils";
32
32
  import { ICache, InMemoryCache } from "./cache";
33
+ import { ISnapshotTreeVersion } from "./definitions";
33
34
 
34
35
  const latestSnapshotId: string = "latest";
35
36
 
@@ -47,13 +48,13 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
47
48
  protected readonly logger: ITelemetryLogger,
48
49
  public readonly policies: IDocumentStorageServicePolicies = {},
49
50
  private readonly blobCache: ICache<ArrayBufferLike> = new InMemoryCache(),
50
- private readonly snapshotTreeCache: ICache<ISnapshotTree> = new InMemoryCache()) {
51
+ private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> = new InMemoryCache()) {
51
52
  this.summaryUploadManager = new WholeSummaryUploadManager(manager);
52
53
  }
53
54
 
54
55
  public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {
55
56
  if (versionId !== this.id && versionId !== null) {
56
- // Blobs in this scenario will never have multiple versions, so return blobId as is
57
+ // Blobs/Trees in this scenario will never have multiple versions, so return versionId as is
57
58
  return [{
58
59
  id: versionId,
59
60
  treeId: undefined!,
@@ -63,9 +64,10 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
63
64
  // Fetch latest summary, cache it, and return its id.
64
65
  if (this.firstVersionsCall && count === 1) {
65
66
  this.firstVersionsCall = false;
67
+ const { id, snapshotTree } = await this.fetchAndCacheSnapshotTree(latestSnapshotId);
66
68
  return [{
67
- id: (await this.fetchAndCacheSnapshotTree(latestSnapshotId)).id,
68
- treeId: undefined!,
69
+ id,
70
+ treeId: snapshotTree.id!,
69
71
  }];
70
72
  }
71
73
 
@@ -83,7 +85,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
83
85
  return commits.map((commit) => ({
84
86
  date: commit.commit.author.date,
85
87
  id: commit.sha,
86
- treeId: undefined!,
88
+ treeId: commit.commit.tree.sha,
87
89
  }));
88
90
  }
89
91
 
@@ -168,10 +170,10 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
168
170
  );
169
171
  }
170
172
 
171
- private async fetchAndCacheSnapshotTree(versionId: string): Promise<{ id: string, snapshotTree: ISnapshotTree }> {
172
- const cachedSnapshotTree = await this.snapshotTreeCache.get(versionId);
173
- if (cachedSnapshotTree !== undefined) {
174
- return { id: cachedSnapshotTree.id!, snapshotTree: cachedSnapshotTree };
173
+ private async fetchAndCacheSnapshotTree(versionId: string): Promise<ISnapshotTreeVersion> {
174
+ const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);
175
+ if (cachedSnapshotTreeVersion !== undefined) {
176
+ return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };
175
177
  }
176
178
 
177
179
  const wholeFlatSummary = await PerformanceEvent.timedExecAsync(
@@ -189,30 +191,32 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
189
191
  },
190
192
  );
191
193
  const normalizedWholeSummary = convertWholeFlatSummaryToSnapshotTreeAndBlobs(wholeFlatSummary);
192
- const snapshotId = normalizedWholeSummary.snapshotTree.id;
193
- assert(snapshotId !== undefined, 0x275 /* "Root tree should contain the id" */);
194
+ const wholeFlatSummaryId: string = wholeFlatSummary.id;
195
+ const snapshotTreeId = normalizedWholeSummary.snapshotTree.id;
196
+ assert(snapshotTreeId !== undefined, 0x275 /* "Root tree should contain the id" */);
197
+ const snapshotTreeVersion = { id: wholeFlatSummaryId , snapshotTree: normalizedWholeSummary.snapshotTree };
194
198
 
195
199
  const cachePs: Promise<any>[] = [
196
200
  this.snapshotTreeCache.put(
197
- snapshotId,
198
- normalizedWholeSummary.snapshotTree,
201
+ snapshotTreeId,
202
+ snapshotTreeVersion,
199
203
  ),
200
204
  this.initBlobCache(normalizedWholeSummary.blobs),
201
205
  ];
202
- if (snapshotId !== versionId) {
206
+ if (snapshotTreeId !== versionId) {
203
207
  // versionId could be "latest". When summarizer checks cache for "latest", we want it to be available.
204
208
  // TODO: For in-memory cache, <latest,snapshotTree> will be a shared pointer with <snapshotId,snapshotTree>,
205
209
  // However, for something like Redis, this will cache the same value twice. Alternatively, could we simply
206
210
  // cache with versionId?
207
211
  cachePs.push(this.snapshotTreeCache.put(
208
212
  versionId,
209
- normalizedWholeSummary.snapshotTree,
213
+ snapshotTreeVersion,
210
214
  ));
211
215
  }
212
216
 
213
217
  await Promise.all(cachePs);
214
218
 
215
- return { id: snapshotId, snapshotTree: normalizedWholeSummary.snapshotTree};
219
+ return snapshotTreeVersion;
216
220
  }
217
221
 
218
222
  private async initBlobCache(blobs: Map<string, ArrayBuffer>): Promise<void> {