@fluidframework/routerlicious-driver 0.59.1000 → 0.59.2000-63294
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.
- package/dist/documentDeltaConnection.d.ts.map +1 -1
- package/dist/documentDeltaConnection.js +3 -1
- package/dist/documentDeltaConnection.js.map +1 -1
- package/dist/documentService.d.ts.map +1 -1
- package/dist/documentService.js +3 -1
- package/dist/documentService.js.map +1 -1
- package/dist/documentServiceFactory.d.ts +1 -1
- package/dist/documentServiceFactory.d.ts.map +1 -1
- package/dist/documentServiceFactory.js +33 -12
- package/dist/documentServiceFactory.js.map +1 -1
- package/dist/documentStorageService.d.ts +2 -1
- package/dist/documentStorageService.d.ts.map +1 -1
- package/dist/documentStorageService.js +5 -4
- package/dist/documentStorageService.js.map +1 -1
- package/dist/errorUtils.d.ts +6 -0
- package/dist/errorUtils.d.ts.map +1 -1
- package/dist/errorUtils.js +2 -0
- package/dist/errorUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/policies.d.ts +5 -0
- package/dist/policies.d.ts.map +1 -1
- package/dist/policies.js.map +1 -1
- package/dist/restWrapper.d.ts.map +1 -1
- package/dist/restWrapper.js +3 -1
- package/dist/restWrapper.js.map +1 -1
- package/dist/urlUtils.d.ts +3 -0
- package/dist/urlUtils.d.ts.map +1 -1
- package/dist/urlUtils.js +28 -1
- package/dist/urlUtils.js.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.d.ts +4 -1
- package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/dist/wholeSummaryDocumentStorageService.js +11 -4
- package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
- package/lib/documentDeltaConnection.d.ts.map +1 -1
- package/lib/documentDeltaConnection.js +3 -1
- package/lib/documentDeltaConnection.js.map +1 -1
- package/lib/documentService.d.ts.map +1 -1
- package/lib/documentService.js +3 -1
- package/lib/documentService.js.map +1 -1
- package/lib/documentServiceFactory.d.ts +1 -1
- package/lib/documentServiceFactory.d.ts.map +1 -1
- package/lib/documentServiceFactory.js +34 -13
- package/lib/documentServiceFactory.js.map +1 -1
- package/lib/documentStorageService.d.ts +2 -1
- package/lib/documentStorageService.d.ts.map +1 -1
- package/lib/documentStorageService.js +5 -4
- package/lib/documentStorageService.js.map +1 -1
- package/lib/errorUtils.d.ts +6 -0
- package/lib/errorUtils.d.ts.map +1 -1
- package/lib/errorUtils.js +2 -0
- package/lib/errorUtils.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/policies.d.ts +5 -0
- package/lib/policies.d.ts.map +1 -1
- package/lib/policies.js.map +1 -1
- package/lib/restWrapper.d.ts.map +1 -1
- package/lib/restWrapper.js +3 -1
- package/lib/restWrapper.js.map +1 -1
- package/lib/urlUtils.d.ts +3 -0
- package/lib/urlUtils.d.ts.map +1 -1
- package/lib/urlUtils.js +26 -0
- package/lib/urlUtils.js.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.d.ts +4 -1
- package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
- package/lib/wholeSummaryDocumentStorageService.js +11 -4
- package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
- package/package.json +15 -11
- package/src/documentDeltaConnection.ts +3 -1
- package/src/documentService.ts +9 -2
- package/src/documentServiceFactory.ts +50 -19
- package/src/documentStorageService.ts +7 -2
- package/src/errorUtils.ts +9 -0
- package/src/packageVersion.ts +1 -1
- package/src/policies.ts +5 -0
- package/src/restWrapper.ts +3 -0
- package/src/urlUtils.ts +31 -0
- 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.
|
|
3
|
+
"version": "0.59.2000-63294",
|
|
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": "
|
|
65
|
+
"@fluidframework/driver-base": "0.59.2000-63294",
|
|
65
66
|
"@fluidframework/driver-definitions": "^0.46.1000",
|
|
66
|
-
"@fluidframework/driver-utils": "
|
|
67
|
+
"@fluidframework/driver-utils": "0.59.2000-63294",
|
|
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": "
|
|
72
|
+
"@fluidframework/telemetry-utils": "0.59.2000-63294",
|
|
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": "
|
|
82
|
-
"@fluidframework/routerlicious-driver-previous": "npm:@fluidframework/routerlicious-driver
|
|
83
|
-
"@microsoft/api-extractor": "^7.
|
|
82
|
+
"@fluidframework/mocha-test-setup": "0.59.2000-63294",
|
|
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-
|
|
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.
|
|
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
|
|
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);
|
package/src/documentService.ts
CHANGED
|
@@ -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
|
-
|
|
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 =
|
|
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
|
-
...
|
|
148
|
+
...fluidResolvedUrl,
|
|
140
149
|
url: parsedUrl.toString(),
|
|
141
150
|
id: documentId,
|
|
142
151
|
endpoints: {
|
|
143
|
-
...
|
|
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
|
|
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
|
|
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);
|
package/src/packageVersion.ts
CHANGED
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
|
package/src/restWrapper.ts
CHANGED
|
@@ -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
|
-
|
|
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 } =
|
|
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 =
|
|
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
|
|
204
|
+
const snapshotTreeVersion = { id: wholeFlatSummaryId, snapshotTree: normalizedWholeSummary.snapshotTree };
|
|
198
205
|
|
|
199
206
|
const cachePs: Promise<any>[] = [
|
|
200
207
|
this.snapshotTreeCache.put(
|