@fluidframework/routerlicious-driver 2.0.0-dev.4.2.0.153917 → 2.0.0-dev.4.3.0.158678

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 (66) hide show
  1. package/dist/contracts.d.ts +15 -0
  2. package/dist/contracts.d.ts.map +1 -0
  3. package/dist/contracts.js +7 -0
  4. package/dist/contracts.js.map +1 -0
  5. package/dist/documentService.d.ts +1 -1
  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 +1 -1
  11. package/dist/documentStorageService.d.ts.map +1 -1
  12. package/dist/documentStorageService.js.map +1 -1
  13. package/dist/packageVersion.d.ts +1 -1
  14. package/dist/packageVersion.js +1 -1
  15. package/dist/packageVersion.js.map +1 -1
  16. package/dist/r11sSnapshotParser.d.ts +15 -0
  17. package/dist/r11sSnapshotParser.d.ts.map +1 -0
  18. package/dist/r11sSnapshotParser.js +75 -0
  19. package/dist/r11sSnapshotParser.js.map +1 -0
  20. package/dist/restWrapper.js +1 -1
  21. package/dist/restWrapper.js.map +1 -1
  22. package/dist/treeUtils.d.ts +1 -1
  23. package/dist/treeUtils.d.ts.map +1 -1
  24. package/dist/treeUtils.js.map +1 -1
  25. package/dist/wholeSummaryDocumentStorageService.d.ts +1 -1
  26. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  27. package/dist/wholeSummaryDocumentStorageService.js +19 -20
  28. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  29. package/lib/contracts.d.ts +15 -0
  30. package/lib/contracts.d.ts.map +1 -0
  31. package/lib/contracts.js +6 -0
  32. package/lib/contracts.js.map +1 -0
  33. package/lib/documentService.d.ts +1 -1
  34. package/lib/documentService.d.ts.map +1 -1
  35. package/lib/documentService.js.map +1 -1
  36. package/lib/documentServiceFactory.d.ts.map +1 -1
  37. package/lib/documentServiceFactory.js.map +1 -1
  38. package/lib/documentStorageService.d.ts +1 -1
  39. package/lib/documentStorageService.d.ts.map +1 -1
  40. package/lib/documentStorageService.js.map +1 -1
  41. package/lib/packageVersion.d.ts +1 -1
  42. package/lib/packageVersion.js +1 -1
  43. package/lib/packageVersion.js.map +1 -1
  44. package/lib/r11sSnapshotParser.d.ts +15 -0
  45. package/lib/r11sSnapshotParser.d.ts.map +1 -0
  46. package/lib/r11sSnapshotParser.js +71 -0
  47. package/lib/r11sSnapshotParser.js.map +1 -0
  48. package/lib/restWrapper.js +1 -1
  49. package/lib/restWrapper.js.map +1 -1
  50. package/lib/treeUtils.d.ts +1 -1
  51. package/lib/treeUtils.d.ts.map +1 -1
  52. package/lib/treeUtils.js.map +1 -1
  53. package/lib/wholeSummaryDocumentStorageService.d.ts +1 -1
  54. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  55. package/lib/wholeSummaryDocumentStorageService.js +17 -18
  56. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  57. package/package.json +9 -9
  58. package/src/contracts.ts +16 -0
  59. package/src/documentService.ts +1 -1
  60. package/src/documentServiceFactory.ts +2 -1
  61. package/src/documentStorageService.ts +1 -1
  62. package/src/packageVersion.ts +1 -1
  63. package/src/r11sSnapshotParser.ts +83 -0
  64. package/src/restWrapper.ts +1 -1
  65. package/src/treeUtils.ts +1 -1
  66. package/src/wholeSummaryDocumentStorageService.ts +18 -29
@@ -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.2.0.153917";
9
+ export const pkgVersion = "2.0.0-dev.4.3.0.158678";
@@ -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
+ }
@@ -203,7 +203,7 @@ export class RouterliciousRestWrapper extends RestWrapper {
203
203
  requestHeaders?: AxiosRequestHeaders | undefined,
204
204
  ): Promise<Record<string, string>> {
205
205
  const token = await this.getToken();
206
- assert(token !== undefined, "token should be present");
206
+ assert(token !== undefined, 0x679 /* token should be present */);
207
207
  const correlationId = requestHeaders?.["x-correlation-id"] ?? uuid();
208
208
 
209
209
  return {
package/src/treeUtils.ts CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  ISummaryTree,
11
11
  SummaryObject,
12
12
  } from "@fluidframework/protocol-definitions";
13
- import { INormalizedWholeSummary } from "@fluidframework/server-services-client";
13
+ import { INormalizedWholeSummary } from "./contracts";
14
14
 
15
15
  /**
16
16
  * Summary tree assembler props
@@ -23,11 +23,7 @@ import {
23
23
  ISummaryTree,
24
24
  IVersion,
25
25
  } from "@fluidframework/protocol-definitions";
26
- import {
27
- convertWholeFlatSummaryToSnapshotTreeAndBlobs,
28
- INormalizedWholeSummary,
29
- IWholeFlatSummary,
30
- } from "@fluidframework/server-services-client";
26
+ import { IWholeFlatSummary } from "@fluidframework/server-services-client";
31
27
  import { PerformanceEvent } from "@fluidframework/telemetry-utils";
32
28
  import { ICache, InMemoryCache } from "./cache";
33
29
  import { IRouterliciousDriverPolicies } from "./policies";
@@ -40,6 +36,8 @@ import { GitManager } from "./gitManager";
40
36
  import { WholeSummaryUploadManager } from "./wholeSummaryUploadManager";
41
37
  import { ISummaryUploadManager } from "./storageContracts";
42
38
  import { IR11sResponse } from "./restWrapper";
39
+ import { INormalizedWholeSummary } from "./contracts";
40
+ import { convertWholeFlatSummaryToSnapshotTreeAndBlobs } from "./r11sSnapshotParser";
43
41
 
44
42
  const latestSnapshotId: string = "latest";
45
43
 
@@ -100,8 +98,8 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
100
98
  );
101
99
 
102
100
  const networkSnapshotP = !this.driverPolicies?.enableDiscovery
103
- ? this.fetchSnapshotTree(latestSnapshotId, false)
104
- : this.fetchSnapshotTree(latestSnapshotId, true);
101
+ ? this.fetchSnapshotTree(latestSnapshotId, false, "getVersions")
102
+ : this.fetchSnapshotTree(latestSnapshotId, true, "getVersions");
105
103
 
106
104
  const promiseRaceWinner = await promiseRaceWithWinner([
107
105
  cachedSnapshotP.catch(() => undefined),
@@ -130,10 +128,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
130
128
  },
131
129
  );
132
130
 
133
- const _id = await this.initializeFromSnapshot(
134
- normalizedSnapshotContents,
135
- latestSnapshotId,
136
- );
131
+ const _id = await this.initializeFromSnapshot(normalizedSnapshotContents);
137
132
  this.firstVersionsCall = false;
138
133
  return [
139
134
  {
@@ -181,7 +176,8 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
181
176
  if (normalizedWholeSnapshot !== undefined) {
182
177
  return normalizedWholeSnapshot.snapshotTree;
183
178
  }
184
- return (await this.fetchSnapshotTree(requestVersion.id)).snapshotTree;
179
+ return (await this.fetchSnapshotTree(requestVersion.id, undefined, "getSnapshotTree"))
180
+ .snapshotTree;
185
181
  }
186
182
 
187
183
  public async readBlob(blobId: string): Promise<ArrayBufferLike> {
@@ -284,12 +280,14 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
284
280
  private async fetchSnapshotTree(
285
281
  versionId: string,
286
282
  disableCache?: boolean,
283
+ scenarioName?: string,
287
284
  ): Promise<INormalizedWholeSummary> {
288
285
  const normalizedWholeSummary = await PerformanceEvent.timedExecAsync(
289
286
  this.logger,
290
287
  {
291
288
  eventName: "getWholeFlatSummary",
292
289
  treeId: versionId,
290
+ scenarioName,
293
291
  },
294
292
  async (event) => {
295
293
  const manager = await this.getStorageManager(disableCache);
@@ -316,35 +314,26 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
316
314
  },
317
315
  );
318
316
 
317
+ // Also add the result into the cache.
318
+ await this.snapshotTreeCache
319
+ .put(this.getCacheKey(versionId), normalizedWholeSummary)
320
+ .catch(() => undefined);
319
321
  return normalizedWholeSummary;
320
322
  }
321
323
 
322
324
  private async initializeFromSnapshot(
323
325
  normalizedWholeSummary: INormalizedWholeSummary,
324
- versionId: string | null,
325
326
  ): Promise<string> {
326
- const wholeFlatSummaryId = normalizedWholeSummary.snapshotTree.id;
327
- assert(wholeFlatSummaryId !== undefined, 0x275 /* "Root tree should contain the id" */);
327
+ const snapshotId = normalizedWholeSummary.id;
328
+ assert(snapshotId !== undefined, 0x275 /* "Root tree should contain the id" */);
328
329
  const cachePs: Promise<any>[] = [
329
- this.snapshotTreeCache.put(
330
- this.getCacheKey(wholeFlatSummaryId),
331
- normalizedWholeSummary,
332
- ),
330
+ this.snapshotTreeCache.put(this.getCacheKey(snapshotId), normalizedWholeSummary),
333
331
  this.initBlobCache(normalizedWholeSummary.blobs),
334
332
  ];
335
- if (wholeFlatSummaryId !== versionId && versionId !== null) {
336
- // versionId could be "latest". When summarizer checks cache for "latest", we want it to be available.
337
- // TODO: For in-memory cache, <latest,snapshotTree> will be a shared pointer with <snapshotId,snapshotTree>,
338
- // However, for something like Redis, this will cache the same value twice. Alternatively, could we simply
339
- // cache with versionId?
340
- cachePs.push(
341
- this.snapshotTreeCache.put(this.getCacheKey(versionId), normalizedWholeSummary),
342
- );
343
- }
344
333
 
345
334
  await Promise.all(cachePs);
346
335
 
347
- return wholeFlatSummaryId;
336
+ return snapshotId;
348
337
  }
349
338
 
350
339
  private async initBlobCache(blobs: Map<string, ArrayBuffer>): Promise<void> {