@fluidframework/tree 2.93.0 → 2.101.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -0
- package/INCREMENTAL_SUMMARY.md +89 -0
- package/README.md +6 -0
- package/api-report/tree.alpha.api.md +6 -1
- package/api-report/tree.beta.api.md +3 -1
- package/api-report/tree.legacy.beta.api.md +3 -1
- package/dist/core/change-family/changeFamily.d.ts +23 -0
- package/dist/core/change-family/changeFamily.d.ts.map +1 -1
- package/dist/core/change-family/changeFamily.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV1.js +2 -0
- package/dist/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV2.js +2 -0
- package/dist/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts +25 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +71 -18
- package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -4
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +31 -4
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +27 -0
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +5 -2
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +10 -2
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +7 -2
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +1 -2
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js +0 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/index.js +2 -1
- package/dist/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts +10 -2
- package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/versions.js +15 -1
- package/dist/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.js +9 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +3 -3
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +8 -8
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts +6 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js +25 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +19 -0
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +76 -22
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.d.ts +2 -14
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js +1 -17
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +4 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/independentView.d.ts.map +1 -1
- package/dist/shared-tree/independentView.js +2 -0
- package/dist/shared-tree/independentView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +35 -1
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +6 -0
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js +1 -0
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +2 -0
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +1 -1
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +2 -0
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.d.ts +3 -0
- package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsCommons.d.ts +14 -0
- package/dist/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsCommons.js +14 -0
- package/dist/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts +3 -0
- package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +3 -0
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.d.ts +9 -1
- package/dist/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js +20 -5
- package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.js +4 -0
- package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.js +4 -0
- package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts +4 -0
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +3 -3
- package/dist/simple-tree/api/schemaFactory.js +3 -3
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.js +9 -0
- package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +102 -20
- package/dist/tableSchema.js.map +1 -1
- package/docs/user-facing/isolated-declarations.md +147 -0
- package/lib/core/change-family/changeFamily.d.ts +23 -0
- package/lib/core/change-family/changeFamily.d.ts.map +1 -1
- package/lib/core/change-family/changeFamily.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV1.js +2 -0
- package/lib/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV2.js +2 -0
- package/lib/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts +25 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +72 -19
- package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -4
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +32 -5
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +27 -0
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +6 -3
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +10 -2
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +8 -3
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +1 -2
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js +0 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/index.js +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts +10 -2
- package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/versions.js +13 -0
- package/lib/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.js +9 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +3 -3
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +8 -8
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts +6 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js +26 -2
- package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +19 -0
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +76 -22
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.d.ts +2 -14
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.js +1 -17
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +4 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/independentView.d.ts.map +1 -1
- package/lib/shared-tree/independentView.js +2 -0
- package/lib/shared-tree/independentView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +35 -1
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +6 -0
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js +1 -0
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +2 -0
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +1 -1
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +2 -0
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.d.ts +3 -0
- package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsCommons.d.ts +14 -0
- package/lib/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsCommons.js +14 -0
- package/lib/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts +3 -0
- package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +3 -0
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.d.ts +9 -1
- package/lib/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js +20 -5
- package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.js +4 -0
- package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.js +4 -0
- package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts +4 -0
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +3 -3
- package/lib/simple-tree/api/schemaFactory.js +3 -3
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +17 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.js +9 -0
- package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +103 -21
- package/lib/tableSchema.js.map +1 -1
- package/package.json +24 -24
- package/src/core/change-family/changeFamily.ts +25 -0
- package/src/core/tree/detachedFieldIndexCodecV1.ts +2 -0
- package/src/core/tree/detachedFieldIndexCodecV2.ts +2 -0
- package/src/feature-libraries/chunked-forest/basicChunk.ts +76 -20
- package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +61 -12
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +34 -1
- package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +9 -3
- package/src/feature-libraries/chunked-forest/codec/format/formatGeneric.ts +0 -1
- package/src/feature-libraries/chunked-forest/codec/format/index.ts +1 -0
- package/src/feature-libraries/chunked-forest/codec/format/versions.ts +15 -0
- package/src/feature-libraries/chunked-forest/codec/nodeEncoder.ts +9 -1
- package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +9 -1
- package/src/feature-libraries/chunked-forest/uniformChunk.ts +32 -2
- package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +116 -31
- package/src/feature-libraries/modular-schema/genericFieldKindFormat.ts +3 -21
- package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +4 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/independentView.ts +2 -0
- package/src/shared-tree/sharedTree.ts +41 -1
- package/src/shared-tree/sharedTreeChangeCodecs.ts +1 -0
- package/src/shared-tree/treeAlpha.ts +2 -0
- package/src/shared-tree/treeCheckout.ts +2 -0
- package/src/shared-tree-core/editManagerCodecs.ts +3 -0
- package/src/shared-tree-core/editManagerCodecsCommons.ts +29 -0
- package/src/shared-tree-core/editManagerCodecsV1toV4.ts +3 -0
- package/src/shared-tree-core/editManagerCodecsVSharedBranches.ts +3 -0
- package/src/shared-tree-core/editManagerSummarizer.ts +17 -5
- package/src/shared-tree-core/messageCodecV1ToV4.ts +4 -0
- package/src/shared-tree-core/messageCodecVSharedBranches.ts +5 -1
- package/src/shared-tree-core/sharedTreeCore.ts +8 -1
- package/src/simple-tree/api/schemaFactory.ts +3 -3
- package/src/simple-tree/api/schemaFactoryAlpha.ts +34 -3
- package/src/tableSchema.ts +134 -35
|
@@ -50,10 +50,12 @@ interface ChunkLoadProperties {
|
|
|
50
50
|
*/
|
|
51
51
|
readonly encodedContents: EncodedFieldBatchV2;
|
|
52
52
|
/**
|
|
53
|
-
* The
|
|
54
|
-
*
|
|
53
|
+
* The reference ID of this chunk's parent in the summary tree, or `undefined` if this chunk is
|
|
54
|
+
* at the top level (directly under the forest summary tree).
|
|
55
|
+
* Stored here so that {@link ForestIncrementalSummaryBuilder.decodeIncrementalChunk} can
|
|
56
|
+
* reconstruct the correct {@link ChunkSummaryProperties} without re-parsing a path string.
|
|
55
57
|
*/
|
|
56
|
-
readonly
|
|
58
|
+
readonly parentReferenceId: ChunkReferenceId | undefined;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/**
|
|
@@ -68,10 +70,20 @@ interface ChunkSummaryProperties {
|
|
|
68
70
|
*/
|
|
69
71
|
readonly referenceId: ChunkReferenceId;
|
|
70
72
|
/**
|
|
71
|
-
* The
|
|
72
|
-
*
|
|
73
|
+
* The reference ID of this chunk's parent in the summary tree, or `undefined` if this chunk
|
|
74
|
+
* is at the top level (has no incremental parent).
|
|
75
|
+
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* Storing only the immediate parent (rather than the full path string) keeps every chunk's
|
|
78
|
+
* tracking entry correct even when an ancestor is re-encoded and receives a new reference ID.
|
|
79
|
+
* The full summary path is computed on demand by {@link ForestIncrementalSummaryBuilder.computeHandlePathInLatestSummary}
|
|
80
|
+
* by walking up the parent chain through {@link TrackedSummaryProperties.latestSummaryRefIdMap}.
|
|
81
|
+
*
|
|
82
|
+
* If a parent chunk is encoded as a handle in the current summary its reference ID is unchanged,
|
|
83
|
+
* so its children's `parentReferenceId` values copied forward by `completeSummary` remain valid
|
|
84
|
+
* without any additional update.
|
|
73
85
|
*/
|
|
74
|
-
readonly
|
|
86
|
+
readonly parentReferenceId: ChunkReferenceId | undefined;
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
/**
|
|
@@ -109,6 +121,13 @@ interface TrackedSummaryProperties {
|
|
|
109
121
|
* Serializes content (including {@link (IFluidHandle:interface)}s) for adding to a summary blob.
|
|
110
122
|
*/
|
|
111
123
|
stringify: SummaryElementStringifier;
|
|
124
|
+
/**
|
|
125
|
+
* Reverse lookup map for the latest summary: maps each chunk's {@link ChunkReferenceId} to its
|
|
126
|
+
* {@link ChunkSummaryProperties}.
|
|
127
|
+
* Used by {@link ForestIncrementalSummaryBuilder.computeHandlePathInLatestSummary} to traverse
|
|
128
|
+
* the parent chain when generating handle paths.
|
|
129
|
+
*/
|
|
130
|
+
readonly latestSummaryRefIdMap: Map<ChunkReferenceId, ChunkSummaryProperties>;
|
|
112
131
|
}
|
|
113
132
|
|
|
114
133
|
/**
|
|
@@ -177,6 +196,16 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
177
196
|
/**
|
|
178
197
|
* For a given summary sequence number, keeps track of a chunk's properties that will be used to generate
|
|
179
198
|
* a summary handle for the chunk if it does not change between summaries.
|
|
199
|
+
*
|
|
200
|
+
* @remarks
|
|
201
|
+
* `chunk` (the TreeChunk object) is used as the map key by object identity.
|
|
202
|
+
* This assumes each chunk appears at exactly one position in the forest — an invariant that holds because every
|
|
203
|
+
* node in a tree has a single parent.
|
|
204
|
+
* If the forest ever introduced structural sharing (two positions backed by the same TreeChunk object),
|
|
205
|
+
* a second call here would silently overwrite the first entry, causing the first position's handle to point
|
|
206
|
+
* to the second position's parent in subsequent summaries. In theory, this should be fine from summary perspective
|
|
207
|
+
* because the chunk contents are the same. But, it could lead to confusing handle paths in the summary tree and
|
|
208
|
+
* may lead to other unexpected behavior. Adequate tests should be added if structural sharing is introduced.
|
|
180
209
|
*/
|
|
181
210
|
private readonly chunkTrackingPropertiesMap: NestedMap<
|
|
182
211
|
number,
|
|
@@ -249,12 +278,14 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
249
278
|
// the contents of incremental chunks in any sub-trees.
|
|
250
279
|
const downloadChunkContentsInTree = async (
|
|
251
280
|
snapshotTree: ISnapshotTree,
|
|
252
|
-
|
|
281
|
+
parentPathSegments: string[],
|
|
282
|
+
parentReferenceId: ChunkReferenceId | undefined,
|
|
253
283
|
): Promise<void> => {
|
|
254
284
|
// All trees in the snapshot tree are for incremental chunks. The key is the chunk's reference ID
|
|
255
285
|
// and the value is the snapshot tree for the chunk.
|
|
256
286
|
for (const [chunkReferenceId, chunkSnapshotTree] of Object.entries(snapshotTree.trees)) {
|
|
257
|
-
const
|
|
287
|
+
const chunkSubTreeSegments = [...parentPathSegments, chunkReferenceId];
|
|
288
|
+
const chunkSubTreePath = chunkSubTreeSegments.join("/");
|
|
258
289
|
const chunkContentsPath = `${chunkSubTreePath}/${summaryContentBlobKey}`;
|
|
259
290
|
if (!(await args.services.contains(chunkContentsPath))) {
|
|
260
291
|
throw new LoggingError(
|
|
@@ -266,7 +297,7 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
266
297
|
)) as EncodedFieldBatchV2; // TODO: this should use a codec to validate the data instead of just type casting.
|
|
267
298
|
this.loadedChunksMap.set(chunkReferenceId, {
|
|
268
299
|
encodedContents: chunkContents,
|
|
269
|
-
|
|
300
|
+
parentReferenceId,
|
|
270
301
|
});
|
|
271
302
|
|
|
272
303
|
const chunkReferenceIdNumber = Number(chunkReferenceId);
|
|
@@ -275,10 +306,15 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
275
306
|
);
|
|
276
307
|
|
|
277
308
|
// Recursively download the contents of chunks in this chunk's sub tree.
|
|
278
|
-
await downloadChunkContentsInTree(
|
|
309
|
+
await downloadChunkContentsInTree(
|
|
310
|
+
chunkSnapshotTree,
|
|
311
|
+
chunkSubTreeSegments,
|
|
312
|
+
brand(chunkReferenceIdNumber),
|
|
313
|
+
);
|
|
279
314
|
}
|
|
280
315
|
};
|
|
281
|
-
|
|
316
|
+
// parentReferenceId is undefined for the root of the forest tree.
|
|
317
|
+
await downloadChunkContentsInTree(forestTree, [], undefined /* parentReferenceId */);
|
|
282
318
|
}
|
|
283
319
|
|
|
284
320
|
/**
|
|
@@ -319,6 +355,19 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
319
355
|
}
|
|
320
356
|
|
|
321
357
|
this.latestSummarySequenceNumber = incrementalSummaryContext.latestSummarySequenceNumber;
|
|
358
|
+
|
|
359
|
+
// Build a reverse lookup map (referenceId → properties) for the latest summary so that
|
|
360
|
+
// computeHandlePathInLatestSummary can traverse the parent chain without iterating the whole map.
|
|
361
|
+
const latestSummaryRefIdMap: Map<ChunkReferenceId, ChunkSummaryProperties> = new Map();
|
|
362
|
+
const latestTracking = this.chunkTrackingPropertiesMap.get(
|
|
363
|
+
this.latestSummarySequenceNumber,
|
|
364
|
+
);
|
|
365
|
+
if (latestTracking !== undefined) {
|
|
366
|
+
for (const properties of latestTracking.values()) {
|
|
367
|
+
latestSummaryRefIdMap.set(properties.referenceId, properties);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
322
371
|
this.trackedSummaryProperties = {
|
|
323
372
|
summarySequenceNumber: incrementalSummaryContext.summarySequenceNumber,
|
|
324
373
|
latestSummaryBasePath: incrementalSummaryContext.summaryPath,
|
|
@@ -326,10 +375,39 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
326
375
|
parentSummaryBuilder: builder,
|
|
327
376
|
fullTree,
|
|
328
377
|
stringify,
|
|
378
|
+
latestSummaryRefIdMap,
|
|
329
379
|
};
|
|
330
380
|
return ForestIncrementalSummaryBehavior.Incremental;
|
|
331
381
|
}
|
|
332
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Computes a chunk's path in the latest summary by traversing up the parent chain via
|
|
385
|
+
* {@link latestSummaryRefIdMap}.
|
|
386
|
+
*
|
|
387
|
+
* Each {@link ChunkSummaryProperties.parentReferenceId} points to the chunk's parent as it
|
|
388
|
+
* appeared in the summary where the entry was last written. Walking up the chain from the
|
|
389
|
+
* chunk to the root produces the full path that can be used in a summary handle path.
|
|
390
|
+
*/
|
|
391
|
+
private computeHandlePathInLatestSummary(chunkProperties: ChunkSummaryProperties): string {
|
|
392
|
+
const { latestSummaryRefIdMap } = this.requireTrackingSummary();
|
|
393
|
+
const pathSegments: string[] = [];
|
|
394
|
+
let current: ChunkSummaryProperties | undefined = chunkProperties;
|
|
395
|
+
while (current !== undefined) {
|
|
396
|
+
pathSegments.push(`${current.referenceId}`);
|
|
397
|
+
if (current.parentReferenceId === undefined) {
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
current = latestSummaryRefIdMap.get(current.parentReferenceId);
|
|
401
|
+
assert(
|
|
402
|
+
current !== undefined,
|
|
403
|
+
0xcf7 /* Parent chunk not found in latest summary tracking */,
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
// Segments are collected leaf-to-root and then reversed. The alternative would be to use unshift
|
|
407
|
+
// instead of push and reverse. However, using push and reverse is O(n) whereas using unshift would be O(n²).
|
|
408
|
+
return pathSegments.reverse().join("/");
|
|
409
|
+
}
|
|
410
|
+
|
|
333
411
|
/**
|
|
334
412
|
* {@link IncrementalEncoder.encodeIncrementalField}
|
|
335
413
|
* @remarks Returns an empty array if the field has no content.
|
|
@@ -344,8 +422,6 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
344
422
|
const chunkReferenceIds: ChunkReferenceId[] = [];
|
|
345
423
|
const chunks = this.getChunkAtCursor(cursor);
|
|
346
424
|
for (const chunk of chunks) {
|
|
347
|
-
let chunkProperties: ChunkSummaryProperties;
|
|
348
|
-
|
|
349
425
|
// Try and get the properties of the chunk from the latest successful summary.
|
|
350
426
|
// If it exists and the summary is not a full tree, use the properties to generate a summary handle.
|
|
351
427
|
// If it does not exist, encode the chunk and generate new properties for it.
|
|
@@ -354,28 +430,29 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
354
430
|
this.latestSummarySequenceNumber,
|
|
355
431
|
chunk,
|
|
356
432
|
);
|
|
433
|
+
let chunkReferenceId: ChunkReferenceId;
|
|
357
434
|
if (previousChunkProperties !== undefined && !trackedSummaryProperties.fullTree) {
|
|
358
|
-
|
|
435
|
+
chunkReferenceId = previousChunkProperties.referenceId;
|
|
436
|
+
// Compute this chunk's path in the latest summary by traversing the parent chain.
|
|
437
|
+
// Using parentReferenceId traversal (rather than a stored path string) ensures the
|
|
438
|
+
// path is correct even when an ancestor was re-encoded in a prior summary and
|
|
439
|
+
// received a new referenceId — the stored summaryPath would have been stale in
|
|
440
|
+
// that case.
|
|
441
|
+
const handlePath = this.computeHandlePathInLatestSummary(previousChunkProperties);
|
|
359
442
|
trackedSummaryProperties.parentSummaryBuilder.addHandle(
|
|
360
|
-
`${
|
|
443
|
+
`${chunkReferenceId}`,
|
|
361
444
|
SummaryType.Tree,
|
|
362
|
-
`${trackedSummaryProperties.latestSummaryBasePath}/${
|
|
445
|
+
`${trackedSummaryProperties.latestSummaryBasePath}/${handlePath}`,
|
|
363
446
|
);
|
|
364
447
|
} else {
|
|
365
448
|
// Generate a new reference ID for the chunk.
|
|
366
449
|
const newReferenceId: ChunkReferenceId = brand(this.nextReferenceId++);
|
|
450
|
+
chunkReferenceId = newReferenceId;
|
|
367
451
|
|
|
368
|
-
// Add the reference ID of this chunk to the chunk summary path
|
|
369
|
-
//
|
|
370
|
-
// This is done before encoding the chunk so that the summary path is updated correctly when encoding
|
|
371
|
-
// any incremental chunks that are under this chunk.
|
|
452
|
+
// Add the reference ID of this chunk to the chunk summary path before encoding so
|
|
453
|
+
// that any incremental chunks in the subtree use the correct parent path.
|
|
372
454
|
trackedSummaryProperties.chunkSummaryPath.push(newReferenceId);
|
|
373
455
|
|
|
374
|
-
chunkProperties = {
|
|
375
|
-
referenceId: newReferenceId,
|
|
376
|
-
summaryPath: trackedSummaryProperties.chunkSummaryPath.join("/"),
|
|
377
|
-
};
|
|
378
|
-
|
|
379
456
|
const parentSummaryBuilder = trackedSummaryProperties.parentSummaryBuilder;
|
|
380
457
|
// Create a new summary builder for this chunk to build its summary tree which will be stored in the
|
|
381
458
|
// parent's summary tree under its reference ID.
|
|
@@ -400,13 +477,21 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
400
477
|
trackedSummaryProperties.chunkSummaryPath.pop();
|
|
401
478
|
}
|
|
402
479
|
|
|
480
|
+
// Get the parent reference ID from the current chunk summary path.
|
|
481
|
+
// For the root of the forest tree, the parent reference ID is undefined.
|
|
482
|
+
// For all other chunks, the parent reference ID is the last element in the current chunk summary path.
|
|
483
|
+
const chunkSummaryPathLength = trackedSummaryProperties.chunkSummaryPath.length;
|
|
484
|
+
const parentReferenceId: ChunkReferenceId | undefined =
|
|
485
|
+
chunkSummaryPathLength > 0
|
|
486
|
+
? trackedSummaryProperties.chunkSummaryPath[chunkSummaryPathLength - 1]
|
|
487
|
+
: undefined;
|
|
403
488
|
setInNestedMap(
|
|
404
489
|
this.chunkTrackingPropertiesMap,
|
|
405
490
|
trackedSummaryProperties.summarySequenceNumber,
|
|
406
491
|
chunk,
|
|
407
|
-
|
|
492
|
+
{ referenceId: chunkReferenceId, parentReferenceId },
|
|
408
493
|
);
|
|
409
|
-
chunkReferenceIds.push(
|
|
494
|
+
chunkReferenceIds.push(chunkReferenceId);
|
|
410
495
|
}
|
|
411
496
|
return chunkReferenceIds;
|
|
412
497
|
}
|
|
@@ -480,9 +565,9 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
480
565
|
referenceId: ChunkReferenceId,
|
|
481
566
|
chunkDecoder: (encoded: EncodedFieldBatchV2) => TreeChunk,
|
|
482
567
|
): TreeChunk {
|
|
483
|
-
const
|
|
484
|
-
assert(
|
|
485
|
-
const chunk = chunkDecoder(
|
|
568
|
+
const chunkLoadProperties = this.loadedChunksMap.get(`${referenceId}`);
|
|
569
|
+
assert(chunkLoadProperties !== undefined, 0xc86 /* Encoded incremental chunk not found */);
|
|
570
|
+
const chunk = chunkDecoder(chunkLoadProperties.encodedContents);
|
|
486
571
|
|
|
487
572
|
// Account for the reference about to be added in `chunkTrackingPropertiesMap`
|
|
488
573
|
// to ensure that no other users of this chunk think they have unique ownership.
|
|
@@ -493,7 +578,7 @@ export class ForestIncrementalSummaryBuilder implements IncrementalEncoderDecode
|
|
|
493
578
|
// when a new client starts to summarize.
|
|
494
579
|
setInNestedMap(this.chunkTrackingPropertiesMap, this.initialSequenceNumber, chunk, {
|
|
495
580
|
referenceId,
|
|
496
|
-
|
|
581
|
+
parentReferenceId: chunkLoadProperties.parentReferenceId,
|
|
497
582
|
});
|
|
498
583
|
return chunk;
|
|
499
584
|
}
|
|
@@ -3,33 +3,17 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { type Static, type TAnySchema, type TSchema, Type } from "@sinclair/typebox";
|
|
7
|
-
|
|
8
6
|
// Many of the return types in this module are intentionally derived, rather than explicitly specified.
|
|
9
7
|
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
* Note: TS doesn't easily support extracting a generic function's return type until 4.7:
|
|
13
|
-
* https://github.com/microsoft/TypeScript/pull/47607
|
|
14
|
-
* This type is a workaround and can be removed once we're on a version of typescript which
|
|
15
|
-
* supports expressions more like:
|
|
16
|
-
* `Static<ReturnType<typeof EncodedGenericChange<Schema>>>`
|
|
17
|
-
*/
|
|
18
|
-
class Wrapper<T extends TSchema> {
|
|
19
|
-
public encodedGenericChange(e: T) {
|
|
20
|
-
return EncodedGenericChange<T>(e);
|
|
21
|
-
}
|
|
22
|
-
public encodedGenericChangeset(e: T) {
|
|
23
|
-
return EncodedGenericChangeset<T>(e);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
9
|
+
import { type Static, type TAnySchema, type TSchema, Type } from "@sinclair/typebox";
|
|
26
10
|
|
|
27
11
|
export const EncodedGenericChange = <NodeChangesetSchema extends TSchema>(
|
|
28
12
|
tNodeChangeset: NodeChangesetSchema,
|
|
29
13
|
) => Type.Tuple([Type.Number({ minimum: 0, multipleOf: 1 }), tNodeChangeset]);
|
|
30
14
|
|
|
31
15
|
export type EncodedGenericChange<Schema extends TSchema = TAnySchema> = Static<
|
|
32
|
-
ReturnType<
|
|
16
|
+
ReturnType<typeof EncodedGenericChange<Schema>>
|
|
33
17
|
>;
|
|
34
18
|
|
|
35
19
|
export const EncodedGenericChangeset = <NodeChangesetSchema extends TSchema>(
|
|
@@ -37,7 +21,5 @@ export const EncodedGenericChangeset = <NodeChangesetSchema extends TSchema>(
|
|
|
37
21
|
) => Type.Array(EncodedGenericChange(tNodeChangeset));
|
|
38
22
|
|
|
39
23
|
export type EncodedGenericChangeset<Schema extends TSchema = TAnySchema> = Static<
|
|
40
|
-
ReturnType<
|
|
24
|
+
ReturnType<typeof EncodedGenericChangeset<Schema>>
|
|
41
25
|
>;
|
|
42
|
-
|
|
43
|
-
/* eslint-enable @typescript-eslint/explicit-function-return-type */
|
|
@@ -330,6 +330,7 @@ export function encodeDetachedNodes(
|
|
|
330
330
|
schema: context.schema,
|
|
331
331
|
originatorId: context.originatorId,
|
|
332
332
|
idCompressor: context.idCompressor,
|
|
333
|
+
isSummary: context.isSummary,
|
|
333
334
|
}),
|
|
334
335
|
};
|
|
335
336
|
}
|
|
@@ -353,6 +354,9 @@ export function decodeDetachedNodes(
|
|
|
353
354
|
encodeType: chunkCompressionStrategy,
|
|
354
355
|
originatorId: context.originatorId,
|
|
355
356
|
idCompressor: context.idCompressor,
|
|
357
|
+
isSummary: context.isSummary,
|
|
358
|
+
healUnresolvableIdentifiersOnDecode: context.healUnresolvableIdentifiersOnDecode,
|
|
359
|
+
sharedObjectId: context.sharedObjectId,
|
|
356
360
|
});
|
|
357
361
|
const getChunk = (index: number): TreeChunk => {
|
|
358
362
|
assert(index < chunks.length, 0x898 /* out of bounds index for build chunk */);
|
package/src/packageVersion.ts
CHANGED
|
@@ -238,6 +238,8 @@ export function createIndependentTreeAlpha<const TSchema extends ImplicitFieldSc
|
|
|
238
238
|
idCompressor,
|
|
239
239
|
originatorId: idCompressor.localSessionId, // Is this right? If so, why is is needed?
|
|
240
240
|
schema: { schema: newSchema, policy: defaultSchemaPolicy },
|
|
241
|
+
// Not a summary blob — this is a synthetic decode of inline content.
|
|
242
|
+
isSummary: false,
|
|
241
243
|
};
|
|
242
244
|
const fieldCursors = fieldBatchCodec.decode(
|
|
243
245
|
options.content.tree as JsonCompatibleReadOnly,
|
|
@@ -246,6 +246,11 @@ export class SharedTreeKernel
|
|
|
246
246
|
encodeType: options.treeEncodeType,
|
|
247
247
|
originatorId: idCompressor.localSessionId,
|
|
248
248
|
idCompressor,
|
|
249
|
+
// ForestSummarizer is the only consumer of this context, and it
|
|
250
|
+
// only invokes the codec in summary encode / load paths.
|
|
251
|
+
isSummary: true,
|
|
252
|
+
healUnresolvableIdentifiersOnDecode: options.healUnresolvableIdentifiersOnDecode,
|
|
253
|
+
sharedObjectId: sharedObject.id,
|
|
249
254
|
};
|
|
250
255
|
const forestSummarizer = new ForestSummarizer(
|
|
251
256
|
forest,
|
|
@@ -570,7 +575,41 @@ export function getCodecTreeForSharedTreeFormat(
|
|
|
570
575
|
* Configuration options for SharedTree.
|
|
571
576
|
* @beta @input
|
|
572
577
|
*/
|
|
573
|
-
export
|
|
578
|
+
export interface SharedTreeOptionsBeta extends ForestOptions, Partial<CodecWriteOptionsBeta> {
|
|
579
|
+
/**
|
|
580
|
+
* When `true`, when an improperly encoded identifier is encountered in a summary,
|
|
581
|
+
* a new identifier will be generated instead of throwing an error.
|
|
582
|
+
*
|
|
583
|
+
* @defaultValue `false`
|
|
584
|
+
*
|
|
585
|
+
* @remarks
|
|
586
|
+
* The intended use is recovering documents whose attach summary was persisted
|
|
587
|
+
* with unresolvable node identifiers (a SharedTree-attaches-to-already-attached-container
|
|
588
|
+
* scenario). Without this flag enabled, a client opening such a document will throw at summary load time.
|
|
589
|
+
* With this flag enabled, unresolvable identifiers are replaced at decode time with stable UUIDs
|
|
590
|
+
* derived deterministically from the data store id and the unresolvable op-space integer,
|
|
591
|
+
* so every reader of the same blob (other than the originator) agrees on the resulting in-memory id.
|
|
592
|
+
* Healed identifiers are written back out at the next summary in their stable UUID form,
|
|
593
|
+
* so the inconsistency does not need to be re-healed on every load.
|
|
594
|
+
*
|
|
595
|
+
* Off by default because enabling it for documents that are not actually corrupt
|
|
596
|
+
* would mask genuine bugs that otherwise surface as decode failures.
|
|
597
|
+
*
|
|
598
|
+
* This mitigation is also not perfect as the client that originated the non-finalized
|
|
599
|
+
* will not apply the same "healing" and will continue to use the original identifier.
|
|
600
|
+
* The difference in identifiers between the originating client and subsequent clients that load
|
|
601
|
+
* the document is not ideal but generally benign to Fluid. However, it may have application-level
|
|
602
|
+
* consequences (e.g. if the application stores the identifiers elsewhere, either in other parts of
|
|
603
|
+
* Fluid data or externally). Applications should consider whether this risk is acceptable before
|
|
604
|
+
* enabling this option.
|
|
605
|
+
*
|
|
606
|
+
* @privateRemarks
|
|
607
|
+
* "Unresolvable" in the public-facing remarks corresponds to non-finalized short IDs persisted without
|
|
608
|
+
* any corresponding context for their originating session. See id-compressor internal documentation
|
|
609
|
+
* for more details.
|
|
610
|
+
*/
|
|
611
|
+
readonly healUnresolvableIdentifiersOnDecode?: boolean;
|
|
612
|
+
}
|
|
574
613
|
|
|
575
614
|
/**
|
|
576
615
|
* Configuration options for SharedTree with alpha features.
|
|
@@ -724,6 +763,7 @@ export const defaultSharedTreeOptions: Required<SharedTreeOptionsInternal> = {
|
|
|
724
763
|
disposeForksAfterTransaction: true,
|
|
725
764
|
shouldEncodeIncrementally: defaultIncrementalEncodingPolicy,
|
|
726
765
|
enableSharedBranches: false,
|
|
766
|
+
healUnresolvableIdentifiersOnDecode: false,
|
|
727
767
|
writeVersionOverrides: new Map(),
|
|
728
768
|
allowPossiblyIncompatibleWriteVersionOverrides: false,
|
|
729
769
|
};
|
|
@@ -954,6 +954,8 @@ export const TreeAlpha: TreeAlpha = {
|
|
|
954
954
|
idCompressor,
|
|
955
955
|
originatorId: idCompressor.localSessionId, // TODO: Why is this needed?
|
|
956
956
|
schema: { schema: storedSchema, policy: defaultSchemaPolicy },
|
|
957
|
+
// Not a summary blob — this is `TreeAlpha`'s ad-hoc encoder.
|
|
958
|
+
isSummary: false,
|
|
957
959
|
};
|
|
958
960
|
const result = codec.encode(batch, context);
|
|
959
961
|
// TODO: codecs should better track which ones can contain handles, and which cannot. When done properly, casts like this can be removed.
|
|
@@ -750,6 +750,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
750
750
|
idCompressor: this.idCompressor,
|
|
751
751
|
originatorId: this.idCompressor.localSessionId,
|
|
752
752
|
revision,
|
|
753
|
+
isSummary: false,
|
|
753
754
|
};
|
|
754
755
|
const encodedChange = this.changeFamily.codecs.resolve(4).encode(change, context);
|
|
755
756
|
|
|
@@ -820,6 +821,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
820
821
|
idCompressor: this.idCompressor,
|
|
821
822
|
originatorId: this.idCompressor.localSessionId,
|
|
822
823
|
revision,
|
|
824
|
+
isSummary: false,
|
|
823
825
|
};
|
|
824
826
|
const decodedChange = this.changeFamily.codecs.resolve(4).decode(change, context);
|
|
825
827
|
// Apply the change to the branch, but _not_ the `activeBranch` - we do not support squashing serialized commits in a transaction.
|
|
@@ -36,6 +36,9 @@ import { EditManagerFormatVersion } from "./editManagerFormatCommons.js";
|
|
|
36
36
|
export interface EditManagerEncodingContext {
|
|
37
37
|
idCompressor: IIdCompressor;
|
|
38
38
|
readonly schema?: SchemaAndPolicy;
|
|
39
|
+
readonly isSummary: boolean;
|
|
40
|
+
readonly healUnresolvableIdentifiersOnDecode?: boolean;
|
|
41
|
+
readonly sharedObjectId?: string;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/**
|
|
@@ -28,6 +28,20 @@ import type {
|
|
|
28
28
|
export interface EditManagerEncodingContext {
|
|
29
29
|
idCompressor: IIdCompressor;
|
|
30
30
|
readonly schema?: SchemaAndPolicy;
|
|
31
|
+
/**
|
|
32
|
+
* See {@link ChangeEncodingContext.isSummary}. EditManager codec callers
|
|
33
|
+
* always set this to `true` (the codec is only invoked for summaries),
|
|
34
|
+
* but it is carried explicitly so downstream codecs can read it.
|
|
35
|
+
*/
|
|
36
|
+
readonly isSummary: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* See {@link ChangeEncodingContext.healUnresolvableIdentifiersOnDecode}.
|
|
39
|
+
*/
|
|
40
|
+
readonly healUnresolvableIdentifiersOnDecode?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* See {@link ChangeEncodingContext.sharedObjectId}.
|
|
43
|
+
*/
|
|
44
|
+
readonly sharedObjectId?: string;
|
|
31
45
|
}
|
|
32
46
|
|
|
33
47
|
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
@@ -53,6 +67,7 @@ function encodeCommit<TChangeset, T extends Commit<TChangeset>>(
|
|
|
53
67
|
originatorId: commit.sessionId,
|
|
54
68
|
idCompressor: context.idCompressor,
|
|
55
69
|
revision: undefined,
|
|
70
|
+
isSummary: context.isSummary,
|
|
56
71
|
}),
|
|
57
72
|
change: changeCodec.encode(commit.change, { ...context, revision: commit.revision }),
|
|
58
73
|
};
|
|
@@ -79,6 +94,7 @@ function decodeCommit<TChangeset, T extends EncodedCommit<JsonCompatibleReadOnly
|
|
|
79
94
|
originatorId: commit.sessionId,
|
|
80
95
|
idCompressor: context.idCompressor,
|
|
81
96
|
revision: undefined,
|
|
97
|
+
isSummary: context.isSummary,
|
|
82
98
|
});
|
|
83
99
|
|
|
84
100
|
return {
|
|
@@ -112,6 +128,7 @@ export function encodeSharedBranch<TChangeset>(
|
|
|
112
128
|
idCompressor: context.idCompressor,
|
|
113
129
|
schema: context.schema,
|
|
114
130
|
revision: undefined,
|
|
131
|
+
isSummary: context.isSummary,
|
|
115
132
|
}),
|
|
116
133
|
),
|
|
117
134
|
peers: Array.from(data.peerLocalBranches.entries(), ([sessionId, branch]) => [
|
|
@@ -121,6 +138,7 @@ export function encodeSharedBranch<TChangeset>(
|
|
|
121
138
|
originatorId: sessionId,
|
|
122
139
|
idCompressor: context.idCompressor,
|
|
123
140
|
revision: undefined,
|
|
141
|
+
isSummary: context.isSummary,
|
|
124
142
|
}),
|
|
125
143
|
commits: branch.commits.map((commit) =>
|
|
126
144
|
encodeCommit(changeCodec, revisionTagCodec, commit, {
|
|
@@ -128,6 +146,7 @@ export function encodeSharedBranch<TChangeset>(
|
|
|
128
146
|
idCompressor: context.idCompressor,
|
|
129
147
|
schema: context.schema,
|
|
130
148
|
revision: undefined,
|
|
149
|
+
isSummary: context.isSummary,
|
|
131
150
|
}),
|
|
132
151
|
),
|
|
133
152
|
},
|
|
@@ -154,6 +173,7 @@ export function encodeSharedBranch<TChangeset>(
|
|
|
154
173
|
originatorId,
|
|
155
174
|
idCompressor: context.idCompressor,
|
|
156
175
|
revision: undefined,
|
|
176
|
+
isSummary: context.isSummary,
|
|
157
177
|
});
|
|
158
178
|
}
|
|
159
179
|
return json;
|
|
@@ -186,6 +206,9 @@ export function decodeSharedBranch<TChangeset>(
|
|
|
186
206
|
originatorId: commit.sessionId,
|
|
187
207
|
idCompressor: context.idCompressor,
|
|
188
208
|
revision: undefined,
|
|
209
|
+
isSummary: context.isSummary,
|
|
210
|
+
healUnresolvableIdentifiersOnDecode: context.healUnresolvableIdentifiersOnDecode,
|
|
211
|
+
sharedObjectId: context.sharedObjectId,
|
|
189
212
|
}),
|
|
190
213
|
),
|
|
191
214
|
peerLocalBranches: new Map(
|
|
@@ -196,6 +219,7 @@ export function decodeSharedBranch<TChangeset>(
|
|
|
196
219
|
originatorId: sessionId,
|
|
197
220
|
idCompressor: context.idCompressor,
|
|
198
221
|
revision: undefined,
|
|
222
|
+
isSummary: context.isSummary,
|
|
199
223
|
}),
|
|
200
224
|
commits: branch.commits.map((commit) =>
|
|
201
225
|
// TODO: sort out EncodedCommit vs Commit, and make this type check without `as`.
|
|
@@ -207,6 +231,10 @@ export function decodeSharedBranch<TChangeset>(
|
|
|
207
231
|
originatorId: commit.sessionId,
|
|
208
232
|
idCompressor: context.idCompressor,
|
|
209
233
|
revision: undefined,
|
|
234
|
+
isSummary: context.isSummary,
|
|
235
|
+
healUnresolvableIdentifiersOnDecode:
|
|
236
|
+
context.healUnresolvableIdentifiersOnDecode,
|
|
237
|
+
sharedObjectId: context.sharedObjectId,
|
|
210
238
|
},
|
|
211
239
|
),
|
|
212
240
|
),
|
|
@@ -239,6 +267,7 @@ export function decodeSharedBranch<TChangeset>(
|
|
|
239
267
|
originatorId,
|
|
240
268
|
idCompressor: context.idCompressor,
|
|
241
269
|
revision: undefined,
|
|
270
|
+
isSummary: context.isSummary,
|
|
242
271
|
});
|
|
243
272
|
}
|
|
244
273
|
return data;
|
|
@@ -25,6 +25,9 @@ import { EncodedEditManager } from "./editManagerFormatV1toV4.js";
|
|
|
25
25
|
export interface EditManagerEncodingContext {
|
|
26
26
|
idCompressor: IIdCompressor;
|
|
27
27
|
readonly schema?: SchemaAndPolicy;
|
|
28
|
+
readonly isSummary: boolean;
|
|
29
|
+
readonly healUnresolvableIdentifiersOnDecode?: boolean;
|
|
30
|
+
readonly sharedObjectId?: string;
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
/**
|
|
@@ -29,6 +29,9 @@ import { EncodedEditManager } from "./editManagerFormatVSharedBranches.js";
|
|
|
29
29
|
export interface EditManagerEncodingContext {
|
|
30
30
|
idCompressor: IIdCompressor;
|
|
31
31
|
readonly schema?: SchemaAndPolicy;
|
|
32
|
+
readonly isSummary: boolean;
|
|
33
|
+
readonly healUnresolvableIdentifiersOnDecode?: boolean;
|
|
34
|
+
readonly sharedObjectId?: string;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
export function makeSharedBranchesCodecWithVersion<TChangeset>(
|
|
@@ -85,6 +85,10 @@ export class EditManagerSummarizer<TChangeset>
|
|
|
85
85
|
private readonly idCompressor: IIdCompressor,
|
|
86
86
|
minVersionForCollab: MinimumVersionForCollab,
|
|
87
87
|
private readonly schemaAndPolicy?: SchemaAndPolicy,
|
|
88
|
+
/** See {@link EditManagerEncodingContext.healUnresolvableIdentifiersOnDecode}. */
|
|
89
|
+
private readonly healUnresolvableIdentifiersOnDecode?: boolean,
|
|
90
|
+
/** See {@link EditManagerEncodingContext.sharedObjectId}. */
|
|
91
|
+
private readonly sharedObjectId?: string,
|
|
88
92
|
) {
|
|
89
93
|
super(
|
|
90
94
|
EditManagerSummarizer.key,
|
|
@@ -103,10 +107,13 @@ export class EditManagerSummarizer<TChangeset>
|
|
|
103
107
|
builder: SummaryTreeBuilder;
|
|
104
108
|
}): void {
|
|
105
109
|
const { stringify, builder } = props;
|
|
106
|
-
const context: EditManagerEncodingContext =
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
const context: EditManagerEncodingContext = {
|
|
111
|
+
idCompressor: this.idCompressor,
|
|
112
|
+
schema: this.schemaAndPolicy,
|
|
113
|
+
isSummary: true,
|
|
114
|
+
healUnresolvableIdentifiersOnDecode: this.healUnresolvableIdentifiersOnDecode,
|
|
115
|
+
sharedObjectId: this.sharedObjectId,
|
|
116
|
+
};
|
|
110
117
|
const jsonCompatible = this.codec.encode(this.editManager.getSummaryData(), context);
|
|
111
118
|
const dataString = stringify(jsonCompatible);
|
|
112
119
|
builder.addBlob(stringKey, dataString);
|
|
@@ -127,7 +134,12 @@ export class EditManagerSummarizer<TChangeset>
|
|
|
127
134
|
);
|
|
128
135
|
|
|
129
136
|
const summary = parse(bufferToString(schemaBuffer, "utf8")) as JsonCompatibleReadOnly;
|
|
130
|
-
const data = this.codec.decode(summary, {
|
|
137
|
+
const data = this.codec.decode(summary, {
|
|
138
|
+
idCompressor: this.idCompressor,
|
|
139
|
+
isSummary: true,
|
|
140
|
+
healUnresolvableIdentifiersOnDecode: this.healUnresolvableIdentifiersOnDecode,
|
|
141
|
+
sharedObjectId: this.sharedObjectId,
|
|
142
|
+
});
|
|
131
143
|
this.editManager.loadSummaryData(data);
|
|
132
144
|
}
|
|
133
145
|
}
|
|
@@ -55,6 +55,7 @@ export function makeV1ToV4CodecWithVersion<TChangeset>(
|
|
|
55
55
|
originatorId,
|
|
56
56
|
idCompressor: context.idCompressor,
|
|
57
57
|
revision: undefined,
|
|
58
|
+
isSummary: false,
|
|
58
59
|
}),
|
|
59
60
|
originatorId,
|
|
60
61
|
changeset: changeCodec.encode(commit.change, {
|
|
@@ -62,6 +63,7 @@ export function makeV1ToV4CodecWithVersion<TChangeset>(
|
|
|
62
63
|
schema: context.schema,
|
|
63
64
|
idCompressor: context.idCompressor,
|
|
64
65
|
revision: commit.revision,
|
|
66
|
+
isSummary: false,
|
|
65
67
|
}),
|
|
66
68
|
version,
|
|
67
69
|
};
|
|
@@ -76,6 +78,7 @@ export function makeV1ToV4CodecWithVersion<TChangeset>(
|
|
|
76
78
|
originatorId,
|
|
77
79
|
revision: undefined,
|
|
78
80
|
idCompressor: context.idCompressor,
|
|
81
|
+
isSummary: false,
|
|
79
82
|
});
|
|
80
83
|
|
|
81
84
|
return {
|
|
@@ -87,6 +90,7 @@ export function makeV1ToV4CodecWithVersion<TChangeset>(
|
|
|
87
90
|
originatorId,
|
|
88
91
|
revision,
|
|
89
92
|
idCompressor: context.idCompressor,
|
|
93
|
+
isSummary: false,
|
|
90
94
|
}),
|
|
91
95
|
},
|
|
92
96
|
sessionId: originatorId,
|