@fluidframework/container-loader 2.0.0-internal.6.1.1 → 2.0.0-internal.6.3.0
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/CHANGELOG.md +42 -0
- package/README.md +4 -3
- package/dist/audience.js +2 -2
- package/dist/audience.js.map +1 -1
- package/dist/catchUpMonitor.js +2 -2
- package/dist/catchUpMonitor.js.map +1 -1
- package/dist/connectionManager.d.ts +1 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +38 -37
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.js +24 -24
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +8 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +117 -98
- package/dist/container.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +10 -9
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +2 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/debugLogger.js +2 -2
- package/dist/debugLogger.js.map +1 -1
- package/dist/deltaManager.d.ts +3 -4
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +39 -38
- package/dist/deltaManager.js.map +1 -1
- package/dist/deltaQueue.d.ts +1 -1
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/deltaQueue.js +9 -8
- package/dist/deltaQueue.js.map +1 -1
- package/dist/disposal.d.ts +2 -2
- package/dist/disposal.d.ts.map +1 -1
- package/dist/disposal.js +1 -1
- package/dist/disposal.js.map +1 -1
- package/dist/error.d.ts +23 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +32 -0
- package/dist/error.js.map +1 -0
- package/dist/loader.d.ts +9 -2
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +12 -7
- package/dist/loader.js.map +1 -1
- package/dist/noopHeuristic.d.ts +2 -2
- package/dist/noopHeuristic.d.ts.map +1 -1
- package/dist/noopHeuristic.js +6 -5
- package/dist/noopHeuristic.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js +4 -4
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +9 -8
- package/dist/utils.js.map +1 -1
- package/lib/audience.js +1 -1
- package/lib/audience.js.map +1 -1
- package/lib/catchUpMonitor.js +1 -1
- package/lib/catchUpMonitor.js.map +1 -1
- package/lib/connectionManager.d.ts +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +10 -9
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.js +1 -1
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +8 -1
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +73 -54
- package/lib/container.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +2 -1
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +2 -2
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/debugLogger.js +1 -1
- package/lib/debugLogger.js.map +1 -1
- package/lib/deltaManager.d.ts +3 -4
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +6 -5
- package/lib/deltaManager.js.map +1 -1
- package/lib/deltaQueue.d.ts +1 -1
- package/lib/deltaQueue.d.ts.map +1 -1
- package/lib/deltaQueue.js +2 -1
- package/lib/deltaQueue.js.map +1 -1
- package/lib/disposal.d.ts +2 -2
- package/lib/disposal.d.ts.map +1 -1
- package/lib/disposal.js +1 -1
- package/lib/disposal.js.map +1 -1
- package/lib/error.d.ts +23 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +28 -0
- package/lib/error.js.map +1 -0
- package/lib/loader.d.ts +9 -2
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js +11 -6
- package/lib/loader.js.map +1 -1
- package/lib/noopHeuristic.d.ts +2 -2
- package/lib/noopHeuristic.d.ts.map +1 -1
- package/lib/noopHeuristic.js +2 -1
- package/lib/noopHeuristic.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js +2 -2
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +4 -3
- package/lib/utils.js.map +1 -1
- package/package.json +21 -27
- package/src/audience.ts +1 -1
- package/src/catchUpMonitor.ts +1 -1
- package/src/connectionManager.ts +20 -10
- package/src/connectionStateHandler.ts +1 -1
- package/src/container.ts +120 -79
- package/src/containerStorageAdapter.ts +2 -1
- package/src/contracts.ts +1 -2
- package/src/debugLogger.ts +1 -1
- package/src/deltaManager.ts +16 -13
- package/src/deltaQueue.ts +2 -1
- package/src/disposal.ts +2 -2
- package/src/error.ts +44 -0
- package/src/loader.ts +30 -5
- package/src/noopHeuristic.ts +3 -2
- package/src/packageVersion.ts +1 -1
- package/src/retriableDocumentStorageService.ts +2 -4
- package/src/utils.ts +4 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerStorageAdapter.d.ts","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"containerStorageAdapter.d.ts","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EACf,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACN,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAIhD;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACzC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,uBAAuB,EAAE,WAAW;IAsBlF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,2BAA2B;IA1B7C,OAAO,CAAC,eAAe,CAAiD;IAExE,OAAO,CAAC,sBAAsB,CAAsB;IACpD;;OAEG;IACH,IAAW,qBAAqB,YAE/B;IAED;;;;;;;;OAQG;gBAEF,mBAAmB,EAAE,oBAAoB,GAAG,SAAS,EACpC,MAAM,EAAE,mBAAmB;IAC5C;;OAEG;IACc,YAAY,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,MAAM,CAAA;KAAO,EAC7D,2BAA2B,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,YAAY,EACzF,gCAAgC,EAAE,OAAO,GAAG,SAAS;IAMtD,QAAQ,EAAE,OAAO,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;IAKf,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BhE,mCAAmC,CAAC,YAAY,EAAE,6BAA6B;IAItF,OAAO,CAAC,eAAe;IASvB,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAOjE;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAC3B,OAAO,CAAC,EAAE,QAAQ,EAClB,YAAY,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAInB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAY9C,WAAW,CACvB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIT,wBAAwB,CACpC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IAIL,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAI9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAG5E;AA+DD;;GAEG;AACH,wBAAsB,uBAAuB,CAC5C,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC,yBAAyB,CAAC,CAIpC;AAoCD;;GAEG;AACH,wBAAgB,uCAAuC,CACtD,QAAQ,EAAE,6BAA6B,GACrC,yBAAyB,CAI3B"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.getBlobContentsFromTreeWithBlobContents = exports.getBlobContentsFromTree = exports.ContainerStorageAdapter = void 0;
|
|
8
|
-
const
|
|
8
|
+
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
9
10
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
10
11
|
const protocolTreeDocumentStorageService_1 = require("./protocolTreeDocumentStorageService");
|
|
11
12
|
const retriableDocumentStorageService_1 = require("./retriableDocumentStorageService");
|
|
@@ -58,7 +59,7 @@ class ContainerStorageAdapter {
|
|
|
58
59
|
this._storageService = new protocolTreeDocumentStorageService_1.ProtocolTreeStorageService(retriableStorage, this.addProtocolSummaryIfMissing);
|
|
59
60
|
}
|
|
60
61
|
// ensure we did not lose that policy in the process of wrapping
|
|
61
|
-
(0,
|
|
62
|
+
(0, core_utils_1.assert)(storageService.policies?.minBlobSize === this._storageService.policies?.minBlobSize, 0x0e0 /* "lost minBlobSize policy" */);
|
|
62
63
|
}
|
|
63
64
|
loadSnapshotForRehydratingContainer(snapshotTree) {
|
|
64
65
|
this.getBlobContents(snapshotTree);
|
|
@@ -90,7 +91,7 @@ class ContainerStorageAdapter {
|
|
|
90
91
|
const maybeBlob = this.blobContents[id];
|
|
91
92
|
if (maybeBlob !== undefined) {
|
|
92
93
|
if (typeof maybeBlob === "string") {
|
|
93
|
-
const blob = (0,
|
|
94
|
+
const blob = (0, client_utils_1.stringToBuffer)(maybeBlob, "utf8");
|
|
94
95
|
return blob;
|
|
95
96
|
}
|
|
96
97
|
return maybeBlob;
|
|
@@ -186,7 +187,7 @@ async function getBlobContentsFromTreeCore(tree, blobs, storage, root = true) {
|
|
|
186
187
|
for (const id of Object.values(tree.blobs)) {
|
|
187
188
|
const blob = await storage.readBlob(id);
|
|
188
189
|
// ArrayBufferLike will not survive JSON.stringify()
|
|
189
|
-
blobs[id] = (0,
|
|
190
|
+
blobs[id] = (0, client_utils_1.bufferToString)(blob, "utf8");
|
|
190
191
|
}
|
|
191
192
|
return Promise.all(treePs);
|
|
192
193
|
}
|
|
@@ -195,7 +196,7 @@ async function getBlobManagerTreeFromTree(tree, blobs, storage) {
|
|
|
195
196
|
const id = tree.blobs[redirectTableBlobName];
|
|
196
197
|
const blob = await storage.readBlob(id);
|
|
197
198
|
// ArrayBufferLike will not survive JSON.stringify()
|
|
198
|
-
blobs[id] = (0,
|
|
199
|
+
blobs[id] = (0, client_utils_1.bufferToString)(blob, "utf8");
|
|
199
200
|
}
|
|
200
201
|
/**
|
|
201
202
|
* Extract blob contents from a snapshot tree with blob contents
|
|
@@ -217,17 +218,17 @@ function getBlobContentsFromTreeWithBlobContentsCore(tree, blobs, root = true) {
|
|
|
217
218
|
}
|
|
218
219
|
for (const id of Object.values(tree.blobs)) {
|
|
219
220
|
const blob = tree.blobsContents[id];
|
|
220
|
-
(0,
|
|
221
|
+
(0, core_utils_1.assert)(blob !== undefined, 0x2ec /* "Blob must be present in blobsContents" */);
|
|
221
222
|
// ArrayBufferLike will not survive JSON.stringify()
|
|
222
|
-
blobs[id] = (0,
|
|
223
|
+
blobs[id] = (0, client_utils_1.bufferToString)(blob, "utf8");
|
|
223
224
|
}
|
|
224
225
|
}
|
|
225
226
|
// save redirect table from .blobs tree but nothing else
|
|
226
227
|
function getBlobManagerTreeFromTreeWithBlobContents(tree, blobs) {
|
|
227
228
|
const id = tree.blobs[redirectTableBlobName];
|
|
228
229
|
const blob = tree.blobsContents[id];
|
|
229
|
-
(0,
|
|
230
|
+
(0, core_utils_1.assert)(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);
|
|
230
231
|
// ArrayBufferLike will not survive JSON.stringify()
|
|
231
|
-
blobs[id] = (0,
|
|
232
|
+
blobs[id] = (0, client_utils_1.bufferToString)(blob, "utf8");
|
|
232
233
|
}
|
|
233
234
|
//# sourceMappingURL=containerStorageAdapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerStorageAdapter.js","sourceRoot":"","sources":["../src/containerStorageAdapter.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 { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { assert, bufferToString, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport {\n\tFetchSource,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentStorageServicePolicies,\n\tISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport { UsageError } from \"@fluidframework/driver-utils\";\nimport {\n\tICreateBlobResponse,\n\tISnapshotTree,\n\tISummaryHandle,\n\tISummaryTree,\n\tIVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDetachedBlobStorage } from \"./loader\";\nimport { ProtocolTreeStorageService } from \"./protocolTreeDocumentStorageService\";\nimport { RetriableDocumentStorageService } from \"./retriableDocumentStorageService\";\n\n/**\n * Stringified blobs from a summary/snapshot tree.\n * @internal\n */\nexport interface ISerializableBlobContents {\n\t[id: string]: string;\n}\n\n/**\n * This class wraps the actual storage and make sure no wrong apis are called according to\n * container attach state.\n */\nexport class ContainerStorageAdapter implements IDocumentStorageService, IDisposable {\n\tprivate _storageService: IDocumentStorageService & Partial<IDisposable>;\n\n\tprivate _summarizeProtocolTree: boolean | undefined;\n\t/**\n\t * Whether the adapter will enforce sending combined summary trees.\n\t */\n\tpublic get summarizeProtocolTree() {\n\t\treturn this._summarizeProtocolTree === true;\n\t}\n\n\t/**\n\t * An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then\n\t * after connecting to a real service augments it with retry and combined summary tree enforcement.\n\t * @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service\n\t * @param logger - Telemetry logger\n\t * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to\n\t * upload, and fix it up with a protocol tree if needed\n\t * @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy\n\t */\n\tpublic constructor(\n\t\tdetachedBlobStorage: IDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\t/**\n\t\t * ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot\n\t\t */\n\t\tprivate readonly blobContents: { [id: string]: ArrayBufferLike | string } = {},\n\t\tprivate readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,\n\t\tforceEnableSummarizeProtocolTree: boolean | undefined,\n\t) {\n\t\tthis._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);\n\t\tthis._summarizeProtocolTree = forceEnableSummarizeProtocolTree;\n\t}\n\n\tdisposed: boolean = false;\n\tdispose(error?: Error): void {\n\t\tthis._storageService?.dispose?.(error);\n\t\tthis.disposed = true;\n\t}\n\n\tpublic async connectToService(service: IDocumentService): Promise<void> {\n\t\tif (!(this._storageService instanceof BlobOnlyStorage)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst storageService = await service.connectToStorage();\n\t\tconst retriableStorage = (this._storageService = new RetriableDocumentStorageService(\n\t\t\tstorageService,\n\t\t\tthis.logger,\n\t\t));\n\n\t\tthis._summarizeProtocolTree =\n\t\t\tthis._summarizeProtocolTree ?? service.policies?.summarizeProtocolTree;\n\t\tif (this.summarizeProtocolTree) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"summarizeProtocolTreeEnabled\" });\n\t\t\tthis._storageService = new ProtocolTreeStorageService(\n\t\t\t\tretriableStorage,\n\t\t\t\tthis.addProtocolSummaryIfMissing,\n\t\t\t);\n\t\t}\n\n\t\t// ensure we did not lose that policy in the process of wrapping\n\t\tassert(\n\t\t\tstorageService.policies?.minBlobSize === this._storageService.policies?.minBlobSize,\n\t\t\t0x0e0 /* \"lost minBlobSize policy\" */,\n\t\t);\n\t}\n\n\tpublic loadSnapshotForRehydratingContainer(snapshotTree: ISnapshotTreeWithBlobContents) {\n\t\tthis.getBlobContents(snapshotTree);\n\t}\n\n\tprivate getBlobContents(snapshotTree: ISnapshotTreeWithBlobContents) {\n\t\tfor (const [id, value] of Object.entries(snapshotTree.blobsContents)) {\n\t\t\tthis.blobContents[id] = value;\n\t\t}\n\t\tfor (const [_, tree] of Object.entries(snapshotTree.trees)) {\n\t\t\tthis.getBlobContents(tree);\n\t\t}\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\t// back-compat 0.40 containerRuntime requests policies even in detached container if storage is present\n\t\t// and storage is always present in >=0.41.\n\t\ttry {\n\t\t\treturn this._storageService.policies;\n\t\t} catch (e) {}\n\t\treturn undefined;\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\treturn this._storageService.repositoryUrl;\n\t}\n\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion,\n\t\tscenarioName?: string,\n\t): Promise<ISnapshotTree | null> {\n\t\treturn this._storageService.getSnapshotTree(version, scenarioName);\n\t}\n\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\tconst maybeBlob = this.blobContents[id];\n\t\tif (maybeBlob !== undefined) {\n\t\t\tif (typeof maybeBlob === \"string\") {\n\t\t\t\tconst blob = stringToBuffer(maybeBlob, \"utf8\");\n\t\t\t\treturn blob;\n\t\t\t}\n\t\t\treturn maybeBlob;\n\t\t}\n\t\treturn this._storageService.readBlob(id);\n\t}\n\n\tpublic async getVersions(\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string,\n\t\tfetchSource?: FetchSource,\n\t): Promise<IVersion[]> {\n\t\treturn this._storageService.getVersions(versionId, count, scenarioName, fetchSource);\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\treturn this._storageService.uploadSummaryWithContext(summary, context);\n\t}\n\n\tpublic async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n\t\treturn this._storageService.downloadSummary(handle);\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this._storageService.createBlob(file);\n\t}\n}\n\n/**\n * Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support\n * blobs in detached containers.\n */\nclass BlobOnlyStorage implements IDocumentStorageService {\n\tconstructor(\n\t\tprivate readonly detachedStorage: IDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {}\n\n\tpublic async createBlob(content: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this.verifyStorage().createBlob(content);\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\treturn this.verifyStorage().readBlob(blobId);\n\t}\n\n\tprivate verifyStorage(): IDetachedBlobStorage {\n\t\tif (this.detachedStorage === undefined) {\n\t\t\tthrow new UsageError(\"Real storage calls not allowed in Unattached container\");\n\t\t}\n\t\treturn this.detachedStorage;\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\treturn this.notCalled();\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\treturn this.notCalled();\n\t}\n\n\t/* eslint-disable @typescript-eslint/unbound-method */\n\tpublic getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;\n\tpublic getVersions: () => Promise<IVersion[]> = this.notCalled;\n\tpublic write: () => Promise<IVersion> = this.notCalled;\n\tpublic uploadSummaryWithContext: () => Promise<string> = this.notCalled;\n\tpublic downloadSummary: () => Promise<ISummaryTree> = this.notCalled;\n\t/* eslint-enable @typescript-eslint/unbound-method */\n\n\tprivate notCalled(): never {\n\t\tthis.verifyStorage();\n\t\ttry {\n\t\t\t// some browsers may not populate stack unless exception is thrown\n\t\t\tthrow new Error(\"BlobOnlyStorage not implemented method used\");\n\t\t} catch (err) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"BlobOnlyStorageWrongCall\" }, err);\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\n// runtime will write a tree to the summary containing \"attachment\" type entries\n// which reference attachment blobs by ID, along with a blob containing the blob redirect table.\n// However, some drivers do not support the \"attachment\" type and will convert them to \"blob\" type\n// entries. We want to avoid saving these to reduce the size of stashed change blobs, but we\n// need to make sure the blob redirect table is saved.\nconst blobsTreeName = \".blobs\";\nconst redirectTableBlobName = \".redirectTable\";\n\n/**\n * Get blob contents of a snapshot tree from storage (or, ideally, cache)\n */\nexport async function getBlobContentsFromTree(\n\tsnapshot: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n): Promise<ISerializableBlobContents> {\n\tconst blobs = {};\n\tawait getBlobContentsFromTreeCore(snapshot, blobs, storage);\n\treturn blobs;\n}\n\nasync function getBlobContentsFromTreeCore(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: IDocumentStorageService,\n\troot = true,\n) {\n\tconst treePs: Promise<any>[] = [];\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\ttreePs.push(getBlobManagerTreeFromTree(subTree, blobs, storage));\n\t\t} else {\n\t\t\ttreePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = await storage.readBlob(id);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n\treturn Promise.all(treePs);\n}\n\n// save redirect table from .blobs tree but nothing else\nasync function getBlobManagerTreeFromTree(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: IDocumentStorageService,\n) {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tconst blob = await storage.readBlob(id);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n\n/**\n * Extract blob contents from a snapshot tree with blob contents\n */\nexport function getBlobContentsFromTreeWithBlobContents(\n\tsnapshot: ISnapshotTreeWithBlobContents,\n): ISerializableBlobContents {\n\tconst blobs = {};\n\tgetBlobContentsFromTreeWithBlobContentsCore(snapshot, blobs);\n\treturn blobs;\n}\n\nfunction getBlobContentsFromTreeWithBlobContentsCore(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n\troot = true,\n) {\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\tgetBlobManagerTreeFromTreeWithBlobContents(subTree, blobs);\n\t\t} else {\n\t\t\tgetBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = tree.blobsContents[id];\n\t\tassert(blob !== undefined, 0x2ec /* \"Blob must be present in blobsContents\" */);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n}\n\n// save redirect table from .blobs tree but nothing else\nfunction getBlobManagerTreeFromTreeWithBlobContents(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n) {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tconst blob = tree.blobsContents[id];\n\tassert(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"containerStorageAdapter.js","sourceRoot":"","sources":["../src/containerStorageAdapter.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 { IDisposable } from \"@fluidframework/core-interfaces\";\nimport { ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { bufferToString, stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport {\n\tFetchSource,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentStorageServicePolicies,\n\tISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport { UsageError } from \"@fluidframework/driver-utils\";\nimport {\n\tICreateBlobResponse,\n\tISnapshotTree,\n\tISummaryHandle,\n\tISummaryTree,\n\tIVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDetachedBlobStorage } from \"./loader\";\nimport { ProtocolTreeStorageService } from \"./protocolTreeDocumentStorageService\";\nimport { RetriableDocumentStorageService } from \"./retriableDocumentStorageService\";\n\n/**\n * Stringified blobs from a summary/snapshot tree.\n * @internal\n */\nexport interface ISerializableBlobContents {\n\t[id: string]: string;\n}\n\n/**\n * This class wraps the actual storage and make sure no wrong apis are called according to\n * container attach state.\n */\nexport class ContainerStorageAdapter implements IDocumentStorageService, IDisposable {\n\tprivate _storageService: IDocumentStorageService & Partial<IDisposable>;\n\n\tprivate _summarizeProtocolTree: boolean | undefined;\n\t/**\n\t * Whether the adapter will enforce sending combined summary trees.\n\t */\n\tpublic get summarizeProtocolTree() {\n\t\treturn this._summarizeProtocolTree === true;\n\t}\n\n\t/**\n\t * An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then\n\t * after connecting to a real service augments it with retry and combined summary tree enforcement.\n\t * @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service\n\t * @param logger - Telemetry logger\n\t * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to\n\t * upload, and fix it up with a protocol tree if needed\n\t * @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy\n\t */\n\tpublic constructor(\n\t\tdetachedBlobStorage: IDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\t/**\n\t\t * ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot\n\t\t */\n\t\tprivate readonly blobContents: { [id: string]: ArrayBufferLike | string } = {},\n\t\tprivate readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,\n\t\tforceEnableSummarizeProtocolTree: boolean | undefined,\n\t) {\n\t\tthis._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);\n\t\tthis._summarizeProtocolTree = forceEnableSummarizeProtocolTree;\n\t}\n\n\tdisposed: boolean = false;\n\tdispose(error?: Error): void {\n\t\tthis._storageService?.dispose?.(error);\n\t\tthis.disposed = true;\n\t}\n\n\tpublic async connectToService(service: IDocumentService): Promise<void> {\n\t\tif (!(this._storageService instanceof BlobOnlyStorage)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst storageService = await service.connectToStorage();\n\t\tconst retriableStorage = (this._storageService = new RetriableDocumentStorageService(\n\t\t\tstorageService,\n\t\t\tthis.logger,\n\t\t));\n\n\t\tthis._summarizeProtocolTree =\n\t\t\tthis._summarizeProtocolTree ?? service.policies?.summarizeProtocolTree;\n\t\tif (this.summarizeProtocolTree) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"summarizeProtocolTreeEnabled\" });\n\t\t\tthis._storageService = new ProtocolTreeStorageService(\n\t\t\t\tretriableStorage,\n\t\t\t\tthis.addProtocolSummaryIfMissing,\n\t\t\t);\n\t\t}\n\n\t\t// ensure we did not lose that policy in the process of wrapping\n\t\tassert(\n\t\t\tstorageService.policies?.minBlobSize === this._storageService.policies?.minBlobSize,\n\t\t\t0x0e0 /* \"lost minBlobSize policy\" */,\n\t\t);\n\t}\n\n\tpublic loadSnapshotForRehydratingContainer(snapshotTree: ISnapshotTreeWithBlobContents) {\n\t\tthis.getBlobContents(snapshotTree);\n\t}\n\n\tprivate getBlobContents(snapshotTree: ISnapshotTreeWithBlobContents) {\n\t\tfor (const [id, value] of Object.entries(snapshotTree.blobsContents)) {\n\t\t\tthis.blobContents[id] = value;\n\t\t}\n\t\tfor (const [_, tree] of Object.entries(snapshotTree.trees)) {\n\t\t\tthis.getBlobContents(tree);\n\t\t}\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\t// back-compat 0.40 containerRuntime requests policies even in detached container if storage is present\n\t\t// and storage is always present in >=0.41.\n\t\ttry {\n\t\t\treturn this._storageService.policies;\n\t\t} catch (e) {}\n\t\treturn undefined;\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\treturn this._storageService.repositoryUrl;\n\t}\n\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion,\n\t\tscenarioName?: string,\n\t): Promise<ISnapshotTree | null> {\n\t\treturn this._storageService.getSnapshotTree(version, scenarioName);\n\t}\n\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\tconst maybeBlob = this.blobContents[id];\n\t\tif (maybeBlob !== undefined) {\n\t\t\tif (typeof maybeBlob === \"string\") {\n\t\t\t\tconst blob = stringToBuffer(maybeBlob, \"utf8\");\n\t\t\t\treturn blob;\n\t\t\t}\n\t\t\treturn maybeBlob;\n\t\t}\n\t\treturn this._storageService.readBlob(id);\n\t}\n\n\tpublic async getVersions(\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string,\n\t\tfetchSource?: FetchSource,\n\t): Promise<IVersion[]> {\n\t\treturn this._storageService.getVersions(versionId, count, scenarioName, fetchSource);\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\treturn this._storageService.uploadSummaryWithContext(summary, context);\n\t}\n\n\tpublic async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n\t\treturn this._storageService.downloadSummary(handle);\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this._storageService.createBlob(file);\n\t}\n}\n\n/**\n * Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support\n * blobs in detached containers.\n */\nclass BlobOnlyStorage implements IDocumentStorageService {\n\tconstructor(\n\t\tprivate readonly detachedStorage: IDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {}\n\n\tpublic async createBlob(content: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this.verifyStorage().createBlob(content);\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\treturn this.verifyStorage().readBlob(blobId);\n\t}\n\n\tprivate verifyStorage(): IDetachedBlobStorage {\n\t\tif (this.detachedStorage === undefined) {\n\t\t\tthrow new UsageError(\"Real storage calls not allowed in Unattached container\");\n\t\t}\n\t\treturn this.detachedStorage;\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\treturn this.notCalled();\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\treturn this.notCalled();\n\t}\n\n\t/* eslint-disable @typescript-eslint/unbound-method */\n\tpublic getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;\n\tpublic getVersions: () => Promise<IVersion[]> = this.notCalled;\n\tpublic write: () => Promise<IVersion> = this.notCalled;\n\tpublic uploadSummaryWithContext: () => Promise<string> = this.notCalled;\n\tpublic downloadSummary: () => Promise<ISummaryTree> = this.notCalled;\n\t/* eslint-enable @typescript-eslint/unbound-method */\n\n\tprivate notCalled(): never {\n\t\tthis.verifyStorage();\n\t\ttry {\n\t\t\t// some browsers may not populate stack unless exception is thrown\n\t\t\tthrow new Error(\"BlobOnlyStorage not implemented method used\");\n\t\t} catch (err) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"BlobOnlyStorageWrongCall\" }, err);\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\n// runtime will write a tree to the summary containing \"attachment\" type entries\n// which reference attachment blobs by ID, along with a blob containing the blob redirect table.\n// However, some drivers do not support the \"attachment\" type and will convert them to \"blob\" type\n// entries. We want to avoid saving these to reduce the size of stashed change blobs, but we\n// need to make sure the blob redirect table is saved.\nconst blobsTreeName = \".blobs\";\nconst redirectTableBlobName = \".redirectTable\";\n\n/**\n * Get blob contents of a snapshot tree from storage (or, ideally, cache)\n */\nexport async function getBlobContentsFromTree(\n\tsnapshot: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n): Promise<ISerializableBlobContents> {\n\tconst blobs = {};\n\tawait getBlobContentsFromTreeCore(snapshot, blobs, storage);\n\treturn blobs;\n}\n\nasync function getBlobContentsFromTreeCore(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: IDocumentStorageService,\n\troot = true,\n) {\n\tconst treePs: Promise<any>[] = [];\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\ttreePs.push(getBlobManagerTreeFromTree(subTree, blobs, storage));\n\t\t} else {\n\t\t\ttreePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = await storage.readBlob(id);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n\treturn Promise.all(treePs);\n}\n\n// save redirect table from .blobs tree but nothing else\nasync function getBlobManagerTreeFromTree(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: IDocumentStorageService,\n) {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tconst blob = await storage.readBlob(id);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n\n/**\n * Extract blob contents from a snapshot tree with blob contents\n */\nexport function getBlobContentsFromTreeWithBlobContents(\n\tsnapshot: ISnapshotTreeWithBlobContents,\n): ISerializableBlobContents {\n\tconst blobs = {};\n\tgetBlobContentsFromTreeWithBlobContentsCore(snapshot, blobs);\n\treturn blobs;\n}\n\nfunction getBlobContentsFromTreeWithBlobContentsCore(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n\troot = true,\n) {\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (root && key === blobsTreeName) {\n\t\t\tgetBlobManagerTreeFromTreeWithBlobContents(subTree, blobs);\n\t\t} else {\n\t\t\tgetBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = tree.blobsContents[id];\n\t\tassert(blob !== undefined, 0x2ec /* \"Blob must be present in blobsContents\" */);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n}\n\n// save redirect table from .blobs tree but nothing else\nfunction getBlobManagerTreeFromTreeWithBlobContents(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n) {\n\tconst id = tree.blobs[redirectTableBlobName];\n\tconst blob = tree.blobsContents[id];\n\tassert(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);\n\t// ArrayBufferLike will not survive JSON.stringify()\n\tblobs[id] = bufferToString(blob, \"utf8\");\n}\n"]}
|
package/dist/contracts.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { ITelemetryProperties } from "@fluidframework/core-interfaces";
|
|
6
|
-
import { IConnectionDetails, ICriticalContainerError, IDeltaQueue,
|
|
5
|
+
import { IErrorBase, ITelemetryProperties } from "@fluidframework/core-interfaces";
|
|
6
|
+
import { IConnectionDetails, ICriticalContainerError, IDeltaQueue, IFluidCodeDetails, ReadOnlyInfo } from "@fluidframework/container-definitions";
|
|
7
7
|
import { ConnectionMode, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage, ISignalClient, ISignalMessage } from "@fluidframework/protocol-definitions";
|
|
8
8
|
import { IContainerPackageInfo } from "@fluidframework/driver-definitions";
|
|
9
9
|
export declare enum ReconnectMode {
|
package/dist/contracts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iFAO+C;AAY/C,IAAY,aAIX;AAJD,WAAY,aAAa;IACxB,gCAAe,CAAA;IACf,sCAAqB,CAAA;IACrB,oCAAmB,CAAA;AACpB,CAAC,EAJW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAIxB;AAsKD;;;;GAIG;AACI,MAAM,cAAc,GAAG,CAC7B,WAA0C,EAClB,EAAE;IAC1B,IAAI,oBAAoB,CAAC;IACzB,IAAI,WAAW,IAAI,MAAM,IAAI,WAAW,EAAE;QACzC,oBAAoB,GAAG,WAAW,CAAC;KACnC;SAAM,IAAI,IAAA,sCAAc,EAAC,WAAW,EAAE,OAAO,CAAC,EAAE;QAChD,oBAAoB,GAAG,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC;KACjD;SAAM;QACN,oBAAoB,GAAG,WAAW,EAAE,OAAO,CAAC;KAC5C;IACD,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;AACvC,CAAC,CAAC;AAZW,QAAA,cAAc,kBAYzB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IErrorBase, ITelemetryProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tIConnectionDetails,\n\tICriticalContainerError,\n\tIDeltaQueue,\n\tIFluidCodeDetails,\n\tisFluidPackage,\n\tReadOnlyInfo,\n} from \"@fluidframework/container-definitions\";\nimport {\n\tConnectionMode,\n\tIClientConfiguration,\n\tIClientDetails,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { IContainerPackageInfo } from \"@fluidframework/driver-definitions\";\n\nexport enum ReconnectMode {\n\tNever = \"Never\",\n\tDisabled = \"Disabled\",\n\tEnabled = \"Enabled\",\n}\n\nexport interface IConnectionStateChangeReason<T extends IErrorBase = IErrorBase> {\n\ttext: string;\n\terror?: T;\n}\n\n/**\n * Internal version of IConnectionDetails with props are only exposed internally\n */\nexport interface IConnectionDetailsInternal extends IConnectionDetails {\n\tmode: ConnectionMode;\n\tversion: string;\n\tinitialClients: ISignalClient[];\n\treason: IConnectionStateChangeReason;\n}\n\n/**\n * Connection manager (implements this interface) is responsible for maintaining connection\n * to relay service.\n */\nexport interface IConnectionManager {\n\treadonly connected: boolean;\n\n\treadonly clientId: string | undefined;\n\n\t/** The queue of outbound delta messages */\n\treadonly outbound: IDeltaQueue<IDocumentMessage[]>;\n\n\t/** Details of client */\n\treadonly clientDetails: IClientDetails;\n\n\t/** Protocol version being used to communicate with the service */\n\treadonly version: string;\n\n\t/** Max message size allowed to the delta manager */\n\treadonly maxMessageSize: number;\n\n\t/** Service configuration provided by the service. */\n\treadonly serviceConfiguration: IClientConfiguration | undefined;\n\n\treadonly readOnlyInfo: ReadOnlyInfo;\n\n\t// Various connectivity properties for telemetry describing type of current connection\n\t// Things like connection mode, service info, etc.\n\t// Called when connection state changes (connect / disconnect)\n\treadonly connectionProps: ITelemetryProperties;\n\n\t// Verbose information about connection logged to telemetry in case of issues with\n\t// maintaining healthy connection, including op gaps, not receiving join op in time, etc.\n\t// Contains details information, like sequence numbers at connection time, initial ops info, etc.\n\treadonly connectionVerboseProps: ITelemetryProperties;\n\n\t/**\n\t * Prepares message to be sent. Fills in clientSequenceNumber.\n\t * Called only when active connection is present.\n\t */\n\tprepareMessageToSend(\n\t\tmessage: Omit<IDocumentMessage, \"clientSequenceNumber\">,\n\t): IDocumentMessage | undefined;\n\n\t/**\n\t * Called before incoming message is processed. Incoming messages can be combing from connection,\n\t * but also could come from storage.\n\t * This call allows connection manager to adjust knowledge about acked ops sent on previous connection.\n\t * Can be called at any time, including when there is no active connection.\n\t */\n\tbeforeProcessingIncomingOp(message: ISequencedDocumentMessage): void;\n\n\t/**\n\t * Submits signal to relay service.\n\t * Called only when active connection is present.\n\t */\n\tsubmitSignal(content: any): void;\n\n\t/**\n\t * Submits messages to relay service.\n\t * Called only when active connection is present.\n\t */\n\tsendMessages(messages: IDocumentMessage[]): void;\n\n\t/**\n\t * Initiates connection to relay service (noop if already connected).\n\t */\n\tconnect(reason: IConnectionStateChangeReason, connectionMode?: ConnectionMode): void;\n\n\t/**\n\t * Disposed connection manager\n\t */\n\tdispose(error?: ICriticalContainerError, switchToReadonly?: boolean): void;\n\n\tget connectionMode(): ConnectionMode;\n}\n\n/**\n * This interface represents a set of callbacks provided by DeltaManager to IConnectionManager on its creation\n * IConnectionManager instance will use them to communicate to DeltaManager about various events.\n */\nexport interface IConnectionManagerFactoryArgs {\n\t/**\n\t * Called by connection manager for each incoming op. Some ops maybe delivered before\n\t * connectHandler is called (initial ops on socket connection)\n\t */\n\treadonly incomingOpHandler: (messages: ISequencedDocumentMessage[], reason: string) => void;\n\n\t/**\n\t * Called by connection manager for each incoming signals.\n\t * Maybe called before connectHandler is called (initial signals on socket connection)\n\t */\n\treadonly signalHandler: (message: ISignalMessage) => void;\n\n\t/**\n\t * Called when connection manager experiences delay in connecting to relay service.\n\t * This can happen because client is offline, or service is busy and asks to not connect for some time.\n\t * Can be called many times while not connected.\n\t * Situation is considered resolved when connection is established and connectHandler is called.\n\t */\n\treadonly reconnectionDelayHandler: (delayMs: number, error: unknown) => void;\n\n\t/**\n\t * Called by connection manager whenever critical error happens and container should be closed.\n\t * Expects dispose() call in response to this call.\n\t */\n\treadonly closeHandler: (error?: any) => void;\n\n\t/**\n\t * Called whenever connection to relay service is lost.\n\t */\n\treadonly disconnectHandler: (reason: IConnectionStateChangeReason) => void;\n\n\t/**\n\t * Called whenever new connection to rely service is established\n\t */\n\treadonly connectHandler: (connection: IConnectionDetailsInternal) => void;\n\n\t/**\n\t * Called whenever ping/pong messages are roundtripped on connection.\n\t */\n\treadonly pongHandler: (latency: number) => void;\n\n\t/**\n\t * Called whenever connection type changes from writable to read-only or vice versa.\n\t *\n\t * @remarks\n\t *\n\t * Connection can be read-only if user has no edit permissions, or if container forced\n\t * connection to be read-only.\n\t * This should not be confused with \"read\" / \"write\"connection mode which is internal\n\t * optimization.\n\t *\n\t * @param readonly - Whether or not the container is now read-only.\n\t * `undefined` indicates that user permissions are not yet known.\n\t */\n\treadonly readonlyChangeHandler: (readonly?: boolean) => void;\n\n\t/**\n\t * Called whenever we try to start establishing a new connection.\n\t */\n\treadonly establishConnectionHandler: (reason: IConnectionStateChangeReason) => void;\n\n\t/**\n\t * Called whenever we cancel the connection in progress.\n\t */\n\treadonly cancelConnectionHandler: (reason: IConnectionStateChangeReason) => void;\n}\n\n/**\n *\n * @param codeDetails- - Data structure used to describe the code to load on the Fluid document\n * @returns The name of the Fluid package\n */\nexport const getPackageName = (\n\tcodeDetails: IFluidCodeDetails | undefined,\n): IContainerPackageInfo => {\n\tlet containerPackageName;\n\tif (codeDetails && \"name\" in codeDetails) {\n\t\tcontainerPackageName = codeDetails;\n\t} else if (isFluidPackage(codeDetails?.package)) {\n\t\tcontainerPackageName = codeDetails?.package.name;\n\t} else {\n\t\tcontainerPackageName = codeDetails?.package;\n\t}\n\treturn { name: containerPackageName };\n};\n"]}
|
package/dist/debugLogger.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.DebugLogger = void 0;
|
|
8
|
-
const
|
|
8
|
+
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
9
|
const debug_1 = require("debug");
|
|
10
10
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
11
11
|
/**
|
|
@@ -65,7 +65,7 @@ class DebugLogger {
|
|
|
65
65
|
}
|
|
66
66
|
newEvent.eventName = undefined;
|
|
67
67
|
let tick = "";
|
|
68
|
-
tick = `tick=${(0, telemetry_utils_1.formatTick)(
|
|
68
|
+
tick = `tick=${(0, telemetry_utils_1.formatTick)(client_utils_1.performance.now())}`;
|
|
69
69
|
// Extract stack to put it last, but also to avoid escaping '\n' in it by JSON.stringify below
|
|
70
70
|
const stack = newEvent.stack ?? "";
|
|
71
71
|
newEvent.stack = undefined;
|
package/dist/debugLogger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debugLogger.js","sourceRoot":"","sources":["../src/debugLogger.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 {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tITelemetryProperties,\n} from \"@fluidframework/core-interfaces\";\nimport { performance } from \"@
|
|
1
|
+
{"version":3,"file":"debugLogger.js","sourceRoot":"","sources":["../src/debugLogger.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 {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tITelemetryProperties,\n} from \"@fluidframework/core-interfaces\";\nimport { performance } from \"@fluid-internal/client-utils\";\nimport { debug as registerDebug, IDebugger } from \"debug\";\nimport {\n\tITelemetryLoggerExt,\n\tITelemetryLoggerPropertyBags,\n\tcreateMultiSinkLogger,\n\teventNamespaceSeparator,\n\tformatTick,\n} from \"@fluidframework/telemetry-utils\";\n\n/**\n * Implementation of debug logger\n */\nexport class DebugLogger implements ITelemetryBaseLogger {\n\t/**\n\t * Mix in debug logger with another logger.\n\t * Returned logger will output events to both newly created debug logger, as well as base logger\n\t * @param namespace - Telemetry event name prefix to add to all events\n\t * @param properties - Base properties to add to all events\n\t * @param propertyGetters - Getters to add additional properties to all events\n\t * @param baseLogger - Base logger to output events (in addition to debug logger being created). Can be undefined.\n\t */\n\tpublic static mixinDebugLogger(\n\t\tnamespace: string,\n\t\tbaseLogger?: ITelemetryBaseLogger,\n\t\tproperties?: ITelemetryLoggerPropertyBags,\n\t): ITelemetryLoggerExt {\n\t\t// Setup base logger upfront, such that host can disable it (if needed)\n\t\tconst debug = registerDebug(namespace);\n\n\t\t// Create one for errors that is always enabled\n\t\t// It can be silenced by replacing console.error if the debug namespace is not enabled.\n\t\tconst debugErr = registerDebug(namespace);\n\t\tdebugErr.log = function (...args) {\n\t\t\tif (debug.enabled === true) {\n\t\t\t\t// if the namespace is enabled, just use the default logger\n\t\t\t\tregisterDebug.log(...args);\n\t\t\t} else {\n\t\t\t\t// other wise, use the console logger (which could be replaced and silenced)\n\t\t\t\tconsole.error(...args);\n\t\t\t}\n\t\t};\n\t\tdebugErr.enabled = true;\n\n\t\treturn createMultiSinkLogger({\n\t\t\tnamespace,\n\t\t\tloggers: [baseLogger, new DebugLogger(debug, debugErr)],\n\t\t\tproperties,\n\t\t\ttryInheritProperties: true,\n\t\t});\n\t}\n\n\tprivate constructor(private readonly debug: IDebugger, private readonly debugErr: IDebugger) {}\n\n\t/**\n\t * Send an event to debug loggers\n\t *\n\t * @param event - the event to send\n\t */\n\tpublic send(event: ITelemetryBaseEvent): void {\n\t\tconst newEvent: ITelemetryProperties = { ...event };\n\t\tconst isError = newEvent.category === \"error\";\n\t\tlet logger = isError ? this.debugErr : this.debug;\n\n\t\t// Use debug's coloring schema for base of the event\n\t\tconst index = event.eventName.lastIndexOf(eventNamespaceSeparator);\n\t\tconst name = event.eventName.substring(index + 1);\n\t\tif (index > 0) {\n\t\t\tlogger = logger.extend(event.eventName.substring(0, index));\n\t\t}\n\t\tnewEvent.eventName = undefined;\n\n\t\tlet tick = \"\";\n\t\ttick = `tick=${formatTick(performance.now())}`;\n\n\t\t// Extract stack to put it last, but also to avoid escaping '\\n' in it by JSON.stringify below\n\t\tconst stack = newEvent.stack ?? \"\";\n\t\tnewEvent.stack = undefined;\n\n\t\t// Watch out for circular references - they can come from two sources\n\t\t// 1) error object - we do not control it and should remove it and retry\n\t\t// 2) properties supplied by telemetry caller - that's a bug that should be addressed!\n\t\tlet payload: string;\n\t\ttry {\n\t\t\tpayload = JSON.stringify(newEvent);\n\t\t} catch (error) {\n\t\t\tnewEvent.error = undefined;\n\t\t\tpayload = JSON.stringify(newEvent);\n\t\t}\n\n\t\tif (payload === \"{}\") {\n\t\t\tpayload = \"\";\n\t\t}\n\n\t\t// Force errors out, to help with diagnostics\n\t\tif (isError) {\n\t\t\tlogger.enabled = true;\n\t\t}\n\n\t\t// Print multi-line.\n\t\tlogger(`${name} ${payload} ${tick} ${stack}`);\n\t}\n}\n"]}
|
package/dist/deltaManager.d.ts
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { IEventProvider } from "@fluidframework/
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { TypedEventEmitter } from "@fluidframework/common-utils";
|
|
5
|
+
import { IThrottlingWarning, IEventProvider, ITelemetryProperties, ITelemetryErrorEvent } from "@fluidframework/core-interfaces";
|
|
6
|
+
import { ICriticalContainerError, IDeltaManager, IDeltaManagerEvents, IDeltaQueue } from "@fluidframework/container-definitions";
|
|
7
|
+
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
9
8
|
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
10
9
|
import { IDocumentService } from "@fluidframework/driver-definitions";
|
|
11
10
|
import { IDocumentMessage, ISequencedDocumentMessage, ISignalMessage, MessageType, ConnectionMode } from "@fluidframework/protocol-definitions";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"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"}
|
package/dist/deltaManager.js
CHANGED
|
@@ -6,14 +6,15 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.DeltaManager = void 0;
|
|
8
8
|
const uuid_1 = require("uuid");
|
|
9
|
-
const
|
|
9
|
+
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
10
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
10
11
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
11
12
|
const driver_definitions_1 = require("@fluidframework/driver-definitions");
|
|
12
13
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
13
14
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
14
|
-
const container_utils_1 = require("@fluidframework/container-utils");
|
|
15
15
|
const deltaQueue_1 = require("./deltaQueue");
|
|
16
16
|
const protocol_1 = require("./protocol");
|
|
17
|
+
const error_1 = require("./error");
|
|
17
18
|
/**
|
|
18
19
|
* Determines if message was sent by client, not service
|
|
19
20
|
*/
|
|
@@ -36,7 +37,7 @@ function isClientMessage(message) {
|
|
|
36
37
|
* Manages the flow of both inbound and outbound messages. This class ensures that shared objects receive delta
|
|
37
38
|
* messages in order regardless of possible network conditions or timings causing out of order delivery.
|
|
38
39
|
*/
|
|
39
|
-
class DeltaManager extends
|
|
40
|
+
class DeltaManager extends client_utils_1.TypedEventEmitter {
|
|
40
41
|
constructor(serviceProvider, logger, _active, createConnectionManager) {
|
|
41
42
|
super();
|
|
42
43
|
this.serviceProvider = serviceProvider;
|
|
@@ -102,7 +103,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
102
103
|
this.processInboundMessage(op);
|
|
103
104
|
});
|
|
104
105
|
this._inbound.on("error", (error) => {
|
|
105
|
-
this.close(
|
|
106
|
+
this.close(telemetry_utils_1.DataProcessingError.wrapIfUnrecognized(error, "deltaManagerInboundErrorHandler", this.lastMessage));
|
|
106
107
|
});
|
|
107
108
|
// Inbound signal queue
|
|
108
109
|
this._inboundSignal = new deltaQueue_1.DeltaQueue((message) => {
|
|
@@ -157,7 +158,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
157
158
|
*/
|
|
158
159
|
get hasCheckpointSequenceNumber() {
|
|
159
160
|
// Valid to be called only if we have active connection.
|
|
160
|
-
(0,
|
|
161
|
+
(0, core_utils_1.assert)(this.connectionManager.connected, 0x0df /* "Missing active connection" */);
|
|
161
162
|
return this._checkpointSequenceNumber !== undefined;
|
|
162
163
|
}
|
|
163
164
|
// Forwarding connection manager properties / IDeltaManager implementation
|
|
@@ -196,7 +197,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
196
197
|
if (message === undefined) {
|
|
197
198
|
return -1;
|
|
198
199
|
}
|
|
199
|
-
(0,
|
|
200
|
+
(0, core_utils_1.assert)(isClientMessage(message), 0x419 /* client sends non-client message */);
|
|
200
201
|
if (contents !== undefined) {
|
|
201
202
|
this.opsSize += contents.length;
|
|
202
203
|
}
|
|
@@ -222,14 +223,14 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
222
223
|
// The prepareFlush event allows listeners to append metadata to the batch prior to submission.
|
|
223
224
|
this.emit("prepareSend", batch);
|
|
224
225
|
if (batch.length === 1) {
|
|
225
|
-
(0,
|
|
226
|
+
(0, core_utils_1.assert)(batch[0].metadata?.batch === undefined, 0x3c9 /* no batch markup on single message */);
|
|
226
227
|
}
|
|
227
228
|
else {
|
|
228
|
-
(0,
|
|
229
|
-
(0,
|
|
229
|
+
(0, core_utils_1.assert)(batch[0].metadata?.batch === true, 0x3ca /* no start batch markup */);
|
|
230
|
+
(0, core_utils_1.assert)(batch[batch.length - 1].metadata?.batch === false, 0x3cb /* no end batch markup */);
|
|
230
231
|
}
|
|
231
232
|
this.connectionManager.sendMessages(batch);
|
|
232
|
-
(0,
|
|
233
|
+
(0, core_utils_1.assert)(this.messageBuffer.length === 0, 0x3cc /* reentrancy */);
|
|
233
234
|
}
|
|
234
235
|
get connectionProps() {
|
|
235
236
|
return {
|
|
@@ -246,7 +247,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
246
247
|
* @param event - Event to log.
|
|
247
248
|
*/
|
|
248
249
|
logConnectionIssue(event) {
|
|
249
|
-
(0,
|
|
250
|
+
(0, core_utils_1.assert)(this.connectionManager.connected, 0x238 /* "called only in connected state" */);
|
|
250
251
|
const pendingSorted = this.pending.sort((a, b) => a.sequenceNumber - b.sequenceNumber);
|
|
251
252
|
this.logger.sendErrorEvent({
|
|
252
253
|
...event,
|
|
@@ -287,7 +288,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
287
288
|
// but it's safe to assume (until better design is put into place) that batches should not exist
|
|
288
289
|
// across multiple connections. Right now we assume runtime will not submit any ops in disconnected
|
|
289
290
|
// state. As requirements change, so should these checks.
|
|
290
|
-
(0,
|
|
291
|
+
(0, core_utils_1.assert)(this.messageBuffer.length === 0, 0x0e9 /* "messageBuffer is not empty on new connection" */);
|
|
291
292
|
this.opsSize = 0;
|
|
292
293
|
this.noOpCount = 0;
|
|
293
294
|
this.emit("connect", connection, checkpointSequenceNumber !== undefined
|
|
@@ -318,16 +319,16 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
318
319
|
this.lastQueuedSequenceNumber = sequenceNumber;
|
|
319
320
|
this.lastObservedSeqNumber = sequenceNumber;
|
|
320
321
|
// We will use same check in other places to make sure all the seq number above are set properly.
|
|
321
|
-
(0,
|
|
322
|
+
(0, core_utils_1.assert)(this.handler === undefined, 0x0e2 /* "DeltaManager already has attached op handler!" */);
|
|
322
323
|
this.handler = handler;
|
|
323
324
|
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
324
|
-
(0,
|
|
325
|
+
(0, core_utils_1.assert)(!!this.handler, 0x0e3 /* "Newly set op handler is null/undefined!" */);
|
|
325
326
|
// There should be no pending fetch!
|
|
326
327
|
// This API is called right after attachOpHandler by Container.load().
|
|
327
328
|
// We might have connection already and it might have called fetchMissingDeltas() from
|
|
328
329
|
// setupNewSuccessfulConnection. But it should do nothing, because there is no way to fetch ops before
|
|
329
330
|
// we know snapshot sequence number that is set in attachOpHandler. So all such calls should be noop.
|
|
330
|
-
(0,
|
|
331
|
+
(0, core_utils_1.assert)(this.fetchReason === undefined, 0x268 /* "There can't be pending fetch that early in boot sequence!" */);
|
|
331
332
|
if (this._closed) {
|
|
332
333
|
return;
|
|
333
334
|
}
|
|
@@ -346,7 +347,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
346
347
|
}
|
|
347
348
|
}
|
|
348
349
|
// Ensure there is no need to call this.processPendingOps() at the end of boot sequence
|
|
349
|
-
(0,
|
|
350
|
+
(0, core_utils_1.assert)(this.fetchReason !== undefined || this.pending.length === 0, 0x269 /* "pending ops are not dropped" */);
|
|
350
351
|
}
|
|
351
352
|
connect(args) {
|
|
352
353
|
const fetchOpsFromStorage = args.fetchOpsFromStorage ?? true;
|
|
@@ -409,7 +410,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
409
410
|
const controller = new AbortController();
|
|
410
411
|
let opsFromFetch = false;
|
|
411
412
|
const opListener = (op) => {
|
|
412
|
-
(0,
|
|
413
|
+
(0, core_utils_1.assert)(op.sequenceNumber === this.lastQueuedSequenceNumber, 0x23a /* "seq#'s" */);
|
|
413
414
|
// Ops that are coming from this request should not cancel itself.
|
|
414
415
|
// This is useless for known ranges (to is defined) as it means request is over either way.
|
|
415
416
|
// And it will cancel unbound request too early, not allowing us to learn where the end of the file is.
|
|
@@ -421,7 +422,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
421
422
|
};
|
|
422
423
|
try {
|
|
423
424
|
this._inbound.on("push", opListener);
|
|
424
|
-
(0,
|
|
425
|
+
(0, core_utils_1.assert)(this.closeAbortController.signal.onabort === null, 0x1e8 /* "reentrancy" */);
|
|
425
426
|
this.closeAbortController.signal.onabort = () =>
|
|
426
427
|
// TODO: Remove when typescript version of the repo contains the AbortSignal.reason property (AB#5045)
|
|
427
428
|
controller.abort(this.closeAbortController.signal.reason);
|
|
@@ -454,7 +455,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
454
455
|
}
|
|
455
456
|
this.closeAbortController.signal.onabort = null;
|
|
456
457
|
this._inbound.off("push", opListener);
|
|
457
|
-
(0,
|
|
458
|
+
(0, core_utils_1.assert)(!opsFromFetch, 0x289 /* "logic error" */);
|
|
458
459
|
}
|
|
459
460
|
}
|
|
460
461
|
/**
|
|
@@ -487,7 +488,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
487
488
|
return;
|
|
488
489
|
}
|
|
489
490
|
if (error !== undefined && !(0, telemetry_utils_1.isFluidError)(error)) {
|
|
490
|
-
throw new
|
|
491
|
+
throw new telemetry_utils_1.UsageError("Error must be a Fluid error");
|
|
491
492
|
}
|
|
492
493
|
this._disposed = true;
|
|
493
494
|
this._closed = true; // We consider "disposed" as a further state than "closed"
|
|
@@ -531,7 +532,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
531
532
|
this.throttlingIdSet.add(id);
|
|
532
533
|
if (delayMs > 0 && timeNow + delayMs > this.timeTillThrottling) {
|
|
533
534
|
this.timeTillThrottling = timeNow + delayMs;
|
|
534
|
-
const throttlingWarning =
|
|
535
|
+
const throttlingWarning = error_1.ThrottlingWarning.wrap(error, delayMs / 1000 /* retryAfterSeconds */, this.logger);
|
|
535
536
|
this.emit("throttled", throttlingWarning);
|
|
536
537
|
}
|
|
537
538
|
}
|
|
@@ -561,7 +562,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
561
562
|
// It's responsibility of
|
|
562
563
|
// - attachOpHandler()
|
|
563
564
|
// - fetchMissingDeltas() after it's done with querying storage
|
|
564
|
-
(0,
|
|
565
|
+
(0, core_utils_1.assert)(this.pending.length === 0 || this.fetchReason !== undefined, 0x1e9 /* "Pending ops" */);
|
|
565
566
|
if (messages.length === 0) {
|
|
566
567
|
return;
|
|
567
568
|
}
|
|
@@ -627,7 +628,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
627
628
|
}
|
|
628
629
|
this.updateLatestKnownOpSeqNumber(messages[messages.length - 1].sequenceNumber);
|
|
629
630
|
const n = this.previouslyProcessedMessage?.sequenceNumber;
|
|
630
|
-
(0,
|
|
631
|
+
(0, core_utils_1.assert)(n === undefined || n === this.lastQueuedSequenceNumber, 0x0ec /* "Unexpected value for previously processed message's sequence number" */);
|
|
631
632
|
for (const message of messages) {
|
|
632
633
|
// Check that the messages are arriving in the expected order
|
|
633
634
|
if (message.sequenceNumber <= this.lastQueuedSequenceNumber) {
|
|
@@ -646,7 +647,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
646
647
|
// instances such that the same sequence number is reused for two different ops.
|
|
647
648
|
// pre-0.58 error message: twoMessagesWithSameSeqNumAndDifferentPayload
|
|
648
649
|
"Found two messages with the same sequenceNumber but different payloads. Likely to be a " +
|
|
649
|
-
"service issue", driver_definitions_1.
|
|
650
|
+
"service issue", driver_definitions_1.DriverErrorTypes.fileOverwrittenInStorage, {
|
|
650
651
|
clientId: this.connectionManager.clientId,
|
|
651
652
|
sequenceNumber: message.sequenceNumber,
|
|
652
653
|
message1,
|
|
@@ -674,18 +675,18 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
674
675
|
}
|
|
675
676
|
processInboundMessage(message) {
|
|
676
677
|
const startTime = Date.now();
|
|
677
|
-
(0,
|
|
678
|
+
(0, core_utils_1.assert)(!this.currentlyProcessingOps, 0x3af /* Already processing ops. */);
|
|
678
679
|
this.currentlyProcessingOps = true;
|
|
679
680
|
this.lastProcessedMessage = message;
|
|
680
681
|
const isString = typeof message.clientId === "string";
|
|
681
|
-
(0,
|
|
682
|
+
(0, core_utils_1.assert)(message.clientId === null || isString, 0x41a /* undefined or string */);
|
|
682
683
|
// All client messages are coming from some client, and should have clientId,
|
|
683
684
|
// and non-client message should not have clientId. But, there are two exceptions:
|
|
684
685
|
// 1. (Legacy) We can see message.type === "attach" or "chunkedOp" for legacy files before RTM
|
|
685
686
|
// 2. Non-immediate noops (contents: null) can be sent by service without clientId
|
|
686
687
|
if (!isString && isClientMessage(message) && message.type !== protocol_definitions_1.MessageType.NoOp) {
|
|
687
|
-
throw new
|
|
688
|
-
...(0,
|
|
688
|
+
throw new telemetry_utils_1.DataCorruptionError("Mismatch in clientId", {
|
|
689
|
+
...(0, telemetry_utils_1.extractSafePropertiesFromMessage)(message),
|
|
689
690
|
messageType: message.type,
|
|
690
691
|
});
|
|
691
692
|
}
|
|
@@ -713,8 +714,8 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
713
714
|
// Watch the minimum sequence number and be ready to update as needed
|
|
714
715
|
if (this.minSequenceNumber > message.minimumSequenceNumber) {
|
|
715
716
|
// pre-0.58 error message: msnMovesBackwards
|
|
716
|
-
throw new
|
|
717
|
-
...(0,
|
|
717
|
+
throw new telemetry_utils_1.DataCorruptionError("Found a lower minimumSequenceNumber (msn) than previously recorded", {
|
|
718
|
+
...(0, telemetry_utils_1.extractSafePropertiesFromMessage)(message),
|
|
718
719
|
clientId: this.connectionManager.clientId,
|
|
719
720
|
});
|
|
720
721
|
}
|
|
@@ -723,19 +724,19 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
723
724
|
// System ops (when no clients are connected) are the only ops where equation is possible.
|
|
724
725
|
const diff = message.sequenceNumber - message.minimumSequenceNumber;
|
|
725
726
|
if (diff < 0 || (diff === 0 && message.clientId !== null)) {
|
|
726
|
-
throw new
|
|
727
|
+
throw new telemetry_utils_1.DataCorruptionError("MSN has to be lower than sequence #", (0, telemetry_utils_1.extractSafePropertiesFromMessage)(message));
|
|
727
728
|
}
|
|
728
729
|
this.minSequenceNumber = message.minimumSequenceNumber;
|
|
729
730
|
if (message.sequenceNumber !== this.lastProcessedSequenceNumber + 1) {
|
|
730
731
|
// pre-0.58 error message: nonSequentialSequenceNumber
|
|
731
|
-
throw new
|
|
732
|
-
...(0,
|
|
732
|
+
throw new telemetry_utils_1.DataCorruptionError("Found a non-Sequential sequenceNumber", {
|
|
733
|
+
...(0, telemetry_utils_1.extractSafePropertiesFromMessage)(message),
|
|
733
734
|
clientId: this.connectionManager.clientId,
|
|
734
735
|
});
|
|
735
736
|
}
|
|
736
737
|
this.lastProcessedSequenceNumber = message.sequenceNumber;
|
|
737
738
|
// a bunch of code assumes that this is true
|
|
738
|
-
(0,
|
|
739
|
+
(0, core_utils_1.assert)(this.lastProcessedSequenceNumber <= this.lastObservedSeqNumber, 0x267 /* "lastObservedSeqNumber should be updated first" */);
|
|
739
740
|
// Back-compat for older server with no term
|
|
740
741
|
if (message.term === undefined) {
|
|
741
742
|
message.term = protocol_1.OnlyValidTermValue;
|
|
@@ -775,7 +776,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
775
776
|
}
|
|
776
777
|
if (this.handler === undefined) {
|
|
777
778
|
// We do not poses yet any information
|
|
778
|
-
(0,
|
|
779
|
+
(0, core_utils_1.assert)(this.lastQueuedSequenceNumber === 0, 0x26b /* "initial state" */);
|
|
779
780
|
return;
|
|
780
781
|
}
|
|
781
782
|
try {
|
|
@@ -787,8 +788,8 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
787
788
|
// Knowing about this mechanism, we could ask for op we already observed to increase validation.
|
|
788
789
|
// This is especially useful when coming out of offline mode or loading from
|
|
789
790
|
// very old cached (by client / driver) snapshot.
|
|
790
|
-
(0,
|
|
791
|
-
(0,
|
|
791
|
+
(0, core_utils_1.assert)(n === this.lastQueuedSequenceNumber, 0x0f2 /* "previouslyProcessedMessage" */);
|
|
792
|
+
(0, core_utils_1.assert)(from > 1, 0x0f3 /* "not positive" */);
|
|
792
793
|
from--;
|
|
793
794
|
}
|
|
794
795
|
const fetchReason = `${reason}_fetch`;
|
|
@@ -815,7 +816,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
815
816
|
if (this._closed) {
|
|
816
817
|
return;
|
|
817
818
|
}
|
|
818
|
-
(0,
|
|
819
|
+
(0, core_utils_1.assert)(this.handler !== undefined, 0x26c /* "handler should be installed" */);
|
|
819
820
|
const pendingSorted = this.pending.sort((a, b) => a.sequenceNumber - b.sequenceNumber);
|
|
820
821
|
this.pending = [];
|
|
821
822
|
// Given that we do not track where these ops came from any more, it's not very
|