@fluidframework/routerlicious-driver 2.0.0-dev.4.1.0.148229 → 2.0.0-dev.4.3.0.157531

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 (163) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +38 -0
  3. package/dist/contracts.d.ts +15 -0
  4. package/dist/contracts.d.ts.map +1 -0
  5. package/dist/contracts.js +7 -0
  6. package/dist/contracts.js.map +1 -0
  7. package/dist/deltaStorageService.d.ts +1 -1
  8. package/dist/deltaStorageService.d.ts.map +1 -1
  9. package/dist/deltaStorageService.js +7 -4
  10. package/dist/deltaStorageService.js.map +1 -1
  11. package/dist/documentService.d.ts +4 -2
  12. package/dist/documentService.d.ts.map +1 -1
  13. package/dist/documentService.js +11 -9
  14. package/dist/documentService.js.map +1 -1
  15. package/dist/documentServiceFactory.d.ts +2 -1
  16. package/dist/documentServiceFactory.d.ts.map +1 -1
  17. package/dist/documentServiceFactory.js +18 -8
  18. package/dist/documentServiceFactory.js.map +1 -1
  19. package/dist/documentStorageService.d.ts +3 -2
  20. package/dist/documentStorageService.d.ts.map +1 -1
  21. package/dist/documentStorageService.js +4 -4
  22. package/dist/documentStorageService.js.map +1 -1
  23. package/dist/gitManager.d.ts +30 -0
  24. package/dist/gitManager.d.ts.map +1 -0
  25. package/dist/gitManager.js +89 -0
  26. package/dist/gitManager.js.map +1 -0
  27. package/dist/historian.d.ts +33 -0
  28. package/dist/historian.d.ts.map +1 -0
  29. package/dist/historian.js +65 -0
  30. package/dist/historian.js.map +1 -0
  31. package/dist/packageVersion.d.ts +1 -1
  32. package/dist/packageVersion.js +1 -1
  33. package/dist/packageVersion.js.map +1 -1
  34. package/dist/r11sSnapshotParser.d.ts +15 -0
  35. package/dist/r11sSnapshotParser.d.ts.map +1 -0
  36. package/dist/r11sSnapshotParser.js +75 -0
  37. package/dist/r11sSnapshotParser.js.map +1 -0
  38. package/dist/restWrapper.d.ts +21 -8
  39. package/dist/restWrapper.d.ts.map +1 -1
  40. package/dist/restWrapper.js +93 -25
  41. package/dist/restWrapper.js.map +1 -1
  42. package/dist/restWrapperBase.d.ts +26 -0
  43. package/dist/restWrapperBase.d.ts.map +1 -0
  44. package/dist/restWrapperBase.js +55 -0
  45. package/dist/restWrapperBase.js.map +1 -0
  46. package/dist/retriableGitManager.d.ts +10 -21
  47. package/dist/retriableGitManager.d.ts.map +1 -1
  48. package/dist/retriableGitManager.js +0 -36
  49. package/dist/retriableGitManager.js.map +1 -1
  50. package/dist/shreddedSummaryDocumentStorageService.d.ts +1 -1
  51. package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  52. package/dist/shreddedSummaryDocumentStorageService.js +6 -6
  53. package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
  54. package/dist/storageContracts.d.ts +44 -0
  55. package/dist/storageContracts.d.ts.map +1 -0
  56. package/dist/storageContracts.js +7 -0
  57. package/dist/storageContracts.js.map +1 -0
  58. package/dist/summaryTreeUploadManager.d.ts +23 -0
  59. package/dist/summaryTreeUploadManager.d.ts.map +1 -0
  60. package/dist/summaryTreeUploadManager.js +110 -0
  61. package/dist/summaryTreeUploadManager.js.map +1 -0
  62. package/dist/treeUtils.d.ts +7 -0
  63. package/dist/treeUtils.d.ts.map +1 -1
  64. package/dist/treeUtils.js +23 -1
  65. package/dist/treeUtils.js.map +1 -1
  66. package/dist/wholeSummaryDocumentStorageService.d.ts +5 -4
  67. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  68. package/dist/wholeSummaryDocumentStorageService.js +74 -42
  69. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  70. package/dist/wholeSummaryUploadManager.d.ts +16 -0
  71. package/dist/wholeSummaryUploadManager.d.ts.map +1 -0
  72. package/dist/wholeSummaryUploadManager.js +38 -0
  73. package/dist/wholeSummaryUploadManager.js.map +1 -0
  74. package/lib/contracts.d.ts +15 -0
  75. package/lib/contracts.d.ts.map +1 -0
  76. package/lib/contracts.js +6 -0
  77. package/lib/contracts.js.map +1 -0
  78. package/lib/deltaStorageService.d.ts +1 -1
  79. package/lib/deltaStorageService.d.ts.map +1 -1
  80. package/lib/deltaStorageService.js +7 -4
  81. package/lib/deltaStorageService.js.map +1 -1
  82. package/lib/documentService.d.ts +4 -2
  83. package/lib/documentService.d.ts.map +1 -1
  84. package/lib/documentService.js +9 -7
  85. package/lib/documentService.js.map +1 -1
  86. package/lib/documentServiceFactory.d.ts +2 -1
  87. package/lib/documentServiceFactory.d.ts.map +1 -1
  88. package/lib/documentServiceFactory.js +18 -8
  89. package/lib/documentServiceFactory.js.map +1 -1
  90. package/lib/documentStorageService.d.ts +3 -2
  91. package/lib/documentStorageService.d.ts.map +1 -1
  92. package/lib/documentStorageService.js +4 -4
  93. package/lib/documentStorageService.js.map +1 -1
  94. package/lib/gitManager.d.ts +30 -0
  95. package/lib/gitManager.d.ts.map +1 -0
  96. package/lib/gitManager.js +85 -0
  97. package/lib/gitManager.js.map +1 -0
  98. package/lib/historian.d.ts +33 -0
  99. package/lib/historian.d.ts.map +1 -0
  100. package/lib/historian.js +60 -0
  101. package/lib/historian.js.map +1 -0
  102. package/lib/packageVersion.d.ts +1 -1
  103. package/lib/packageVersion.js +1 -1
  104. package/lib/packageVersion.js.map +1 -1
  105. package/lib/r11sSnapshotParser.d.ts +15 -0
  106. package/lib/r11sSnapshotParser.d.ts.map +1 -0
  107. package/lib/r11sSnapshotParser.js +71 -0
  108. package/lib/r11sSnapshotParser.js.map +1 -0
  109. package/lib/restWrapper.d.ts +21 -8
  110. package/lib/restWrapper.d.ts.map +1 -1
  111. package/lib/restWrapper.js +92 -26
  112. package/lib/restWrapper.js.map +1 -1
  113. package/lib/restWrapperBase.d.ts +26 -0
  114. package/lib/restWrapperBase.d.ts.map +1 -0
  115. package/lib/restWrapperBase.js +50 -0
  116. package/lib/restWrapperBase.js.map +1 -0
  117. package/lib/retriableGitManager.d.ts +10 -21
  118. package/lib/retriableGitManager.d.ts.map +1 -1
  119. package/lib/retriableGitManager.js +0 -36
  120. package/lib/retriableGitManager.js.map +1 -1
  121. package/lib/shreddedSummaryDocumentStorageService.d.ts +1 -1
  122. package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  123. package/lib/shreddedSummaryDocumentStorageService.js +5 -5
  124. package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
  125. package/lib/storageContracts.d.ts +44 -0
  126. package/lib/storageContracts.d.ts.map +1 -0
  127. package/lib/storageContracts.js +6 -0
  128. package/lib/storageContracts.js.map +1 -0
  129. package/lib/summaryTreeUploadManager.d.ts +23 -0
  130. package/lib/summaryTreeUploadManager.d.ts.map +1 -0
  131. package/lib/summaryTreeUploadManager.js +106 -0
  132. package/lib/summaryTreeUploadManager.js.map +1 -0
  133. package/lib/treeUtils.d.ts +7 -0
  134. package/lib/treeUtils.d.ts.map +1 -1
  135. package/lib/treeUtils.js +20 -0
  136. package/lib/treeUtils.js.map +1 -1
  137. package/lib/wholeSummaryDocumentStorageService.d.ts +5 -4
  138. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  139. package/lib/wholeSummaryDocumentStorageService.js +74 -42
  140. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  141. package/lib/wholeSummaryUploadManager.d.ts +16 -0
  142. package/lib/wholeSummaryUploadManager.d.ts.map +1 -0
  143. package/lib/wholeSummaryUploadManager.js +34 -0
  144. package/lib/wholeSummaryUploadManager.js.map +1 -0
  145. package/package.json +9 -10
  146. package/src/contracts.ts +16 -0
  147. package/src/deltaStorageService.ts +11 -3
  148. package/src/documentService.ts +11 -11
  149. package/src/documentServiceFactory.ts +35 -16
  150. package/src/documentStorageService.ts +8 -4
  151. package/src/gitManager.ts +116 -0
  152. package/src/historian.ts +121 -0
  153. package/src/packageVersion.ts +1 -1
  154. package/src/r11sSnapshotParser.ts +83 -0
  155. package/src/restWrapper.ts +114 -38
  156. package/src/restWrapperBase.ts +146 -0
  157. package/src/retriableGitManager.ts +17 -95
  158. package/src/shreddedSummaryDocumentStorageService.ts +7 -9
  159. package/src/storageContracts.ts +63 -0
  160. package/src/summaryTreeUploadManager.ts +160 -0
  161. package/src/treeUtils.ts +30 -0
  162. package/src/wholeSummaryDocumentStorageService.ts +117 -58
  163. package/src/wholeSummaryUploadManager.ts +64 -0
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { assert } from "@fluidframework/common-utils";
7
+ import { getW3CData } from "@fluidframework/driver-base";
7
8
  import {
8
9
  FiveDaysMs,
9
10
  IDocumentService,
@@ -33,6 +34,7 @@ import { parseFluidUrl, replaceDocumentIdInPath, getDiscoveredFluidResolvedUrl }
33
34
  import { ICache, InMemoryCache, NullCache } from "./cache";
34
35
  import { pkgVersion as driverVersion } from "./packageVersion";
35
36
  import { ISnapshotTreeVersion } from "./definitions";
37
+ import { INormalizedWholeSummary } from "./contracts";
36
38
 
37
39
  const maximumSnapshotCacheDurationMs: FiveDaysMs = 432_000_000; // 5 days in ms
38
40
 
@@ -54,7 +56,8 @@ const defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {
54
56
  export class RouterliciousDocumentServiceFactory implements IDocumentServiceFactory {
55
57
  private readonly driverPolicies: IRouterliciousDriverPolicies;
56
58
  private readonly blobCache: ICache<ArrayBufferLike>;
57
- private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>;
59
+ private readonly wholeSnapshotTreeCache: ICache<INormalizedWholeSummary> = new NullCache();
60
+ private readonly shreddedSummaryTreeCache: ICache<ISnapshotTreeVersion> = new NullCache();
58
61
 
59
62
  constructor(
60
63
  private readonly tokenProvider: ITokenProvider,
@@ -68,9 +71,17 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
68
71
  ...driverPolicies,
69
72
  };
70
73
  this.blobCache = new InMemoryCache<ArrayBufferLike>();
71
- this.snapshotTreeCache = this.driverPolicies.enableInternalSummaryCaching
72
- ? new InMemoryCache<ISnapshotTreeVersion>(snapshotCacheExpiryMs)
73
- : new NullCache<ISnapshotTreeVersion>();
74
+ if (this.driverPolicies.enableInternalSummaryCaching) {
75
+ if (this.driverPolicies.enableWholeSummaryUpload) {
76
+ this.wholeSnapshotTreeCache = new InMemoryCache<INormalizedWholeSummary>(
77
+ snapshotCacheExpiryMs,
78
+ );
79
+ } else {
80
+ this.shreddedSummaryTreeCache = new InMemoryCache<ISnapshotTreeVersion>(
81
+ snapshotCacheExpiryMs,
82
+ );
83
+ }
84
+ }
74
85
  }
75
86
 
76
87
  /**
@@ -128,15 +139,17 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
128
139
  },
129
140
  async (event) => {
130
141
  // @TODO: Remove returned "string" type when removing back-compat code
131
- const postRes = await ordererRestWrapper.post<
132
- { id: string; token?: string; session?: ISession } | string
133
- >(`/documents/${tenantId}`, {
134
- summary: convertSummaryToCreateNewSummary(appSummary),
135
- sequenceNumber: documentAttributes.sequenceNumber,
136
- values: quorumValues,
137
- enableDiscovery: this.driverPolicies.enableDiscovery,
138
- generateToken: this.tokenProvider.documentPostCreateCallback !== undefined,
139
- });
142
+ const postRes = (
143
+ await ordererRestWrapper.post<
144
+ { id: string; token?: string; session?: ISession } | string
145
+ >(`/documents/${tenantId}`, {
146
+ summary: convertSummaryToCreateNewSummary(appSummary),
147
+ sequenceNumber: documentAttributes.sequenceNumber,
148
+ values: quorumValues,
149
+ enableDiscovery: this.driverPolicies.enableDiscovery,
150
+ generateToken: this.tokenProvider.documentPostCreateCallback !== undefined,
151
+ })
152
+ ).content;
140
153
 
141
154
  event.end({
142
155
  docId: typeof postRes === "string" ? postRes : postRes.id,
@@ -253,11 +266,16 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
253
266
  eventName: "DiscoverSession",
254
267
  docId: documentId,
255
268
  },
256
- async () => {
269
+ async (event) => {
257
270
  // The service responds with the current document session associated with the container.
258
- return ordererRestWrapper.get<ISession>(
271
+ const response = await ordererRestWrapper.get<ISession>(
259
272
  `${resolvedUrl.endpoints.ordererUrl}/documents/${tenantId}/session/${documentId}`,
260
273
  );
274
+ event.end({
275
+ ...response.propsToLog,
276
+ ...getW3CData(response.requestUrl, "xmlhttprequest"),
277
+ });
278
+ return response.content;
261
279
  },
262
280
  );
263
281
  return getDiscoveredFluidResolvedUrl(resolvedUrl, discoveredSession);
@@ -299,7 +317,8 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
299
317
  documentStorageServicePolicies,
300
318
  this.driverPolicies,
301
319
  this.blobCache,
302
- this.snapshotTreeCache,
320
+ this.wholeSnapshotTreeCache,
321
+ this.shreddedSummaryTreeCache,
303
322
  discoverFluidResolvedUrl,
304
323
  );
305
324
  }
@@ -10,7 +10,6 @@ import {
10
10
  LoaderCachingPolicy,
11
11
  } from "@fluidframework/driver-definitions";
12
12
  import { ISnapshotTree, IVersion } from "@fluidframework/protocol-definitions";
13
- import { GitManager } from "@fluidframework/server-services-client";
14
13
  import {
15
14
  DocumentStorageServiceProxy,
16
15
  PrefetchDocumentStorageService,
@@ -19,7 +18,9 @@ import { IRouterliciousDriverPolicies } from "./policies";
19
18
  import { ICache } from "./cache";
20
19
  import { WholeSummaryDocumentStorageService } from "./wholeSummaryDocumentStorageService";
21
20
  import { ShreddedSummaryDocumentStorageService } from "./shreddedSummaryDocumentStorageService";
21
+ import { GitManager } from "./gitManager";
22
22
  import { ISnapshotTreeVersion } from "./definitions";
23
+ import { INormalizedWholeSummary } from "./contracts";
23
24
 
24
25
  export class DocumentStorageService extends DocumentStorageServiceProxy {
25
26
  private _logTailSha: string | undefined = undefined;
@@ -35,7 +36,8 @@ export class DocumentStorageService extends DocumentStorageServiceProxy {
35
36
  policies: IDocumentStorageServicePolicies,
36
37
  driverPolicies?: IRouterliciousDriverPolicies,
37
38
  blobCache?: ICache<ArrayBufferLike>,
38
- snapshotTreeCache?: ICache<ISnapshotTreeVersion>,
39
+ snapshotTreeCache?: ICache<INormalizedWholeSummary>,
40
+ shreddedSummaryTreeCache?: ICache<ISnapshotTreeVersion>,
39
41
  noCacheGitManager?: GitManager,
40
42
  getStorageManager?: (disableCache?: boolean) => Promise<GitManager>,
41
43
  ): IDocumentStorageService {
@@ -58,7 +60,7 @@ export class DocumentStorageService extends DocumentStorageServiceProxy {
58
60
  policies,
59
61
  driverPolicies,
60
62
  blobCache,
61
- snapshotTreeCache,
63
+ shreddedSummaryTreeCache,
62
64
  getStorageManager,
63
65
  );
64
66
  // TODO: worth prefetching latest summary making version + snapshot call with WholeSummary storage?
@@ -78,7 +80,8 @@ export class DocumentStorageService extends DocumentStorageServiceProxy {
78
80
  policies: IDocumentStorageServicePolicies,
79
81
  driverPolicies?: IRouterliciousDriverPolicies,
80
82
  blobCache?: ICache<ArrayBufferLike>,
81
- snapshotTreeCache?: ICache<ISnapshotTreeVersion>,
83
+ snapshotTreeCache?: ICache<INormalizedWholeSummary>,
84
+ shreddedSummaryTreeCache?: ICache<ISnapshotTreeVersion>,
82
85
  public noCacheGitManager?: GitManager,
83
86
  getStorageManager?: (disableCache?: boolean) => Promise<GitManager>,
84
87
  ) {
@@ -91,6 +94,7 @@ export class DocumentStorageService extends DocumentStorageServiceProxy {
91
94
  driverPolicies,
92
95
  blobCache,
93
96
  snapshotTreeCache,
97
+ shreddedSummaryTreeCache,
94
98
  noCacheGitManager,
95
99
  getStorageManager,
96
100
  ),
@@ -0,0 +1,116 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import * as resources from "@fluidframework/gitresources";
7
+ import {
8
+ IWholeFlatSummary,
9
+ IWholeSummaryPayload,
10
+ IWriteSummaryResponse,
11
+ } from "@fluidframework/server-services-client";
12
+ import { IGitManager, IHistorian } from "./storageContracts";
13
+ import { IR11sResponse, createR11sResponseFromContent } from "./restWrapper";
14
+
15
+ export class GitManager implements IGitManager {
16
+ private readonly blobCache = new Map<string, resources.IBlob>();
17
+ private readonly commitCache = new Map<string, resources.ICommit>();
18
+ private readonly treeCache = new Map<string, resources.ITree>();
19
+ private readonly refCache = new Map<string, string>();
20
+
21
+ constructor(private readonly historian: IHistorian) {}
22
+
23
+ /**
24
+ * Reads the object with the given ID. We defer to the client implementation to do the actual read.
25
+ */
26
+ public async getCommits(
27
+ shaOrRef: string,
28
+ count: number,
29
+ ): Promise<IR11sResponse<resources.ICommitDetails[]>> {
30
+ let sha: string | undefined = shaOrRef;
31
+
32
+ // See if the sha is really a ref and convert
33
+ if (this.refCache.has(shaOrRef)) {
34
+ sha = this.refCache.get(shaOrRef);
35
+
36
+ // Delete refcache after first use
37
+ this.refCache.delete(shaOrRef);
38
+
39
+ // If null is stored for the ref then there are no commits - return an empty array
40
+ if (!sha) {
41
+ return createR11sResponseFromContent([]);
42
+ }
43
+ }
44
+
45
+ // See if the commit sha is hashed and return it if so
46
+ const commit = this.commitCache.get(sha);
47
+ if (commit !== undefined) {
48
+ return createR11sResponseFromContent([
49
+ {
50
+ commit: {
51
+ author: commit.author,
52
+ committer: commit.committer,
53
+ message: commit.message,
54
+ tree: commit.tree,
55
+ url: commit.url,
56
+ },
57
+ parents: commit.parents,
58
+ sha: commit.sha,
59
+ url: commit.url,
60
+ },
61
+ ]);
62
+ }
63
+
64
+ // Otherwise fall back to the historian
65
+ return this.historian.getCommits(sha, count);
66
+ }
67
+
68
+ /**
69
+ * Reads the object with the given ID. We defer to the client implementation to do the actual read.
70
+ */
71
+ public async getTree(root: string, recursive = true): Promise<IR11sResponse<resources.ITree>> {
72
+ const tree = this.treeCache.get(root);
73
+ if (tree !== undefined) {
74
+ return createR11sResponseFromContent(tree);
75
+ }
76
+
77
+ return this.historian.getTree(root, recursive);
78
+ }
79
+
80
+ public async getBlob(sha: string): Promise<IR11sResponse<resources.IBlob>> {
81
+ const blob = this.blobCache.get(sha);
82
+ if (blob !== undefined) {
83
+ return createR11sResponseFromContent(blob);
84
+ }
85
+ return this.historian.getBlob(sha);
86
+ }
87
+
88
+ public async createBlob(
89
+ content: string,
90
+ encoding: "utf-8" | "base64",
91
+ ): Promise<IR11sResponse<resources.ICreateBlobResponse>> {
92
+ const blob: resources.ICreateBlobParams = {
93
+ content,
94
+ encoding,
95
+ };
96
+ return this.historian.createBlob(blob);
97
+ }
98
+
99
+ public async createGitTree(
100
+ params: resources.ICreateTreeParams,
101
+ ): Promise<IR11sResponse<resources.ITree>> {
102
+ const treeP = this.historian.createTree(params);
103
+ return treeP;
104
+ }
105
+
106
+ public async createSummary(
107
+ summary: IWholeSummaryPayload,
108
+ initial: boolean = false,
109
+ ): Promise<IR11sResponse<IWriteSummaryResponse>> {
110
+ return this.historian.createSummary(summary, initial);
111
+ }
112
+
113
+ public async getSummary(sha: string): Promise<IR11sResponse<IWholeFlatSummary>> {
114
+ return this.historian.getSummary(sha);
115
+ }
116
+ }
@@ -0,0 +1,121 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { fromUtf8ToBase64 } from "@fluidframework/common-utils";
7
+ import * as git from "@fluidframework/gitresources";
8
+ import {
9
+ IWholeFlatSummary,
10
+ IWholeSummaryPayload,
11
+ IWriteSummaryResponse,
12
+ } from "@fluidframework/server-services-client";
13
+ import { QueryStringType, RestWrapper } from "./restWrapperBase";
14
+ import { IR11sResponse } from "./restWrapper";
15
+ import { IHistorian } from "./storageContracts";
16
+
17
+ export interface ICredentials {
18
+ user: string;
19
+ password: string;
20
+ }
21
+
22
+ export const getAuthorizationTokenFromCredentials = (credentials: ICredentials): string =>
23
+ `Basic ${fromUtf8ToBase64(`${credentials.user}:${credentials.password}`)}`;
24
+
25
+ /**
26
+ * Implementation of the IHistorian interface that calls out to a REST interface
27
+ */
28
+ export class Historian implements IHistorian {
29
+ private readonly defaultQueryString: QueryStringType = {};
30
+ private readonly cacheBust: boolean;
31
+
32
+ constructor(
33
+ private readonly historianApi: boolean,
34
+ disableCache: boolean,
35
+ private readonly restWrapper: RestWrapper,
36
+ ) {
37
+ if (disableCache && this.historianApi) {
38
+ this.defaultQueryString.disableCache = disableCache;
39
+ this.cacheBust = false;
40
+ } else {
41
+ this.cacheBust = disableCache;
42
+ }
43
+ }
44
+
45
+ public async getBlob(sha: string): Promise<IR11sResponse<git.IBlob>> {
46
+ return this.restWrapper.get<git.IBlob>(
47
+ `/git/blobs/${encodeURIComponent(sha)}`,
48
+ this.getQueryString(),
49
+ );
50
+ }
51
+
52
+ public async createBlob(
53
+ blob: git.ICreateBlobParams,
54
+ ): Promise<IR11sResponse<git.ICreateBlobResponse>> {
55
+ return this.restWrapper.post<git.ICreateBlobResponse>(
56
+ `/git/blobs`,
57
+ blob,
58
+ this.getQueryString(),
59
+ );
60
+ }
61
+
62
+ public async getCommits(
63
+ sha: string,
64
+ count: number,
65
+ ): Promise<IR11sResponse<git.ICommitDetails[]>> {
66
+ return this.restWrapper
67
+ .get<git.ICommitDetails[]>(`/commits`, this.getQueryString({ count, sha }))
68
+ .catch((error) =>
69
+ error.statusCode === 400 || error.statusCode === 404
70
+ ? {
71
+ content: [],
72
+ headers: new Map(),
73
+ propsToLog: {},
74
+ requestUrl: "",
75
+ }
76
+ : Promise.reject<IR11sResponse<git.ICommitDetails[]>>(error),
77
+ );
78
+ }
79
+
80
+ public async createTree(tree: git.ICreateTreeParams): Promise<IR11sResponse<git.ITree>> {
81
+ return this.restWrapper.post<git.ITree>(`/git/trees`, tree, this.getQueryString());
82
+ }
83
+
84
+ public async getTree(sha: string, recursive: boolean): Promise<IR11sResponse<git.ITree>> {
85
+ return this.restWrapper.get<git.ITree>(
86
+ `/git/trees/${encodeURIComponent(sha)}`,
87
+ this.getQueryString({ recursive: recursive ? 1 : 0 }),
88
+ );
89
+ }
90
+ public async createSummary(
91
+ summary: IWholeSummaryPayload,
92
+ initial?: boolean,
93
+ ): Promise<IR11sResponse<IWriteSummaryResponse>> {
94
+ return this.restWrapper.post<IWriteSummaryResponse>(
95
+ `/git/summaries`,
96
+ summary,
97
+ this.getQueryString(initial !== undefined ? { initial } : undefined),
98
+ );
99
+ }
100
+
101
+ public async getSummary(sha: string): Promise<IR11sResponse<IWholeFlatSummary>> {
102
+ return this.restWrapper.get<IWholeFlatSummary>(
103
+ `/git/summaries/${sha}`,
104
+ this.getQueryString(),
105
+ );
106
+ }
107
+
108
+ private getQueryString(queryString?: QueryStringType): QueryStringType {
109
+ if (this.cacheBust) {
110
+ return {
111
+ cacheBust: Date.now(),
112
+ ...this.defaultQueryString,
113
+ ...queryString,
114
+ };
115
+ }
116
+ return {
117
+ ...this.defaultQueryString,
118
+ ...queryString,
119
+ };
120
+ }
121
+ }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/routerlicious-driver";
9
- export const pkgVersion = "2.0.0-dev.4.1.0.148229";
9
+ export const pkgVersion = "2.0.0-dev.4.3.0.157531";
@@ -0,0 +1,83 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { ISnapshotTree } from "@fluidframework/protocol-definitions";
7
+ import { IWholeFlatSummary, IWholeFlatSummaryTree } from "@fluidframework/server-services-client";
8
+ import { stringToBuffer } from "@fluidframework/common-utils";
9
+ import { INormalizedWholeSummary } from "./contracts";
10
+
11
+ /**
12
+ * Build a tree heirarchy from a flat tree.
13
+ *
14
+ * @param flatTree - a flat tree
15
+ * @param treePrefixToRemove - tree prefix to strip
16
+ * @returns the heirarchical tree
17
+ */
18
+ function buildHierarchy(
19
+ flatTree: IWholeFlatSummaryTree,
20
+ treePrefixToRemove: string,
21
+ ): ISnapshotTree {
22
+ const lookup: { [path: string]: ISnapshotTree } = {};
23
+ // Root tree id will be used to determine which version was downloaded.
24
+ const root: ISnapshotTree = { id: flatTree.id, blobs: {}, trees: {} };
25
+ lookup[""] = root;
26
+
27
+ for (const entry of flatTree.entries) {
28
+ // Strip the `treePrefixToRemove` path from tree entries such that they are stored under root.
29
+ const entryPath = entry.path.replace(new RegExp(`^${treePrefixToRemove}/`), "");
30
+ const lastIndex = entryPath.lastIndexOf("/");
31
+ const entryPathDir = entryPath.slice(0, Math.max(0, lastIndex));
32
+ const entryPathBase = entryPath.slice(lastIndex + 1);
33
+
34
+ // The flat output is breadth-first so we can assume we see tree nodes prior to their contents
35
+ const node = lookup[entryPathDir];
36
+
37
+ // Add in either the blob or tree
38
+ if (entry.type === "tree") {
39
+ const newTree: ISnapshotTree = {
40
+ blobs: {},
41
+ trees: {},
42
+ unreferenced: entry.unreferenced,
43
+ };
44
+ node.trees[decodeURIComponent(entryPathBase)] = newTree;
45
+ lookup[entryPath] = newTree;
46
+ } else if (entry.type === "blob") {
47
+ node.blobs[decodeURIComponent(entryPathBase)] = entry.id;
48
+ } else {
49
+ throw new Error(`Unknown entry type!!`);
50
+ }
51
+ }
52
+
53
+ return root;
54
+ }
55
+
56
+ /**
57
+ * Converts existing IWholeFlatSummary to snapshot tree, blob array, and sequence number.
58
+ *
59
+ * @param flatSummary - flat summary
60
+ * @param treePrefixToRemove - tree prefix to strip. By default we are stripping ".app" prefix
61
+ * @returns snapshot tree, blob array, and sequence number
62
+ */
63
+ export function convertWholeFlatSummaryToSnapshotTreeAndBlobs(
64
+ flatSummary: IWholeFlatSummary,
65
+ treePrefixToRemove: string = ".app",
66
+ ): INormalizedWholeSummary {
67
+ const blobs = new Map<string, ArrayBuffer>();
68
+ if (flatSummary.blobs) {
69
+ flatSummary.blobs.forEach((blob) => {
70
+ blobs.set(blob.id, stringToBuffer(blob.content, blob.encoding ?? "utf-8"));
71
+ });
72
+ }
73
+ const flatSummaryTree = flatSummary.trees?.[0];
74
+ const sequenceNumber = flatSummaryTree?.sequenceNumber;
75
+ const snapshotTree = buildHierarchy(flatSummaryTree, treePrefixToRemove);
76
+
77
+ return {
78
+ blobs,
79
+ snapshotTree,
80
+ sequenceNumber,
81
+ id: flatSummary.id,
82
+ };
83
+ }