@fluidframework/merge-tree 2.0.0-rc.2.0.6 → 2.0.0-rc.2.0.8
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/snapshotLoader.d.ts +1 -1
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +4 -4
- package/dist/snapshotLoader.js.map +1 -1
- package/lib/snapshotLoader.d.ts +1 -1
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +4 -4
- package/lib/snapshotLoader.js.map +1 -1
- package/package.json +14 -14
- package/src/snapshotLoader.ts +3 -6
package/dist/snapshotLoader.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare class SnapshotLoader {
|
|
|
26
26
|
/**
|
|
27
27
|
* If loading from a snapshot, get the catchup messages.
|
|
28
28
|
* @param rawMessages - The messages in original encoding
|
|
29
|
-
* @returns The decoded messages
|
|
29
|
+
* @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in
|
|
30
30
|
* SharedObject.processCore.
|
|
31
31
|
*/
|
|
32
32
|
private loadCatchupOps;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAEN,mBAAmB,EAEnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA4BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAsD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IA0FtB,OAAO,CAAC,kBAAkB;IAwB1B;;;;;OAKG;YACW,cAAc;
|
|
1
|
+
{"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAEN,mBAAmB,EAEnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA4BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAsD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IA0FtB,OAAO,CAAC,kBAAkB;IAwB1B;;;;;OAKG;YACW,cAAc;CAK5B"}
|
package/dist/snapshotLoader.js
CHANGED
|
@@ -92,7 +92,7 @@ class SnapshotLoader {
|
|
|
92
92
|
(0, core_utils_1.assert)(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);
|
|
93
93
|
// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.
|
|
94
94
|
// (See https://github.com/microsoft/FluidFramework/issues/84)
|
|
95
|
-
return this.loadCatchupOps(services.readBlob(blobs[0])
|
|
95
|
+
return this.loadCatchupOps(services.readBlob(blobs[0]));
|
|
96
96
|
}
|
|
97
97
|
else if (blobs.length !== headerChunk.headerMetadata.orderedChunkMetadata.length) {
|
|
98
98
|
throw new Error("Unexpected blobs in snapshot");
|
|
@@ -200,11 +200,11 @@ class SnapshotLoader {
|
|
|
200
200
|
/**
|
|
201
201
|
* If loading from a snapshot, get the catchup messages.
|
|
202
202
|
* @param rawMessages - The messages in original encoding
|
|
203
|
-
* @returns The decoded messages
|
|
203
|
+
* @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in
|
|
204
204
|
* SharedObject.processCore.
|
|
205
205
|
*/
|
|
206
|
-
async loadCatchupOps(rawMessages
|
|
207
|
-
return
|
|
206
|
+
async loadCatchupOps(rawMessages) {
|
|
207
|
+
return JSON.parse((0, client_utils_1.bufferToString)(await rawMessages, "utf8"));
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
exports.SnapshotLoader = SnapshotLoader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.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\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport {\n\tcreateChildLogger,\n\tITelemetryLoggerExt,\n\tUsageError,\n} from \"@fluidframework/telemetry-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\n// eslint-disable-next-line import/no-deprecated\nimport { Client } from \"./client.js\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants.js\";\nimport { ISegment } from \"./mergeTreeNodes.js\";\nimport { IJSONSegment } from \"./ops.js\";\nimport { IJSONSegmentWithMergeInfo, hasMergeInfo, MergeTreeChunkV1 } from \"./snapshotChunks.js\";\nimport { SnapshotV1 } from \"./snapshotV1.js\";\nimport { SnapshotLegacy } from \"./snapshotlegacy.js\";\nimport { MergeTree } from \"./mergeTree.js\";\n\nexport class SnapshotLoader {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\t// eslint-disable-next-line import/no-deprecated\n\t\tprivate readonly client: Client,\n\t\tprivate readonly mergeTree: MergeTree,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly serializer: IFluidSerializer,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"SnapshotLoader\" });\n\t}\n\n\tpublic async initialize(\n\t\tservices: IChannelStorageService,\n\t): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n\t\tconst headerLoadedP = services.readBlob(SnapshotLegacy.header).then((header) => {\n\t\t\tassert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n\t\t\treturn this.loadHeader(bufferToString(header, \"utf8\"));\n\t\t});\n\n\t\tconst catchupOpsP = this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n\t\tcatchupOpsP.catch((err) =>\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" }, err),\n\t\t);\n\n\t\tawait headerLoadedP;\n\n\t\treturn { catchupOpsP };\n\t}\n\n\tprivate async loadBodyAndCatchupOps(\n\t\theaderChunkP: Promise<MergeTreeChunkV1>,\n\t\tservices: IChannelStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst blobsP = services.list(\"\");\n\t\tconst headerChunk = await headerChunkP;\n\n\t\t// TODO we shouldn't need to wait on the body being complete to finish initialization.\n\t\t// To fully support this we need to be able to process inbound ops for pending segments.\n\t\tawait this.loadBody(headerChunk, services);\n\n\t\tconst blobs = await blobsP;\n\t\tif (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n\t\t\theaderChunk.headerMetadata!.orderedChunkMetadata.forEach((md) =>\n\t\t\t\tblobs.splice(blobs.indexOf(md.id), 1),\n\t\t\t);\n\t\t\tassert(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);\n\n\t\t\t// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\n\t\t\treturn this.loadCatchupOps(services.readBlob(blobs[0]), this.serializer);\n\t\t} else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n\t\t\tthrow new Error(\"Unexpected blobs in snapshot\");\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate readonly specToSegment = (spec: IJSONSegment | IJSONSegmentWithMergeInfo) => {\n\t\tlet seg: ISegment;\n\n\t\tif (hasMergeInfo(spec)) {\n\t\t\tseg = this.client.specToSegment(spec.json);\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. Overwrite this with\n\t\t\t// the `spec` client (if specified). Otherwise overwrite with `NonCollabClient`.\n\t\t\tseg.clientId =\n\t\t\t\tspec.client !== undefined\n\t\t\t\t\t? this.client.getOrAddShortClientId(spec.client)\n\t\t\t\t\t: NonCollabClient;\n\n\t\t\tseg.seq = spec.seq ?? UniversalSequenceNumber;\n\n\t\t\tif (spec.removedSeq !== undefined) {\n\t\t\t\tseg.removedSeq = spec.removedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeq !== undefined) {\n\t\t\t\tseg.movedSeq = spec.movedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeqs !== undefined) {\n\t\t\t\tseg.movedSeqs = spec.movedSeqs;\n\t\t\t}\n\t\t\t// this format had a bug where it didn't store all the overlap clients\n\t\t\t// this is for back compat, so we change the singular id to an array\n\t\t\t// this will only cause problems if there is an overlapping delete\n\t\t\t// spanning the snapshot, which should be rare\n\t\t\tconst specAsBuggyFormat: IJSONSegmentWithMergeInfo & { removedClient?: string } = spec;\n\t\t\tif (specAsBuggyFormat.removedClient !== undefined) {\n\t\t\t\tseg.removedClientIds = [\n\t\t\t\t\tthis.client.getOrAddShortClientId(specAsBuggyFormat.removedClient),\n\t\t\t\t];\n\t\t\t}\n\t\t\tif (spec.removedClientIds !== undefined) {\n\t\t\t\tseg.removedClientIds = spec.removedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (spec.movedClientIds !== undefined) {\n\t\t\t\tseg.movedClientIds = spec.movedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tseg = this.client.specToSegment(spec);\n\t\t\tseg.seq = UniversalSequenceNumber;\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. We must overwrite this with\n\t\t\t// `NonCollabClient`.\n\t\t\tseg.clientId = NonCollabClient;\n\t\t}\n\n\t\treturn seg;\n\t};\n\n\tprivate loadHeader(header: string): MergeTreeChunkV1 {\n\t\tconst chunk = SnapshotV1.processChunk(\n\t\t\tSnapshotLegacy.header,\n\t\t\theader,\n\t\t\tthis.logger,\n\t\t\tthis.mergeTree.options,\n\t\t\tthis.serializer,\n\t\t);\n\t\tconst segs = chunk.segments.map(this.specToSegment);\n\t\tthis.extractAttribution(segs, chunk);\n\n\t\tthis.mergeTree.reloadFromSegments(segs);\n\n\t\tif (chunk.headerMetadata === undefined) {\n\t\t\tthrow new Error(\"header metadata not available\");\n\t\t}\n\t\t// If we load a detached container from snapshot, then we don't supply a default clientId\n\t\t// because we don't want to start collaboration.\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t// specify a default client id, \"snapshot\" here as we\n\t\t\t// should enter collaboration/op sending mode if we load\n\t\t\t// a snapshot in any case (summary or attach message)\n\t\t\t// once we get a client id this will be called with that\n\t\t\t// clientId in the connected event\n\t\t\tthis.client.startOrUpdateCollaboration(\n\t\t\t\tthis.runtime.clientId ?? \"snapshot\",\n\n\t\t\t\t// TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n\t\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\t\t\t\t/* minSeq: */ chunk.headerMetadata.minSequenceNumber ??\n\t\t\t\t\tchunk.headerMetadata.sequenceNumber,\n\t\t\t\t/* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\treturn chunk;\n\t}\n\n\tprivate async loadBody(\n\t\tchunk1: MergeTreeChunkV1,\n\t\tservices: IChannelStorageService,\n\t): Promise<void> {\n\t\tconst headerMetadata = chunk1.headerMetadata!;\n\t\tassert(chunk1.length <= headerMetadata.totalLength, 0x061 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount <= headerMetadata.totalSegmentCount,\n\t\t\t0x062 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\tif (chunk1.segmentCount === headerMetadata.totalSegmentCount) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet chunksWithAttribution = chunk1.attribution !== undefined ? 1 : 0;\n\t\tconst segs: ISegment[] = [];\n\t\tlet lengthSofar = chunk1.length;\n\t\tfor (\n\t\t\tlet chunkIndex = 1;\n\t\t\tchunkIndex < headerMetadata.orderedChunkMetadata.length;\n\t\t\tchunkIndex++\n\t\t) {\n\t\t\tconst chunk = await SnapshotV1.loadChunk(\n\t\t\t\tservices,\n\t\t\t\theaderMetadata.orderedChunkMetadata[chunkIndex].id,\n\t\t\t\tthis.logger,\n\t\t\t\tthis.mergeTree.options,\n\t\t\t\tthis.serializer,\n\t\t\t);\n\t\t\tlengthSofar += chunk.length;\n\t\t\t// Deserialize each chunk segment and append it to the end of the MergeTree.\n\t\t\tconst newSegs = chunk.segments.map(this.specToSegment);\n\t\t\tthis.extractAttribution(newSegs, chunk);\n\t\t\tchunksWithAttribution += chunk.attribution !== undefined ? 1 : 0;\n\t\t\tsegs.push(...newSegs);\n\t\t}\n\n\t\tassert(\n\t\t\tchunksWithAttribution === 0 ||\n\t\t\t\tchunksWithAttribution === headerMetadata.orderedChunkMetadata.length,\n\t\t\t0x4c0 /* all or no chunks should have attribution information */,\n\t\t);\n\n\t\tassert(lengthSofar === headerMetadata.totalLength, 0x063 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount + segs.length === headerMetadata.totalSegmentCount,\n\t\t\t0x064 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\t// Helper to insert segments at the end of the MergeTree.\n\t\tconst mergeTree = this.mergeTree;\n\t\tconst append = (segments: ISegment[], cli: number, seq: number) => {\n\t\t\tmergeTree.insertSegments(\n\t\t\t\tmergeTree.root.cachedLength ?? 0,\n\t\t\t\tsegments,\n\t\t\t\t/* refSeq: */ UniversalSequenceNumber,\n\t\t\t\tcli,\n\t\t\t\tseq,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t};\n\n\t\t// Helpers to batch-insert segments that are below the min seq\n\t\tconst batch: ISegment[] = [];\n\t\tconst flushBatch = () => {\n\t\t\tif (batch.length > 0) {\n\t\t\t\tappend(batch, NonCollabClient, UniversalSequenceNumber);\n\t\t\t}\n\t\t};\n\n\t\tfor (const seg of segs) {\n\t\t\tconst cli = seg.clientId;\n\t\t\tconst seq = seg.seq;\n\n\t\t\t// If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n\t\t\t// any batched segments and then insert the current segment individually.\n\t\t\tif (cli === NonCollabClient && seq === UniversalSequenceNumber) {\n\t\t\t\tbatch.push(seg);\n\t\t\t} else {\n\t\t\t\tflushBatch();\n\t\t\t\tappend([seg], cli, seq!);\n\t\t\t}\n\t\t}\n\n\t\tflushBatch();\n\t}\n\n\tprivate extractAttribution(segments: ISegment[], chunk: MergeTreeChunkV1): void {\n\t\tthis.mergeTree.options ??= {};\n\t\tthis.mergeTree.options.attribution ??= {};\n\t\tif (chunk.attribution) {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"Attribution policy must be provided when loading a document with attribution information.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { isAttached, attach, serializer } = attributionPolicy;\n\t\t\tif (!isAttached) {\n\t\t\t\tattach(this.client);\n\t\t\t}\n\t\t\tserializer.populateAttributionCollections(segments, chunk.attribution);\n\t\t} else {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy?.isAttached) {\n\t\t\t\tattributionPolicy?.detach();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If loading from a snapshot, get the catchup messages.\n\t * @param rawMessages - The messages in original encoding\n\t * @returns The decoded messages with parsed+hydrated handles. Matches the format that will be passed in\n\t * SharedObject.processCore.\n\t */\n\tprivate async loadCatchupOps(\n\t\trawMessages: Promise<ArrayBufferLike>,\n\t\tserializer: IFluidSerializer,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\treturn serializer.parse(\n\t\t\tbufferToString(await rawMessages, \"utf8\"),\n\t\t) as ISequencedDocumentMessage[];\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.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\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport {\n\tcreateChildLogger,\n\tITelemetryLoggerExt,\n\tUsageError,\n} from \"@fluidframework/telemetry-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\n// eslint-disable-next-line import/no-deprecated\nimport { Client } from \"./client.js\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants.js\";\nimport { ISegment } from \"./mergeTreeNodes.js\";\nimport { IJSONSegment } from \"./ops.js\";\nimport { IJSONSegmentWithMergeInfo, hasMergeInfo, MergeTreeChunkV1 } from \"./snapshotChunks.js\";\nimport { SnapshotV1 } from \"./snapshotV1.js\";\nimport { SnapshotLegacy } from \"./snapshotlegacy.js\";\nimport { MergeTree } from \"./mergeTree.js\";\n\nexport class SnapshotLoader {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\t// eslint-disable-next-line import/no-deprecated\n\t\tprivate readonly client: Client,\n\t\tprivate readonly mergeTree: MergeTree,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly serializer: IFluidSerializer,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"SnapshotLoader\" });\n\t}\n\n\tpublic async initialize(\n\t\tservices: IChannelStorageService,\n\t): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n\t\tconst headerLoadedP = services.readBlob(SnapshotLegacy.header).then((header) => {\n\t\t\tassert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n\t\t\treturn this.loadHeader(bufferToString(header, \"utf8\"));\n\t\t});\n\n\t\tconst catchupOpsP = this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n\t\tcatchupOpsP.catch((err) =>\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" }, err),\n\t\t);\n\n\t\tawait headerLoadedP;\n\n\t\treturn { catchupOpsP };\n\t}\n\n\tprivate async loadBodyAndCatchupOps(\n\t\theaderChunkP: Promise<MergeTreeChunkV1>,\n\t\tservices: IChannelStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst blobsP = services.list(\"\");\n\t\tconst headerChunk = await headerChunkP;\n\n\t\t// TODO we shouldn't need to wait on the body being complete to finish initialization.\n\t\t// To fully support this we need to be able to process inbound ops for pending segments.\n\t\tawait this.loadBody(headerChunk, services);\n\n\t\tconst blobs = await blobsP;\n\t\tif (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n\t\t\theaderChunk.headerMetadata!.orderedChunkMetadata.forEach((md) =>\n\t\t\t\tblobs.splice(blobs.indexOf(md.id), 1),\n\t\t\t);\n\t\t\tassert(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);\n\n\t\t\t// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\n\t\t\treturn this.loadCatchupOps(services.readBlob(blobs[0]));\n\t\t} else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n\t\t\tthrow new Error(\"Unexpected blobs in snapshot\");\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate readonly specToSegment = (spec: IJSONSegment | IJSONSegmentWithMergeInfo) => {\n\t\tlet seg: ISegment;\n\n\t\tif (hasMergeInfo(spec)) {\n\t\t\tseg = this.client.specToSegment(spec.json);\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. Overwrite this with\n\t\t\t// the `spec` client (if specified). Otherwise overwrite with `NonCollabClient`.\n\t\t\tseg.clientId =\n\t\t\t\tspec.client !== undefined\n\t\t\t\t\t? this.client.getOrAddShortClientId(spec.client)\n\t\t\t\t\t: NonCollabClient;\n\n\t\t\tseg.seq = spec.seq ?? UniversalSequenceNumber;\n\n\t\t\tif (spec.removedSeq !== undefined) {\n\t\t\t\tseg.removedSeq = spec.removedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeq !== undefined) {\n\t\t\t\tseg.movedSeq = spec.movedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeqs !== undefined) {\n\t\t\t\tseg.movedSeqs = spec.movedSeqs;\n\t\t\t}\n\t\t\t// this format had a bug where it didn't store all the overlap clients\n\t\t\t// this is for back compat, so we change the singular id to an array\n\t\t\t// this will only cause problems if there is an overlapping delete\n\t\t\t// spanning the snapshot, which should be rare\n\t\t\tconst specAsBuggyFormat: IJSONSegmentWithMergeInfo & { removedClient?: string } = spec;\n\t\t\tif (specAsBuggyFormat.removedClient !== undefined) {\n\t\t\t\tseg.removedClientIds = [\n\t\t\t\t\tthis.client.getOrAddShortClientId(specAsBuggyFormat.removedClient),\n\t\t\t\t];\n\t\t\t}\n\t\t\tif (spec.removedClientIds !== undefined) {\n\t\t\t\tseg.removedClientIds = spec.removedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (spec.movedClientIds !== undefined) {\n\t\t\t\tseg.movedClientIds = spec.movedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tseg = this.client.specToSegment(spec);\n\t\t\tseg.seq = UniversalSequenceNumber;\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. We must overwrite this with\n\t\t\t// `NonCollabClient`.\n\t\t\tseg.clientId = NonCollabClient;\n\t\t}\n\n\t\treturn seg;\n\t};\n\n\tprivate loadHeader(header: string): MergeTreeChunkV1 {\n\t\tconst chunk = SnapshotV1.processChunk(\n\t\t\tSnapshotLegacy.header,\n\t\t\theader,\n\t\t\tthis.logger,\n\t\t\tthis.mergeTree.options,\n\t\t\tthis.serializer,\n\t\t);\n\t\tconst segs = chunk.segments.map(this.specToSegment);\n\t\tthis.extractAttribution(segs, chunk);\n\n\t\tthis.mergeTree.reloadFromSegments(segs);\n\n\t\tif (chunk.headerMetadata === undefined) {\n\t\t\tthrow new Error(\"header metadata not available\");\n\t\t}\n\t\t// If we load a detached container from snapshot, then we don't supply a default clientId\n\t\t// because we don't want to start collaboration.\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t// specify a default client id, \"snapshot\" here as we\n\t\t\t// should enter collaboration/op sending mode if we load\n\t\t\t// a snapshot in any case (summary or attach message)\n\t\t\t// once we get a client id this will be called with that\n\t\t\t// clientId in the connected event\n\t\t\tthis.client.startOrUpdateCollaboration(\n\t\t\t\tthis.runtime.clientId ?? \"snapshot\",\n\n\t\t\t\t// TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n\t\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\t\t\t\t/* minSeq: */ chunk.headerMetadata.minSequenceNumber ??\n\t\t\t\t\tchunk.headerMetadata.sequenceNumber,\n\t\t\t\t/* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\treturn chunk;\n\t}\n\n\tprivate async loadBody(\n\t\tchunk1: MergeTreeChunkV1,\n\t\tservices: IChannelStorageService,\n\t): Promise<void> {\n\t\tconst headerMetadata = chunk1.headerMetadata!;\n\t\tassert(chunk1.length <= headerMetadata.totalLength, 0x061 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount <= headerMetadata.totalSegmentCount,\n\t\t\t0x062 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\tif (chunk1.segmentCount === headerMetadata.totalSegmentCount) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet chunksWithAttribution = chunk1.attribution !== undefined ? 1 : 0;\n\t\tconst segs: ISegment[] = [];\n\t\tlet lengthSofar = chunk1.length;\n\t\tfor (\n\t\t\tlet chunkIndex = 1;\n\t\t\tchunkIndex < headerMetadata.orderedChunkMetadata.length;\n\t\t\tchunkIndex++\n\t\t) {\n\t\t\tconst chunk = await SnapshotV1.loadChunk(\n\t\t\t\tservices,\n\t\t\t\theaderMetadata.orderedChunkMetadata[chunkIndex].id,\n\t\t\t\tthis.logger,\n\t\t\t\tthis.mergeTree.options,\n\t\t\t\tthis.serializer,\n\t\t\t);\n\t\t\tlengthSofar += chunk.length;\n\t\t\t// Deserialize each chunk segment and append it to the end of the MergeTree.\n\t\t\tconst newSegs = chunk.segments.map(this.specToSegment);\n\t\t\tthis.extractAttribution(newSegs, chunk);\n\t\t\tchunksWithAttribution += chunk.attribution !== undefined ? 1 : 0;\n\t\t\tsegs.push(...newSegs);\n\t\t}\n\n\t\tassert(\n\t\t\tchunksWithAttribution === 0 ||\n\t\t\t\tchunksWithAttribution === headerMetadata.orderedChunkMetadata.length,\n\t\t\t0x4c0 /* all or no chunks should have attribution information */,\n\t\t);\n\n\t\tassert(lengthSofar === headerMetadata.totalLength, 0x063 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount + segs.length === headerMetadata.totalSegmentCount,\n\t\t\t0x064 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\t// Helper to insert segments at the end of the MergeTree.\n\t\tconst mergeTree = this.mergeTree;\n\t\tconst append = (segments: ISegment[], cli: number, seq: number) => {\n\t\t\tmergeTree.insertSegments(\n\t\t\t\tmergeTree.root.cachedLength ?? 0,\n\t\t\t\tsegments,\n\t\t\t\t/* refSeq: */ UniversalSequenceNumber,\n\t\t\t\tcli,\n\t\t\t\tseq,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t};\n\n\t\t// Helpers to batch-insert segments that are below the min seq\n\t\tconst batch: ISegment[] = [];\n\t\tconst flushBatch = () => {\n\t\t\tif (batch.length > 0) {\n\t\t\t\tappend(batch, NonCollabClient, UniversalSequenceNumber);\n\t\t\t}\n\t\t};\n\n\t\tfor (const seg of segs) {\n\t\t\tconst cli = seg.clientId;\n\t\t\tconst seq = seg.seq;\n\n\t\t\t// If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n\t\t\t// any batched segments and then insert the current segment individually.\n\t\t\tif (cli === NonCollabClient && seq === UniversalSequenceNumber) {\n\t\t\t\tbatch.push(seg);\n\t\t\t} else {\n\t\t\t\tflushBatch();\n\t\t\t\tappend([seg], cli, seq!);\n\t\t\t}\n\t\t}\n\n\t\tflushBatch();\n\t}\n\n\tprivate extractAttribution(segments: ISegment[], chunk: MergeTreeChunkV1): void {\n\t\tthis.mergeTree.options ??= {};\n\t\tthis.mergeTree.options.attribution ??= {};\n\t\tif (chunk.attribution) {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"Attribution policy must be provided when loading a document with attribution information.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { isAttached, attach, serializer } = attributionPolicy;\n\t\t\tif (!isAttached) {\n\t\t\t\tattach(this.client);\n\t\t\t}\n\t\t\tserializer.populateAttributionCollections(segments, chunk.attribution);\n\t\t} else {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy?.isAttached) {\n\t\t\t\tattributionPolicy?.detach();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If loading from a snapshot, get the catchup messages.\n\t * @param rawMessages - The messages in original encoding\n\t * @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in\n\t * SharedObject.processCore.\n\t */\n\tprivate async loadCatchupOps(\n\t\trawMessages: Promise<ArrayBufferLike>,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\treturn JSON.parse(bufferToString(await rawMessages, \"utf8\")) as ISequencedDocumentMessage[];\n\t}\n}\n"]}
|
package/lib/snapshotLoader.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare class SnapshotLoader {
|
|
|
26
26
|
/**
|
|
27
27
|
* If loading from a snapshot, get the catchup messages.
|
|
28
28
|
* @param rawMessages - The messages in original encoding
|
|
29
|
-
* @returns The decoded messages
|
|
29
|
+
* @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in
|
|
30
30
|
* SharedObject.processCore.
|
|
31
31
|
*/
|
|
32
32
|
private loadCatchupOps;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAEN,mBAAmB,EAEnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA4BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAsD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IA0FtB,OAAO,CAAC,kBAAkB;IAwB1B;;;;;OAKG;YACW,cAAc;
|
|
1
|
+
{"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAEN,mBAAmB,EAEnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,uCAAuC,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA4BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAsD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IA0FtB,OAAO,CAAC,kBAAkB;IAwB1B;;;;;OAKG;YACW,cAAc;CAK5B"}
|
package/lib/snapshotLoader.js
CHANGED
|
@@ -89,7 +89,7 @@ export class SnapshotLoader {
|
|
|
89
89
|
assert(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);
|
|
90
90
|
// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.
|
|
91
91
|
// (See https://github.com/microsoft/FluidFramework/issues/84)
|
|
92
|
-
return this.loadCatchupOps(services.readBlob(blobs[0])
|
|
92
|
+
return this.loadCatchupOps(services.readBlob(blobs[0]));
|
|
93
93
|
}
|
|
94
94
|
else if (blobs.length !== headerChunk.headerMetadata.orderedChunkMetadata.length) {
|
|
95
95
|
throw new Error("Unexpected blobs in snapshot");
|
|
@@ -197,11 +197,11 @@ export class SnapshotLoader {
|
|
|
197
197
|
/**
|
|
198
198
|
* If loading from a snapshot, get the catchup messages.
|
|
199
199
|
* @param rawMessages - The messages in original encoding
|
|
200
|
-
* @returns The decoded messages
|
|
200
|
+
* @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in
|
|
201
201
|
* SharedObject.processCore.
|
|
202
202
|
*/
|
|
203
|
-
async loadCatchupOps(rawMessages
|
|
204
|
-
return
|
|
203
|
+
async loadCatchupOps(rawMessages) {
|
|
204
|
+
return JSON.parse(bufferToString(await rawMessages, "utf8"));
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
//# sourceMappingURL=snapshotLoader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.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\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport {\n\tcreateChildLogger,\n\tITelemetryLoggerExt,\n\tUsageError,\n} from \"@fluidframework/telemetry-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\n// eslint-disable-next-line import/no-deprecated\nimport { Client } from \"./client.js\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants.js\";\nimport { ISegment } from \"./mergeTreeNodes.js\";\nimport { IJSONSegment } from \"./ops.js\";\nimport { IJSONSegmentWithMergeInfo, hasMergeInfo, MergeTreeChunkV1 } from \"./snapshotChunks.js\";\nimport { SnapshotV1 } from \"./snapshotV1.js\";\nimport { SnapshotLegacy } from \"./snapshotlegacy.js\";\nimport { MergeTree } from \"./mergeTree.js\";\n\nexport class SnapshotLoader {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\t// eslint-disable-next-line import/no-deprecated\n\t\tprivate readonly client: Client,\n\t\tprivate readonly mergeTree: MergeTree,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly serializer: IFluidSerializer,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"SnapshotLoader\" });\n\t}\n\n\tpublic async initialize(\n\t\tservices: IChannelStorageService,\n\t): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n\t\tconst headerLoadedP = services.readBlob(SnapshotLegacy.header).then((header) => {\n\t\t\tassert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n\t\t\treturn this.loadHeader(bufferToString(header, \"utf8\"));\n\t\t});\n\n\t\tconst catchupOpsP = this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n\t\tcatchupOpsP.catch((err) =>\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" }, err),\n\t\t);\n\n\t\tawait headerLoadedP;\n\n\t\treturn { catchupOpsP };\n\t}\n\n\tprivate async loadBodyAndCatchupOps(\n\t\theaderChunkP: Promise<MergeTreeChunkV1>,\n\t\tservices: IChannelStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst blobsP = services.list(\"\");\n\t\tconst headerChunk = await headerChunkP;\n\n\t\t// TODO we shouldn't need to wait on the body being complete to finish initialization.\n\t\t// To fully support this we need to be able to process inbound ops for pending segments.\n\t\tawait this.loadBody(headerChunk, services);\n\n\t\tconst blobs = await blobsP;\n\t\tif (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n\t\t\theaderChunk.headerMetadata!.orderedChunkMetadata.forEach((md) =>\n\t\t\t\tblobs.splice(blobs.indexOf(md.id), 1),\n\t\t\t);\n\t\t\tassert(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);\n\n\t\t\t// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\n\t\t\treturn this.loadCatchupOps(services.readBlob(blobs[0]), this.serializer);\n\t\t} else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n\t\t\tthrow new Error(\"Unexpected blobs in snapshot\");\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate readonly specToSegment = (spec: IJSONSegment | IJSONSegmentWithMergeInfo) => {\n\t\tlet seg: ISegment;\n\n\t\tif (hasMergeInfo(spec)) {\n\t\t\tseg = this.client.specToSegment(spec.json);\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. Overwrite this with\n\t\t\t// the `spec` client (if specified). Otherwise overwrite with `NonCollabClient`.\n\t\t\tseg.clientId =\n\t\t\t\tspec.client !== undefined\n\t\t\t\t\t? this.client.getOrAddShortClientId(spec.client)\n\t\t\t\t\t: NonCollabClient;\n\n\t\t\tseg.seq = spec.seq ?? UniversalSequenceNumber;\n\n\t\t\tif (spec.removedSeq !== undefined) {\n\t\t\t\tseg.removedSeq = spec.removedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeq !== undefined) {\n\t\t\t\tseg.movedSeq = spec.movedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeqs !== undefined) {\n\t\t\t\tseg.movedSeqs = spec.movedSeqs;\n\t\t\t}\n\t\t\t// this format had a bug where it didn't store all the overlap clients\n\t\t\t// this is for back compat, so we change the singular id to an array\n\t\t\t// this will only cause problems if there is an overlapping delete\n\t\t\t// spanning the snapshot, which should be rare\n\t\t\tconst specAsBuggyFormat: IJSONSegmentWithMergeInfo & { removedClient?: string } = spec;\n\t\t\tif (specAsBuggyFormat.removedClient !== undefined) {\n\t\t\t\tseg.removedClientIds = [\n\t\t\t\t\tthis.client.getOrAddShortClientId(specAsBuggyFormat.removedClient),\n\t\t\t\t];\n\t\t\t}\n\t\t\tif (spec.removedClientIds !== undefined) {\n\t\t\t\tseg.removedClientIds = spec.removedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (spec.movedClientIds !== undefined) {\n\t\t\t\tseg.movedClientIds = spec.movedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tseg = this.client.specToSegment(spec);\n\t\t\tseg.seq = UniversalSequenceNumber;\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. We must overwrite this with\n\t\t\t// `NonCollabClient`.\n\t\t\tseg.clientId = NonCollabClient;\n\t\t}\n\n\t\treturn seg;\n\t};\n\n\tprivate loadHeader(header: string): MergeTreeChunkV1 {\n\t\tconst chunk = SnapshotV1.processChunk(\n\t\t\tSnapshotLegacy.header,\n\t\t\theader,\n\t\t\tthis.logger,\n\t\t\tthis.mergeTree.options,\n\t\t\tthis.serializer,\n\t\t);\n\t\tconst segs = chunk.segments.map(this.specToSegment);\n\t\tthis.extractAttribution(segs, chunk);\n\n\t\tthis.mergeTree.reloadFromSegments(segs);\n\n\t\tif (chunk.headerMetadata === undefined) {\n\t\t\tthrow new Error(\"header metadata not available\");\n\t\t}\n\t\t// If we load a detached container from snapshot, then we don't supply a default clientId\n\t\t// because we don't want to start collaboration.\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t// specify a default client id, \"snapshot\" here as we\n\t\t\t// should enter collaboration/op sending mode if we load\n\t\t\t// a snapshot in any case (summary or attach message)\n\t\t\t// once we get a client id this will be called with that\n\t\t\t// clientId in the connected event\n\t\t\tthis.client.startOrUpdateCollaboration(\n\t\t\t\tthis.runtime.clientId ?? \"snapshot\",\n\n\t\t\t\t// TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n\t\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\t\t\t\t/* minSeq: */ chunk.headerMetadata.minSequenceNumber ??\n\t\t\t\t\tchunk.headerMetadata.sequenceNumber,\n\t\t\t\t/* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\treturn chunk;\n\t}\n\n\tprivate async loadBody(\n\t\tchunk1: MergeTreeChunkV1,\n\t\tservices: IChannelStorageService,\n\t): Promise<void> {\n\t\tconst headerMetadata = chunk1.headerMetadata!;\n\t\tassert(chunk1.length <= headerMetadata.totalLength, 0x061 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount <= headerMetadata.totalSegmentCount,\n\t\t\t0x062 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\tif (chunk1.segmentCount === headerMetadata.totalSegmentCount) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet chunksWithAttribution = chunk1.attribution !== undefined ? 1 : 0;\n\t\tconst segs: ISegment[] = [];\n\t\tlet lengthSofar = chunk1.length;\n\t\tfor (\n\t\t\tlet chunkIndex = 1;\n\t\t\tchunkIndex < headerMetadata.orderedChunkMetadata.length;\n\t\t\tchunkIndex++\n\t\t) {\n\t\t\tconst chunk = await SnapshotV1.loadChunk(\n\t\t\t\tservices,\n\t\t\t\theaderMetadata.orderedChunkMetadata[chunkIndex].id,\n\t\t\t\tthis.logger,\n\t\t\t\tthis.mergeTree.options,\n\t\t\t\tthis.serializer,\n\t\t\t);\n\t\t\tlengthSofar += chunk.length;\n\t\t\t// Deserialize each chunk segment and append it to the end of the MergeTree.\n\t\t\tconst newSegs = chunk.segments.map(this.specToSegment);\n\t\t\tthis.extractAttribution(newSegs, chunk);\n\t\t\tchunksWithAttribution += chunk.attribution !== undefined ? 1 : 0;\n\t\t\tsegs.push(...newSegs);\n\t\t}\n\n\t\tassert(\n\t\t\tchunksWithAttribution === 0 ||\n\t\t\t\tchunksWithAttribution === headerMetadata.orderedChunkMetadata.length,\n\t\t\t0x4c0 /* all or no chunks should have attribution information */,\n\t\t);\n\n\t\tassert(lengthSofar === headerMetadata.totalLength, 0x063 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount + segs.length === headerMetadata.totalSegmentCount,\n\t\t\t0x064 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\t// Helper to insert segments at the end of the MergeTree.\n\t\tconst mergeTree = this.mergeTree;\n\t\tconst append = (segments: ISegment[], cli: number, seq: number) => {\n\t\t\tmergeTree.insertSegments(\n\t\t\t\tmergeTree.root.cachedLength ?? 0,\n\t\t\t\tsegments,\n\t\t\t\t/* refSeq: */ UniversalSequenceNumber,\n\t\t\t\tcli,\n\t\t\t\tseq,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t};\n\n\t\t// Helpers to batch-insert segments that are below the min seq\n\t\tconst batch: ISegment[] = [];\n\t\tconst flushBatch = () => {\n\t\t\tif (batch.length > 0) {\n\t\t\t\tappend(batch, NonCollabClient, UniversalSequenceNumber);\n\t\t\t}\n\t\t};\n\n\t\tfor (const seg of segs) {\n\t\t\tconst cli = seg.clientId;\n\t\t\tconst seq = seg.seq;\n\n\t\t\t// If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n\t\t\t// any batched segments and then insert the current segment individually.\n\t\t\tif (cli === NonCollabClient && seq === UniversalSequenceNumber) {\n\t\t\t\tbatch.push(seg);\n\t\t\t} else {\n\t\t\t\tflushBatch();\n\t\t\t\tappend([seg], cli, seq!);\n\t\t\t}\n\t\t}\n\n\t\tflushBatch();\n\t}\n\n\tprivate extractAttribution(segments: ISegment[], chunk: MergeTreeChunkV1): void {\n\t\tthis.mergeTree.options ??= {};\n\t\tthis.mergeTree.options.attribution ??= {};\n\t\tif (chunk.attribution) {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"Attribution policy must be provided when loading a document with attribution information.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { isAttached, attach, serializer } = attributionPolicy;\n\t\t\tif (!isAttached) {\n\t\t\t\tattach(this.client);\n\t\t\t}\n\t\t\tserializer.populateAttributionCollections(segments, chunk.attribution);\n\t\t} else {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy?.isAttached) {\n\t\t\t\tattributionPolicy?.detach();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If loading from a snapshot, get the catchup messages.\n\t * @param rawMessages - The messages in original encoding\n\t * @returns The decoded messages with parsed+hydrated handles. Matches the format that will be passed in\n\t * SharedObject.processCore.\n\t */\n\tprivate async loadCatchupOps(\n\t\trawMessages: Promise<ArrayBufferLike>,\n\t\tserializer: IFluidSerializer,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\treturn serializer.parse(\n\t\t\tbufferToString(await rawMessages, \"utf8\"),\n\t\t) as ISequencedDocumentMessage[];\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.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\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport {\n\tcreateChildLogger,\n\tITelemetryLoggerExt,\n\tUsageError,\n} from \"@fluidframework/telemetry-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\n// eslint-disable-next-line import/no-deprecated\nimport { Client } from \"./client.js\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants.js\";\nimport { ISegment } from \"./mergeTreeNodes.js\";\nimport { IJSONSegment } from \"./ops.js\";\nimport { IJSONSegmentWithMergeInfo, hasMergeInfo, MergeTreeChunkV1 } from \"./snapshotChunks.js\";\nimport { SnapshotV1 } from \"./snapshotV1.js\";\nimport { SnapshotLegacy } from \"./snapshotlegacy.js\";\nimport { MergeTree } from \"./mergeTree.js\";\n\nexport class SnapshotLoader {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\t// eslint-disable-next-line import/no-deprecated\n\t\tprivate readonly client: Client,\n\t\tprivate readonly mergeTree: MergeTree,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly serializer: IFluidSerializer,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"SnapshotLoader\" });\n\t}\n\n\tpublic async initialize(\n\t\tservices: IChannelStorageService,\n\t): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n\t\tconst headerLoadedP = services.readBlob(SnapshotLegacy.header).then((header) => {\n\t\t\tassert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n\t\t\treturn this.loadHeader(bufferToString(header, \"utf8\"));\n\t\t});\n\n\t\tconst catchupOpsP = this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n\t\tcatchupOpsP.catch((err) =>\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" }, err),\n\t\t);\n\n\t\tawait headerLoadedP;\n\n\t\treturn { catchupOpsP };\n\t}\n\n\tprivate async loadBodyAndCatchupOps(\n\t\theaderChunkP: Promise<MergeTreeChunkV1>,\n\t\tservices: IChannelStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst blobsP = services.list(\"\");\n\t\tconst headerChunk = await headerChunkP;\n\n\t\t// TODO we shouldn't need to wait on the body being complete to finish initialization.\n\t\t// To fully support this we need to be able to process inbound ops for pending segments.\n\t\tawait this.loadBody(headerChunk, services);\n\n\t\tconst blobs = await blobsP;\n\t\tif (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n\t\t\theaderChunk.headerMetadata!.orderedChunkMetadata.forEach((md) =>\n\t\t\t\tblobs.splice(blobs.indexOf(md.id), 1),\n\t\t\t);\n\t\t\tassert(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);\n\n\t\t\t// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\n\t\t\treturn this.loadCatchupOps(services.readBlob(blobs[0]));\n\t\t} else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n\t\t\tthrow new Error(\"Unexpected blobs in snapshot\");\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate readonly specToSegment = (spec: IJSONSegment | IJSONSegmentWithMergeInfo) => {\n\t\tlet seg: ISegment;\n\n\t\tif (hasMergeInfo(spec)) {\n\t\t\tseg = this.client.specToSegment(spec.json);\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. Overwrite this with\n\t\t\t// the `spec` client (if specified). Otherwise overwrite with `NonCollabClient`.\n\t\t\tseg.clientId =\n\t\t\t\tspec.client !== undefined\n\t\t\t\t\t? this.client.getOrAddShortClientId(spec.client)\n\t\t\t\t\t: NonCollabClient;\n\n\t\t\tseg.seq = spec.seq ?? UniversalSequenceNumber;\n\n\t\t\tif (spec.removedSeq !== undefined) {\n\t\t\t\tseg.removedSeq = spec.removedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeq !== undefined) {\n\t\t\t\tseg.movedSeq = spec.movedSeq;\n\t\t\t}\n\t\t\tif (spec.movedSeqs !== undefined) {\n\t\t\t\tseg.movedSeqs = spec.movedSeqs;\n\t\t\t}\n\t\t\t// this format had a bug where it didn't store all the overlap clients\n\t\t\t// this is for back compat, so we change the singular id to an array\n\t\t\t// this will only cause problems if there is an overlapping delete\n\t\t\t// spanning the snapshot, which should be rare\n\t\t\tconst specAsBuggyFormat: IJSONSegmentWithMergeInfo & { removedClient?: string } = spec;\n\t\t\tif (specAsBuggyFormat.removedClient !== undefined) {\n\t\t\t\tseg.removedClientIds = [\n\t\t\t\t\tthis.client.getOrAddShortClientId(specAsBuggyFormat.removedClient),\n\t\t\t\t];\n\t\t\t}\n\t\t\tif (spec.removedClientIds !== undefined) {\n\t\t\t\tseg.removedClientIds = spec.removedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (spec.movedClientIds !== undefined) {\n\t\t\t\tseg.movedClientIds = spec.movedClientIds?.map((sid) =>\n\t\t\t\t\tthis.client.getOrAddShortClientId(sid),\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tseg = this.client.specToSegment(spec);\n\t\t\tseg.seq = UniversalSequenceNumber;\n\n\t\t\t// `specToSegment()` initializes `seg` with the LocalClientId. We must overwrite this with\n\t\t\t// `NonCollabClient`.\n\t\t\tseg.clientId = NonCollabClient;\n\t\t}\n\n\t\treturn seg;\n\t};\n\n\tprivate loadHeader(header: string): MergeTreeChunkV1 {\n\t\tconst chunk = SnapshotV1.processChunk(\n\t\t\tSnapshotLegacy.header,\n\t\t\theader,\n\t\t\tthis.logger,\n\t\t\tthis.mergeTree.options,\n\t\t\tthis.serializer,\n\t\t);\n\t\tconst segs = chunk.segments.map(this.specToSegment);\n\t\tthis.extractAttribution(segs, chunk);\n\n\t\tthis.mergeTree.reloadFromSegments(segs);\n\n\t\tif (chunk.headerMetadata === undefined) {\n\t\t\tthrow new Error(\"header metadata not available\");\n\t\t}\n\t\t// If we load a detached container from snapshot, then we don't supply a default clientId\n\t\t// because we don't want to start collaboration.\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t// specify a default client id, \"snapshot\" here as we\n\t\t\t// should enter collaboration/op sending mode if we load\n\t\t\t// a snapshot in any case (summary or attach message)\n\t\t\t// once we get a client id this will be called with that\n\t\t\t// clientId in the connected event\n\t\t\tthis.client.startOrUpdateCollaboration(\n\t\t\t\tthis.runtime.clientId ?? \"snapshot\",\n\n\t\t\t\t// TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n\t\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\t\t\t\t/* minSeq: */ chunk.headerMetadata.minSequenceNumber ??\n\t\t\t\t\tchunk.headerMetadata.sequenceNumber,\n\t\t\t\t/* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\treturn chunk;\n\t}\n\n\tprivate async loadBody(\n\t\tchunk1: MergeTreeChunkV1,\n\t\tservices: IChannelStorageService,\n\t): Promise<void> {\n\t\tconst headerMetadata = chunk1.headerMetadata!;\n\t\tassert(chunk1.length <= headerMetadata.totalLength, 0x061 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount <= headerMetadata.totalSegmentCount,\n\t\t\t0x062 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\tif (chunk1.segmentCount === headerMetadata.totalSegmentCount) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet chunksWithAttribution = chunk1.attribution !== undefined ? 1 : 0;\n\t\tconst segs: ISegment[] = [];\n\t\tlet lengthSofar = chunk1.length;\n\t\tfor (\n\t\t\tlet chunkIndex = 1;\n\t\t\tchunkIndex < headerMetadata.orderedChunkMetadata.length;\n\t\t\tchunkIndex++\n\t\t) {\n\t\t\tconst chunk = await SnapshotV1.loadChunk(\n\t\t\t\tservices,\n\t\t\t\theaderMetadata.orderedChunkMetadata[chunkIndex].id,\n\t\t\t\tthis.logger,\n\t\t\t\tthis.mergeTree.options,\n\t\t\t\tthis.serializer,\n\t\t\t);\n\t\t\tlengthSofar += chunk.length;\n\t\t\t// Deserialize each chunk segment and append it to the end of the MergeTree.\n\t\t\tconst newSegs = chunk.segments.map(this.specToSegment);\n\t\t\tthis.extractAttribution(newSegs, chunk);\n\t\t\tchunksWithAttribution += chunk.attribution !== undefined ? 1 : 0;\n\t\t\tsegs.push(...newSegs);\n\t\t}\n\n\t\tassert(\n\t\t\tchunksWithAttribution === 0 ||\n\t\t\t\tchunksWithAttribution === headerMetadata.orderedChunkMetadata.length,\n\t\t\t0x4c0 /* all or no chunks should have attribution information */,\n\t\t);\n\n\t\tassert(lengthSofar === headerMetadata.totalLength, 0x063 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount + segs.length === headerMetadata.totalSegmentCount,\n\t\t\t0x064 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\t// Helper to insert segments at the end of the MergeTree.\n\t\tconst mergeTree = this.mergeTree;\n\t\tconst append = (segments: ISegment[], cli: number, seq: number) => {\n\t\t\tmergeTree.insertSegments(\n\t\t\t\tmergeTree.root.cachedLength ?? 0,\n\t\t\t\tsegments,\n\t\t\t\t/* refSeq: */ UniversalSequenceNumber,\n\t\t\t\tcli,\n\t\t\t\tseq,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t};\n\n\t\t// Helpers to batch-insert segments that are below the min seq\n\t\tconst batch: ISegment[] = [];\n\t\tconst flushBatch = () => {\n\t\t\tif (batch.length > 0) {\n\t\t\t\tappend(batch, NonCollabClient, UniversalSequenceNumber);\n\t\t\t}\n\t\t};\n\n\t\tfor (const seg of segs) {\n\t\t\tconst cli = seg.clientId;\n\t\t\tconst seq = seg.seq;\n\n\t\t\t// If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n\t\t\t// any batched segments and then insert the current segment individually.\n\t\t\tif (cli === NonCollabClient && seq === UniversalSequenceNumber) {\n\t\t\t\tbatch.push(seg);\n\t\t\t} else {\n\t\t\t\tflushBatch();\n\t\t\t\tappend([seg], cli, seq!);\n\t\t\t}\n\t\t}\n\n\t\tflushBatch();\n\t}\n\n\tprivate extractAttribution(segments: ISegment[], chunk: MergeTreeChunkV1): void {\n\t\tthis.mergeTree.options ??= {};\n\t\tthis.mergeTree.options.attribution ??= {};\n\t\tif (chunk.attribution) {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"Attribution policy must be provided when loading a document with attribution information.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { isAttached, attach, serializer } = attributionPolicy;\n\t\t\tif (!isAttached) {\n\t\t\t\tattach(this.client);\n\t\t\t}\n\t\t\tserializer.populateAttributionCollections(segments, chunk.attribution);\n\t\t} else {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy?.isAttached) {\n\t\t\t\tattributionPolicy?.detach();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If loading from a snapshot, get the catchup messages.\n\t * @param rawMessages - The messages in original encoding\n\t * @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in\n\t * SharedObject.processCore.\n\t */\n\tprivate async loadCatchupOps(\n\t\trawMessages: Promise<ArrayBufferLike>,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\treturn JSON.parse(bufferToString(await rawMessages, \"utf8\")) as ISequencedDocumentMessage[];\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/merge-tree",
|
|
3
|
-
"version": "2.0.0-rc.2.0.
|
|
3
|
+
"version": "2.0.0-rc.2.0.8",
|
|
4
4
|
"description": "Merge tree",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -89,29 +89,29 @@
|
|
|
89
89
|
"temp-directory": "nyc/.nyc_output"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@fluid-internal/client-utils": ">=2.0.0-rc.2.0.
|
|
93
|
-
"@fluidframework/container-definitions": ">=2.0.0-rc.2.0.
|
|
94
|
-
"@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.
|
|
95
|
-
"@fluidframework/core-utils": ">=2.0.0-rc.2.0.
|
|
96
|
-
"@fluidframework/datastore-definitions": ">=2.0.0-rc.2.0.
|
|
92
|
+
"@fluid-internal/client-utils": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
93
|
+
"@fluidframework/container-definitions": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
94
|
+
"@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
95
|
+
"@fluidframework/core-utils": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
96
|
+
"@fluidframework/datastore-definitions": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
97
97
|
"@fluidframework/protocol-definitions": "^3.2.0",
|
|
98
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-rc.2.0.
|
|
99
|
-
"@fluidframework/runtime-utils": ">=2.0.0-rc.2.0.
|
|
100
|
-
"@fluidframework/shared-object-base": ">=2.0.0-rc.2.0.
|
|
101
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.
|
|
98
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
99
|
+
"@fluidframework/runtime-utils": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
100
|
+
"@fluidframework/shared-object-base": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
101
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0"
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
104
|
"@arethetypeswrong/cli": "^0.13.3",
|
|
105
|
-
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.
|
|
106
|
-
"@fluid-private/stochastic-test-utils": ">=2.0.0-rc.2.0.
|
|
107
|
-
"@fluid-private/test-pairwise-generator": ">=2.0.0-rc.2.0.
|
|
105
|
+
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
106
|
+
"@fluid-private/stochastic-test-utils": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
107
|
+
"@fluid-private/test-pairwise-generator": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
108
108
|
"@fluid-tools/benchmark": "^0.48.0",
|
|
109
109
|
"@fluid-tools/build-cli": "^0.34.0",
|
|
110
110
|
"@fluidframework/build-common": "^2.0.3",
|
|
111
111
|
"@fluidframework/build-tools": "^0.34.0",
|
|
112
112
|
"@fluidframework/eslint-config-fluid": "^4.0.0",
|
|
113
113
|
"@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.0.0-internal.8.0.0",
|
|
114
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.2.0.
|
|
114
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.2.0.8 <2.0.0-rc.2.1.0",
|
|
115
115
|
"@microsoft/api-extractor": "^7.42.3",
|
|
116
116
|
"@types/diff": "^3.5.1",
|
|
117
117
|
"@types/mocha": "^9.1.1",
|
package/src/snapshotLoader.ts
CHANGED
|
@@ -83,7 +83,7 @@ export class SnapshotLoader {
|
|
|
83
83
|
// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.
|
|
84
84
|
// (See https://github.com/microsoft/FluidFramework/issues/84)
|
|
85
85
|
|
|
86
|
-
return this.loadCatchupOps(services.readBlob(blobs[0])
|
|
86
|
+
return this.loadCatchupOps(services.readBlob(blobs[0]));
|
|
87
87
|
} else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {
|
|
88
88
|
throw new Error("Unexpected blobs in snapshot");
|
|
89
89
|
}
|
|
@@ -301,15 +301,12 @@ export class SnapshotLoader {
|
|
|
301
301
|
/**
|
|
302
302
|
* If loading from a snapshot, get the catchup messages.
|
|
303
303
|
* @param rawMessages - The messages in original encoding
|
|
304
|
-
* @returns The decoded messages
|
|
304
|
+
* @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in
|
|
305
305
|
* SharedObject.processCore.
|
|
306
306
|
*/
|
|
307
307
|
private async loadCatchupOps(
|
|
308
308
|
rawMessages: Promise<ArrayBufferLike>,
|
|
309
|
-
serializer: IFluidSerializer,
|
|
310
309
|
): Promise<ISequencedDocumentMessage[]> {
|
|
311
|
-
return
|
|
312
|
-
bufferToString(await rawMessages, "utf8"),
|
|
313
|
-
) as ISequencedDocumentMessage[];
|
|
310
|
+
return JSON.parse(bufferToString(await rawMessages, "utf8")) as ISequencedDocumentMessage[];
|
|
314
311
|
}
|
|
315
312
|
}
|