diff --git a/packages/dds/tree/src/codec/codec.ts b/packages/dds/tree/src/codec/codec.ts index 4b09a8ff54cc..0290645643cc 100644 --- a/packages/dds/tree/src/codec/codec.ts +++ b/packages/dds/tree/src/codec/codec.ts @@ -465,8 +465,14 @@ export function withSchemaValidation< * If the need arises, they might be added in the future. * * @privateRemarks - * Entries in these enums should document the user facing impact of opting into a particular version. - * For example, document if there is an encoding efficiency improvement of oping into that version or newer. + * The entries in these enums should document the following: + * - The user facing impact of opting into a particular version. This will help customers decide if they want to opt into + * a new version. For example, document if there is an encoding efficiency improvement of oping into that version or newer. + * - Any new data formats that are introduced in that version. This will help developers tell which data formats a given + * version will write. For example, document if a new summary or encoding format is added in a version. + * - Whether the above features or data formats introduced in a version are enabled by default or require the + * {@link minVersionForCollab} option to be set to that particular version. + * * Versions with no notable impact can be omitted. * * This scheme assumes a single version will always be enough to communicate compatibility. @@ -505,10 +511,10 @@ export const FluidClientVersion = { * Fluid Framework Client 2.43 and newer. * @remarks * New formats introduced in 2.43: - * - SchemaFormatVersion.v2 - * - MessageFormatVersion.v4 - * - EditManagerFormatVersion.v4 - * - Sequence format version 3 + * - SchemaFormatVersion.v2 - written when minVersionForCollab \>= 2.43 + * - MessageFormatVersion.v4 - written when minVersionForCollab \>= 2.43 + * - EditManagerFormatVersion.v4 - written when minVersionForCollab \>= 2.43 + * - sequence-field/formatV3 - written when minVersionForCollab \>= 2.43 */ v2_43: "2.43.0", @@ -516,7 +522,7 @@ export const FluidClientVersion = { * Fluid Framework Client 2.52 and newer. * @remarks * New formats introduced in 2.52: - * - DetachedFieldIndexFormatVersion.v2 + * - DetachedFieldIndexFormatVersion.v2 - written when minVersionForCollab \>= 2.52 */ v2_52: "2.52.0", @@ -524,7 +530,7 @@ export const FluidClientVersion = { * Fluid Framework Client 2.73 and newer. * @remarks * New formats introduced in 2.73: - * - FieldBatchFormatVersion v2 + * - FieldBatchFormatVersion.v2 - written when minVersionForCollab \>= 2.73 */ v2_73: "2.73.0", @@ -532,11 +538,13 @@ export const FluidClientVersion = { * Fluid Framework Client 2.74 and newer. * @remarks * New formats introduced in 2.74: - * - SharedTreeSummaryFormatVersion v2 - * - DetachedFieldIndexSummaryFormatVersion v2 - * - SchemaSummaryFormatVersion v2 - * - EditManagerSummaryFormatVersion v2 - * - ForestSummaryFormatVersion v2 + * - SharedTreeSummaryFormatVersion.v2 - written by default + * - DetachedFieldIndexSummaryFormatVersion.v2 - written by default + * - SchemaSummaryFormatVersion.v2 - written by default + * - EditManagerSummaryFormatVersion.v2 - written by default + * - ForestSummaryFormatVersion.v2 - written by default + * - ForestFormatVersion.v2 - written when minVersionForCollab \>= 2.74 + * - ForestSummaryFormatVersion.v3 - written when minVersionForCollab \>= 2.74 */ v2_74: "2.74.0", } as const satisfies Record; diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/codec.ts b/packages/dds/tree/src/feature-libraries/forest-summary/codec.ts index 4558906942b9..dcb13faac9d7 100644 --- a/packages/dds/tree/src/feature-libraries/forest-summary/codec.ts +++ b/packages/dds/tree/src/feature-libraries/forest-summary/codec.ts @@ -5,35 +5,49 @@ import { assert, oob } from "@fluidframework/core-utils/internal"; import type { MinimumVersionForCollab } from "@fluidframework/runtime-definitions/internal"; +import { + getConfigForMinVersionForCollab, + lowestMinVersionForCollab, +} from "@fluidframework/runtime-utils/internal"; import { type CodecTree, type CodecWriteOptions, + FluidClientVersion, type IJsonCodec, makeVersionedValidatedCodec, } from "../../codec/index.js"; import type { FieldKey, ITreeCursorSynchronous } from "../../core/index.js"; import type { FieldBatchCodec, FieldBatchEncodingContext } from "../chunked-forest/index.js"; -import { FormatV1, ForestFormatVersion } from "./format.js"; +import { + ForestFormatVersion, + validVersions, + type Format, + FormatCommon, +} from "./formatCommon.js"; import { brand } from "../../util/index.js"; /** * Uses field cursors */ export type FieldSet = ReadonlyMap; -export type ForestCodec = IJsonCodec; +export type ForestCodec = IJsonCodec; /** * Convert a MinimumVersionForCollab to a ForestFormatVersion. * @param clientVersion - The MinimumVersionForCollab to convert. * @returns The ForestFormatVersion that corresponds to the provided MinimumVersionForCollab. */ -function clientVersionToForestSummaryFormatVersion( +export function clientVersionToForestFormatVersion( clientVersion: MinimumVersionForCollab, ): ForestFormatVersion { - // Currently, forest summary codec only writes in version 1. - return brand(ForestFormatVersion.v1); + return brand( + getConfigForMinVersionForCollab(clientVersion, { + [lowestMinVersionForCollab]: ForestFormatVersion.v1, + [FluidClientVersion.v2_74]: ForestFormatVersion.v2, + }), + ); } export function makeForestSummarizerCodec( @@ -41,12 +55,10 @@ export function makeForestSummarizerCodec( fieldBatchCodec: FieldBatchCodec, ): ForestCodec { const inner = fieldBatchCodec; - // TODO: AB#41865 - // This needs to be updated to support multiple versions. - // The second version will be used to enable incremental summarization. - const writeVersion = clientVersionToForestSummaryFormatVersion(options.minVersionForCollab); - return makeVersionedValidatedCodec(options, new Set([ForestFormatVersion.v1]), FormatV1, { - encode: (data: FieldSet, context: FieldBatchEncodingContext): FormatV1 => { + const writeVersion = clientVersionToForestFormatVersion(options.minVersionForCollab); + const formatSchema = FormatCommon(writeVersion); + return makeVersionedValidatedCodec(options, validVersions, formatSchema, { + encode: (data: FieldSet, context: FieldBatchEncodingContext): Format => { const keys: FieldKey[] = []; const fields: ITreeCursorSynchronous[] = []; for (const [key, value] of data) { @@ -55,7 +67,7 @@ export function makeForestSummarizerCodec( } return { keys, fields: inner.encode(fields, context), version: writeVersion }; }, - decode: (data: FormatV1, context: FieldBatchEncodingContext): FieldSet => { + decode: (data: Format, context: FieldBatchEncodingContext): FieldSet => { const out: Map = new Map(); const fields = inner.decode(data.fields, context); assert(data.keys.length === fields.length, 0x891 /* mismatched lengths */); @@ -70,5 +82,5 @@ export function makeForestSummarizerCodec( export function getCodecTreeForForestFormat( clientVersion: MinimumVersionForCollab, ): CodecTree { - return { name: "Forest", version: clientVersionToForestSummaryFormatVersion(clientVersion) }; + return { name: "Forest", version: clientVersionToForestFormatVersion(clientVersion) }; } diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/forestSummarizer.ts b/packages/dds/tree/src/feature-libraries/forest-summary/forestSummarizer.ts index adf53f75cf48..d3ac849b8383 100644 --- a/packages/dds/tree/src/feature-libraries/forest-summary/forestSummarizer.ts +++ b/packages/dds/tree/src/feature-libraries/forest-summary/forestSummarizer.ts @@ -42,19 +42,26 @@ import { type IncrementalEncodingPolicy, } from "../chunked-forest/index.js"; -import { type ForestCodec, makeForestSummarizerCodec } from "./codec.js"; +import { + clientVersionToForestFormatVersion, + type ForestCodec, + makeForestSummarizerCodec, +} from "./codec.js"; import { ForestIncrementalSummaryBehavior, ForestIncrementalSummaryBuilder, } from "./incrementalSummaryBuilder.js"; import { - forestSummaryContentKey, - forestSummaryKey, minVersionToForestSummaryFormatVersion, - supportedForestSummaryFormatVersions, - type ForestSummaryFormatVersion, + getForestRootSummaryContentKey, } from "./summaryTypes.js"; import { TreeCompressionStrategy } from "../treeCompressionUtils.js"; +import { ForestFormatVersion } from "./formatCommon.js"; +import { + ForestSummaryFormatVersion, + forestSummaryKey, + supportedForestSummaryFormatVersions, +} from "./summaryFormatCommon.js"; /** * Provides methods for summarizing and loading a forest. @@ -66,6 +73,7 @@ export class ForestSummarizer private readonly codec: ForestCodec; private readonly incrementalSummaryBuilder: ForestIncrementalSummaryBuilder; + private readonly forestRootSummaryContentKey: string; /** * @param encoderContext - The schema if provided here must be mutated by the caller to keep it up to date. @@ -87,11 +95,25 @@ export class ForestSummarizer true /* supportPreVersioningFormat */, ); - // TODO: this should take in CodecWriteOptions, and use it to pick the write version. this.codec = makeForestSummarizerCodec(options, fieldBatchCodec); + + const forestFormatWriteVersion = clientVersionToForestFormatVersion( + options.minVersionForCollab, + ); + const summaryFormatWriteVersion = minVersionToForestSummaryFormatVersion( + options.minVersionForCollab, + ); + this.forestRootSummaryContentKey = getForestRootSummaryContentKey( + summaryFormatWriteVersion, + ); + + // Incremental summary is supported from ForestFormatVersion.v2 and ForestSummaryFormatVersion.v3 onwards. + const enableIncrementalSummary = + forestFormatWriteVersion >= ForestFormatVersion.v2 && + summaryFormatWriteVersion >= ForestSummaryFormatVersion.v3 && + encoderContext.encodeType === TreeCompressionStrategy.CompressedIncremental; this.incrementalSummaryBuilder = new ForestIncrementalSummaryBuilder( - encoderContext.encodeType === - TreeCompressionStrategy.CompressedIncremental /* enableIncrementalSummary */, + enableIncrementalSummary, (cursor: ITreeCursorSynchronous) => this.forest.chunkField(cursor), shouldEncodeIncrementally, initialSequenceNumber, @@ -153,7 +175,8 @@ export class ForestSummarizer this.incrementalSummaryBuilder.completeSummary({ incrementalSummaryContext, - forestSummaryContent: stringify(encoded), + forestSummaryRootContent: stringify(encoded), + forestSummaryRootContentKey: this.forestRootSummaryContentKey, builder, }); } @@ -161,15 +184,17 @@ export class ForestSummarizer protected async loadInternal( services: IChannelStorageService, parse: SummaryElementParser, + version: ForestSummaryFormatVersion | undefined, ): Promise { - // The contents of the top-level forest must be present under a summary blob named `forestSummaryContentKey`. + // Get the key of the summary blob where the top-level forest content is stored based on the summary format version. // If the summary was generated as `ForestIncrementalSummaryBehavior.SingleBlob`, this blob will contain all // of forest's contents. // If the summary was generated as `ForestIncrementalSummaryBehavior.Incremental`, this blob will contain only // the top-level forest node's contents. // The contents of the incremental chunks will be in separate tree nodes and will be read later during decoding. + const forestSummaryRootContentKey = getForestRootSummaryContentKey(version); assert( - await services.contains(forestSummaryContentKey), + await services.contains(forestSummaryRootContentKey), 0xc21 /* Forest summary content missing in snapshot */, ); @@ -184,7 +209,7 @@ export class ForestSummarizer // TODO: this code is parsing data without an optional validator, this should be defined in a typebox schema as part of the // forest summary format. const fields = this.codec.decode( - await readAndParseSnapshotBlob(forestSummaryContentKey, services, parse), + await readAndParseSnapshotBlob(forestSummaryRootContentKey, services, parse), { ...this.encoderContext, incrementalEncoderDecoder: this.incrementalSummaryBuilder, diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/format.ts b/packages/dds/tree/src/feature-libraries/forest-summary/formatCommon.ts similarity index 75% rename from packages/dds/tree/src/feature-libraries/forest-summary/format.ts rename to packages/dds/tree/src/feature-libraries/forest-summary/formatCommon.ts index 6c33d7b31e39..084e08b51890 100644 --- a/packages/dds/tree/src/feature-libraries/forest-summary/format.ts +++ b/packages/dds/tree/src/feature-libraries/forest-summary/formatCommon.ts @@ -6,7 +6,7 @@ import { type Static, Type } from "@sinclair/typebox"; import { schemaFormatV1 } from "../../core/index.js"; -import { brand, type Brand } from "../../util/index.js"; +import type { Brand } from "../../util/index.js"; import { EncodedFieldBatch } from "../chunked-forest/index.js"; /** @@ -14,13 +14,17 @@ import { EncodedFieldBatch } from "../chunked-forest/index.js"; */ export const ForestFormatVersion = { v1: 1, + /** This format supports incremental encoding */ + v2: 2, } as const; export type ForestFormatVersion = Brand< (typeof ForestFormatVersion)[keyof typeof ForestFormatVersion], "ForestFormatVersion" >; -const FormatGeneric = ( +export const validVersions = new Set([...Object.values(ForestFormatVersion)]); + +export const FormatCommon = ( version: ForestFormatVersion, // Return type is intentionally derived. // eslint-disable-next-line @typescript-eslint/explicit-function-return-type @@ -33,6 +37,4 @@ const FormatGeneric = ( }, { additionalProperties: false }, ); - -export const FormatV1 = FormatGeneric(brand(ForestFormatVersion.v1)); -export type FormatV1 = Static; +export type Format = Static>; diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/formatV1.ts b/packages/dds/tree/src/feature-libraries/forest-summary/formatV1.ts new file mode 100644 index 000000000000..4023e992dcd0 --- /dev/null +++ b/packages/dds/tree/src/feature-libraries/forest-summary/formatV1.ts @@ -0,0 +1,12 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import type { Static } from "@sinclair/typebox"; + +import { brand } from "../../util/index.js"; +import { FormatCommon, ForestFormatVersion } from "./formatCommon.js"; + +export const FormatV1 = FormatCommon(brand(ForestFormatVersion.v1)); +export type FormatV1 = Static; diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/formatV2.ts b/packages/dds/tree/src/feature-libraries/forest-summary/formatV2.ts new file mode 100644 index 000000000000..1793444ec77d --- /dev/null +++ b/packages/dds/tree/src/feature-libraries/forest-summary/formatV2.ts @@ -0,0 +1,12 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import type { Static } from "@sinclair/typebox"; + +import { brand } from "../../util/index.js"; +import { FormatCommon, ForestFormatVersion } from "./formatCommon.js"; + +export const FormatV2 = FormatCommon(brand(ForestFormatVersion.v2)); +export type FormatV2 = Static; diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts b/packages/dds/tree/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts index a73dfc060e81..7859b1a40ac3 100644 --- a/packages/dds/tree/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +++ b/packages/dds/tree/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts @@ -27,7 +27,7 @@ import type { ISnapshotTree } from "@fluidframework/driver-definitions/internal" import { LoggingError } from "@fluidframework/telemetry-utils/internal"; import type { IFluidHandle } from "@fluidframework/core-interfaces"; import type { SummaryElementStringifier } from "../../shared-tree-core/index.js"; -import { chunkContentsBlobKey, forestSummaryContentKey } from "./summaryTypes.js"; +import { summaryContentBlobKey } from "./summaryFormatV3.js"; /** * State that tells whether a summary is currently being tracked. @@ -189,7 +189,7 @@ function validateReadyToTrackSummary( * * An example summary tree with incremental summary: * Forest - * ├── ForestTree + * ├── contents * ├── 0 * | ├── contents * | ├── 1 @@ -202,7 +202,7 @@ function validateReadyToTrackSummary( * | ├── ... * ├── 5 - "/.../Forest/ForestTree/5" * - Forest is a summary tree node added by the shared tree and contains the following: - * - The inline portion of the top-level forest content is stored in a summary blob called "ForestTree". + * - The inline portion of the top-level forest content is stored in a summary blob called "contents". * It also contains the {@link ChunkReferenceId}s of the incremental chunks under it. * - The summary for each incremental chunk under it is stored against its {@link ChunkReferenceId}. * - For each chunk, the structure of the summary tree is the same as the Forest. It contains the following: @@ -210,16 +210,6 @@ function validateReadyToTrackSummary( * It also contains the {@link ChunkReferenceId}s of the incremental chunks under it. * - The summary for each incremental chunk under it is stored against its {@link ChunkReferenceId}. * - Chunks that do not change between summaries are summarized as handles in the summary tree. - * @remarks - * It may seem inconsistent that although the structure for the top-level forest tree is similar to that of - * an incremental chunk, its content is stored in a summary blob called "ForestTree" while the content for - * the incremental chunks are stored in a summary blob called "contents". - * This is to keep this summary backwards compatible with old format (before incremental summaries were added) - * where the entire forest content was in a summary blob called "ForestTree". So, if incremental summaries were - * disabled, the forest content will be fully backwards compatible. - * Note that this limits reusing the root node in a location other than root and a non-root node in the root. - * We could phase this out by switching to write the top-level contents under "contents" if we want to support - * the above. However, there is no plan to do that for now. * * TODO: AB#46752 * Add strong types for the summary structure to document it better. It will help make it super clear what the actual @@ -305,7 +295,7 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode // and the value is the snapshot tree for the chunk. for (const [chunkReferenceId, chunkSnapshotTree] of Object.entries(snapshotTree.trees)) { const chunkSubTreePath = `${parentTreeKey}${chunkReferenceId}`; - const chunkContentsPath = `${chunkSubTreePath}/${chunkContentsBlobKey}`; + const chunkContentsPath = `${chunkSubTreePath}/${summaryContentBlobKey}`; if (!(await args.services.contains(chunkContentsPath))) { throw new LoggingError( `SharedTree: Cannot find contents for incremental chunk ${chunkContentsPath}`, @@ -422,7 +412,7 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode const chunkSummaryBuilder = new SummaryTreeBuilder(); this.trackedSummaryProperties.parentSummaryBuilder = chunkSummaryBuilder; chunkSummaryBuilder.addBlob( - chunkContentsBlobKey, + summaryContentBlobKey, this.trackedSummaryProperties.stringify(chunkEncoder(chunk)), ); @@ -454,26 +444,33 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode * It clears any tracking state and deletes the tracking properties for summaries that are older than the * latest successful summary. * @param incrementalSummaryContext - The context for the incremental summary that contains the sequence numbers. - * If this is undefined, the summary tree will only contain a summary blob for `forestSummaryContent`. - * @param forestSummaryContent - The stringified ForestCodec output of top-level Forest content. + * If this is undefined, the summary tree will only contain a summary blob for `forestSummaryRootContent`. + * @param forestSummaryRootContent - The stringified ForestCodec output of top-level Forest content. + * @param forestSummaryRootContentKey - The key to use for the blob containing `forestSummaryRootContent`. * @param builder - The summary tree builder to use to add the forest's contents. Note that if tracking an incremental * summary, this builder will be the same as the one tracked in `trackedSummaryProperties`. * @returns the Forest's summary tree. */ public completeSummary(args: { incrementalSummaryContext: IExperimentalIncrementalSummaryContext | undefined; - forestSummaryContent: string; + forestSummaryRootContent: string; + forestSummaryRootContentKey: string; builder: SummaryTreeBuilder; }): void { - const { incrementalSummaryContext, forestSummaryContent, builder } = args; + const { + incrementalSummaryContext, + forestSummaryRootContent, + forestSummaryRootContentKey, + builder, + } = args; if (!this.enableIncrementalSummary || incrementalSummaryContext === undefined) { - builder.addBlob(forestSummaryContentKey, forestSummaryContent); + builder.addBlob(forestSummaryRootContentKey, forestSummaryRootContent); return; } validateTrackingSummary(this.forestSummaryState, this.trackedSummaryProperties); - builder.addBlob(forestSummaryContentKey, forestSummaryContent); + builder.addBlob(forestSummaryRootContentKey, forestSummaryRootContent); // Copy over the entries from the latest summary to the current summary. // In the current summary, there can be fields that haven't changed since the latest summary and the chunks diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/index.ts b/packages/dds/tree/src/feature-libraries/forest-summary/index.ts index 5410c3a185e1..48a07ddcf8b5 100644 --- a/packages/dds/tree/src/feature-libraries/forest-summary/index.ts +++ b/packages/dds/tree/src/feature-libraries/forest-summary/index.ts @@ -5,5 +5,4 @@ export { ForestSummarizer } from "./forestSummarizer.js"; export { getCodecTreeForForestFormat } from "./codec.js"; -export { ForestFormatVersion } from "./format.js"; -export { forestSummaryKey } from "./summaryTypes.js"; +export { ForestFormatVersion } from "./formatCommon.js"; diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatCommon.ts b/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatCommon.ts new file mode 100644 index 000000000000..bed39348c1a5 --- /dev/null +++ b/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatCommon.ts @@ -0,0 +1,41 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * The key for the tree that contains the overall forest's summary tree. + * This tree is added by the parent of the forest summarizer. + * See {@link ForestIncrementalSummaryBuilder} for details on the summary structure. + */ +export const forestSummaryKey = "Forest"; + +/** + * The versions for the forest summary. + */ +export enum ForestSummaryFormatVersion { + /** + * This version represents summary format before summary versioning was introduced. + */ + v1 = 1, + /** + * This version adds metadata to the summary. This is backward compatible with version 1. + */ + v2 = 2, + /** + * This version adds support for summaries with incremental chunks. Also, the ForestSummarizer's root contents are + * stored in {@link summaryContentBlobKeyV3} instead of {@link summaryContentBlobKeyV1}. + * This is not backward compatible with versions 1 and 2. + */ + v3 = 3, + /** + * The latest version of the summary. Must be updated when a new version is added. + */ + vLatest = v3, +} + +export const supportedForestSummaryFormatVersions = new Set([ + ForestSummaryFormatVersion.v1, + ForestSummaryFormatVersion.v2, + ForestSummaryFormatVersion.v3, +]); diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatV1ToV2.ts b/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatV1ToV2.ts new file mode 100644 index 000000000000..0213a16707e1 --- /dev/null +++ b/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatV1ToV2.ts @@ -0,0 +1,11 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * The entire contents of the ForestSummarizer's summary (ForestCodec's output) is added to a blob with this key. + * This was added in {@link ForestSummaryFormatVersion.v1 | version 1} and is used in + * {@link ForestSummaryFormatVersion.v1 | version 1} and {@link ForestSummaryFormatVersion.v2 | version 2}. + */ +export const summaryContentBlobKey = "ForestTree"; diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatV3.ts b/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatV3.ts new file mode 100644 index 000000000000..0cd7bfd80f74 --- /dev/null +++ b/packages/dds/tree/src/feature-libraries/forest-summary/summaryFormatV3.ts @@ -0,0 +1,18 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * From {@link ForestSummaryFormatVersion.v3 | version 3} onwards, the inline portion of the top-level forest content + * is stored in a summary blob with this key. + * If the summary is not incremental, the content stored is the entire forest content. + * If the summary is incremental, the contents of the incremental chunks is stored separately: + * The contents of an incremental chunk is under a summary tree node with its {@link ChunkReferenceId} as the key. + * The inline portion of the chunk content is encoded with the forest codec and is stored in a blob with this key as + * well. The rest of the chunk contents is stored in the summary tree under the summary tree node. + * + * @remarks + * See the summary format in {@link ForestIncrementalSummaryBuilder} for more details. + */ +export const summaryContentBlobKey = "contents"; diff --git a/packages/dds/tree/src/feature-libraries/forest-summary/summaryTypes.ts b/packages/dds/tree/src/feature-libraries/forest-summary/summaryTypes.ts index e1e05bc42a2a..b25cb70c72dd 100644 --- a/packages/dds/tree/src/feature-libraries/forest-summary/summaryTypes.ts +++ b/packages/dds/tree/src/feature-libraries/forest-summary/summaryTypes.ts @@ -4,58 +4,38 @@ */ import type { MinimumVersionForCollab } from "@fluidframework/runtime-definitions/internal"; +import { + getConfigForMinVersionForCollab, + lowestMinVersionForCollab, +} from "@fluidframework/runtime-utils/internal"; -/** - * The key for the tree that contains the overall forest's summary tree. - * This tree is added by the parent of the forest summarizer. - * See {@link ForestIncrementalSummaryBuilder} for details on the summary structure. - */ -export const forestSummaryKey = "Forest"; - -/** - * The key for the blob under ForestSummarizer's root. - * This blob contains the ForestCodec's output. - * See {@link ForestIncrementalSummaryBuilder} for details on the summary structure. - */ -export const forestSummaryContentKey = "ForestTree"; - -/** - * The contents of an incremental chunk is under a summary tree node with its {@link ChunkReferenceId} as the key. - * The inline portion of the chunk content is encoded with the forest codec is stored in a blob with this key. - * The rest of the chunk contents is stored in the summary tree under the summary tree node. - * See the summary format in {@link ForestIncrementalSummaryBuilder} for more details. - */ -export const chunkContentsBlobKey = "contents"; +import { FluidClientVersion } from "../../codec/index.js"; +import { ForestSummaryFormatVersion } from "./summaryFormatCommon.js"; +import { summaryContentBlobKey as summaryContentBlobKeyV1ToV2 } from "./summaryFormatV1ToV2.js"; +import { summaryContentBlobKey as summaryContentBlobKeyV3 } from "./summaryFormatV3.js"; /** - * The versions for the forest summary. + * Returns the summary format version to use as per the given minimum version for collab. */ -export enum ForestSummaryFormatVersion { - /** - * This version represents summary format before summary versioning was introduced. - */ - v1 = 1, - /** - * This version adds metadata to the summary. This is backward compatible with version 1. - */ - v2 = 2, - /** - * The latest version of the summary. Must be updated when a new version is added. - */ - vLatest = v2, +export function minVersionToForestSummaryFormatVersion( + version: MinimumVersionForCollab, +): ForestSummaryFormatVersion { + return getConfigForMinVersionForCollab(version, { + [lowestMinVersionForCollab]: ForestSummaryFormatVersion.v2, + [FluidClientVersion.v2_74]: ForestSummaryFormatVersion.v3, + }); } -export const supportedForestSummaryFormatVersions = new Set([ - ForestSummaryFormatVersion.v1, - ForestSummaryFormatVersion.v2, -]); - /** - * Returns the summary version to use as per the given minimum version for collab. + * Gets the key for the blob containing the forest summary root content based on the summary format version. + * @param summaryFormatVersion - The version of the forest summary format. + * @returns The key for the forest summary root content blob. */ -export function minVersionToForestSummaryFormatVersion( - version: MinimumVersionForCollab, -): ForestSummaryFormatVersion { - // Currently, version 2 is written which adds metadata blob to the summary. - return ForestSummaryFormatVersion.v2; +export function getForestRootSummaryContentKey( + summaryFormatVersion: ForestSummaryFormatVersion | undefined, +): string { + return summaryFormatVersion === undefined || + summaryFormatVersion < ForestSummaryFormatVersion.v3 + ? summaryContentBlobKeyV1ToV2 + : summaryContentBlobKeyV3; } diff --git a/packages/dds/tree/src/shared-tree-core/versionedSummarizer.ts b/packages/dds/tree/src/shared-tree-core/versionedSummarizer.ts index cc732f5dcefd..8871f835efd9 100644 --- a/packages/dds/tree/src/shared-tree-core/versionedSummarizer.ts +++ b/packages/dds/tree/src/shared-tree-core/versionedSummarizer.ts @@ -67,6 +67,11 @@ export abstract class VersionedSummarizer implements Su protected abstract loadInternal( services: IChannelStorageService, parse: SummaryElementParser, + /** + * The format version of the summary being loaded, or undefined if this is pre-versioning format, + * i.e., the summary has no version metadata. + */ + version: TVersion | undefined, ): Promise; public summarize(props: { @@ -89,19 +94,20 @@ export abstract class VersionedSummarizer implements Su services: IChannelStorageService, parse: SummaryElementParser, ): Promise { + let version: TVersion | undefined; if (await services.contains(summarizablesMetadataKey)) { const metadata = await readAndParseSnapshotBlob( summarizablesMetadataKey, services, (contents) => parse(contents), ); - const version = metadata.version as TVersion; + version = metadata.version as TVersion; if (!this.supportedVersions.has(version)) { throw new UsageError(`Cannot read version ${version} of shared tree summary.`); } } else if (!this.supportPreVersioningFormat) { throw new UsageError(`Cannot read summary without versioning for shared tree summary.`); } - await this.loadInternal(services, parse); + await this.loadInternal(services, parse, version); } } diff --git a/packages/dds/tree/src/test/feature-libraries/chunked-forest/chunkEncodingEndToEnd.spec.ts b/packages/dds/tree/src/test/feature-libraries/chunked-forest/chunkEncodingEndToEnd.spec.ts index 1d6f665c6c44..69607bd56971 100644 --- a/packages/dds/tree/src/test/feature-libraries/chunked-forest/chunkEncodingEndToEnd.spec.ts +++ b/packages/dds/tree/src/test/feature-libraries/chunked-forest/chunkEncodingEndToEnd.spec.ts @@ -73,7 +73,7 @@ import { toInitialSchema, } from "../../../simple-tree/index.js"; // eslint-disable-next-line import-x/no-internal-modules -import type { FormatV1 } from "../../../feature-libraries/forest-summary/format.js"; +import type { FormatV1 } from "../../../feature-libraries/forest-summary/formatV1.js"; import type { FieldBatchEncodingContext, // eslint-disable-next-line import-x/no-internal-modules diff --git a/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizer.spec.ts b/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizer.spec.ts index ecc37eff6175..936a14077196 100644 --- a/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizer.spec.ts +++ b/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizer.spec.ts @@ -30,7 +30,7 @@ import { } from "../../../feature-libraries/index.js"; import { brand } from "../../../util/index.js"; // eslint-disable-next-line import-x/no-internal-modules -import type { FormatV1 } from "../../../feature-libraries/forest-summary/format.js"; +import type { FormatV1 } from "../../../feature-libraries/forest-summary/formatV1.js"; import { checkoutWithContent, fieldCursorFromInsertable, @@ -59,10 +59,17 @@ import { } from "../../../simple-tree/index.js"; import { fieldJsonCursor } from "../../json/index.js"; import { - forestSummaryContentKey, ForestSummaryFormatVersion, // eslint-disable-next-line import-x/no-internal-modules -} from "../../../feature-libraries/forest-summary/summaryTypes.js"; +} from "../../../feature-libraries/forest-summary/summaryFormatCommon.js"; +import { + summaryContentBlobKey, + // eslint-disable-next-line import-x/no-internal-modules +} from "../../../feature-libraries/forest-summary/summaryFormatV3.js"; +import { + summaryContentBlobKey as summaryContentBlobKeyV1ToV2, + // eslint-disable-next-line import-x/no-internal-modules +} from "../../../feature-libraries/forest-summary/summaryFormatV1ToV2.js"; import { summarizablesMetadataKey, type SharedTreeSummarizableMetadata, @@ -198,7 +205,7 @@ function validateSummaryIsIncremental(summary: ISummaryTree, incrementalNodeCoun let incrementalNodesFound = 0; for (const [key, value] of Object.entries(summary.tree)) { - if (key === forestSummaryContentKey || key === summarizablesMetadataKey) { + if (key === summaryContentBlobKey || key === summarizablesMetadataKey) { assert(value.type === SummaryType.Blob, "Forest summary blob not as expected"); } else { assert(value.type === SummaryType.Tree, "Incremental summary node should be a tree"); @@ -360,7 +367,7 @@ describe("ForestSummarizer", () => { "Summary tree should only contain two entries", ); const forestContentsBlob: SummaryObject | undefined = - summary.summary.tree[forestSummaryContentKey]; + summary.summary.tree[summaryContentBlobKeyV1ToV2]; assert( forestContentsBlob?.type === SummaryType.Blob, "Forest summary contents not found", @@ -400,7 +407,7 @@ describe("ForestSummarizer", () => { "Summary tree should only contain two entries", ); const forestContentsBlob: SummaryObject | undefined = - summary.summary.tree[forestSummaryContentKey]; + summary.summary.tree[summaryContentBlobKeyV1ToV2]; assert( forestContentsBlob?.type === SummaryType.Blob, "Forest summary contents not found", @@ -812,6 +819,7 @@ describe("ForestSummarizer", () => { const { forestSummarizer } = createForestSummarizer({ encodeType: TreeCompressionStrategy.Compressed, forestType: ForestTypeOptimized, + minVersionForCollab: FluidClientVersion.v2_73, }); const summary = forestSummarizer.summarize({ stringify: JSON.stringify }); @@ -835,6 +843,7 @@ describe("ForestSummarizer", () => { const { forestSummarizer } = createForestSummarizer({ encodeType: TreeCompressionStrategy.Compressed, forestType: ForestTypeOptimized, + minVersionForCollab: FluidClientVersion.v2_73, }); const summary = forestSummarizer.summarize({ stringify: JSON.stringify }); @@ -858,6 +867,7 @@ describe("ForestSummarizer", () => { const { forestSummarizer: forestSummarizer2 } = createForestSummarizer({ encodeType: TreeCompressionStrategy.Compressed, forestType: ForestTypeOptimized, + minVersionForCollab: FluidClientVersion.v2_73, }); // Should load successfully with version 2 @@ -883,7 +893,7 @@ describe("ForestSummarizer", () => { const summaryTree: ISummaryTree = { type: SummaryType.Tree, tree: { - [forestSummaryContentKey]: forestContentBlob, + [summaryContentBlobKeyV1ToV2]: forestContentBlob, }, }; @@ -892,6 +902,7 @@ describe("ForestSummarizer", () => { const { forestSummarizer } = createForestSummarizer({ encodeType: TreeCompressionStrategy.Compressed, forestType: ForestTypeOptimized, + minVersionForCollab: FluidClientVersion.v2_73, }); await assert.doesNotReject(async () => forestSummarizer.load(mockStorage, JSON.parse)); diff --git a/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizerCodec.spec.ts b/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizerCodec.spec.ts index 65c22d01d7c2..02b7c628656a 100644 --- a/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizerCodec.spec.ts +++ b/packages/dds/tree/src/test/feature-libraries/forest-summary/forestSummarizerCodec.spec.ts @@ -26,9 +26,9 @@ import { // eslint-disable-next-line import-x/no-internal-modules } from "../../../feature-libraries/forest-summary/codec.js"; // eslint-disable-next-line import-x/no-internal-modules -import { ForestFormatVersion } from "../../../feature-libraries/forest-summary/format.js"; +import { ForestFormatVersion } from "../../../feature-libraries/forest-summary/formatCommon.js"; // eslint-disable-next-line import-x/no-internal-modules -import type { FormatV1 } from "../../../feature-libraries/forest-summary/format.js"; +import type { FormatV1 } from "../../../feature-libraries/forest-summary/formatV1.js"; import { FieldBatchFormatVersion, TreeCompressionStrategy, @@ -124,7 +124,7 @@ describe("ForestSummarizerCodec", () => { () => codec.decode( { - version: 2 as ForestFormatVersion, + version: 2.5 as ForestFormatVersion, fields: { version: brand(FieldBatchFormatVersion.v1), identifiers: [], @@ -135,7 +135,7 @@ describe("ForestSummarizerCodec", () => { }, context, ), - validateUsageError(/Unsupported version 2 encountered while decoding data/), + validateUsageError(/Unsupported version 2.5 encountered while decoding data/), ); }); @@ -146,7 +146,7 @@ describe("ForestSummarizerCodec", () => { { version: brand(ForestFormatVersion.v1), fields: { - version: 3 as FieldBatchFormatVersion, + version: 2.5 as FieldBatchFormatVersion, identifiers: [], shapes: [], data: [], diff --git a/packages/dds/tree/src/test/feature-libraries/forest-summary/incrementalSummaryBuilder.spec.ts b/packages/dds/tree/src/test/feature-libraries/forest-summary/incrementalSummaryBuilder.spec.ts index c82243df4810..adebd6c9f9bb 100644 --- a/packages/dds/tree/src/test/feature-libraries/forest-summary/incrementalSummaryBuilder.spec.ts +++ b/packages/dds/tree/src/test/feature-libraries/forest-summary/incrementalSummaryBuilder.spec.ts @@ -18,6 +18,14 @@ import { ForestSummaryTrackingState, // eslint-disable-next-line import-x/no-internal-modules } from "../../../feature-libraries/forest-summary/incrementalSummaryBuilder.js"; +import { + summaryContentBlobKey, + // eslint-disable-next-line import-x/no-internal-modules +} from "../../../feature-libraries/forest-summary/summaryFormatV3.js"; +import { + summaryContentBlobKey as summaryContentBlobKeyV1ToV2, + // eslint-disable-next-line import-x/no-internal-modules +} from "../../../feature-libraries/forest-summary/summaryFormatV1ToV2.js"; import { type EncodedFieldBatch, type ChunkReferenceId, @@ -89,7 +97,7 @@ function getMockChunk(): TreeChunk { const testCursor = { getFieldLength: () => 1 } as unknown as ITreeCursorSynchronous; const stringify = JSON.stringify; -const mockForestSummaryContent = "test-summary-content"; +const mockForestSummaryRootContent = "test-summary-content"; const mockEncodedChunk = {} as unknown as EncodedFieldBatch; const initialSequenceNumber = 0; @@ -178,7 +186,8 @@ describe("ForestIncrementalSummaryBuilder", () => { const summaryTreeBuilder = new SummaryTreeBuilder(); builder.completeSummary({ incrementalSummaryContext: undefined, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKeyV1ToV2, builder: summaryTreeBuilder, }); const summary = summaryTreeBuilder.getSummaryTree(); @@ -201,7 +210,8 @@ describe("ForestIncrementalSummaryBuilder", () => { builder.encodeIncrementalField(testCursor, () => mockEncodedChunk); builder.completeSummary({ incrementalSummaryContext, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder, }); const summary = summaryTreeBuilder.getSummaryTree(); @@ -225,7 +235,8 @@ describe("ForestIncrementalSummaryBuilder", () => { builder.completeSummary({ incrementalSummaryContext: localIncrementalSummaryContext, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder, }); assert.equal(builder.forestSummaryState, ForestSummaryTrackingState.ReadyToTrack); @@ -239,7 +250,8 @@ describe("ForestIncrementalSummaryBuilder", () => { () => builder.completeSummary({ incrementalSummaryContext: localIncrementalSummaryContext, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: new SummaryTreeBuilder(), }), validateAssertionError(/Not tracking/), @@ -414,7 +426,8 @@ describe("ForestIncrementalSummaryBuilder", () => { // Complete first summary builder.completeSummary({ incrementalSummaryContext, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder1, }); @@ -451,7 +464,8 @@ describe("ForestIncrementalSummaryBuilder", () => { const referenceIds1 = builder.encodeIncrementalField(testCursor, () => mockEncodedChunk); builder.completeSummary({ incrementalSummaryContext: incrementalSummaryContext1, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder1, }); @@ -477,7 +491,8 @@ describe("ForestIncrementalSummaryBuilder", () => { const referenceId1 = referenceIds1[0]; builder.completeSummary({ incrementalSummaryContext: incrementalSummaryContext2, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder2, }); const summary = summaryTreeBuilder2.getSummaryTree(); @@ -500,7 +515,8 @@ describe("ForestIncrementalSummaryBuilder", () => { const referenceIds1 = builder.encodeIncrementalField(testCursor, () => mockEncodedChunk); builder.completeSummary({ incrementalSummaryContext, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder1, }); @@ -515,7 +531,8 @@ describe("ForestIncrementalSummaryBuilder", () => { }); builder.completeSummary({ incrementalSummaryContext: incrementalSummaryContext2, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder2, }); @@ -539,7 +556,8 @@ describe("ForestIncrementalSummaryBuilder", () => { const referenceId1 = referenceIds1[0]; builder.completeSummary({ incrementalSummaryContext: incrementalSummaryContext3, - forestSummaryContent: mockForestSummaryContent, + forestSummaryRootContent: mockForestSummaryRootContent, + forestSummaryRootContentKey: summaryContentBlobKey, builder: summaryTreeBuilder3, }); const summary = summaryTreeBuilder3.getSummaryTree(); diff --git a/packages/dds/tree/src/test/snapshots/output/codec-tree/MinVersionForCollab.v2_74.json b/packages/dds/tree/src/test/snapshots/output/codec-tree/MinVersionForCollab.v2_74.json index 6c370dcc02c1..e2f3d44366c1 100644 --- a/packages/dds/tree/src/test/snapshots/output/codec-tree/MinVersionForCollab.v2_74.json +++ b/packages/dds/tree/src/test/snapshots/output/codec-tree/MinVersionForCollab.v2_74.json @@ -4,7 +4,7 @@ "children": [ { "name": "Forest", - "version": 1 + "version": 2 }, { "name": "Schema", diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/attachment-tree-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/attachment-tree-final.json index 15ff4a984f4f..d7490c0814eb 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/attachment-tree-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/attachment-tree-final.json @@ -109,14 +109,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -158,7 +158,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-0.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-0.json index 4690645e1de4..94b70c2d67da 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-0.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-0.json @@ -338,14 +338,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -393,7 +393,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-1.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-1.json index f0b2f79ad6e8..8512f5420bae 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-1.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-1.json @@ -353,14 +353,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -408,7 +408,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-2.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-2.json index 5081eae6d374..23ea13850968 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-2.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-2.json @@ -353,14 +353,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -408,7 +408,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-3.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-3.json index 00a880aa207c..b18925fa5fc2 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-3.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/competing-removes-index-3.json @@ -353,14 +353,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -408,7 +408,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/complete-3x3-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/complete-3x3-final.json index dea80962879b..88d916232903 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/complete-3x3-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/complete-3x3-final.json @@ -643,14 +643,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -1022,7 +1022,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree2.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree2.json index 7de43c196474..8abe6cf6e7e8 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree2.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree2.json @@ -415,14 +415,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -467,7 +467,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree3.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree3.json index dc986de24114..5aed8425291e 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree3.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/concurrent-inserts-tree3.json @@ -418,14 +418,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -474,7 +474,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/empty-root-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/empty-root-final.json index 46235665f2fb..68a02f1b38e7 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/empty-root-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/empty-root-final.json @@ -148,14 +148,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [], @@ -165,7 +165,7 @@ "shapes": [], "data": [] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/has-handle-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/has-handle-final.json index a965c9d46848..b198d67c9d11 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/has-handle-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/has-handle-final.json @@ -181,14 +181,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -232,7 +232,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-after-insert.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-after-insert.json index f81035c72fe9..8843c92d2c12 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-after-insert.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-after-insert.json @@ -182,14 +182,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -230,7 +230,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-final.json index cc814a3642b0..42b5b8e075b9 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-0-final.json @@ -151,14 +151,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -202,7 +202,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-1-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-1-final.json index 1b291c096950..f4f913aa5f65 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-1-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/insert-and-remove-tree-1-final.json @@ -159,14 +159,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -210,7 +210,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/move-across-fields-tree-0-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/move-across-fields-tree-0-final.json index 4ae3018fcb8b..198d1297bdf0 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/move-across-fields-tree-0-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/move-across-fields-tree-0-final.json @@ -447,14 +447,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -518,7 +518,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/nested-sequence-change-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/nested-sequence-change-final.json index ef0e525b05fd..ae1dc1ef50d9 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/nested-sequence-change-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/nested-sequence-change-final.json @@ -236,14 +236,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -300,7 +300,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/optional-field-scenarios-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/optional-field-scenarios-final.json index 0f6cdc7f90e0..6b66898566da 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/optional-field-scenarios-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/optional-field-scenarios-final.json @@ -459,14 +459,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -541,7 +541,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/tree-with-identifier-field-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/tree-with-identifier-field-final.json index a28dab7a2762..1485cf13e048 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/tree-with-identifier-field-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Compressed/v2_74/tree-with-identifier-field-final.json @@ -265,14 +265,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -308,7 +308,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/attachment-tree-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/attachment-tree-final.json index 3e3ba416e8d5..e167df9413bf 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/attachment-tree-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/attachment-tree-final.json @@ -109,14 +109,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -158,7 +158,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-0.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-0.json index 3bd61c0f7617..2c9f47582dc0 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-0.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-0.json @@ -338,14 +338,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -401,7 +401,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-1.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-1.json index 27dc6292bad6..22f0eac886f1 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-1.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-1.json @@ -353,14 +353,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -416,7 +416,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-2.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-2.json index b5147216b25d..2d3834dfa05d 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-2.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-2.json @@ -353,14 +353,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -416,7 +416,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-3.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-3.json index 77a6c4eaf3c3..109066ed72f7 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-3.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/competing-removes-index-3.json @@ -353,14 +353,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -416,7 +416,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/complete-3x3-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/complete-3x3-final.json index 1f1436208653..d9bf32a68e89 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/complete-3x3-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/complete-3x3-final.json @@ -980,14 +980,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -1696,7 +1696,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree2.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree2.json index 53d443319cb3..c41ac73e265f 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree2.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree2.json @@ -436,14 +436,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -497,7 +497,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree3.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree3.json index b78d0f47b7ca..0754f8d40340 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree3.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/concurrent-inserts-tree3.json @@ -439,14 +439,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -516,7 +516,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/empty-root-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/empty-root-final.json index 8a7a5a3ea30b..5e8b225fdb95 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/empty-root-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/empty-root-final.json @@ -148,14 +148,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [], @@ -174,7 +174,7 @@ ], "data": [] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/has-handle-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/has-handle-final.json index d870224611b7..7f81805d567e 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/has-handle-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/has-handle-final.json @@ -188,14 +188,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -236,7 +236,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-after-insert.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-after-insert.json index c5c3bc9da5ba..d98c29d980d5 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-after-insert.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-after-insert.json @@ -189,14 +189,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -234,7 +234,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-final.json index 4a03ff452bab..83db2221a896 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-0-final.json @@ -151,14 +151,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -198,7 +198,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-1-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-1-final.json index b726e6082860..f15bf65f790e 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-1-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/insert-and-remove-tree-1-final.json @@ -159,14 +159,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -206,7 +206,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/move-across-fields-tree-0-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/move-across-fields-tree-0-final.json index 88794f8fd668..848b310a1240 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/move-across-fields-tree-0-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/move-across-fields-tree-0-final.json @@ -458,14 +458,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -540,7 +540,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/nested-sequence-change-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/nested-sequence-change-final.json index 10996a158f06..71070c5f2a65 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/nested-sequence-change-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/nested-sequence-change-final.json @@ -234,14 +234,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -299,7 +299,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/optional-field-scenarios-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/optional-field-scenarios-final.json index 8bbf5721ddb5..1dfb65fd4345 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/optional-field-scenarios-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/optional-field-scenarios-final.json @@ -471,14 +471,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -570,7 +570,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" } diff --git a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/tree-with-identifier-field-final.json b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/tree-with-identifier-field-final.json index 2659585c167d..751b36668656 100644 --- a/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/tree-with-identifier-field-final.json +++ b/packages/dds/tree/src/test/snapshots/output/summary/Uncompressed/v2_74/tree-with-identifier-field-final.json @@ -267,14 +267,14 @@ ".metadata": { "type": "blob", "content": { - "version": 2 + "version": 3 }, "encoding": "utf-8" } }, { "type": "blob", - "ForestTree": { + "contents": { "type": "blob", "content": { "keys": [ @@ -312,7 +312,7 @@ ] ] }, - "version": 1 + "version": 2 }, "encoding": "utf-8" }