@fluidframework/routerlicious-driver 0.59.1001-62246 → 0.59.2000

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 (83) hide show
  1. package/dist/documentDeltaConnection.d.ts.map +1 -1
  2. package/dist/documentDeltaConnection.js +3 -1
  3. package/dist/documentDeltaConnection.js.map +1 -1
  4. package/dist/documentService.d.ts.map +1 -1
  5. package/dist/documentService.js +3 -1
  6. package/dist/documentService.js.map +1 -1
  7. package/dist/documentServiceFactory.d.ts +1 -1
  8. package/dist/documentServiceFactory.d.ts.map +1 -1
  9. package/dist/documentServiceFactory.js +33 -12
  10. package/dist/documentServiceFactory.js.map +1 -1
  11. package/dist/documentStorageService.d.ts +2 -1
  12. package/dist/documentStorageService.d.ts.map +1 -1
  13. package/dist/documentStorageService.js +5 -4
  14. package/dist/documentStorageService.js.map +1 -1
  15. package/dist/errorUtils.d.ts +6 -0
  16. package/dist/errorUtils.d.ts.map +1 -1
  17. package/dist/errorUtils.js +2 -0
  18. package/dist/errorUtils.js.map +1 -1
  19. package/dist/packageVersion.d.ts +1 -1
  20. package/dist/packageVersion.d.ts.map +1 -1
  21. package/dist/packageVersion.js +1 -1
  22. package/dist/packageVersion.js.map +1 -1
  23. package/dist/policies.d.ts +5 -0
  24. package/dist/policies.d.ts.map +1 -1
  25. package/dist/policies.js.map +1 -1
  26. package/dist/restWrapper.d.ts.map +1 -1
  27. package/dist/restWrapper.js +3 -1
  28. package/dist/restWrapper.js.map +1 -1
  29. package/dist/urlUtils.d.ts +3 -0
  30. package/dist/urlUtils.d.ts.map +1 -1
  31. package/dist/urlUtils.js +28 -1
  32. package/dist/urlUtils.js.map +1 -1
  33. package/dist/wholeSummaryDocumentStorageService.d.ts +4 -1
  34. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  35. package/dist/wholeSummaryDocumentStorageService.js +11 -4
  36. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  37. package/lib/documentDeltaConnection.d.ts.map +1 -1
  38. package/lib/documentDeltaConnection.js +3 -1
  39. package/lib/documentDeltaConnection.js.map +1 -1
  40. package/lib/documentService.d.ts.map +1 -1
  41. package/lib/documentService.js +3 -1
  42. package/lib/documentService.js.map +1 -1
  43. package/lib/documentServiceFactory.d.ts +1 -1
  44. package/lib/documentServiceFactory.d.ts.map +1 -1
  45. package/lib/documentServiceFactory.js +34 -13
  46. package/lib/documentServiceFactory.js.map +1 -1
  47. package/lib/documentStorageService.d.ts +2 -1
  48. package/lib/documentStorageService.d.ts.map +1 -1
  49. package/lib/documentStorageService.js +5 -4
  50. package/lib/documentStorageService.js.map +1 -1
  51. package/lib/errorUtils.d.ts +6 -0
  52. package/lib/errorUtils.d.ts.map +1 -1
  53. package/lib/errorUtils.js +2 -0
  54. package/lib/errorUtils.js.map +1 -1
  55. package/lib/packageVersion.d.ts +1 -1
  56. package/lib/packageVersion.d.ts.map +1 -1
  57. package/lib/packageVersion.js +1 -1
  58. package/lib/packageVersion.js.map +1 -1
  59. package/lib/policies.d.ts +5 -0
  60. package/lib/policies.d.ts.map +1 -1
  61. package/lib/policies.js.map +1 -1
  62. package/lib/restWrapper.d.ts.map +1 -1
  63. package/lib/restWrapper.js +3 -1
  64. package/lib/restWrapper.js.map +1 -1
  65. package/lib/urlUtils.d.ts +3 -0
  66. package/lib/urlUtils.d.ts.map +1 -1
  67. package/lib/urlUtils.js +26 -0
  68. package/lib/urlUtils.js.map +1 -1
  69. package/lib/wholeSummaryDocumentStorageService.d.ts +4 -1
  70. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  71. package/lib/wholeSummaryDocumentStorageService.js +11 -4
  72. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  73. package/package.json +15 -11
  74. package/src/documentDeltaConnection.ts +3 -1
  75. package/src/documentService.ts +9 -2
  76. package/src/documentServiceFactory.ts +50 -19
  77. package/src/documentStorageService.ts +7 -2
  78. package/src/errorUtils.ts +9 -0
  79. package/src/packageVersion.ts +1 -1
  80. package/src/policies.ts +5 -0
  81. package/src/restWrapper.ts +3 -0
  82. package/src/urlUtils.ts +31 -0
  83. package/src/wholeSummaryDocumentStorageService.ts +13 -6
@@ -1 +1 @@
1
- {"version":3,"file":"wholeSummaryDocumentStorageService.js","sourceRoot":"","sources":["../src/wholeSummaryDocumentStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n assert,\n stringToBuffer,\n Uint8ArrayToString,\n} from \"@fluidframework/common-utils\";\nimport {\n IDocumentStorageService,\n ISummaryContext,\n IDocumentStorageServicePolicies,\n } from \"@fluidframework/driver-definitions\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n ITree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n convertWholeFlatSummaryToSnapshotTreeAndBlobs,\n GitManager,\n ISummaryUploadManager,\n WholeSummaryUploadManager,\n} from \"@fluidframework/server-services-client\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { ICache, InMemoryCache } from \"./cache\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\n\nconst latestSnapshotId: string = \"latest\";\n\nexport class WholeSummaryDocumentStorageService implements IDocumentStorageService {\n private readonly summaryUploadManager: ISummaryUploadManager;\n private firstVersionsCall: boolean = true;\n\n public get repositoryUrl(): string {\n return \"\";\n }\n\n constructor(\n protected readonly id: string,\n protected readonly manager: GitManager,\n protected readonly logger: ITelemetryLogger,\n public readonly policies: IDocumentStorageServicePolicies = {},\n private readonly blobCache: ICache<ArrayBufferLike> = new InMemoryCache(),\n private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> = new InMemoryCache()) {\n this.summaryUploadManager = new WholeSummaryUploadManager(manager);\n }\n\n public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n if (versionId !== this.id && versionId !== null) {\n // Blobs/Trees in this scenario will never have multiple versions, so return versionId as is\n return [{\n id: versionId,\n treeId: undefined!,\n }];\n }\n // If this is the first versions call for the document, we know we will want the latest summary.\n // Fetch latest summary, cache it, and return its id.\n if (this.firstVersionsCall && count === 1) {\n this.firstVersionsCall = false;\n const { id: _id, snapshotTree } = await this.fetchAndCacheSnapshotTree(latestSnapshotId);\n return [{\n id: _id,\n treeId: snapshotTree.id!,\n }];\n }\n\n // Otherwise, get the latest version of the document as normal.\n const id = versionId ? versionId : this.id;\n const commits = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getVersions\",\n versionId: id,\n count,\n },\n async () => this.manager.getCommits(id, count),\n );\n return commits.map((commit) => ({\n date: commit.commit.author.date,\n id: commit.sha,\n treeId: commit.commit.tree.sha,\n }));\n }\n\n public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n let requestVersion = version;\n if (!requestVersion) {\n const versions = await this.getVersions(this.id, 1);\n if (versions.length === 0) {\n return null;\n }\n\n requestVersion = versions[0];\n }\n\n return (await this.fetchAndCacheSnapshotTree(requestVersion.id)).snapshotTree;\n }\n\n public async readBlob(blobId: string): Promise<ArrayBufferLike> {\n const cachedBlob = await this.blobCache.get(blobId);\n if (cachedBlob !== undefined) {\n return cachedBlob;\n }\n\n const blob = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"readBlob\",\n blobId,\n },\n async (event) => {\n const response = await this.manager.getBlob(blobId);\n event.end({\n size: response.size,\n });\n return response;\n },\n );\n const bufferValue = stringToBuffer(blob.content, blob.encoding);\n\n await this.blobCache.put(blob.sha, bufferValue);\n\n return bufferValue;\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n const summaryHandle = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"uploadSummaryWithContext\",\n },\n async () => this.summaryUploadManager.writeSummaryTree(summary, context.ackHandle ?? \"\", \"channel\"),\n );\n return summaryHandle;\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async write(tree: ITree, parents: string[], message: string, ref: string): Promise<IVersion> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n const uint8ArrayFile = new Uint8Array(file);\n return PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"createBlob\",\n size: uint8ArrayFile.length,\n },\n async (event) => {\n const response = await this.manager.createBlob(\n Uint8ArrayToString(\n uint8ArrayFile, \"base64\"),\n \"base64\").then((r) => ({ id: r.sha, url: r.url }));\n event.end({\n blobId: response.id,\n });\n return response;\n },\n );\n }\n\n private async fetchAndCacheSnapshotTree(versionId: string): Promise<ISnapshotTreeVersion> {\n const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);\n if (cachedSnapshotTreeVersion !== undefined) {\n return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };\n }\n\n const wholeFlatSummary = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getWholeFlatSummary\",\n treeId: versionId,\n },\n async (event) => {\n const response = await this.manager.getSummary(versionId);\n event.end({\n size: response.trees[0]?.entries.length,\n });\n return response;\n },\n );\n const normalizedWholeSummary = convertWholeFlatSummaryToSnapshotTreeAndBlobs(wholeFlatSummary);\n const wholeFlatSummaryId: string = wholeFlatSummary.id;\n const snapshotTreeId = normalizedWholeSummary.snapshotTree.id;\n assert(snapshotTreeId !== undefined, 0x275 /* \"Root tree should contain the id\" */);\n const snapshotTreeVersion = { id: wholeFlatSummaryId , snapshotTree: normalizedWholeSummary.snapshotTree };\n\n const cachePs: Promise<any>[] = [\n this.snapshotTreeCache.put(\n snapshotTreeId,\n snapshotTreeVersion,\n ),\n this.initBlobCache(normalizedWholeSummary.blobs),\n ];\n if (snapshotTreeId !== versionId) {\n // versionId could be \"latest\". When summarizer checks cache for \"latest\", we want it to be available.\n // TODO: For in-memory cache, <latest,snapshotTree> will be a shared pointer with <snapshotId,snapshotTree>,\n // However, for something like Redis, this will cache the same value twice. Alternatively, could we simply\n // cache with versionId?\n cachePs.push(this.snapshotTreeCache.put(\n versionId,\n snapshotTreeVersion,\n ));\n }\n\n await Promise.all(cachePs);\n\n return snapshotTreeVersion;\n }\n\n private async initBlobCache(blobs: Map<string, ArrayBuffer>): Promise<void> {\n const blobCachePutPs: Promise<void>[] = [];\n blobs.forEach((value, id) => {\n blobCachePutPs.push(this.blobCache.put(id, value));\n });\n await Promise.all(blobCachePutPs);\n }\n}\n"]}
1
+ {"version":3,"file":"wholeSummaryDocumentStorageService.js","sourceRoot":"","sources":["../src/wholeSummaryDocumentStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport {\n assert,\n stringToBuffer,\n Uint8ArrayToString,\n} from \"@fluidframework/common-utils\";\nimport {\n IDocumentStorageService,\n ISummaryContext,\n IDocumentStorageServicePolicies,\n} from \"@fluidframework/driver-definitions\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n ITree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n convertWholeFlatSummaryToSnapshotTreeAndBlobs,\n GitManager,\n ISummaryUploadManager,\n WholeSummaryUploadManager,\n} from \"@fluidframework/server-services-client\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { ICache, InMemoryCache } from \"./cache\";\nimport { ISnapshotTreeVersion } from \"./definitions\";\nimport { IRouterliciousDriverPolicies } from \"./policies\";\n\nconst latestSnapshotId: string = \"latest\";\n\nexport class WholeSummaryDocumentStorageService implements IDocumentStorageService {\n private readonly summaryUploadManager: ISummaryUploadManager;\n private firstVersionsCall: boolean = true;\n\n public get repositoryUrl(): string {\n return \"\";\n }\n\n constructor(\n protected readonly id: string,\n protected readonly manager: GitManager,\n protected readonly logger: ITelemetryLogger,\n public readonly policies: IDocumentStorageServicePolicies = {},\n private readonly driverPolicies?: IRouterliciousDriverPolicies,\n private readonly blobCache: ICache<ArrayBufferLike> = new InMemoryCache(),\n private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> = new InMemoryCache(),\n protected readonly noCacheGitManager?: GitManager) {\n this.summaryUploadManager = new WholeSummaryUploadManager(manager);\n }\n\n public async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n if (versionId !== this.id && versionId !== null) {\n // Blobs/Trees in this scenario will never have multiple versions, so return versionId as is\n return [{\n id: versionId,\n treeId: undefined!,\n }];\n }\n // If this is the first versions call for the document, we know we will want the latest summary.\n // Fetch latest summary, cache it, and return its id.\n if (this.firstVersionsCall && count === 1) {\n this.firstVersionsCall = false;\n const { id: _id, snapshotTree } = !this.driverPolicies?.enableDiscovery ?\n await this.fetchAndCacheSnapshotTree(latestSnapshotId, false) :\n await this.fetchAndCacheSnapshotTree(latestSnapshotId, true);\n return [{\n id: _id,\n treeId: snapshotTree.id!,\n }];\n }\n\n // Otherwise, get the latest version of the document as normal.\n const id = versionId ? versionId : this.id;\n const commits = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getVersions\",\n versionId: id,\n count,\n },\n async () => this.manager.getCommits(id, count),\n );\n return commits.map((commit) => ({\n date: commit.commit.author.date,\n id: commit.sha,\n treeId: commit.commit.tree.sha,\n }));\n }\n\n public async getSnapshotTree(version?: IVersion): Promise<ISnapshotTree | null> {\n let requestVersion = version;\n if (!requestVersion) {\n const versions = await this.getVersions(this.id, 1);\n if (versions.length === 0) {\n return null;\n }\n\n requestVersion = versions[0];\n }\n\n return (await this.fetchAndCacheSnapshotTree(requestVersion.id)).snapshotTree;\n }\n\n public async readBlob(blobId: string): Promise<ArrayBufferLike> {\n const cachedBlob = await this.blobCache.get(blobId);\n if (cachedBlob !== undefined) {\n return cachedBlob;\n }\n\n const blob = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"readBlob\",\n blobId,\n },\n async (event) => {\n const response = await this.manager.getBlob(blobId);\n event.end({\n size: response.size,\n });\n return response;\n },\n );\n const bufferValue = stringToBuffer(blob.content, blob.encoding);\n\n await this.blobCache.put(blob.sha, bufferValue);\n\n return bufferValue;\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n const summaryHandle = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"uploadSummaryWithContext\",\n },\n async () => this.summaryUploadManager.writeSummaryTree(summary, context.ackHandle ?? \"\", \"channel\"),\n );\n return summaryHandle;\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async write(tree: ITree, parents: string[], message: string, ref: string): Promise<IVersion> {\n throw new Error(\"NOT IMPLEMENTED!\");\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n const uint8ArrayFile = new Uint8Array(file);\n return PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"createBlob\",\n size: uint8ArrayFile.length,\n },\n async (event) => {\n const response = await this.manager.createBlob(\n Uint8ArrayToString(\n uint8ArrayFile, \"base64\"),\n \"base64\").then((r) => ({ id: r.sha, url: r.url }));\n event.end({\n blobId: response.id,\n });\n return response;\n },\n );\n }\n\n private async fetchAndCacheSnapshotTree(versionId: string, disableCache?: boolean): Promise<ISnapshotTreeVersion> {\n const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);\n if (cachedSnapshotTreeVersion !== undefined) {\n return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };\n }\n\n const wholeFlatSummary = await PerformanceEvent.timedExecAsync(\n this.logger,\n {\n eventName: \"getWholeFlatSummary\",\n treeId: versionId,\n },\n async (event) => {\n const response = disableCache && this.noCacheGitManager !== undefined ?\n await this.noCacheGitManager.getSummary(versionId) :\n await this.manager.getSummary(versionId);\n event.end({\n size: response.trees[0]?.entries.length,\n });\n return response;\n },\n );\n const normalizedWholeSummary = convertWholeFlatSummaryToSnapshotTreeAndBlobs(wholeFlatSummary);\n const wholeFlatSummaryId: string = wholeFlatSummary.id;\n const snapshotTreeId = normalizedWholeSummary.snapshotTree.id;\n assert(snapshotTreeId !== undefined, 0x275 /* \"Root tree should contain the id\" */);\n const snapshotTreeVersion = { id: wholeFlatSummaryId, snapshotTree: normalizedWholeSummary.snapshotTree };\n\n const cachePs: Promise<any>[] = [\n this.snapshotTreeCache.put(\n snapshotTreeId,\n snapshotTreeVersion,\n ),\n this.initBlobCache(normalizedWholeSummary.blobs),\n ];\n if (snapshotTreeId !== versionId) {\n // versionId could be \"latest\". When summarizer checks cache for \"latest\", we want it to be available.\n // TODO: For in-memory cache, <latest,snapshotTree> will be a shared pointer with <snapshotId,snapshotTree>,\n // However, for something like Redis, this will cache the same value twice. Alternatively, could we simply\n // cache with versionId?\n cachePs.push(this.snapshotTreeCache.put(\n versionId,\n snapshotTreeVersion,\n ));\n }\n\n await Promise.all(cachePs);\n\n return snapshotTreeVersion;\n }\n\n private async initBlobCache(blobs: Map<string, ArrayBuffer>): Promise<void> {\n const blobCachePutPs: Promise<void>[] = [];\n blobs.forEach((value, id) => {\n blobCachePutPs.push(this.blobCache.put(id, value));\n });\n await Promise.all(blobCachePutPs);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/routerlicious-driver",
3
- "version": "0.59.1001-62246",
3
+ "version": "0.59.2000",
4
4
  "description": "Socket.IO + Git implementation of Fluid service API",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -16,7 +16,7 @@
16
16
  "types": "dist/index.d.ts",
17
17
  "scripts": {
18
18
  "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
19
- "build:commonjs": "npm run tsc && npm run build:test",
19
+ "build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
20
20
  "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
21
21
  "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
22
22
  "build:esnext": "tsc --project ./tsconfig.esnext.json",
@@ -36,7 +36,8 @@
36
36
  "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
37
37
  "tsc": "tsc",
38
38
  "tsfmt": "tsfmt --verify",
39
- "tsfmt:fix": "tsfmt --replace"
39
+ "tsfmt:fix": "tsfmt --replace",
40
+ "typetests:gen": "fluid-type-validator -g -d ."
40
41
  },
41
42
  "nyc": {
42
43
  "all": true,
@@ -61,14 +62,14 @@
61
62
  "dependencies": {
62
63
  "@fluidframework/common-definitions": "^0.20.1",
63
64
  "@fluidframework/common-utils": "^0.32.1",
64
- "@fluidframework/driver-base": "0.59.1001-62246",
65
+ "@fluidframework/driver-base": "^0.59.2000",
65
66
  "@fluidframework/driver-definitions": "^0.46.1000",
66
- "@fluidframework/driver-utils": "0.59.1001-62246",
67
+ "@fluidframework/driver-utils": "^0.59.2000",
67
68
  "@fluidframework/gitresources": "^0.1036.1000",
68
69
  "@fluidframework/protocol-base": "^0.1036.1000",
69
70
  "@fluidframework/protocol-definitions": "^0.1028.1000",
70
71
  "@fluidframework/server-services-client": "^0.1036.1000",
71
- "@fluidframework/telemetry-utils": "0.59.1001-62246",
72
+ "@fluidframework/telemetry-utils": "^0.59.2000",
72
73
  "cross-fetch": "^3.1.5",
73
74
  "json-stringify-safe": "5.0.1",
74
75
  "socket.io-client": "^4.4.1",
@@ -78,9 +79,9 @@
78
79
  "devDependencies": {
79
80
  "@fluidframework/build-common": "^0.23.0",
80
81
  "@fluidframework/eslint-config-fluid": "^0.28.1000",
81
- "@fluidframework/mocha-test-setup": "0.59.1001-62246",
82
- "@fluidframework/routerlicious-driver-previous": "npm:@fluidframework/routerlicious-driver@^0.58.0",
83
- "@microsoft/api-extractor": "^7.16.1",
82
+ "@fluidframework/mocha-test-setup": "^0.59.2000",
83
+ "@fluidframework/routerlicious-driver-previous": "npm:@fluidframework/routerlicious-driver@0.59.1000",
84
+ "@microsoft/api-extractor": "^7.22.2",
84
85
  "@rushstack/eslint-config": "^2.5.1",
85
86
  "@types/mocha": "^8.2.2",
86
87
  "@types/nock": "^9.3.0",
@@ -96,8 +97,11 @@
96
97
  "eslint-plugin-editorconfig": "~3.2.0",
97
98
  "eslint-plugin-eslint-comments": "~3.2.0",
98
99
  "eslint-plugin-import": "~2.25.4",
99
- "eslint-plugin-no-null": "~1.0.2",
100
+ "eslint-plugin-jest": "~26.1.3",
101
+ "eslint-plugin-mocha": "~10.0.3",
102
+ "eslint-plugin-promise": "~6.0.0",
100
103
  "eslint-plugin-react": "~7.28.0",
104
+ "eslint-plugin-tsdoc": "~0.2.14",
101
105
  "eslint-plugin-unicorn": "~40.0.0",
102
106
  "mocha": "^8.4.0",
103
107
  "nock": "^10.0.1",
@@ -107,7 +111,7 @@
107
111
  "typescript-formatter": "7.1.0"
108
112
  },
109
113
  "typeValidation": {
110
- "version": "0.59.1000",
114
+ "version": "0.59.2000",
111
115
  "broken": {}
112
116
  }
113
117
  }
@@ -10,6 +10,7 @@ import { IAnyDriverError } from "@fluidframework/driver-utils";
10
10
  import { IClient, IConnect } from "@fluidframework/protocol-definitions";
11
11
  import type { io as SocketIOClientStatic } from "socket.io-client";
12
12
  import { errorObjectFromSocketError, IR11sSocketError } from "./errorUtils";
13
+ import { pkgVersion as driverVersion } from "./packageVersion";
13
14
 
14
15
  const protocolVersions = ["^0.4.0", "^0.3.0", "^0.2.0", "^0.1.0"];
15
16
 
@@ -47,6 +48,7 @@ export class R11sDocumentDeltaConnection extends DocumentDeltaConnection
47
48
  tenantId,
48
49
  token, // Token is going to indicate tenant level information, etc...
49
50
  versions: protocolVersions,
51
+ relayUserAgent: [client.details.environment, ` driverVersion:${driverVersion}`].join(";"),
50
52
  };
51
53
 
52
54
  // TODO: expose to host at factory level
@@ -62,7 +64,7 @@ export class R11sDocumentDeltaConnection extends DocumentDeltaConnection
62
64
  */
63
65
  protected createErrorObject(handler: string, error?: any, canRetry = true): IAnyDriverError {
64
66
  // Note: we suspect the incoming error object is either:
65
- // - a socketError: add it to the OdspError object for driver to be able to parse it and reason over it.
67
+ // - a socketError: add it to the R11sError object for driver to be able to parse it and reason over it.
66
68
  // - anything else: let base class handle it
67
69
  if (canRetry && Number.isInteger(error?.code) && typeof error?.message === "string") {
68
70
  return errorObjectFromSocketError(error as IR11sSocketError, handler);
@@ -74,6 +74,12 @@ export class DocumentService implements api.IDocumentService {
74
74
  false,
75
75
  storageRestWrapper);
76
76
  const gitManager = new GitManager(historian);
77
+ const noCacheHistorian = new Historian(
78
+ this.gitUrl,
79
+ true,
80
+ true,
81
+ storageRestWrapper);
82
+ const noCacheGitManager = new GitManager(noCacheHistorian);
77
83
  const documentStorageServicePolicies: api.IDocumentStorageServicePolicies = {
78
84
  caching: this.driverPolicies.enablePrefetch
79
85
  ? api.LoaderCachingPolicy.Prefetch
@@ -88,7 +94,8 @@ export class DocumentService implements api.IDocumentService {
88
94
  documentStorageServicePolicies,
89
95
  this.driverPolicies,
90
96
  this.blobCache,
91
- this.snapshotTreeCache);
97
+ this.snapshotTreeCache,
98
+ noCacheGitManager);
92
99
  return this.documentStorageService;
93
100
  }
94
101
 
@@ -142,7 +149,7 @@ export class DocumentService implements api.IDocumentService {
142
149
  try {
143
150
  const connection = await connect();
144
151
  return connection;
145
- } catch (error) {
152
+ } catch (error: any) {
146
153
  if (error?.statusCode === 401) {
147
154
  // Fetch new token and retry once,
148
155
  // otherwise 401 will be bubbled up as non-retriable AuthorizationError.
@@ -18,12 +18,13 @@ import {
18
18
  RateLimiter,
19
19
  } from "@fluidframework/driver-utils";
20
20
  import { ChildLogger } from "@fluidframework/telemetry-utils";
21
+ import { ISession } from "@fluidframework/server-services-client";
21
22
  import { DocumentService } from "./documentService";
22
23
  import { IRouterliciousDriverPolicies } from "./policies";
23
24
  import { ITokenProvider } from "./tokens";
24
25
  import { RouterliciousOrdererRestWrapper } from "./restWrapper";
25
26
  import { convertSummaryToCreateNewSummary } from "./createNewUtils";
26
- import { parseFluidUrl, replaceDocumentIdInPath } from "./urlUtils";
27
+ import { parseFluidUrl, replaceDocumentIdInPath, getDiscoveredFluidResolvedUrl } from "./urlUtils";
27
28
  import { InMemoryCache } from "./cache";
28
29
  import { pkgVersion as driverVersion } from "./packageVersion";
29
30
  import { ISnapshotTreeVersion } from "./definitions";
@@ -33,6 +34,7 @@ const defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {
33
34
  maxConcurrentStorageRequests: 100,
34
35
  maxConcurrentOrdererRequests: 100,
35
36
  aggregateBlobsSmallerThanBytes: undefined,
37
+ enableDiscovery: false,
36
38
  enableWholeSummaryUpload: false,
37
39
  enableRestLess: true,
38
40
  };
@@ -66,7 +68,7 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
66
68
  ensureFluidResolvedUrl(resolvedUrl);
67
69
  assert(!!createNewSummary, 0x204 /* "create empty file not supported" */);
68
70
  assert(!!resolvedUrl.endpoints.ordererUrl, 0x0b2 /* "Missing orderer URL!" */);
69
- const parsedUrl = parseFluidUrl(resolvedUrl.url);
71
+ let parsedUrl = parseFluidUrl(resolvedUrl.url);
70
72
  if (!parsedUrl.pathname) {
71
73
  throw new Error("Parsed url should contain tenant and doc Id!!");
72
74
  }
@@ -92,15 +94,14 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
92
94
  resolvedUrl.endpoints.ordererUrl,
93
95
  );
94
96
 
95
- // the backend responds with the actual document ID associated with the new container.
96
-
97
97
  // @TODO: Remove returned "string" type when removing back-compat code
98
- const res = await ordererRestWrapper.post<{ id: string, token?: string } | string>(
98
+ const res = await ordererRestWrapper.post<{ id: string, token?: string, session?: ISession } | string>(
99
99
  `/documents/${tenantId}`,
100
100
  {
101
101
  summary: convertSummaryToCreateNewSummary(appSummary),
102
102
  sequenceNumber: documentAttributes.sequenceNumber,
103
103
  values: quorumValues,
104
+ enableDiscovery: this.driverPolicies.enableDiscovery,
104
105
  generateToken: this.tokenProvider.documentPostCreateCallback !== undefined,
105
106
  },
106
107
  );
@@ -111,13 +112,21 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
111
112
 
112
113
  let documentId: string;
113
114
  let token: string | undefined;
114
-
115
+ let session: ISession | undefined;
116
+ let fluidResolvedUrl: IResolvedUrl;
115
117
  if (typeof res === "string") {
116
118
  documentId = res;
117
119
  } else {
118
120
  documentId = res.id;
119
121
  token = res.token;
122
+ session = res.session;
120
123
  }
124
+ if (session && this.driverPolicies.enableDiscovery) {
125
+ fluidResolvedUrl = getDiscoveredFluidResolvedUrl(resolvedUrl, session);
126
+ } else {
127
+ fluidResolvedUrl = resolvedUrl;
128
+ }
129
+ parsedUrl = parseFluidUrl(fluidResolvedUrl.url);
121
130
 
122
131
  // @TODO: Remove token from the condition, checking the documentPostCreateCallback !== undefined
123
132
  // is sufficient to determine if the token will be undefined or not.
@@ -126,7 +135,7 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
126
135
  }
127
136
 
128
137
  parsedUrl.set("pathname", replaceDocumentIdInPath(parsedUrl.pathname, documentId));
129
- const deltaStorageUrl = resolvedUrl.endpoints.deltaStorageUrl;
138
+ const deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
130
139
  if (!deltaStorageUrl) {
131
140
  throw new Error(
132
141
  `All endpoints urls must be provided. [deltaStorageUrl:${deltaStorageUrl}]`);
@@ -136,16 +145,17 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
136
145
 
137
146
  return this.createDocumentService(
138
147
  {
139
- ...resolvedUrl,
148
+ ...fluidResolvedUrl,
140
149
  url: parsedUrl.toString(),
141
150
  id: documentId,
142
151
  endpoints: {
143
- ...resolvedUrl.endpoints,
152
+ ...fluidResolvedUrl.endpoints,
144
153
  deltaStorageUrl: parsedDeltaStorageUrl.toString(),
145
154
  },
146
155
  },
147
156
  logger,
148
157
  clientIsSummarizer,
158
+ true,
149
159
  );
150
160
  }
151
161
 
@@ -159,10 +169,40 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
159
169
  resolvedUrl: IResolvedUrl,
160
170
  logger?: ITelemetryBaseLogger,
161
171
  clientIsSummarizer?: boolean,
172
+ isCreateContainer?: boolean,
162
173
  ): Promise<IDocumentService> {
163
174
  ensureFluidResolvedUrl(resolvedUrl);
164
175
 
165
- const fluidResolvedUrl = resolvedUrl;
176
+ const parsedUrl = parseFluidUrl(resolvedUrl.url);
177
+ const [, tenantId, documentId] = parsedUrl.pathname.split("/");
178
+ if (!documentId || !tenantId) {
179
+ throw new Error(
180
+ `Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`);
181
+ }
182
+ const logger2 = ChildLogger.create(logger, "RouterliciousDriver", { all: { driverVersion }});
183
+
184
+ let fluidResolvedUrl: IResolvedUrl;
185
+ if (!isCreateContainer && this.driverPolicies.enableDiscovery) {
186
+ const rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);
187
+ const ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(
188
+ tenantId,
189
+ documentId,
190
+ this.tokenProvider,
191
+ logger2,
192
+ rateLimiter,
193
+ this.driverPolicies.enableRestLess,
194
+ resolvedUrl.endpoints.ordererUrl,
195
+ );
196
+
197
+ // the backend responds with the actual document session associated with the container.
198
+ const session: ISession = await ordererRestWrapper.get<ISession>(
199
+ `/documents/${tenantId}/session/${documentId}`,
200
+ );
201
+ fluidResolvedUrl = getDiscoveredFluidResolvedUrl(resolvedUrl, session);
202
+ } else {
203
+ fluidResolvedUrl = resolvedUrl;
204
+ }
205
+
166
206
  const storageUrl = fluidResolvedUrl.endpoints.storageUrl;
167
207
  const ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;
168
208
  const deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
@@ -171,15 +211,6 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
171
211
  `All endpoints urls must be provided. [ordererUrl:${ordererUrl}][deltaStorageUrl:${deltaStorageUrl}]`);
172
212
  }
173
213
 
174
- const parsedUrl = parseFluidUrl(fluidResolvedUrl.url);
175
- const [, tenantId, documentId] = parsedUrl.pathname.split("/");
176
- if (!documentId || !tenantId) {
177
- throw new Error(
178
- `Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`);
179
- }
180
-
181
- const logger2 = ChildLogger.create(logger, "RouterliciousDriver", { all: { driverVersion }});
182
-
183
214
  return new DocumentService(
184
215
  fluidResolvedUrl,
185
216
  ordererUrl,
@@ -37,15 +37,18 @@ export class DocumentStorageService extends DocumentStorageServiceProxy {
37
37
  policies: IDocumentStorageServicePolicies,
38
38
  driverPolicies?: IRouterliciousDriverPolicies,
39
39
  blobCache?: ICache<ArrayBufferLike>,
40
- snapshotTreeCache?: ICache<ISnapshotTreeVersion>): IDocumentStorageService {
40
+ snapshotTreeCache?: ICache<ISnapshotTreeVersion>,
41
+ noCacheGitManager?: GitManager): IDocumentStorageService {
41
42
  const storageService = driverPolicies?.enableWholeSummaryUpload ?
42
43
  new WholeSummaryDocumentStorageService(
43
44
  id,
44
45
  manager,
45
46
  logger,
46
47
  policies,
48
+ driverPolicies,
47
49
  blobCache,
48
50
  snapshotTreeCache,
51
+ noCacheGitManager,
49
52
  ) :
50
53
  new ShreddedSummaryDocumentStorageService(
51
54
  id,
@@ -70,7 +73,8 @@ export class DocumentStorageService extends DocumentStorageServiceProxy {
70
73
  policies: IDocumentStorageServicePolicies = {},
71
74
  driverPolicies?: IRouterliciousDriverPolicies,
72
75
  blobCache?: ICache<ArrayBufferLike>,
73
- snapshotTreeCache?: ICache<ISnapshotTreeVersion>) {
76
+ snapshotTreeCache?: ICache<ISnapshotTreeVersion>,
77
+ public noCacheGitManager?: GitManager) {
74
78
  super(DocumentStorageService.loadInternalDocumentStorageService(
75
79
  id,
76
80
  manager,
@@ -79,6 +83,7 @@ export class DocumentStorageService extends DocumentStorageServiceProxy {
79
83
  driverPolicies,
80
84
  blobCache,
81
85
  snapshotTreeCache,
86
+ noCacheGitManager,
82
87
  ));
83
88
  }
84
89
 
package/src/errorUtils.ts CHANGED
@@ -18,6 +18,7 @@ export enum R11sErrorType {
18
18
 
19
19
  /**
20
20
  * Interface for error responses for the WebSocket connection
21
+ * Intended to be compatible with output from {@link NetworkError.toJSON}
21
22
  */
22
23
  export interface IR11sSocketError {
23
24
  /**
@@ -36,6 +37,12 @@ export interface IR11sSocketError {
36
37
  * Optional Retry-After time in seconds.
37
38
  * The client should wait this many seconds before retrying its request.
38
39
  */
40
+ retryAfter?: number;
41
+
42
+ /**
43
+ * Optional Retry-After time in milliseconds.
44
+ * The client should wait this many milliseconds before retrying its request.
45
+ */
39
46
  retryAfterMs?: number;
40
47
  }
41
48
 
@@ -61,6 +68,8 @@ export function createR11sNetworkError(
61
68
  return new GenericNetworkError(
62
69
  errorMessage, errorMessage.startsWith("NetworkError"), props);
63
70
  case 401:
71
+ // The first 401 is manually retried in RouterliciousRestWrapper with a refreshed token,
72
+ // so we treat repeat 401s the same as 403.
64
73
  case 403:
65
74
  return new AuthorizationError(
66
75
  errorMessage, undefined, undefined, props);
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/routerlicious-driver";
9
- export const pkgVersion = "0.59.1001-62246";
9
+ export const pkgVersion = "0.59.2000";
package/src/policies.ts CHANGED
@@ -32,6 +32,11 @@ export interface IRouterliciousDriverPolicies {
32
32
  * Default: false
33
33
  */
34
34
  enableWholeSummaryUpload: boolean;
35
+ /**
36
+ * Enable service endpoint discovery when creating or joining a session.
37
+ * Default: false
38
+ */
39
+ enableDiscovery?: boolean;
35
40
  /**
36
41
  * Enable using RestLess which avoids CORS preflight requests.
37
42
  * Default: true
@@ -17,6 +17,7 @@ import safeStringify from "json-stringify-safe";
17
17
  import { v4 as uuid } from "uuid";
18
18
  import { throwR11sNetworkError } from "./errorUtils";
19
19
  import { ITokenProvider } from "./tokens";
20
+ import { pkgVersion as driverVersion } from "./packageVersion";
20
21
 
21
22
  type AuthorizationHeaderGetter = (refresh?: boolean) => Promise<string | undefined>;
22
23
 
@@ -107,8 +108,10 @@ export class RouterliciousRestWrapper extends RestWrapper {
107
108
 
108
109
  return {
109
110
  ...requestHeaders,
111
+ // TODO: replace header names with CorrelationIdHeaderName and DriverVersionHeaderName from services-client
110
112
  // NOTE: Can correlationId actually be number | true?
111
113
  "x-correlation-id": correlationId as string,
114
+ "x-driver-version": driverVersion,
112
115
  // NOTE: If this.authorizationHeader is undefined, should "Authorization" be removed entirely?
113
116
  "Authorization": this.authorizationHeader!,
114
117
  };
package/src/urlUtils.ts CHANGED
@@ -3,7 +3,9 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { IFluidResolvedUrl } from "@fluidframework/driver-definitions";
6
7
  import URLParse from "url-parse";
8
+ import { ISession } from "@fluidframework/server-services-client";
7
9
 
8
10
  export const parseFluidUrl = (fluidUrl: string): URLParse => {
9
11
  return new URLParse(fluidUrl, true);
@@ -17,3 +19,32 @@ export const parseFluidUrl = (fluidUrl: string): URLParse => {
17
19
  */
18
20
  export const replaceDocumentIdInPath = (urlPath: string, documentId: string): string =>
19
21
  urlPath.split("/").slice(0, -1).concat([documentId]).join("/");
22
+
23
+ export const getDiscoveredFluidResolvedUrl = (resolvedUrl: IFluidResolvedUrl, session: ISession): IFluidResolvedUrl => {
24
+ if (session) {
25
+ const discoveredOrdererUrl = new URLParse(session.ordererUrl);
26
+ const deltaStorageUrl = new URLParse(resolvedUrl.endpoints.deltaStorageUrl);
27
+ deltaStorageUrl.set("host", discoveredOrdererUrl.host);
28
+
29
+ const discoveredStorageUrl = new URLParse(session.historianUrl);
30
+ const storageUrl = new URLParse(resolvedUrl.endpoints.storageUrl);
31
+ storageUrl.set("host", discoveredStorageUrl.host);
32
+
33
+ const parsedUrl = parseFluidUrl(resolvedUrl.url);
34
+ const discoveredResolvedUrl: IFluidResolvedUrl = {
35
+ endpoints: {
36
+ deltaStorageUrl: deltaStorageUrl.toString(),
37
+ ordererUrl: session.ordererUrl,
38
+ storageUrl: storageUrl.toString(),
39
+ },
40
+ id: resolvedUrl.id,
41
+ tokens: resolvedUrl.tokens,
42
+ type: resolvedUrl.type,
43
+ url: new URLParse(`fluid://${discoveredOrdererUrl.host}${parsedUrl.pathname}`).toString(),
44
+ };
45
+
46
+ return discoveredResolvedUrl;
47
+ } else {
48
+ return resolvedUrl;
49
+ }
50
+ };
@@ -13,7 +13,7 @@ import {
13
13
  IDocumentStorageService,
14
14
  ISummaryContext,
15
15
  IDocumentStorageServicePolicies,
16
- } from "@fluidframework/driver-definitions";
16
+ } from "@fluidframework/driver-definitions";
17
17
  import {
18
18
  ICreateBlobResponse,
19
19
  ISnapshotTree,
@@ -31,6 +31,7 @@ import {
31
31
  import { PerformanceEvent } from "@fluidframework/telemetry-utils";
32
32
  import { ICache, InMemoryCache } from "./cache";
33
33
  import { ISnapshotTreeVersion } from "./definitions";
34
+ import { IRouterliciousDriverPolicies } from "./policies";
34
35
 
35
36
  const latestSnapshotId: string = "latest";
36
37
 
@@ -47,8 +48,10 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
47
48
  protected readonly manager: GitManager,
48
49
  protected readonly logger: ITelemetryLogger,
49
50
  public readonly policies: IDocumentStorageServicePolicies = {},
51
+ private readonly driverPolicies?: IRouterliciousDriverPolicies,
50
52
  private readonly blobCache: ICache<ArrayBufferLike> = new InMemoryCache(),
51
- private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> = new InMemoryCache()) {
53
+ private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion> = new InMemoryCache(),
54
+ protected readonly noCacheGitManager?: GitManager) {
52
55
  this.summaryUploadManager = new WholeSummaryUploadManager(manager);
53
56
  }
54
57
 
@@ -64,7 +67,9 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
64
67
  // Fetch latest summary, cache it, and return its id.
65
68
  if (this.firstVersionsCall && count === 1) {
66
69
  this.firstVersionsCall = false;
67
- const { id: _id, snapshotTree } = await this.fetchAndCacheSnapshotTree(latestSnapshotId);
70
+ const { id: _id, snapshotTree } = !this.driverPolicies?.enableDiscovery ?
71
+ await this.fetchAndCacheSnapshotTree(latestSnapshotId, false) :
72
+ await this.fetchAndCacheSnapshotTree(latestSnapshotId, true);
68
73
  return [{
69
74
  id: _id,
70
75
  treeId: snapshotTree.id!,
@@ -170,7 +175,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
170
175
  );
171
176
  }
172
177
 
173
- private async fetchAndCacheSnapshotTree(versionId: string): Promise<ISnapshotTreeVersion> {
178
+ private async fetchAndCacheSnapshotTree(versionId: string, disableCache?: boolean): Promise<ISnapshotTreeVersion> {
174
179
  const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);
175
180
  if (cachedSnapshotTreeVersion !== undefined) {
176
181
  return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };
@@ -183,7 +188,9 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
183
188
  treeId: versionId,
184
189
  },
185
190
  async (event) => {
186
- const response = await this.manager.getSummary(versionId);
191
+ const response = disableCache && this.noCacheGitManager !== undefined ?
192
+ await this.noCacheGitManager.getSummary(versionId) :
193
+ await this.manager.getSummary(versionId);
187
194
  event.end({
188
195
  size: response.trees[0]?.entries.length,
189
196
  });
@@ -194,7 +201,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
194
201
  const wholeFlatSummaryId: string = wholeFlatSummary.id;
195
202
  const snapshotTreeId = normalizedWholeSummary.snapshotTree.id;
196
203
  assert(snapshotTreeId !== undefined, 0x275 /* "Root tree should contain the id" */);
197
- const snapshotTreeVersion = { id: wholeFlatSummaryId , snapshotTree: normalizedWholeSummary.snapshotTree };
204
+ const snapshotTreeVersion = { id: wholeFlatSummaryId, snapshotTree: normalizedWholeSummary.snapshotTree };
198
205
 
199
206
  const cachePs: Promise<any>[] = [
200
207
  this.snapshotTreeCache.put(