@fluidframework/tree 2.116.0-416006 → 2.116.1
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 +84 -0
- package/README.md +5 -3
- package/api-report/tree.alpha.api.md +4 -2
- package/api-report/tree.beta.api.md +1 -1
- package/api-report/tree.legacy.beta.api.md +1 -1
- package/dist/codec/codec.d.ts +6 -6
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +3 -3
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/versioned/codec.d.ts +3 -3
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/core/forest/editableForest.d.ts +2 -0
- package/dist/core/forest/editableForest.d.ts.map +1 -1
- package/dist/core/forest/editableForest.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/tree/index.d.ts +1 -1
- package/dist/core/tree/index.d.ts.map +1 -1
- package/dist/core/tree/index.js +2 -2
- package/dist/core/tree/index.js.map +1 -1
- package/dist/core/tree/visitorUtils.d.ts +24 -3
- package/dist/core/tree/visitorUtils.d.ts.map +1 -1
- package/dist/core/tree/visitorUtils.js +24 -6
- package/dist/core/tree/visitorUtils.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +30 -6
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +146 -54
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/comparison-forest/comparisonForest.d.ts +2 -1
- package/dist/feature-libraries/comparison-forest/comparisonForest.d.ts.map +1 -1
- package/dist/feature-libraries/comparison-forest/comparisonForest.js +87 -70
- package/dist/feature-libraries/comparison-forest/comparisonForest.js.map +1 -1
- package/dist/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +5 -0
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +127 -107
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts +2 -2
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/summaryTypes.js.map +1 -1
- package/dist/feature-libraries/indexing/anchorTreeIndex.js +1 -1
- package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
- package/dist/feature-libraries/modular-schema/invert.js +1 -1
- package/dist/feature-libraries/modular-schema/invert.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +2 -11
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeUtils.d.ts +11 -16
- package/dist/feature-libraries/modular-schema/modularChangeUtils.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeUtils.js +10 -3
- package/dist/feature-libraries/modular-schema/modularChangeUtils.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +34 -13
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts +2 -2
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.js +1 -1
- package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +1 -1
- package/dist/feature-libraries/sequence-field/utils.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 -4
- package/dist/shared-tree/independentView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +30 -5
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +8 -8
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +2 -2
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.d.ts +25 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.js +24 -0
- package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +21 -10
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +56 -24
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branchCommitEnricher.d.ts +2 -1
- package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
- package/dist/shared-tree-core/branchCommitEnricher.js +3 -2
- package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
- package/dist/shared-tree-core/changeEnricher.d.ts +3 -2
- package/dist/shared-tree-core/changeEnricher.d.ts.map +1 -1
- package/dist/shared-tree-core/changeEnricher.js.map +1 -1
- package/dist/shared-tree-core/defaultResubmitMachine.d.ts +9 -1
- package/dist/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
- package/dist/shared-tree-core/defaultResubmitMachine.js +7 -2
- package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
- package/dist/shared-tree-core/editManager.d.ts.map +1 -1
- package/dist/shared-tree-core/editManager.js +2 -2
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.d.ts +2 -2
- 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/editManagerSummarizer.d.ts +2 -2
- package/dist/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/dist/shared-tree-core/messageCodecs.d.ts +2 -2
- package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecs.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts +11 -2
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +11 -8
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/shared-tree-core/summaryTypes.d.ts +2 -2
- package/dist/shared-tree-core/summaryTypes.d.ts.map +1 -1
- package/dist/shared-tree-core/summaryTypes.js.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/dist/simple-tree/api/storedSchema.d.ts +2 -2
- package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/storedSchema.js.map +1 -1
- package/dist/simple-tree/api/treeChangeEvents.d.ts +5 -1
- package/dist/simple-tree/api/treeChangeEvents.d.ts.map +1 -1
- package/dist/simple-tree/api/treeChangeEvents.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +10 -0
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNode.js +19 -2
- package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/dist/tableSchema.d.ts +1 -1
- package/dist/tableSchema.js +1 -1
- package/dist/tableSchema.js.map +1 -1
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +1 -1
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/breakable.d.ts +14 -2
- package/dist/util/breakable.d.ts.map +1 -1
- package/dist/util/breakable.js +9 -1
- package/dist/util/breakable.js.map +1 -1
- package/dist/util/compressedIds.d.ts +2 -2
- package/dist/util/compressedIds.d.ts.map +1 -1
- package/dist/util/compressedIds.js +1 -6
- package/dist/util/compressedIds.js.map +1 -1
- package/lib/codec/codec.d.ts +6 -6
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +3 -3
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/versioned/codec.d.ts +3 -3
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/core/forest/editableForest.d.ts +2 -0
- package/lib/core/forest/editableForest.d.ts.map +1 -1
- package/lib/core/forest/editableForest.js.map +1 -1
- package/lib/core/index.d.ts +1 -1
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +1 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/tree/index.d.ts +1 -1
- package/lib/core/tree/index.d.ts.map +1 -1
- package/lib/core/tree/index.js +1 -1
- package/lib/core/tree/index.js.map +1 -1
- package/lib/core/tree/visitorUtils.d.ts +24 -3
- package/lib/core/tree/visitorUtils.d.ts.map +1 -1
- package/lib/core/tree/visitorUtils.js +22 -4
- package/lib/core/tree/visitorUtils.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +30 -6
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +146 -56
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/comparison-forest/comparisonForest.d.ts +2 -1
- package/lib/feature-libraries/comparison-forest/comparisonForest.d.ts.map +1 -1
- package/lib/feature-libraries/comparison-forest/comparisonForest.js +88 -70
- package/lib/feature-libraries/comparison-forest/comparisonForest.js.map +1 -1
- package/lib/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +5 -0
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +129 -108
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts +2 -2
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/summaryTypes.js.map +1 -1
- package/lib/feature-libraries/indexing/anchorTreeIndex.js +1 -1
- package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
- package/lib/feature-libraries/modular-schema/invert.js +2 -2
- package/lib/feature-libraries/modular-schema/invert.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +2 -11
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeUtils.d.ts +11 -16
- package/lib/feature-libraries/modular-schema/modularChangeUtils.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeUtils.js +10 -3
- package/lib/feature-libraries/modular-schema/modularChangeUtils.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +35 -14
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts +2 -2
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.js +2 -2
- package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +1 -1
- package/lib/feature-libraries/sequence-field/utils.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 +3 -5
- package/lib/shared-tree/independentView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +30 -5
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +8 -8
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +2 -2
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.d.ts +25 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.js +24 -0
- package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +21 -10
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +56 -24
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branchCommitEnricher.d.ts +2 -1
- package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
- package/lib/shared-tree-core/branchCommitEnricher.js +3 -2
- package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
- package/lib/shared-tree-core/changeEnricher.d.ts +3 -2
- package/lib/shared-tree-core/changeEnricher.d.ts.map +1 -1
- package/lib/shared-tree-core/changeEnricher.js.map +1 -1
- package/lib/shared-tree-core/defaultResubmitMachine.d.ts +9 -1
- package/lib/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
- package/lib/shared-tree-core/defaultResubmitMachine.js +7 -2
- package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
- package/lib/shared-tree-core/editManager.d.ts.map +1 -1
- package/lib/shared-tree-core/editManager.js +2 -2
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.d.ts +2 -2
- 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/editManagerSummarizer.d.ts +2 -2
- package/lib/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/lib/shared-tree-core/messageCodecs.d.ts +2 -2
- package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecs.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts +11 -2
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +11 -8
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/shared-tree-core/summaryTypes.d.ts +2 -2
- package/lib/shared-tree-core/summaryTypes.d.ts.map +1 -1
- package/lib/shared-tree-core/summaryTypes.js.map +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/lib/simple-tree/api/storedSchema.d.ts +2 -2
- package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/storedSchema.js.map +1 -1
- package/lib/simple-tree/api/treeChangeEvents.d.ts +5 -1
- package/lib/simple-tree/api/treeChangeEvents.d.ts.map +1 -1
- package/lib/simple-tree/api/treeChangeEvents.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +10 -0
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNode.js +19 -2
- package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/lib/tableSchema.d.ts +1 -1
- package/lib/tableSchema.js +1 -1
- package/lib/tableSchema.js.map +1 -1
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +1 -1
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/breakable.d.ts +14 -2
- package/lib/util/breakable.d.ts.map +1 -1
- package/lib/util/breakable.js +9 -1
- package/lib/util/breakable.js.map +1 -1
- package/lib/util/compressedIds.d.ts +2 -2
- package/lib/util/compressedIds.d.ts.map +1 -1
- package/lib/util/compressedIds.js +1 -6
- package/lib/util/compressedIds.js.map +1 -1
- package/package.json +27 -27
- package/src/codec/codec.ts +7 -7
- package/src/codec/versioned/codec.ts +5 -5
- package/src/core/forest/editableForest.ts +2 -0
- package/src/core/index.ts +1 -1
- package/src/core/tree/index.ts +1 -1
- package/src/core/tree/visitorUtils.ts +37 -12
- package/src/feature-libraries/chunked-forest/chunkedForest.ts +214 -59
- package/src/feature-libraries/comparison-forest/comparisonForest.ts +6 -1
- package/src/feature-libraries/detachedFieldIndexSummarizer.ts +2 -2
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +10 -0
- package/src/feature-libraries/forest-summary/summaryTypes.ts +2 -2
- package/src/feature-libraries/indexing/anchorTreeIndex.ts +1 -1
- package/src/feature-libraries/modular-schema/invert.ts +2 -2
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +2 -23
- package/src/feature-libraries/modular-schema/modularChangeUtils.ts +12 -21
- package/src/feature-libraries/object-forest/objectForest.ts +48 -14
- package/src/feature-libraries/schema-index/schemaSummarizer.ts +3 -3
- package/src/feature-libraries/sequence-field/rebase.ts +2 -2
- package/src/feature-libraries/sequence-field/utils.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/independentView.ts +5 -12
- package/src/shared-tree/sharedTree.ts +41 -10
- package/src/shared-tree/sharedTreeChangeCodecs.ts +2 -2
- package/src/shared-tree/sharedTreeChangeEnricher.ts +25 -1
- package/src/shared-tree/treeCheckout.ts +53 -24
- package/src/shared-tree-core/branchCommitEnricher.ts +6 -2
- package/src/shared-tree-core/changeEnricher.ts +7 -2
- package/src/shared-tree-core/defaultResubmitMachine.ts +5 -0
- package/src/shared-tree-core/editManager.ts +2 -4
- package/src/shared-tree-core/editManagerCodecs.ts +2 -2
- package/src/shared-tree-core/editManagerSummarizer.ts +3 -3
- package/src/shared-tree-core/messageCodecs.ts +2 -2
- package/src/shared-tree-core/sharedTreeCore.ts +29 -11
- package/src/shared-tree-core/summaryTypes.ts +2 -2
- package/src/simple-tree/api/snapshotCompatibilityChecker.ts +1 -1
- package/src/simple-tree/api/storedSchema.ts +2 -2
- package/src/simple-tree/api/treeChangeEvents.ts +5 -1
- package/src/simple-tree/node-kinds/array/arrayNode.ts +15 -0
- package/src/simple-tree/node-kinds/map/mapNode.ts +23 -2
- package/src/tableSchema.ts +1 -1
- package/src/treeFactory.ts +0 -1
- package/src/util/breakable.ts +9 -1
- package/src/util/compressedIds.ts +7 -13
|
@@ -334,14 +334,11 @@ export function createTreeCheckout(
|
|
|
334
334
|
fieldBatchCodec?: FieldBatchCodec;
|
|
335
335
|
removedRoots?: DetachedFieldIndex;
|
|
336
336
|
chunkCompressionStrategy?: TreeCompressionStrategy;
|
|
337
|
-
logger?: TelemetryLoggerExt;
|
|
338
|
-
breaker?: Breakable;
|
|
339
337
|
codecOptions?: Partial<CodecWriteOptions>;
|
|
340
338
|
},
|
|
341
339
|
): TreeCheckout {
|
|
342
|
-
const breaker = args?.breaker ?? new Breakable("TreeCheckout", args?.logger);
|
|
343
340
|
const schema = args?.schema ?? new TreeStoredSchemaRepository();
|
|
344
|
-
const forest = args?.forest ?? buildForest(
|
|
341
|
+
const forest = args?.forest ?? buildForest(new Breakable("TreeCheckout"), schema);
|
|
345
342
|
const defaultCodecOptions: CodecWriteOptions = {
|
|
346
343
|
jsonValidator: FormatValidatorNoOp,
|
|
347
344
|
minVersionForCollab: FluidClientVersion.v2_0,
|
|
@@ -380,8 +377,6 @@ export function createTreeCheckout(
|
|
|
380
377
|
revisionTagCodec,
|
|
381
378
|
idCompressor,
|
|
382
379
|
args?.removedRoots,
|
|
383
|
-
args?.logger,
|
|
384
|
-
breaker,
|
|
385
380
|
);
|
|
386
381
|
}
|
|
387
382
|
|
|
@@ -489,6 +484,31 @@ export function assertValidConstraint(
|
|
|
489
484
|
export class TreeCheckout implements ITreeCheckout {
|
|
490
485
|
public disposed = false;
|
|
491
486
|
|
|
487
|
+
/**
|
|
488
|
+
* Logger for telemetry events related to this checkout.
|
|
489
|
+
* @remarks
|
|
490
|
+
* This logger is provided by the {@link Breakable} passed to the constructor, and may be `undefined` if no logger was provided.
|
|
491
|
+
* See the explanation on {@link Breakable.logger} for why this pattern makes sense.
|
|
492
|
+
*/
|
|
493
|
+
private get logger(): TelemetryLoggerExt | undefined {
|
|
494
|
+
return this.breaker.logger;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* The breaker for this checkout.
|
|
499
|
+
* @remarks
|
|
500
|
+
* As the forest is part of the mutable state of the checkout,
|
|
501
|
+
* we want to be broken if it is broken, so we use the forest's breaker as our own.
|
|
502
|
+
*
|
|
503
|
+
* This does mean that if something goes wrong in the checkout, we break the forest,
|
|
504
|
+
* which is not strictly necessary, but may be desirable as if something is wrong with the checkout,
|
|
505
|
+
* while the forest might be internally consistent, it likely doesn't contain the correct content
|
|
506
|
+
* (since the checkout is keeping it up to date properly anymore).
|
|
507
|
+
*/
|
|
508
|
+
public get breaker(): Breakable {
|
|
509
|
+
return this.forest.breaker;
|
|
510
|
+
}
|
|
511
|
+
|
|
492
512
|
private editLock: EditLock;
|
|
493
513
|
|
|
494
514
|
/**
|
|
@@ -566,9 +586,6 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
566
586
|
private readonly revisionTagCodec: RevisionTagCodec,
|
|
567
587
|
private readonly idCompressor: IIdCompressor,
|
|
568
588
|
private readonly _removedRoots: DetachedFieldIndex = makeDetachedFieldIndex("repair"),
|
|
569
|
-
/** Optional logger for telemetry. */
|
|
570
|
-
private readonly logger?: TelemetryLoggerExt,
|
|
571
|
-
public readonly breaker: Breakable = new Breakable("TreeCheckout", logger),
|
|
572
589
|
public readonly disposeForksAfterTransaction = true,
|
|
573
590
|
) {
|
|
574
591
|
this.#transaction = this.createTransactionStack(branch);
|
|
@@ -833,7 +850,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
833
850
|
);
|
|
834
851
|
this.revertibleCommitBranches.set(
|
|
835
852
|
revision,
|
|
836
|
-
this.#transaction.
|
|
853
|
+
this.#transaction.branch.fork(commit),
|
|
837
854
|
);
|
|
838
855
|
this.revertibles.set(revision, revertible);
|
|
839
856
|
return revertible;
|
|
@@ -1119,6 +1136,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1119
1136
|
});
|
|
1120
1137
|
};
|
|
1121
1138
|
|
|
1139
|
+
@breakingMethod
|
|
1122
1140
|
private withCombinedVisitor(fn: (visitor: DeltaVisitor) => void): void {
|
|
1123
1141
|
const anchorVisitor = this.forest.anchors.acquireVisitor();
|
|
1124
1142
|
const combinedVisitor = combineVisitors([this.forest.acquireVisitor(), anchorVisitor]);
|
|
@@ -1132,7 +1150,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1132
1150
|
if (usageError !== undefined) {
|
|
1133
1151
|
throw new UsageError(usageError);
|
|
1134
1152
|
}
|
|
1135
|
-
|
|
1153
|
+
fail(0x911 /* Invalid operation on a disposed TreeCheckout */);
|
|
1136
1154
|
}
|
|
1137
1155
|
}
|
|
1138
1156
|
|
|
@@ -1189,9 +1207,9 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1189
1207
|
}
|
|
1190
1208
|
|
|
1191
1209
|
const commitToRevert = revertibleBranch.getHead();
|
|
1192
|
-
const
|
|
1210
|
+
const branchHead = targetCheckout.#transaction.branch.getHead();
|
|
1193
1211
|
|
|
1194
|
-
if (isAncestor(commitToRevert,
|
|
1212
|
+
if (isAncestor(commitToRevert, branchHead, true) === false) {
|
|
1195
1213
|
throw new UsageError(
|
|
1196
1214
|
"Cannot clone revertible for a commit that is not present on the given branch.",
|
|
1197
1215
|
);
|
|
@@ -1290,7 +1308,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1290
1308
|
throw new UsageError("A view cannot be forked while it has a pending transaction.");
|
|
1291
1309
|
}
|
|
1292
1310
|
|
|
1293
|
-
const branch = this.#transaction.
|
|
1311
|
+
const branch = this.#transaction.branch.fork();
|
|
1294
1312
|
const storedSchema = this.storedSchema.clone();
|
|
1295
1313
|
const forkBreaker = new Breakable("TreeCheckout", this.logger);
|
|
1296
1314
|
const forest = this.forest.clone(storedSchema, forkBreaker);
|
|
@@ -1304,8 +1322,6 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1304
1322
|
this.revisionTagCodec,
|
|
1305
1323
|
this.idCompressor,
|
|
1306
1324
|
this._removedRoots.clone(),
|
|
1307
|
-
this.logger,
|
|
1308
|
-
forkBreaker,
|
|
1309
1325
|
);
|
|
1310
1326
|
this.#events.emit("fork", checkout);
|
|
1311
1327
|
return checkout;
|
|
@@ -1365,7 +1381,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1365
1381
|
0xa5d /* Shared branches cannot be rebased onto another branch. */,
|
|
1366
1382
|
);
|
|
1367
1383
|
|
|
1368
|
-
checkout.#transaction.
|
|
1384
|
+
checkout.#transaction.branch.rebaseOnto(this.#transaction.branch);
|
|
1369
1385
|
}
|
|
1370
1386
|
|
|
1371
1387
|
public rebaseOnto(branch: TreeBranch): void {
|
|
@@ -1430,7 +1446,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1430
1446
|
"Views with an open transaction cannot be merged into another view.",
|
|
1431
1447
|
);
|
|
1432
1448
|
}
|
|
1433
|
-
this.#transaction.
|
|
1449
|
+
this.#transaction.branch.merge(checkout.#transaction.branch);
|
|
1434
1450
|
if (disposeMerged && !checkout.isSharedBranch) {
|
|
1435
1451
|
// Dispose the merged checkout unless it is a shared branch.
|
|
1436
1452
|
checkout[disposeSymbol]();
|
|
@@ -1529,7 +1545,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1529
1545
|
revisionForInvert,
|
|
1530
1546
|
);
|
|
1531
1547
|
|
|
1532
|
-
const headCommit = this.#transaction.
|
|
1548
|
+
const headCommit = this.#transaction.branch.getHead();
|
|
1533
1549
|
// Rebase the inverted change onto any commits that occurred after the undoable commits.
|
|
1534
1550
|
if (commitToRevert !== headCommit) {
|
|
1535
1551
|
// The inverse may be rebased over newer commits which (despite being present in the history)
|
|
@@ -1562,7 +1578,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1562
1578
|
const previousLabelTreeNode = this.labelTreeNode;
|
|
1563
1579
|
this.labelTreeNode = labelTree;
|
|
1564
1580
|
try {
|
|
1565
|
-
this.#transaction.
|
|
1581
|
+
this.#transaction.branch.apply(
|
|
1566
1582
|
change,
|
|
1567
1583
|
kind === CommitKind.Default || kind === CommitKind.Redo
|
|
1568
1584
|
? CommitKind.Undo
|
|
@@ -1704,6 +1720,7 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1704
1720
|
public enrich(
|
|
1705
1721
|
context: GraphCommit<SharedTreeChange>,
|
|
1706
1722
|
changes: readonly TaggedChange<SharedTreeChange>[],
|
|
1723
|
+
forceValidation: boolean,
|
|
1707
1724
|
): SharedTreeChange[] {
|
|
1708
1725
|
if (!hasSome(changes)) {
|
|
1709
1726
|
return [];
|
|
@@ -1734,13 +1751,25 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1734
1751
|
return makeAnonChange(diff);
|
|
1735
1752
|
});
|
|
1736
1753
|
}
|
|
1737
|
-
const
|
|
1754
|
+
const enrichedChanges: SharedTreeChange[] = [];
|
|
1738
1755
|
for (const change of changes) {
|
|
1739
|
-
|
|
1740
|
-
|
|
1756
|
+
const enrichedChange = enricher.enrich(change.change);
|
|
1757
|
+
enrichedChanges.push(enrichedChange);
|
|
1758
|
+
// We could either apply the original or the enriched change: either should allow subsequent changes to be enriched correctly.
|
|
1759
|
+
// We choose to apply the enriched change in order to more closely replicate what a peer will experience (assuming no concurrent changes).
|
|
1760
|
+
// This makes it more likely that we'll detect a bug in the enrichment logic.
|
|
1761
|
+
// Note that enqueueing the change does not guarantee that it will be applied unless `forceValidation` is enabled.
|
|
1762
|
+
enricher.enqueueChange(tagChange(enrichedChange, change.revision));
|
|
1763
|
+
}
|
|
1764
|
+
if (forceValidation) {
|
|
1765
|
+
// Ensure that all changes can be applied successfully.
|
|
1766
|
+
// This is useful for catching bugs in the enrichment logic and in the rebasing logic that may have been involved in producing the changes.
|
|
1767
|
+
// Note that we cannot guarantee that the enriched change will be applied successfully even in the absence of concurrent changes,
|
|
1768
|
+
// because the checkout state we are applying this enriched change to was derived from the state of the checkout, which may be different from that of a peer.
|
|
1769
|
+
enricher.purgeChangeQueue();
|
|
1741
1770
|
}
|
|
1742
1771
|
enricher[disposeSymbol]();
|
|
1743
|
-
return
|
|
1772
|
+
return enrichedChanges;
|
|
1744
1773
|
}
|
|
1745
1774
|
|
|
1746
1775
|
public get mainBranch(): SharedTreeBranch<
|
|
@@ -28,12 +28,16 @@ export class BranchCommitEnricher<TChange> {
|
|
|
28
28
|
/**
|
|
29
29
|
* Process the given commits for later {@link BranchCommitEnricher.retrieveChange | retrieval}.
|
|
30
30
|
* @param commits - The commits to prepare.
|
|
31
|
+
* @param forceValidation - Attempt to {@link SharedTreeOptions.validateCommitsOnFirstSubmission|validate} commits before submission in order to fail (throw) locally rather than risk corrupting persisted data.
|
|
31
32
|
*/
|
|
32
|
-
public prepareChanges(
|
|
33
|
+
public prepareChanges(
|
|
34
|
+
commits: readonly GraphCommit<TChange>[],
|
|
35
|
+
forceValidation: boolean,
|
|
36
|
+
): void {
|
|
33
37
|
if (hasSome(commits)) {
|
|
34
38
|
const startingState = commits[0].parent;
|
|
35
39
|
assert(startingState !== undefined, 0xcc1 /* New commits must have a parent. */);
|
|
36
|
-
const enrichedCommits = this.enricher.enrich(startingState, commits);
|
|
40
|
+
const enrichedCommits = this.enricher.enrich(startingState, commits, forceValidation);
|
|
37
41
|
for (const [index, commit] of commits.entries()) {
|
|
38
42
|
const enrichedCommit = enrichedCommits[index];
|
|
39
43
|
assert(enrichedCommit !== undefined, 0xcc2 /* Missing enriched commit. */);
|
|
@@ -13,7 +13,12 @@ export interface ChangeEnricher<TChange> {
|
|
|
13
13
|
* Runs a batch of change enrichments.
|
|
14
14
|
* @param context - The branch head after which the `changes` would apply.
|
|
15
15
|
* @param changes - The changes to be enriched.
|
|
16
|
-
* @
|
|
16
|
+
* @param forceValidation - Attempt to validate enriched changes before submission in order to fail (throw) locally rather than risk corrupting persisted data.
|
|
17
|
+
* See {@link SharedTreeOptions.validateCommitsOnFirstSubmission} and {@link SharedTreeOptions.validateRebasedCommitsBeforeResubmission}.
|
|
17
18
|
*/
|
|
18
|
-
enrich(
|
|
19
|
+
enrich(
|
|
20
|
+
context: GraphCommit<TChange>,
|
|
21
|
+
changes: readonly TaggedChange<TChange>[],
|
|
22
|
+
forceValidation: boolean,
|
|
23
|
+
): TChange[];
|
|
19
24
|
}
|
|
@@ -37,6 +37,10 @@ export class DefaultResubmitMachine<TChange> implements ResubmitMachine<TChange>
|
|
|
37
37
|
* commits are applied and automatically rebased).
|
|
38
38
|
*/
|
|
39
39
|
private readonly enricher: ChangeEnricher<TChange>,
|
|
40
|
+
/**
|
|
41
|
+
* Attempt to {@link SharedTreeOptions.validateRebasedCommitsBeforeResubmission|validate} commits before resubmission in order to fail (throw) locally rather than risk corrupting persisted data.
|
|
42
|
+
*/
|
|
43
|
+
private readonly forceValidation: boolean,
|
|
40
44
|
) {}
|
|
41
45
|
|
|
42
46
|
public onCommitSubmitted(commit: GraphCommit<TChange>): void {
|
|
@@ -95,6 +99,7 @@ export class DefaultResubmitMachine<TChange> implements ResubmitMachine<TChange>
|
|
|
95
99
|
const enriched = this.enricher.enrich(
|
|
96
100
|
startingState,
|
|
97
101
|
newCommits.slice(0, staleChanges.length),
|
|
102
|
+
this.forceValidation,
|
|
98
103
|
);
|
|
99
104
|
for (const [index, { pending, newCommit }] of staleChanges.entries()) {
|
|
100
105
|
const enrichedChange = enriched[index];
|
|
@@ -351,8 +351,7 @@ export class EditManager<
|
|
|
351
351
|
// Only the last trimmed commit, which is the new trunk base, should remain accessible.
|
|
352
352
|
for (const commit of trimmedCommits.slice(0, -1)) {
|
|
353
353
|
Reflect.defineProperty(commit, "change", {
|
|
354
|
-
get: () =>
|
|
355
|
-
assert(false, 0xa5e /* Should not access 'change' property of an evicted commit */),
|
|
354
|
+
get: () => fail(0xa5e /* Should not access 'change' property of an evicted commit */),
|
|
356
355
|
});
|
|
357
356
|
Reflect.defineProperty(commit, "revision", {
|
|
358
357
|
get: () =>
|
|
@@ -362,8 +361,7 @@ export class EditManager<
|
|
|
362
361
|
),
|
|
363
362
|
});
|
|
364
363
|
Reflect.defineProperty(commit, "parent", {
|
|
365
|
-
get: () =>
|
|
366
|
-
assert(false, 0xa60 /* Should not access 'parent' property of an evicted commit */),
|
|
364
|
+
get: () => fail(0xa60 /* Should not access 'parent' property of an evicted commit */),
|
|
367
365
|
});
|
|
368
366
|
}
|
|
369
367
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { OldestSupportedClientVersion } from "@fluidframework/runtime-definitions/internal";
|
|
7
7
|
import { lowestMinVersionForCollab } from "@fluidframework/runtime-utils/internal";
|
|
8
8
|
|
|
9
9
|
import {
|
|
@@ -132,7 +132,7 @@ export function makeEditManagerCodecBuilder<TChangeset>(): VersionDispatchingCod
|
|
|
132
132
|
* with the provided change codec tree as a child.
|
|
133
133
|
*/
|
|
134
134
|
export function getCodecTreeForEditManagerFormatWithChange(
|
|
135
|
-
clientVersion:
|
|
135
|
+
clientVersion: OldestSupportedClientVersion,
|
|
136
136
|
changeFormat: CodecTree,
|
|
137
137
|
): CodecTree {
|
|
138
138
|
const builder = makeEditManagerCodecBuilder();
|
|
@@ -10,7 +10,7 @@ import type { IIdCompressor } from "@fluidframework/id-compressor";
|
|
|
10
10
|
import type {
|
|
11
11
|
IExperimentalIncrementalSummaryContext,
|
|
12
12
|
ITelemetryContext,
|
|
13
|
-
|
|
13
|
+
OldestSupportedClientVersion,
|
|
14
14
|
} from "@fluidframework/runtime-definitions/internal";
|
|
15
15
|
import type { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
|
|
16
16
|
|
|
@@ -59,7 +59,7 @@ const supportedVersions = new Set<EditManagerSummaryFormatVersion>([
|
|
|
59
59
|
* Returns the summary version to use as per the given minimum version for collab.
|
|
60
60
|
*/
|
|
61
61
|
function minVersionToEditManagerSummaryFormatVersion(
|
|
62
|
-
version:
|
|
62
|
+
version: OldestSupportedClientVersion,
|
|
63
63
|
): EditManagerSummaryFormatVersion {
|
|
64
64
|
// Currently, version 2 is written which adds metadata blob to the summary.
|
|
65
65
|
return EditManagerSummaryFormatVersion.v2;
|
|
@@ -87,7 +87,7 @@ export class EditManagerSummarizer<TChangeset, TChangeProcessingContext>
|
|
|
87
87
|
EditManagerDecodingContext
|
|
88
88
|
>,
|
|
89
89
|
private readonly idCompressor: IIdCompressor,
|
|
90
|
-
minVersionForCollab:
|
|
90
|
+
minVersionForCollab: OldestSupportedClientVersion,
|
|
91
91
|
private readonly schemaAndPolicy?: SchemaAndPolicy,
|
|
92
92
|
/** See {@link IdentifierHealingConfig}. */
|
|
93
93
|
private readonly healing?: IdentifierHealingConfig,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { IIdCompressor } from "@fluidframework/id-compressor";
|
|
7
|
-
import type {
|
|
7
|
+
import type { OldestSupportedClientVersion } from "@fluidframework/runtime-definitions/internal";
|
|
8
8
|
import { lowestMinVersionForCollab } from "@fluidframework/runtime-utils/internal";
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -143,7 +143,7 @@ export function makeMessageCodecBuilder<TChangeset>(): VersionDispatchingCodecBu
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
export function getCodecTreeForMessageFormatWithChange(
|
|
146
|
-
clientVersion:
|
|
146
|
+
clientVersion: OldestSupportedClientVersion,
|
|
147
147
|
changeFormat: CodecTree,
|
|
148
148
|
): CodecTree {
|
|
149
149
|
const builder = makeMessageCodecBuilder();
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { IFluidLoadable
|
|
6
|
+
import type { IFluidLoadable } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert, fail, unreachableCase } from "@fluidframework/core-utils/internal";
|
|
8
8
|
import type { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
|
|
9
9
|
import type { ISnapshotTree } from "@fluidframework/driver-definitions/internal";
|
|
@@ -84,6 +84,15 @@ export interface SharedTreeCoreOptionsInternal extends CodecWriteOptions {
|
|
|
84
84
|
* {@inheritDoc SharedTreeOptions.retainHistory}
|
|
85
85
|
*/
|
|
86
86
|
readonly retainHistory?: boolean;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* {@inheritDoc SharedTreeOptions.validateCommitsOnFirstSubmission}
|
|
90
|
+
*/
|
|
91
|
+
readonly validateCommitsOnFirstSubmission?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* {@inheritDoc SharedTreeOptions.validateRebasedCommitsBeforeResubmission}
|
|
94
|
+
*/
|
|
95
|
+
readonly validateRebasedCommitsBeforeResubmission?: boolean;
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
export interface EnrichmentConfig<TChange> {
|
|
@@ -152,10 +161,9 @@ export class SharedTreeCore<
|
|
|
152
161
|
public readonly sharedObject: IChannelView & IFluidLoadable,
|
|
153
162
|
public readonly serializer: IFluidSerializer,
|
|
154
163
|
public readonly submitLocalMessage: (content: unknown, localOpMetadata?: unknown) => void,
|
|
155
|
-
logger: ITelemetryBaseLogger | undefined,
|
|
156
164
|
summarizables: readonly Summarizable[],
|
|
157
165
|
protected readonly changeFamily: ChangeFamily<TEditor, TChange, TChangeProcessingContext>,
|
|
158
|
-
|
|
166
|
+
private readonly coreOptions: SharedTreeCoreOptionsInternal,
|
|
159
167
|
changeFormatVersionForEditManager: DependentFormatVersion<EditManagerFormatVersion>,
|
|
160
168
|
changeFormatVersionForMessage: DependentFormatVersion<MessageFormatVersion>,
|
|
161
169
|
protected readonly idCompressor: IIdCompressor,
|
|
@@ -166,7 +174,7 @@ export class SharedTreeCore<
|
|
|
166
174
|
) {
|
|
167
175
|
super(
|
|
168
176
|
summarizablesTreeKey,
|
|
169
|
-
minVersionToSharedTreeSummaryFormatVersion(
|
|
177
|
+
minVersionToSharedTreeSummaryFormatVersion(coreOptions.minVersionForCollab),
|
|
170
178
|
supportedSharedTreeSummaryFormatVersions,
|
|
171
179
|
true /* supportPreVersioningFormat */,
|
|
172
180
|
);
|
|
@@ -176,6 +184,8 @@ export class SharedTreeCore<
|
|
|
176
184
|
policy: schemaPolicy,
|
|
177
185
|
};
|
|
178
186
|
|
|
187
|
+
const logger = breaker.logger;
|
|
188
|
+
|
|
179
189
|
const rebaseLogger = createChildLogger({
|
|
180
190
|
logger,
|
|
181
191
|
namespace: "Rebase",
|
|
@@ -194,14 +204,14 @@ export class SharedTreeCore<
|
|
|
194
204
|
this.mintRevisionTag,
|
|
195
205
|
(branchId) => this.registerSharedBranch(branchId),
|
|
196
206
|
rebaseLogger,
|
|
197
|
-
|
|
207
|
+
coreOptions.retainHistory ?? false,
|
|
198
208
|
);
|
|
199
209
|
|
|
200
210
|
this.registerSharedBranch("main");
|
|
201
211
|
|
|
202
212
|
const revisionTagCodec = new RevisionTagCodec(idCompressor);
|
|
203
213
|
const editManagerCodec = makeEditManagerCodecBuilder<TChange>().build({
|
|
204
|
-
...
|
|
214
|
+
...coreOptions,
|
|
205
215
|
changeCodecs: this.editManager.changeFamily.codecs,
|
|
206
216
|
dependentChangeFormatVersion: changeFormatVersionForEditManager,
|
|
207
217
|
revisionTagCodec,
|
|
@@ -211,9 +221,9 @@ export class SharedTreeCore<
|
|
|
211
221
|
this.editManager,
|
|
212
222
|
editManagerCodec,
|
|
213
223
|
this.idCompressor,
|
|
214
|
-
|
|
224
|
+
coreOptions.minVersionForCollab,
|
|
215
225
|
this.schemaAndPolicy,
|
|
216
|
-
|
|
226
|
+
coreOptions.healUnresolvableIdentifiersOnDecode === true
|
|
217
227
|
? { sharedObjectId: sharedObject.id, logger }
|
|
218
228
|
: undefined,
|
|
219
229
|
),
|
|
@@ -225,7 +235,7 @@ export class SharedTreeCore<
|
|
|
225
235
|
);
|
|
226
236
|
|
|
227
237
|
this.messageCodec = makeMessageCodecBuilder<TChange>().build({
|
|
228
|
-
...
|
|
238
|
+
...coreOptions,
|
|
229
239
|
changeCodecs: changeFamily.codecs,
|
|
230
240
|
dependentChangeFormatVersion: changeFormatVersionForMessage,
|
|
231
241
|
revisionTagCodec: new RevisionTagCodec(idCompressor),
|
|
@@ -335,7 +345,10 @@ export class SharedTreeCore<
|
|
|
335
345
|
if (change.type === "append") {
|
|
336
346
|
if (this.detachedRevision === undefined) {
|
|
337
347
|
// Commit enrichment is only necessary for changes that will be submitted as ops, and changes issued while detached are not submitted.
|
|
338
|
-
this.getCommitEnricher(branchId).prepareChanges(
|
|
348
|
+
this.getCommitEnricher(branchId).prepareChanges(
|
|
349
|
+
change.newCommits,
|
|
350
|
+
this.coreOptions.validateCommitsOnFirstSubmission ?? false,
|
|
351
|
+
);
|
|
339
352
|
}
|
|
340
353
|
|
|
341
354
|
for (const commit of change.newCommits) {
|
|
@@ -681,7 +694,12 @@ export class SharedTreeCore<
|
|
|
681
694
|
assert(!this.enrichers.has(branchId), 0xc6d /* Branch already registered */);
|
|
682
695
|
this.enrichers.set(branchId, {
|
|
683
696
|
enricher: commitEnricher,
|
|
684
|
-
resubmitMachine:
|
|
697
|
+
resubmitMachine:
|
|
698
|
+
resubmitMachine ??
|
|
699
|
+
new DefaultResubmitMachine(
|
|
700
|
+
enricher,
|
|
701
|
+
this.coreOptions.validateRebasedCommitsBeforeResubmission ?? false,
|
|
702
|
+
),
|
|
685
703
|
});
|
|
686
704
|
}
|
|
687
705
|
|
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
IExperimentalIncrementalSummaryContext,
|
|
9
9
|
ISummaryTreeWithStats,
|
|
10
10
|
ITelemetryContext,
|
|
11
|
-
|
|
11
|
+
OldestSupportedClientVersion,
|
|
12
12
|
} from "@fluidframework/runtime-definitions/internal";
|
|
13
13
|
|
|
14
14
|
// TODO: Organize this to be adjacent to persisted types.
|
|
@@ -115,7 +115,7 @@ export const supportedSharedTreeSummaryFormatVersions =
|
|
|
115
115
|
* Returns the summary version to use as per the given minimum version for collab.
|
|
116
116
|
*/
|
|
117
117
|
export function minVersionToSharedTreeSummaryFormatVersion(
|
|
118
|
-
version:
|
|
118
|
+
version: OldestSupportedClientVersion,
|
|
119
119
|
): SharedTreeSummaryFormatVersion {
|
|
120
120
|
// Currently, version 2 is written which adds metadata blob to the summary.
|
|
121
121
|
return SharedTreeSummaryFormatVersion.v2;
|
|
@@ -313,7 +313,7 @@ export interface SnapshotSchemaCompatibilityOptions {
|
|
|
313
313
|
* Such applications can set this to the oldest version currently deployed,
|
|
314
314
|
* then rely on {@link snapshotSchemaCompatibility} to verify that no schema changes are made which would break collaboration with that (or newer) versions.
|
|
315
315
|
*
|
|
316
|
-
* This is the same approach used by {@link @fluidframework/runtime-definitions#
|
|
316
|
+
* This is the same approach used by {@link @fluidframework/runtime-definitions#OldestSupportedClientVersion}
|
|
317
317
|
* except that type is specifically for use with the version of the Fluid Framework client packages,
|
|
318
318
|
* and this corresponds to whatever versioning scheme is used with {@link SnapshotSchemaCompatibilityOptions.version}.
|
|
319
319
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { OldestSupportedClientVersion } from "@fluidframework/runtime-definitions/internal";
|
|
7
7
|
|
|
8
8
|
import { FormatValidatorNoOp, type ICodecOptions } from "../../codec/index.js";
|
|
9
9
|
import { schemaCodecBuilder } from "../../feature-libraries/index.js";
|
|
@@ -50,7 +50,7 @@ import type { SchemaCompatibilityStatus } from "./tree.js";
|
|
|
50
50
|
*/
|
|
51
51
|
export function extractPersistedSchema(
|
|
52
52
|
schema: ImplicitFieldSchema,
|
|
53
|
-
minVersionForCollab:
|
|
53
|
+
minVersionForCollab: OldestSupportedClientVersion,
|
|
54
54
|
includeStaged: (upgrade: SchemaUpgrade) => boolean,
|
|
55
55
|
): JsonCompatible {
|
|
56
56
|
const stored = toStoredSchema(schema, {
|
|
@@ -66,7 +66,11 @@ export interface TreeChangeEvents {
|
|
|
66
66
|
* node, or when the node has to be updated due to resolution of a merge conflict
|
|
67
67
|
* (for example a previously applied local change might be undone, then reapplied differently or not at all).
|
|
68
68
|
*
|
|
69
|
-
*
|
|
69
|
+
* Event ordering: when multiple nodes are directly changed in a single batch,
|
|
70
|
+
* events fire in the order nodes were first edited. At each node, `nodeChanged` fires before `treeChanged`.
|
|
71
|
+
* When only a leaf node changes, this naturally produces bottom-up ordering
|
|
72
|
+
* (leaf events first, then ancestor `treeChanged` propagating up).
|
|
73
|
+
* See `treeChangeEventOrdering.spec.ts` for comprehensive ordering tests.
|
|
70
74
|
*/
|
|
71
75
|
nodeChanged(unstable?: unknown): void;
|
|
72
76
|
|
|
@@ -910,6 +910,21 @@ function createArrayNodeProxy(
|
|
|
910
910
|
return proxyTarget.constructor;
|
|
911
911
|
}
|
|
912
912
|
|
|
913
|
+
// If the property is a function on Array.prototype but not on the dispatch target,
|
|
914
|
+
// return a function that throws a descriptive TypeError when called.
|
|
915
|
+
if (
|
|
916
|
+
typeof key === "string" &&
|
|
917
|
+
!(key in dispatchTarget) &&
|
|
918
|
+
key in Array.prototype &&
|
|
919
|
+
typeof (Array.prototype as unknown as Record<string, unknown>)[key] === "function"
|
|
920
|
+
) {
|
|
921
|
+
return () => {
|
|
922
|
+
throw new TypeError(
|
|
923
|
+
`ArrayNode does not support '${key}'. Use the ArrayNode API (e.g., insertAt, removeAt, moveToIndex, splice).`,
|
|
924
|
+
);
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
|
|
913
928
|
// Pass the proxy as the receiver here, so that any methods on
|
|
914
929
|
// the prototype receive `proxy` as `this`.
|
|
915
930
|
return Reflect.get(dispatchTarget, key, receiver) as unknown;
|
|
@@ -277,6 +277,27 @@ const handler: ProxyHandler<TreeMapNodeAlpha<any>> = {
|
|
|
277
277
|
getPrototypeOf: () => {
|
|
278
278
|
return Map.prototype;
|
|
279
279
|
},
|
|
280
|
+
get: (target, key, receiver) => {
|
|
281
|
+
const value = Reflect.get(target, key, receiver) as unknown;
|
|
282
|
+
if (value !== undefined) {
|
|
283
|
+
return value;
|
|
284
|
+
}
|
|
285
|
+
// If the property is a function on Map.prototype but not on the target,
|
|
286
|
+
// return a function that throws a descriptive TypeError when called.
|
|
287
|
+
if (
|
|
288
|
+
typeof key === "string" &&
|
|
289
|
+
!(key in target) &&
|
|
290
|
+
key in Map.prototype &&
|
|
291
|
+
typeof (Map.prototype as unknown as Record<string, unknown>)[key] === "function"
|
|
292
|
+
) {
|
|
293
|
+
return () => {
|
|
294
|
+
throw new TypeError(
|
|
295
|
+
`MapNode does not support '${key}'. Use the MapNode API (e.g., set, get, delete, keys, values, entries).`,
|
|
296
|
+
);
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
return value;
|
|
300
|
+
},
|
|
280
301
|
};
|
|
281
302
|
|
|
282
303
|
abstract class CustomMapNodeBase<const T extends ImplicitAllowedTypes> extends TreeNodeValid<
|
|
@@ -322,9 +343,9 @@ abstract class CustomMapNodeBase<const T extends ImplicitAllowedTypes> extends T
|
|
|
322
343
|
public has(key: string): boolean {
|
|
323
344
|
return this.innerNode.tryGetField(brand(key)) !== undefined;
|
|
324
345
|
}
|
|
325
|
-
public keys(): IterableIterator<string> {
|
|
346
|
+
public *keys(): IterableIterator<string> {
|
|
326
347
|
const node = this.innerNode;
|
|
327
|
-
|
|
348
|
+
yield* node.keys();
|
|
328
349
|
}
|
|
329
350
|
public set(key: string, value: InsertableTreeNodeFromImplicitAllowedTypes<T>): this {
|
|
330
351
|
const kernel = getKernel(this);
|
package/src/tableSchema.ts
CHANGED
|
@@ -1590,7 +1590,7 @@ function removeRangeFromArray<TNodeSchema extends ImplicitAllowedTypes>(
|
|
|
1590
1590
|
*
|
|
1591
1591
|
* Also note: these APIs leverage `SharedTree` functionality that was added in version `2.80.0`,
|
|
1592
1592
|
* which is not compatible with previous versions of this library.
|
|
1593
|
-
* To ensure safe collaboration, you will need to configure the {@link @fluidframework/runtime-definitions#
|
|
1593
|
+
* To ensure safe collaboration, you will need to configure the {@link @fluidframework/runtime-definitions#OldestSupportedClientVersion}
|
|
1594
1594
|
* for the Fluid Runtime and/or `SharedTree` to at least `2.80.0`.
|
|
1595
1595
|
* To set this minimum version for `SharedTree`, use {@link configuredSharedTreeBeta}.
|
|
1596
1596
|
*
|
package/src/treeFactory.ts
CHANGED
package/src/util/breakable.ts
CHANGED
|
@@ -10,6 +10,10 @@ import { UsageError, type TelemetryLoggerExt } from "@fluidframework/telemetry-u
|
|
|
10
10
|
* An object which can enter a "broken" state where trying to use it is a UsageError.
|
|
11
11
|
* @remarks
|
|
12
12
|
* Use {@link WithBreakable} to apply this to another object.
|
|
13
|
+
*
|
|
14
|
+
* A common pattern is to pass a single breaker to all code which shares mutable state and thus could be put into an invalidate state together.
|
|
15
|
+
* Thus a breaker often represents a scope for or dependency on mutable state which also forms a scope for fault isolation.
|
|
16
|
+
* As such a scope can have issues (if it couldn't it would need a breaker), an optional {@link Breakable.logger} is included which can be used to log telemetry within this scope.
|
|
13
17
|
* @sealed
|
|
14
18
|
*/
|
|
15
19
|
export class Breakable {
|
|
@@ -26,7 +30,11 @@ export class Breakable {
|
|
|
26
30
|
* Optional logger for telemetry.
|
|
27
31
|
* @remarks
|
|
28
32
|
* When provided, subsystems that have access to a Breakable can use this logger to emit telemetry
|
|
29
|
-
* without requiring additional plumbing.
|
|
33
|
+
* without requiring additional plumbing of a logger which also corresponds to the same scope/context of this Breakable.
|
|
34
|
+
*
|
|
35
|
+
* Currently, Breakable itself does not eagerly log breakages into the logger, but we may want to change that in the future.
|
|
36
|
+
* Instead it is assumed that fatal errors will result in exceptions logged through other means,
|
|
37
|
+
* and the logger here is exposed for users of breaker to log telemetry as desired (for example reporting non-fatal errors or other telemetry).
|
|
30
38
|
*/
|
|
31
39
|
public readonly logger?: TelemetryLoggerExt,
|
|
32
40
|
) {}
|