@fluidframework/tree 2.0.0-dev-rc.5.0.0.271262 → 2.0.0-dev-rc.5.0.0.272251
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/api-extractor/api-extractor-lint-beta.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-beta.esm.json +5 -0
- package/api-extractor/api-extractor-lint-bundle.json +5 -0
- package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-public.esm.json +5 -0
- package/api-report/tree.alpha.api.md +2 -13
- package/api-report/tree.beta.api.md +2 -13
- package/api-report/tree.public.api.md +2 -13
- package/dist/beta.d.ts +0 -1
- package/dist/codec/codec.js +0 -1
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/discriminatedUnions.js +0 -1
- package/dist/codec/discriminatedUnions.js.map +1 -1
- package/dist/core/change-family/editBuilder.js +0 -2
- package/dist/core/change-family/editBuilder.js.map +1 -1
- package/dist/core/rebase/revisionTagCodec.js +0 -2
- package/dist/core/rebase/revisionTagCodec.js.map +1 -1
- package/dist/core/schema-stored/schema.js +0 -4
- package/dist/core/schema-stored/schema.js.map +1 -1
- package/dist/core/schema-stored/storedSchemaRepository.js +1 -3
- package/dist/core/schema-stored/storedSchemaRepository.js.map +1 -1
- package/dist/core/schema-view/view.js +0 -2
- package/dist/core/schema-view/view.js.map +1 -1
- package/dist/core/tree/anchorSet.js +46 -51
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/core/tree/detachedFieldIndex.js +2 -8
- package/dist/core/tree/detachedFieldIndex.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodec.js +0 -3
- package/dist/core/tree/detachedFieldIndexCodec.js.map +1 -1
- package/dist/core/tree/sparseTree.js +11 -15
- package/dist/core/tree/sparseTree.js.map +1 -1
- package/dist/domains/schemaBuilder.js +70 -70
- package/dist/domains/schemaBuilder.js.map +1 -1
- package/dist/events/events.js +1 -2
- package/dist/events/events.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +1 -14
- package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +6 -13
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +2 -9
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js +3 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -3
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +6 -11
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +3 -3
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +2 -5
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +0 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +4 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +13 -25
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeShape.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeShape.js +5 -8
- package/dist/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/sequenceChunk.js +0 -1
- package/dist/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js +5 -40
- package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js +0 -2
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/detachedFieldIndexSummarizer.js +1 -2
- package/dist/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/dist/feature-libraries/editableTreeBinder.js +12 -13
- package/dist/feature-libraries/editableTreeBinder.js.map +1 -1
- package/dist/feature-libraries/flex-map-tree/mapTreeNode.js +11 -12
- package/dist/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js +3 -7
- package/dist/feature-libraries/flex-tree/context.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyEntity.js +22 -13
- package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +0 -6
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +17 -10
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -6
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +1 -1
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +2 -3
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +7 -7
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.js +6 -6
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldKind.js +0 -2
- package/dist/feature-libraries/modular-schema/fieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldKindWithEditor.js +0 -3
- package/dist/feature-libraries/modular-schema/fieldKindWithEditor.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +2 -2
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +2 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +2 -0
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +39 -24
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/node-key/mockNodeKeyManager.js +4 -2
- package/dist/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
- package/dist/feature-libraries/node-key/nodeKeyIndex.js +0 -3
- package/dist/feature-libraries/node-key/nodeKeyIndex.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +28 -23
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +5 -3
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -5
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/schemaBuilderBase.js +3 -14
- package/dist/feature-libraries/schemaBuilderBase.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +0 -6
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/markListFactory.js +4 -3
- package/dist/feature-libraries/sequence-field/markListFactory.js.map +1 -1
- package/dist/feature-libraries/sequence-field/markQueue.js +2 -4
- package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.d.ts +2 -2
- package/dist/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.js +20 -20
- package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/dist/feature-libraries/treeCursorUtils.js +9 -13
- package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
- package/dist/feature-libraries/typed-schema/typedTreeSchema.js +4 -23
- package/dist/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
- package/dist/feature-libraries/typed-schema/view.js +0 -7
- package/dist/feature-libraries/typed-schema/view.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/public.d.ts +0 -1
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +10 -27
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +4 -0
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +13 -10
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.js +11 -14
- package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.js +3 -5
- package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/dist/shared-tree/sharedTreeEditBuilder.js +0 -2
- package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/dist/shared-tree/treeCheckout.js +11 -22
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree/treeView.js +0 -6
- package/dist/shared-tree/treeView.js.map +1 -1
- package/dist/shared-tree-core/branch.d.ts +18 -0
- package/dist/shared-tree-core/branch.d.ts.map +1 -1
- package/dist/shared-tree-core/branch.js +28 -31
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/branchCommitEnricher.d.ts +4 -2
- package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
- package/dist/shared-tree-core/branchCommitEnricher.js +19 -15
- package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
- package/dist/shared-tree-core/defaultResubmitMachine.js +19 -21
- package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
- package/dist/shared-tree-core/editManager.js +37 -53
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js +1 -5
- package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +16 -24
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/shared-tree-core/transactionEnricher.d.ts +11 -1
- package/dist/shared-tree-core/transactionEnricher.d.ts.map +1 -1
- package/dist/shared-tree-core/transactionEnricher.js +25 -4
- package/dist/shared-tree-core/transactionEnricher.js.map +1 -1
- package/dist/shared-tree-core/transactionStack.js +3 -1
- package/dist/shared-tree-core/transactionStack.js.map +1 -1
- package/dist/simple-tree/arrayNode.js +34 -26
- package/dist/simple-tree/arrayNode.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.js +2 -4
- package/dist/simple-tree/leafNodeSchema.js.map +1 -1
- package/dist/simple-tree/mapNode.js +5 -5
- package/dist/simple-tree/mapNode.js.map +1 -1
- package/dist/simple-tree/objectNode.js +6 -6
- package/dist/simple-tree/objectNode.js.map +1 -1
- package/dist/simple-tree/schemaFactory.d.ts +18 -5
- package/dist/simple-tree/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/schemaFactory.js +65 -53
- package/dist/simple-tree/schemaFactory.js.map +1 -1
- package/dist/simple-tree/schemaTypes.js +3 -12
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/tree.d.ts +1 -22
- package/dist/simple-tree/tree.d.ts.map +1 -1
- package/dist/simple-tree/tree.js +0 -21
- package/dist/simple-tree/tree.js.map +1 -1
- package/dist/simple-tree/treeNodeApi.d.ts +13 -4
- package/dist/simple-tree/treeNodeApi.d.ts.map +1 -1
- package/dist/simple-tree/treeNodeApi.js +8 -3
- package/dist/simple-tree/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/types.d.ts +26 -6
- package/dist/simple-tree/types.d.ts.map +1 -1
- package/dist/simple-tree/types.js +79 -54
- package/dist/simple-tree/types.js.map +1 -1
- package/dist/treeFactory.js +10 -9
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/brand.js +0 -1
- package/dist/util/brand.js.map +1 -1
- package/dist/util/nestedMap.js +4 -2
- package/dist/util/nestedMap.js.map +1 -1
- package/dist/util/offsetList.js +4 -2
- package/dist/util/offsetList.js.map +1 -1
- package/dist/util/referenceCounting.js +0 -1
- package/dist/util/referenceCounting.js.map +1 -1
- package/dist/util/stackyIterator.js +2 -3
- package/dist/util/stackyIterator.js.map +1 -1
- package/lib/beta.d.ts +0 -1
- package/lib/codec/codec.js +0 -1
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/discriminatedUnions.js +0 -1
- package/lib/codec/discriminatedUnions.js.map +1 -1
- package/lib/core/change-family/editBuilder.js +0 -2
- package/lib/core/change-family/editBuilder.js.map +1 -1
- package/lib/core/rebase/revisionTagCodec.js +0 -2
- package/lib/core/rebase/revisionTagCodec.js.map +1 -1
- package/lib/core/schema-stored/schema.js +0 -4
- package/lib/core/schema-stored/schema.js.map +1 -1
- package/lib/core/schema-stored/storedSchemaRepository.js +1 -3
- package/lib/core/schema-stored/storedSchemaRepository.js.map +1 -1
- package/lib/core/schema-view/view.js +0 -2
- package/lib/core/schema-view/view.js.map +1 -1
- package/lib/core/tree/anchorSet.js +46 -51
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/core/tree/detachedFieldIndex.js +2 -8
- package/lib/core/tree/detachedFieldIndex.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodec.js +0 -3
- package/lib/core/tree/detachedFieldIndexCodec.js.map +1 -1
- package/lib/core/tree/sparseTree.js +11 -15
- package/lib/core/tree/sparseTree.js.map +1 -1
- package/lib/domains/schemaBuilder.js +70 -70
- package/lib/domains/schemaBuilder.js.map +1 -1
- package/lib/events/events.js +1 -2
- package/lib/events/events.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +1 -14
- package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +6 -13
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +2 -9
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js +3 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkCodecUtilities.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +13 -3
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +6 -11
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +3 -3
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +2 -5
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +0 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +4 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +13 -25
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeShape.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeShape.js +5 -8
- package/lib/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/sequenceChunk.js +0 -1
- package/lib/feature-libraries/chunked-forest/sequenceChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js +5 -40
- package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js +0 -2
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/detachedFieldIndexSummarizer.js +1 -2
- package/lib/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/lib/feature-libraries/editableTreeBinder.js +12 -13
- package/lib/feature-libraries/editableTreeBinder.js.map +1 -1
- package/lib/feature-libraries/flex-map-tree/mapTreeNode.js +11 -12
- package/lib/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js +3 -7
- package/lib/feature-libraries/flex-tree/context.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyEntity.js +22 -13
- package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +0 -6
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +17 -10
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -6
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +1 -1
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +1 -1
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +7 -7
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.js +5 -5
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldKind.js +0 -2
- package/lib/feature-libraries/modular-schema/fieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldKindWithEditor.js +0 -3
- package/lib/feature-libraries/modular-schema/fieldKindWithEditor.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js +1 -1
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +2 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +2 -0
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +40 -25
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/node-key/mockNodeKeyManager.js +4 -2
- package/lib/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
- package/lib/feature-libraries/node-key/nodeKeyIndex.js +0 -3
- package/lib/feature-libraries/node-key/nodeKeyIndex.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +28 -23
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +6 -4
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -5
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/schemaBuilderBase.js +3 -14
- package/lib/feature-libraries/schemaBuilderBase.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +0 -6
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/markListFactory.js +4 -3
- package/lib/feature-libraries/sequence-field/markListFactory.js.map +1 -1
- package/lib/feature-libraries/sequence-field/markQueue.js +2 -4
- package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.d.ts +2 -2
- package/lib/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.js +21 -21
- package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/lib/feature-libraries/treeCursorUtils.js +9 -13
- package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
- package/lib/feature-libraries/typed-schema/typedTreeSchema.js +4 -23
- package/lib/feature-libraries/typed-schema/typedTreeSchema.js.map +1 -1
- package/lib/feature-libraries/typed-schema/view.js +0 -7
- package/lib/feature-libraries/typed-schema/view.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +0 -1
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +10 -27
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +4 -0
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +13 -10
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.js +11 -14
- package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.js +3 -5
- package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/lib/shared-tree/sharedTreeEditBuilder.js +0 -2
- package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/lib/shared-tree/treeCheckout.js +11 -22
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree/treeView.js +0 -6
- package/lib/shared-tree/treeView.js.map +1 -1
- package/lib/shared-tree-core/branch.d.ts +18 -0
- package/lib/shared-tree-core/branch.d.ts.map +1 -1
- package/lib/shared-tree-core/branch.js +28 -31
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/branchCommitEnricher.d.ts +4 -2
- package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
- package/lib/shared-tree-core/branchCommitEnricher.js +19 -15
- package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
- package/lib/shared-tree-core/defaultResubmitMachine.js +19 -21
- package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
- package/lib/shared-tree-core/editManager.js +37 -53
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js +1 -5
- package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +16 -24
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/shared-tree-core/transactionEnricher.d.ts +11 -1
- package/lib/shared-tree-core/transactionEnricher.d.ts.map +1 -1
- package/lib/shared-tree-core/transactionEnricher.js +25 -4
- package/lib/shared-tree-core/transactionEnricher.js.map +1 -1
- package/lib/shared-tree-core/transactionStack.js +3 -1
- package/lib/shared-tree-core/transactionStack.js.map +1 -1
- package/lib/simple-tree/arrayNode.js +34 -26
- package/lib/simple-tree/arrayNode.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.js +2 -4
- package/lib/simple-tree/leafNodeSchema.js.map +1 -1
- package/lib/simple-tree/mapNode.js +5 -5
- package/lib/simple-tree/mapNode.js.map +1 -1
- package/lib/simple-tree/objectNode.js +6 -6
- package/lib/simple-tree/objectNode.js.map +1 -1
- package/lib/simple-tree/schemaFactory.d.ts +18 -5
- package/lib/simple-tree/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/schemaFactory.js +65 -53
- package/lib/simple-tree/schemaFactory.js.map +1 -1
- package/lib/simple-tree/schemaTypes.js +3 -12
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/tree.d.ts +1 -22
- package/lib/simple-tree/tree.d.ts.map +1 -1
- package/lib/simple-tree/tree.js +0 -21
- package/lib/simple-tree/tree.js.map +1 -1
- package/lib/simple-tree/treeNodeApi.d.ts +13 -4
- package/lib/simple-tree/treeNodeApi.d.ts.map +1 -1
- package/lib/simple-tree/treeNodeApi.js +8 -3
- package/lib/simple-tree/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/types.d.ts +26 -6
- package/lib/simple-tree/types.d.ts.map +1 -1
- package/lib/simple-tree/types.js +78 -54
- package/lib/simple-tree/types.js.map +1 -1
- package/lib/treeFactory.js +10 -9
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/brand.js +0 -1
- package/lib/util/brand.js.map +1 -1
- package/lib/util/nestedMap.js +4 -2
- package/lib/util/nestedMap.js.map +1 -1
- package/lib/util/offsetList.js +4 -2
- package/lib/util/offsetList.js.map +1 -1
- package/lib/util/referenceCounting.js +0 -1
- package/lib/util/referenceCounting.js.map +1 -1
- package/lib/util/stackyIterator.js +2 -3
- package/lib/util/stackyIterator.js.map +1 -1
- package/package.json +27 -24
- package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +22 -6
- package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +2 -2
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +6 -2
- package/src/feature-libraries/chunked-forest/codec/nodeShape.ts +8 -3
- package/src/feature-libraries/index.ts +0 -1
- package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +6 -7
- package/src/feature-libraries/modular-schema/index.ts +1 -1
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +2 -0
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +55 -23
- package/src/feature-libraries/optional-field/optionalField.ts +3 -3
- package/src/feature-libraries/sequence-field/rebase.ts +15 -33
- package/src/index.ts +0 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +0 -2
- package/src/shared-tree/sharedTree.ts +8 -1
- package/src/shared-tree-core/branch.ts +24 -0
- package/src/shared-tree-core/branchCommitEnricher.ts +15 -6
- package/src/shared-tree-core/sharedTreeCore.ts +9 -0
- package/src/shared-tree-core/transactionEnricher.ts +27 -1
- package/src/simple-tree/arrayNode.ts +17 -17
- package/src/simple-tree/schemaFactory.ts +18 -5
- package/src/simple-tree/tree.ts +1 -26
- package/src/simple-tree/treeNodeApi.ts +25 -7
- package/src/simple-tree/types.ts +57 -9
- package/tsdoc.json +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editManager.js","sourceRoot":"","sources":["../../src/shared-tree-core/editManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { SessionId } from \"@fluidframework/id-compressor\";\nimport { BTree } from \"@tylerbu/sorted-btree-es6\";\n\nimport {\n\ttype ChangeFamily,\n\ttype ChangeFamilyEditor,\n\ttype GraphCommit,\n\ttype RevisionTag,\n\tfindAncestor,\n\tfindCommonAncestor,\n\tmintCommit,\n\trebaseChange,\n} from \"../core/index.js\";\nimport { type Mutable, brand, fail, getOrCreate, mapIterable } from \"../util/index.js\";\n\nimport {\n\tSharedTreeBranch,\n\ttype BranchTrimmingEvents,\n\tgetChangeReplaceType,\n\tonForkTransitive,\n} from \"./branch.js\";\nimport type {\n\tCommit,\n\tSeqNumber,\n\tSequenceId,\n\tSequencedCommit,\n\tSummarySessionBranch,\n} from \"./editManagerFormat.js\";\nimport {\n\tdecrementSequenceId,\n\tequalSequenceIds,\n\tmaxSequenceId,\n\tminSequenceId,\n\tsequenceIdComparator,\n} from \"./sequenceIdUtils.js\";\nimport { createEmitter } from \"../events/index.js\";\n\nexport const minimumPossibleSequenceNumber: SeqNumber = brand(Number.MIN_SAFE_INTEGER);\nconst minimumPossibleSequenceId: SequenceId = {\n\tsequenceNumber: minimumPossibleSequenceNumber,\n};\n\n/**\n * Represents a local branch of a document and interprets the effect on the document of adding sequenced changes,\n * which were based on a given session's branch, to the document history\n */\n// TODO: Try to reduce this to a single type parameter\nexport class EditManager<\n\tTEditor extends ChangeFamilyEditor,\n\tTChangeset,\n\tTChangeFamily extends ChangeFamily<TEditor, TChangeset>,\n> {\n\tprivate readonly _events = createEmitter<BranchTrimmingEvents>();\n\n\t/** The \"trunk\" branch. The trunk represents the list of received sequenced changes. */\n\tprivate readonly trunk: SharedTreeBranch<TEditor, TChangeset>;\n\n\t/**\n\t * Records extra data associated with commits in the {@link trunk}.\n\t * This does not include an entry for the {@link trunkBase}.\n\t */\n\tprivate readonly trunkMetadata = new Map<\n\t\tRevisionTag,\n\t\t{ sequenceId: SequenceId; sessionId: SessionId }\n\t>();\n\t/**\n\t * A map from a sequence id to the commit in the {@link trunk} which has that sequence id.\n\t * This also includes an entry for the {@link trunkBase} which always has the lowest key in the map.\n\t */\n\tprivate readonly sequenceMap = new BTree<SequenceId, GraphCommit<TChangeset>>(\n\t\tundefined,\n\t\tsequenceIdComparator,\n\t);\n\n\t/**\n\t * Branches are maintained to represent the local change list that the issuing client had\n\t * at the time of submitting the latest known edit on the branch.\n\t * This means the head commit of each branch is always in its original (non-rebased) form.\n\t */\n\tprivate readonly peerLocalBranches: Map<SessionId, SharedTreeBranch<TEditor, TChangeset>> =\n\t\tnew Map();\n\n\t/**\n\t * This branch holds the changes made by this client which have not yet been confirmed as sequenced changes.\n\t */\n\tpublic readonly localBranch: SharedTreeBranch<TEditor, TChangeset>;\n\n\t/**\n\t * Tracks where on the trunk all registered branches are based. Each key is the sequence id of a commit on\n\t * the trunk, and the value is the set of all branches who have that commit as their common ancestor with the trunk.\n\t *\n\t * @remarks\n\t * This does not include the local branch.\n\t */\n\tprivate readonly trunkBranches = new BTree<\n\t\tSequenceId,\n\t\tSet<SharedTreeBranch<TEditor, TChangeset>>\n\t>(undefined, sequenceIdComparator);\n\n\t/**\n\t * The sequence number of the newest commit on the trunk that has been received by all peers.\n\t * Defaults to {@link minimumPossibleSequenceNumber} if no commits have been received.\n\t *\n\t * @remarks If there are more than one commit with the same sequence number we assume this refers to the last commit in the batch.\n\t */\n\tprivate minimumSequenceNumber = minimumPossibleSequenceNumber;\n\n\t/**\n\t * A special commit that is a \"base\" (tail) of the trunk, though not part of the trunk itself.\n\t * This makes it possible to model the trunk in the same way as any other branch (it branches off of a base commit)\n\t * which allows it to use branching APIs to interact with the other branches.\n\t * Each time trunk eviction occurs, the most recent evicted commit becomes the new `trunkBase`.\n\t */\n\tprivate trunkBase: GraphCommit<TChangeset>;\n\n\t/**\n\t * The list of commits (from oldest to most recent) that are on the local branch but not on the trunk.\n\t * When a local commit is sequenced, the first commit in this list shifted onto the tip of the trunk.\n\t */\n\tprivate readonly localCommits: GraphCommit<TChangeset>[] = [];\n\n\t/**\n\t * @param changeFamily - the change family of changes on the trunk and local branch\n\t * @param localSessionId - the id of the local session that will be used for local commits\n\t */\n\tpublic constructor(\n\t\tpublic readonly changeFamily: TChangeFamily,\n\t\tpublic readonly localSessionId: SessionId,\n\t\tprivate readonly mintRevisionTag: () => RevisionTag,\n\t) {\n\t\tthis.trunkBase = {\n\t\t\trevision: \"root\",\n\t\t\tchange: changeFamily.rebaser.compose([]),\n\t\t};\n\t\tthis.sequenceMap.set(minimumPossibleSequenceId, this.trunkBase);\n\t\tthis.trunk = new SharedTreeBranch(\n\t\t\tthis.trunkBase,\n\t\t\tchangeFamily,\n\t\t\tmintRevisionTag,\n\t\t\tthis._events,\n\t\t);\n\t\tthis.localBranch = new SharedTreeBranch(\n\t\t\tthis.trunk.getHead(),\n\t\t\tchangeFamily,\n\t\t\tmintRevisionTag,\n\t\t\tthis._events,\n\t\t);\n\n\t\tthis.localBranch.on(\"afterChange\", (event) => {\n\t\t\tif (event.type === \"append\") {\n\t\t\t\tfor (const commit of event.newCommits) {\n\t\t\t\t\tthis.localCommits.push(commit);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.localCommits.length = 0;\n\t\t\t\tfindCommonAncestor(\n\t\t\t\t\t[this.localBranch.getHead(), this.localCommits],\n\t\t\t\t\tthis.trunk.getHead(),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\t// Track all forks of the local branch for purposes of trunk eviction. Unlike the local branch, they have\n\t\t// an unknown lifetime and rebase frequency, so we can not make any assumptions about which trunk commits\n\t\t// they require and therefore we monitor them explicitly.\n\t\tonForkTransitive(this.localBranch, (fork) => this.registerBranch(fork));\n\t}\n\n\t/**\n\t * Make the given branch known to the `EditManager`. The `EditManager` will ensure that all registered\n\t * branches remain usable even as the minimum sequence number advances.\n\t *\n\t * TODO#AB6926: Refactor local branch management into a separate class that encapsulates `trunkBranches` and everything\n\t * that touches it.\n\t * TODO#AB6925: Maintain the divergence point between each branch and the trunk so that we don't have to recompute\n\t * it so often.\n\t */\n\tprivate registerBranch(branch: SharedTreeBranch<TEditor, TChangeset>): void {\n\t\tthis.trackBranch(branch);\n\t\t// Whenever the branch is rebased, update our record of its base trunk commit\n\t\tconst offBeforeRebase = branch.on(\"beforeChange\", (args) => {\n\t\t\tif (args.type === \"replace\" && getChangeReplaceType(args) === \"rebase\") {\n\t\t\t\tthis.untrackBranch(branch);\n\t\t\t}\n\t\t});\n\t\tconst offAfterRebase = branch.on(\"afterChange\", (args) => {\n\t\t\tif (args.type === \"replace\" && getChangeReplaceType(args) === \"rebase\") {\n\t\t\t\tthis.trackBranch(branch);\n\t\t\t\tthis.trimTrunk();\n\t\t\t}\n\t\t});\n\t\t// When the branch is disposed, update our branch set and trim the trunk\n\t\tconst offDispose = branch.on(\"dispose\", () => {\n\t\t\tthis.untrackBranch(branch);\n\t\t\tthis.trimTrunk();\n\t\t\toffBeforeRebase();\n\t\t\toffAfterRebase();\n\t\t\toffDispose();\n\t\t});\n\t}\n\n\tprivate trackBranch(b: SharedTreeBranch<TEditor, TChangeset>): void {\n\t\tconst trunkCommit =\n\t\t\tfindCommonAncestor(this.trunk.getHead(), b.getHead()) ??\n\t\t\tfail(\"Expected branch to be related to trunk\");\n\t\tconst sequenceId = this.getCommitSequenceId(trunkCommit);\n\t\tconst branches = getOrCreate(this.trunkBranches, sequenceId, () => new Set());\n\n\t\tassert(!branches.has(b), 0x670 /* Branch was registered more than once */);\n\t\tbranches.add(b);\n\t}\n\n\tprivate untrackBranch(b: SharedTreeBranch<TEditor, TChangeset>): void {\n\t\tconst trunkCommit =\n\t\t\tfindCommonAncestor(this.trunk.getHead(), b.getHead()) ??\n\t\t\tfail(\"Expected branch to be related to trunk\");\n\t\tconst sequenceId = this.getCommitSequenceId(trunkCommit);\n\t\tconst branches =\n\t\t\tthis.trunkBranches.get(sequenceId) ?? fail(\"Expected branch to be tracked\");\n\n\t\tassert(branches.delete(b), 0x671 /* Expected branch to be tracked */);\n\t\tif (branches.size === 0) {\n\t\t\tthis.trunkBranches.delete(sequenceId);\n\t\t}\n\t}\n\n\t/**\n\t * Updates the `trunkBranches` map to reflect the fact that a new local commit was fast-forwarded to the trunk.\n\t * @param priorTrunkCommit - The trunk head prior to the fast-forward.\n\t * @param newId - The ID of the new trunk head.\n\t */\n\tprivate fastForwardBranches(\n\t\tpriorTrunkCommit: GraphCommit<TChangeset>,\n\t\tnewId: SequenceId,\n\t): void {\n\t\tconst currentId = this.getCommitSequenceId(priorTrunkCommit);\n\t\tconst currentBranches = this.trunkBranches.get(currentId);\n\t\tif (currentBranches !== undefined) {\n\t\t\tconst newBranches = getOrCreate(this.trunkBranches, newId, () => new Set());\n\t\t\tfor (const branch of currentBranches) {\n\t\t\t\tif (branch.getHead() !== priorTrunkCommit) {\n\t\t\t\t\tnewBranches.add(branch);\n\t\t\t\t\tcurrentBranches.delete(branch);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (currentBranches.size === 0) {\n\t\t\t\tthis.trunkBranches.delete(currentId);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Advances the minimum sequence number, and removes all commits from the trunk which lie outside the collaboration window,\n\t * if they are not retained by revertibles or local branches.\n\t * @param minimumSequenceNumber - the sequence number of the newest commit that all peers (including this one) have received and applied to their trunks.\n\t *\n\t * @remarks If there are more than one commit with the same sequence number we assume this refers to the last commit in the batch.\n\t */\n\tpublic advanceMinimumSequenceNumber(minimumSequenceNumber: SeqNumber): void {\n\t\tif (minimumSequenceNumber === this.minimumSequenceNumber) {\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\tminimumSequenceNumber > this.minimumSequenceNumber,\n\t\t\t0x476 /* number must be larger or equal to current minimumSequenceNumber. */,\n\t\t);\n\n\t\tthis.minimumSequenceNumber = minimumSequenceNumber;\n\t\tthis.trimTrunk();\n\t}\n\n\t/**\n\t * Examines the latest known minimum sequence number and the trunk bases of any registered branches to determine\n\t * if any commits on the trunk are unreferenced and unneeded for future computation; those found are evicted from the trunk.\n\t * @returns the number of commits that were removed from the trunk\n\t */\n\tprivate trimTrunk(): void {\n\t\t/** The sequence id of the oldest commit on the trunk that will be retained */\n\t\tlet trunkTailSequenceId: SequenceId = {\n\t\t\tsequenceNumber: this.minimumSequenceNumber,\n\t\t\tindexInBatch: Number.POSITIVE_INFINITY,\n\t\t};\n\t\t// If there are any outstanding registered branches, get the one that is the oldest (has the \"most behind\" trunk base)\n\t\tconst minimumBranchBaseSequenceId = this.trunkBranches.minKey();\n\t\tif (minimumBranchBaseSequenceId !== undefined) {\n\t\t\t// If that branch is behind the minimum sequence id, we only want to evict commits older than it,\n\t\t\t// even if those commits are behind the minimum sequence id\n\t\t\tconst sequenceIdBeforeMinimumBranchBase = decrementSequenceId(\n\t\t\t\tminimumBranchBaseSequenceId,\n\t\t\t);\n\t\t\ttrunkTailSequenceId = minSequenceId(\n\t\t\t\ttrunkTailSequenceId,\n\t\t\t\tsequenceIdBeforeMinimumBranchBase,\n\t\t\t);\n\t\t}\n\n\t\tconst [sequenceId, latestEvicted] = this.getClosestTrunkCommit(\n\t\t\tmaxSequenceId(\n\t\t\t\ttrunkTailSequenceId,\n\t\t\t\tthis.sequenceMap.minKey() ?? minimumPossibleSequenceId,\n\t\t\t),\n\t\t);\n\n\t\t// Don't do any work if the commit found by the search is already the tail of the trunk\n\t\tif (latestEvicted !== this.trunkBase) {\n\t\t\t// The minimum sequence number informs us that all peer branches are at least caught up to the tail commit,\n\t\t\t// so rebase them accordingly. This is necessary to prevent peer branches from referencing any evicted commits.\n\t\t\tfor (const [, branch] of this.peerLocalBranches) {\n\t\t\t\tbranch.rebaseOnto(this.trunk, latestEvicted);\n\t\t\t}\n\n\t\t\t// This mutation is a performance hack. If commits are truly immutable, then changing the trunk's tail requires\n\t\t\t// regenerating the entire commit graph. Instead, we can simply chop off the tail like this if we're certain\n\t\t\t// that there are no outstanding references to any of the commits being removed (other than the references via\n\t\t\t// the trunk). The peer branches have been rebased to the head of the trunk, the local branch is already rebased\n\t\t\t// to the head of the trunk, and all other branches are tracked by `trunkBranches` and known to be ahead of or at\n\t\t\t// `newTrunkBase`. Therefore, no branches should have unique references to any of the commits being evicted here.\n\t\t\t// We mutate the most recent of the evicted commits to become the new trunk base. That way, any other commits that\n\t\t\t// have parent pointers to the latest evicted commit will stay linked, even though that it is no longer part of the trunk.\n\t\t\tconst newTrunkBase = latestEvicted as Mutable<typeof latestEvicted>;\n\t\t\t// The metadata for new trunk base revision needs to be deleted before modifying it.\n\t\t\tthis.trunkMetadata.delete(newTrunkBase.revision);\n\t\t\t// collect the revisions that will be trimmed to send as part of the branch trimmed event\n\t\t\tconst trimmedRevisions: RevisionTag[] = getPathFromBase(\n\t\t\t\tnewTrunkBase,\n\t\t\t\tthis.trunkBase,\n\t\t\t).map((c) => c.revision);\n\t\t\t// Copying the revision of the old trunk base into the new trunk base means we don't need to write out the original\n\t\t\t// revision to summaries. All clients agree that the trunk base always has the same hardcoded revision.\n\t\t\tnewTrunkBase.revision = this.trunkBase.revision;\n\t\t\t// Overwriting the change is not strictly necessary, but done here for consistency (so all trunk bases are deeply equal).\n\t\t\tnewTrunkBase.change = this.trunkBase.change;\n\t\t\t// Dropping the parent field removes (transitively) all references to the evicted commits so they can be garbage collected.\n\t\t\tdelete newTrunkBase.parent;\n\t\t\tthis.trunkBase = newTrunkBase;\n\n\t\t\t// Update any state that is derived from trunk commits\n\t\t\tthis.sequenceMap.editRange(\n\t\t\t\tminimumPossibleSequenceId,\n\t\t\t\tsequenceId,\n\t\t\t\ttrue,\n\t\t\t\t(s, { revision }) => {\n\t\t\t\t\t// Cleanup look-aside data for each evicted commit\n\t\t\t\t\tthis.trunkMetadata.delete(revision);\n\t\t\t\t\t// Delete all evicted commits from `sequenceMap` except for the latest one, which is the new `trunkBase`\n\t\t\t\t\tif (equalSequenceIds(s, sequenceId)) {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\trevision === newTrunkBase.revision,\n\t\t\t\t\t\t\t0x729 /* Expected last evicted commit to be new trunk base */,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn { delete: true };\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst trunkSize = getPathFromBase(this.trunk.getHead(), this.trunkBase).length;\n\t\t\tassert(\n\t\t\t\tthis.sequenceMap.size === trunkSize + 1,\n\t\t\t\t0x744 /* The size of the sequenceMap must have one element more than the trunk */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tthis.trunkMetadata.size === trunkSize,\n\t\t\t\t0x745 /* The size of the trunkMetadata must be the same as the trunk */,\n\t\t\t);\n\n\t\t\tthis._events.emit(\"ancestryTrimmed\", trimmedRevisions);\n\t\t}\n\t}\n\n\tpublic isEmpty(): boolean {\n\t\treturn (\n\t\t\tthis.trunk.getHead() === this.trunkBase &&\n\t\t\tthis.peerLocalBranches.size === 0 &&\n\t\t\tthis.localBranch.getHead() === this.trunk.getHead() &&\n\t\t\tthis.minimumSequenceNumber === minimumPossibleSequenceNumber\n\t\t);\n\t}\n\n\tpublic getSummaryData(): SummaryData<TChangeset> {\n\t\t// The assert below is acceptable at present because summarization only ever occurs on a client with no\n\t\t// local/in-flight changes.\n\t\t// In the future we may wish to relax this constraint. For that to work, the current implementation of\n\t\t// `EditManager` would have to be amended in one of two ways:\n\t\t// A) Changes made by the local session should be represented by a branch in `EditManager.branches`.\n\t\t// B) The contents of such a branch should be computed on demand based on the trunk.\n\t\t// Note that option (A) would be a simple change to `addSequencedChange` whereas (B) would likely require\n\t\t// rebasing trunk changes over the inverse of trunk changes.\n\t\tassert(\n\t\t\tthis.localBranch.getHead() === this.trunk.getHead(),\n\t\t\t0x428 /* Clients with local changes cannot be used to generate summaries */,\n\t\t);\n\n\t\tlet oldestCommitInCollabWindow = this.getClosestTrunkCommit(this.minimumSequenceNumber)[1];\n\t\tassert(\n\t\t\toldestCommitInCollabWindow.parent !== undefined ||\n\t\t\t\toldestCommitInCollabWindow === this.trunkBase,\n\t\t\t0x8c7 /* Expected oldest commit in collab window to have a parent or be the trunk base */,\n\t\t);\n\n\t\t// Path construction is exclusive, so we need to use the parent of the oldest commit in the window if it exists\n\t\toldestCommitInCollabWindow =\n\t\t\toldestCommitInCollabWindow.parent ?? oldestCommitInCollabWindow;\n\n\t\tconst trunk = getPathFromBase(this.trunk.getHead(), oldestCommitInCollabWindow).map((c) => {\n\t\t\tconst metadata =\n\t\t\t\tthis.trunkMetadata.get(c.revision) ?? fail(\"Expected metadata for trunk commit\");\n\t\t\tconst commit: SequencedCommit<TChangeset> = {\n\t\t\t\tchange: c.change,\n\t\t\t\trevision: c.revision,\n\t\t\t\tsequenceNumber: metadata.sequenceId.sequenceNumber,\n\t\t\t\tsessionId: metadata.sessionId,\n\t\t\t};\n\t\t\tif (metadata.sequenceId.indexInBatch !== undefined) {\n\t\t\t\tcommit.indexInBatch = metadata.sequenceId.indexInBatch;\n\t\t\t}\n\t\t\treturn commit;\n\t\t});\n\n\t\tconst peerLocalBranches = new Map<SessionId, SummarySessionBranch<TChangeset>>(\n\t\t\tmapIterable(this.peerLocalBranches.entries(), ([sessionId, branch]) => {\n\t\t\t\tconst branchPath: GraphCommit<TChangeset>[] = [];\n\t\t\t\tconst ancestor =\n\t\t\t\t\tfindCommonAncestor([branch.getHead(), branchPath], this.trunk.getHead()) ??\n\t\t\t\t\tfail(\"Expected branch to be based on trunk\");\n\n\t\t\t\treturn [\n\t\t\t\t\tsessionId,\n\t\t\t\t\t{\n\t\t\t\t\t\tbase: ancestor.revision,\n\t\t\t\t\t\tcommits: branchPath.map((c) => {\n\t\t\t\t\t\t\tconst commit: Commit<TChangeset> = {\n\t\t\t\t\t\t\t\tchange: c.change,\n\t\t\t\t\t\t\t\trevision: c.revision,\n\t\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\treturn commit;\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}),\n\t\t);\n\n\t\treturn { trunk, peerLocalBranches };\n\t}\n\n\tpublic loadSummaryData(data: SummaryData<TChangeset>): void {\n\t\tassert(\n\t\t\tthis.isEmpty(),\n\t\t\t0x68a /* Attempted to load from summary after edit manager was already mutated */,\n\t\t);\n\t\t// Record the tags of each trunk commit as we generate the trunk so they can be looked up quickly\n\t\t// when hydrating the peer branches below\n\t\tconst trunkRevisionCache = new Map<RevisionTag, GraphCommit<TChangeset>>();\n\t\ttrunkRevisionCache.set(this.trunkBase.revision, this.trunkBase);\n\t\tthis.trunk.setHead(\n\t\t\tdata.trunk.reduce((base, c) => {\n\t\t\t\tconst sequenceId: SequenceId =\n\t\t\t\t\tc.indexInBatch === undefined\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tsequenceNumber: c.sequenceNumber,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tsequenceNumber: c.sequenceNumber,\n\t\t\t\t\t\t\t\tindexInBatch: c.indexInBatch,\n\t\t\t\t\t\t };\n\t\t\t\tconst commit = mintCommit(base, c);\n\t\t\t\tthis.sequenceMap.set(sequenceId, commit);\n\t\t\t\tthis.trunkMetadata.set(c.revision, {\n\t\t\t\t\tsequenceId,\n\t\t\t\t\tsessionId: c.sessionId,\n\t\t\t\t});\n\t\t\t\ttrunkRevisionCache.set(c.revision, commit);\n\t\t\t\treturn commit;\n\t\t\t}, this.trunkBase),\n\t\t);\n\n\t\tthis.localBranch.setHead(this.trunk.getHead());\n\n\t\tfor (const [sessionId, branch] of data.peerLocalBranches) {\n\t\t\tconst commit =\n\t\t\t\ttrunkRevisionCache.get(branch.base) ??\n\t\t\t\tfail(\"Expected summary branch to be based off of a revision in the trunk\");\n\n\t\t\tthis.peerLocalBranches.set(\n\t\t\t\tsessionId,\n\t\t\t\tnew SharedTreeBranch(\n\t\t\t\t\tbranch.commits.reduce(mintCommit, commit),\n\t\t\t\t\tthis.changeFamily,\n\t\t\t\t\tthis.mintRevisionTag,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate getCommitSequenceId(commit: GraphCommit<TChangeset>): SequenceId {\n\t\treturn this.trunkMetadata.get(commit.revision)?.sequenceId ?? minimumPossibleSequenceId;\n\t}\n\n\tpublic getTrunkChanges(): readonly TChangeset[] {\n\t\treturn this.getTrunkCommits().map((c) => c.change);\n\t}\n\n\tpublic getTrunkCommits(): readonly GraphCommit<TChangeset>[] {\n\t\treturn getPathFromBase(this.trunk.getHead(), this.trunkBase);\n\t}\n\n\tpublic getTrunkHead(): GraphCommit<TChangeset> {\n\t\treturn this.trunk.getHead();\n\t}\n\n\tpublic getLocalChanges(): readonly TChangeset[] {\n\t\treturn this.getLocalCommits().map((c) => c.change);\n\t}\n\n\tpublic getLocalCommits(): readonly GraphCommit<TChangeset>[] {\n\t\treturn this.localCommits;\n\t}\n\n\t/**\n\t * @returns The length of the longest branch maintained by this EditManager.\n\t * This may be the length of a peer branch or the local branch.\n\t * The length is counted from the lowest common ancestor with the trunk such that a fully sequenced branch would\n\t * have length zero.\n\t */\n\tpublic getLongestBranchLength(): number {\n\t\tlet max = 0;\n\t\tconst trunkHead = this.trunk.getHead();\n\t\tfor (const branch of this.peerLocalBranches.values()) {\n\t\t\tconst branchPath = getPathFromBase(branch.getHead(), trunkHead);\n\t\t\tif (branchPath.length > max) {\n\t\t\t\tmax = branchPath.length;\n\t\t\t}\n\t\t}\n\t\tconst localPath = getPathFromBase(this.localBranch.getHead(), trunkHead);\n\t\treturn Math.max(max, localPath.length);\n\t}\n\n\tpublic addSequencedChange(\n\t\tnewCommit: Commit<TChangeset>,\n\t\tsequenceNumber: SeqNumber,\n\t\treferenceSequenceNumber: SeqNumber,\n\t): void {\n\t\tassert(\n\t\t\tsequenceNumber > this.minimumSequenceNumber,\n\t\t\t0x713 /* Expected change sequence number to exceed the last known minimum sequence number */,\n\t\t);\n\n\t\tconst commitsSequenceNumber = this.getBatch(sequenceNumber);\n\t\tconst sequenceId: SequenceId =\n\t\t\tcommitsSequenceNumber.length === 0\n\t\t\t\t? {\n\t\t\t\t\t\tsequenceNumber,\n\t\t\t\t }\n\t\t\t\t: {\n\t\t\t\t\t\tsequenceNumber,\n\t\t\t\t\t\tindexInBatch: commitsSequenceNumber.length,\n\t\t\t\t };\n\n\t\tif (newCommit.sessionId === this.localSessionId) {\n\t\t\tconst headTrunkCommit = this.trunk.getHead();\n\t\t\tconst firstLocalCommit = this.localCommits.shift();\n\t\t\tassert(\n\t\t\t\tfirstLocalCommit !== undefined,\n\t\t\t\t0x6b5 /* Received a sequenced change from the local session despite having no local changes */,\n\t\t\t);\n\n\t\t\t// The first local branch commit is already rebased over the trunk, so we can push it directly to the trunk.\n\t\t\tthis.pushGraphCommitToTrunk(sequenceId, firstLocalCommit, this.localSessionId);\n\t\t\tthis.fastForwardBranches(headTrunkCommit, sequenceId);\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the revision that the remote change is based on\n\t\tconst [, baseRevisionInTrunk] = this.getClosestTrunkCommit(referenceSequenceNumber);\n\t\t// Rebase that branch over the part of the trunk up to the base revision\n\t\t// This will be a no-op if the sending client has not advanced since the last time we received an edit from it\n\t\tconst peerLocalBranch = getOrCreate(\n\t\t\tthis.peerLocalBranches,\n\t\t\tnewCommit.sessionId,\n\t\t\t() =>\n\t\t\t\tnew SharedTreeBranch(baseRevisionInTrunk, this.changeFamily, this.mintRevisionTag),\n\t\t);\n\t\tpeerLocalBranch.rebaseOnto(this.trunk, baseRevisionInTrunk);\n\n\t\tif (peerLocalBranch.getHead() === this.trunk.getHead()) {\n\t\t\t// If the branch is fully caught up and empty after being rebased, then push to the trunk directly\n\t\t\tthis.pushCommitToTrunk(sequenceId, newCommit);\n\t\t\tpeerLocalBranch.setHead(this.trunk.getHead());\n\t\t} else {\n\t\t\t// Otherwise, rebase the change over the trunk and append it, and append the original change to the peer branch.\n\t\t\tconst newChangeFullyRebased = rebaseChange(\n\t\t\t\tthis.changeFamily.rebaser,\n\t\t\t\tnewCommit,\n\t\t\t\tpeerLocalBranch.getHead(),\n\t\t\t\tthis.trunk.getHead(),\n\t\t\t\tthis.mintRevisionTag,\n\t\t\t);\n\n\t\t\tpeerLocalBranch.apply(newCommit.change, newCommit.revision);\n\t\t\tthis.pushCommitToTrunk(sequenceId, {\n\t\t\t\t...newCommit,\n\t\t\t\tchange: newChangeFullyRebased.change,\n\t\t\t});\n\t\t}\n\n\t\tthis.localBranch.rebaseOnto(this.trunk);\n\t}\n\n\tpublic findLocalCommit(\n\t\trevision: RevisionTag,\n\t): [commit: GraphCommit<TChangeset>, commitsAfter: GraphCommit<TChangeset>[]] {\n\t\tconst commits: GraphCommit<TChangeset>[] = [];\n\t\tconst commit = findAncestor(\n\t\t\t[this.localBranch.getHead(), commits],\n\t\t\t(c) => c.revision === revision,\n\t\t);\n\t\tassert(commit !== undefined, 0x599 /* Expected local branch to contain revision */);\n\t\treturn [commit, commits];\n\t}\n\n\tprivate pushCommitToTrunk(\n\t\tsequenceId: SequenceId,\n\t\tcommit: Commit<TChangeset>,\n\t\tlocal = false,\n\t): void {\n\t\tconst mintedCommit = mintCommit(this.trunk.getHead(), commit);\n\t\tthis.pushGraphCommitToTrunk(sequenceId, mintedCommit, commit.sessionId);\n\t}\n\n\tprivate pushGraphCommitToTrunk(\n\t\tsequenceId: SequenceId,\n\t\tgraphCommit: GraphCommit<TChangeset>,\n\t\tsessionId: SessionId,\n\t): void {\n\t\tthis.trunk.setHead(graphCommit);\n\t\tconst trunkHead = this.trunk.getHead();\n\t\tthis.sequenceMap.set(sequenceId, trunkHead);\n\t\tthis.trunkMetadata.set(trunkHead.revision, { sequenceId, sessionId });\n\t}\n\n\t/**\n\t * Finds the most recent trunk commit that was sequenced at or before the given point.\n\t * @param searchBy - the sequence number or the sequence id to search for\n\t * @remarks Fails if there is no eligible commit.\n\t * @returns the closest commit and its sequence id\n\t */\n\tprivate getClosestTrunkCommit(searchBy: SeqNumber): [SequenceId, GraphCommit<TChangeset>];\n\tprivate getClosestTrunkCommit(searchBy: SequenceId): [SequenceId, GraphCommit<TChangeset>];\n\tprivate getClosestTrunkCommit(\n\t\tsearchBy: SeqNumber | SequenceId,\n\t): [SequenceId, GraphCommit<TChangeset>] {\n\t\tconst sequenceId: SequenceId =\n\t\t\ttypeof searchBy === \"number\"\n\t\t\t\t? {\n\t\t\t\t\t\t// This is to make sure that the correct commit is selected in this 2 scenarios:\n\t\t\t\t\t\t// 1) The commit is unique for that sequence number\n\t\t\t\t\t\t// 2) There are more than one commit for the same sequence number, in this case we need to select the last one.\n\t\t\t\t\t\tsequenceNumber: searchBy,\n\t\t\t\t\t\tindexInBatch: Number.POSITIVE_INFINITY,\n\t\t\t\t }\n\t\t\t\t: searchBy;\n\n\t\tconst commit = this.sequenceMap.getPairOrNextLower(sequenceId);\n\t\tassert(commit !== undefined, 0x746 /* sequence id has been evicted */);\n\t\treturn commit;\n\t}\n\n\tprivate getBatch(sequenceNumber: SeqNumber): [SequenceId, GraphCommit<TChangeset>][] {\n\t\tconst startSequenceId: SequenceId = {\n\t\t\tsequenceNumber,\n\t\t};\n\t\tconst endSequenceId: SequenceId = {\n\t\t\tsequenceNumber: brand((sequenceNumber as number) + 1),\n\t\t};\n\n\t\treturn this.sequenceMap.getRange(startSequenceId, endSequenceId, false);\n\t}\n}\n\n/**\n * The in-memory data that summaries contain\n */\nexport interface SummaryData<TChangeset> {\n\treadonly trunk: readonly SequencedCommit<TChangeset>[];\n\treadonly peerLocalBranches: ReadonlyMap<SessionId, SummarySessionBranch<TChangeset>>;\n}\n\n/**\n * @returns the path from the base of a branch to its head\n */\nfunction getPathFromBase<TCommit extends { parent?: TCommit }>(\n\tbranchHead: TCommit,\n\tbaseBranchHead: TCommit,\n): TCommit[] {\n\tconst path: TCommit[] = [];\n\tassert(\n\t\tfindCommonAncestor([branchHead, path], baseBranchHead) !== undefined,\n\t\t0x573 /* Expected branches to be related */,\n\t);\n\treturn path;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"editManager.js","sourceRoot":"","sources":["../../src/shared-tree-core/editManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { SessionId } from \"@fluidframework/id-compressor\";\nimport { BTree } from \"@tylerbu/sorted-btree-es6\";\n\nimport {\n\ttype ChangeFamily,\n\ttype ChangeFamilyEditor,\n\ttype GraphCommit,\n\ttype RevisionTag,\n\tfindAncestor,\n\tfindCommonAncestor,\n\tmintCommit,\n\trebaseChange,\n} from \"../core/index.js\";\nimport { type Mutable, brand, fail, getOrCreate, mapIterable } from \"../util/index.js\";\n\nimport {\n\tSharedTreeBranch,\n\ttype BranchTrimmingEvents,\n\tgetChangeReplaceType,\n\tonForkTransitive,\n} from \"./branch.js\";\nimport type {\n\tCommit,\n\tSeqNumber,\n\tSequenceId,\n\tSequencedCommit,\n\tSummarySessionBranch,\n} from \"./editManagerFormat.js\";\nimport {\n\tdecrementSequenceId,\n\tequalSequenceIds,\n\tmaxSequenceId,\n\tminSequenceId,\n\tsequenceIdComparator,\n} from \"./sequenceIdUtils.js\";\nimport { createEmitter } from \"../events/index.js\";\n\nexport const minimumPossibleSequenceNumber: SeqNumber = brand(Number.MIN_SAFE_INTEGER);\nconst minimumPossibleSequenceId: SequenceId = {\n\tsequenceNumber: minimumPossibleSequenceNumber,\n};\n\n/**\n * Represents a local branch of a document and interprets the effect on the document of adding sequenced changes,\n * which were based on a given session's branch, to the document history\n */\n// TODO: Try to reduce this to a single type parameter\nexport class EditManager<\n\tTEditor extends ChangeFamilyEditor,\n\tTChangeset,\n\tTChangeFamily extends ChangeFamily<TEditor, TChangeset>,\n> {\n\tprivate readonly _events = createEmitter<BranchTrimmingEvents>();\n\n\t/** The \"trunk\" branch. The trunk represents the list of received sequenced changes. */\n\tprivate readonly trunk: SharedTreeBranch<TEditor, TChangeset>;\n\n\t/**\n\t * Records extra data associated with commits in the {@link trunk}.\n\t * This does not include an entry for the {@link trunkBase}.\n\t */\n\tprivate readonly trunkMetadata = new Map<\n\t\tRevisionTag,\n\t\t{ sequenceId: SequenceId; sessionId: SessionId }\n\t>();\n\t/**\n\t * A map from a sequence id to the commit in the {@link trunk} which has that sequence id.\n\t * This also includes an entry for the {@link trunkBase} which always has the lowest key in the map.\n\t */\n\tprivate readonly sequenceMap = new BTree<SequenceId, GraphCommit<TChangeset>>(\n\t\tundefined,\n\t\tsequenceIdComparator,\n\t);\n\n\t/**\n\t * Branches are maintained to represent the local change list that the issuing client had\n\t * at the time of submitting the latest known edit on the branch.\n\t * This means the head commit of each branch is always in its original (non-rebased) form.\n\t */\n\tprivate readonly peerLocalBranches: Map<SessionId, SharedTreeBranch<TEditor, TChangeset>> =\n\t\tnew Map();\n\n\t/**\n\t * This branch holds the changes made by this client which have not yet been confirmed as sequenced changes.\n\t */\n\tpublic readonly localBranch: SharedTreeBranch<TEditor, TChangeset>;\n\n\t/**\n\t * Tracks where on the trunk all registered branches are based. Each key is the sequence id of a commit on\n\t * the trunk, and the value is the set of all branches who have that commit as their common ancestor with the trunk.\n\t *\n\t * @remarks\n\t * This does not include the local branch.\n\t */\n\tprivate readonly trunkBranches = new BTree<\n\t\tSequenceId,\n\t\tSet<SharedTreeBranch<TEditor, TChangeset>>\n\t>(undefined, sequenceIdComparator);\n\n\t/**\n\t * The sequence number of the newest commit on the trunk that has been received by all peers.\n\t * Defaults to {@link minimumPossibleSequenceNumber} if no commits have been received.\n\t *\n\t * @remarks If there are more than one commit with the same sequence number we assume this refers to the last commit in the batch.\n\t */\n\tprivate minimumSequenceNumber = minimumPossibleSequenceNumber;\n\n\t/**\n\t * A special commit that is a \"base\" (tail) of the trunk, though not part of the trunk itself.\n\t * This makes it possible to model the trunk in the same way as any other branch (it branches off of a base commit)\n\t * which allows it to use branching APIs to interact with the other branches.\n\t * Each time trunk eviction occurs, the most recent evicted commit becomes the new `trunkBase`.\n\t */\n\tprivate trunkBase: GraphCommit<TChangeset>;\n\n\t/**\n\t * The list of commits (from oldest to most recent) that are on the local branch but not on the trunk.\n\t * When a local commit is sequenced, the first commit in this list shifted onto the tip of the trunk.\n\t */\n\tprivate readonly localCommits: GraphCommit<TChangeset>[] = [];\n\n\t/**\n\t * @param changeFamily - the change family of changes on the trunk and local branch\n\t * @param localSessionId - the id of the local session that will be used for local commits\n\t */\n\tpublic constructor(\n\t\tpublic readonly changeFamily: TChangeFamily,\n\t\tpublic readonly localSessionId: SessionId,\n\t\tprivate readonly mintRevisionTag: () => RevisionTag,\n\t) {\n\t\tthis.trunkBase = {\n\t\t\trevision: \"root\",\n\t\t\tchange: changeFamily.rebaser.compose([]),\n\t\t};\n\t\tthis.sequenceMap.set(minimumPossibleSequenceId, this.trunkBase);\n\t\tthis.trunk = new SharedTreeBranch(\n\t\t\tthis.trunkBase,\n\t\t\tchangeFamily,\n\t\t\tmintRevisionTag,\n\t\t\tthis._events,\n\t\t);\n\t\tthis.localBranch = new SharedTreeBranch(\n\t\t\tthis.trunk.getHead(),\n\t\t\tchangeFamily,\n\t\t\tmintRevisionTag,\n\t\t\tthis._events,\n\t\t);\n\n\t\tthis.localBranch.on(\"afterChange\", (event) => {\n\t\t\tif (event.type === \"append\") {\n\t\t\t\tfor (const commit of event.newCommits) {\n\t\t\t\t\tthis.localCommits.push(commit);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.localCommits.length = 0;\n\t\t\t\tfindCommonAncestor(\n\t\t\t\t\t[this.localBranch.getHead(), this.localCommits],\n\t\t\t\t\tthis.trunk.getHead(),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\t// Track all forks of the local branch for purposes of trunk eviction. Unlike the local branch, they have\n\t\t// an unknown lifetime and rebase frequency, so we can not make any assumptions about which trunk commits\n\t\t// they require and therefore we monitor them explicitly.\n\t\tonForkTransitive(this.localBranch, (fork) => this.registerBranch(fork));\n\t}\n\n\t/**\n\t * Make the given branch known to the `EditManager`. The `EditManager` will ensure that all registered\n\t * branches remain usable even as the minimum sequence number advances.\n\t *\n\t * TODO#AB6926: Refactor local branch management into a separate class that encapsulates `trunkBranches` and everything\n\t * that touches it.\n\t * TODO#AB6925: Maintain the divergence point between each branch and the trunk so that we don't have to recompute\n\t * it so often.\n\t */\n\tprivate registerBranch(branch: SharedTreeBranch<TEditor, TChangeset>): void {\n\t\tthis.trackBranch(branch);\n\t\t// Whenever the branch is rebased, update our record of its base trunk commit\n\t\tconst offBeforeRebase = branch.on(\"beforeChange\", (args) => {\n\t\t\tif (args.type === \"replace\" && getChangeReplaceType(args) === \"rebase\") {\n\t\t\t\tthis.untrackBranch(branch);\n\t\t\t}\n\t\t});\n\t\tconst offAfterRebase = branch.on(\"afterChange\", (args) => {\n\t\t\tif (args.type === \"replace\" && getChangeReplaceType(args) === \"rebase\") {\n\t\t\t\tthis.trackBranch(branch);\n\t\t\t\tthis.trimTrunk();\n\t\t\t}\n\t\t});\n\t\t// When the branch is disposed, update our branch set and trim the trunk\n\t\tconst offDispose = branch.on(\"dispose\", () => {\n\t\t\tthis.untrackBranch(branch);\n\t\t\tthis.trimTrunk();\n\t\t\toffBeforeRebase();\n\t\t\toffAfterRebase();\n\t\t\toffDispose();\n\t\t});\n\t}\n\n\tprivate trackBranch(b: SharedTreeBranch<TEditor, TChangeset>): void {\n\t\tconst trunkCommit =\n\t\t\tfindCommonAncestor(this.trunk.getHead(), b.getHead()) ??\n\t\t\tfail(\"Expected branch to be related to trunk\");\n\t\tconst sequenceId = this.getCommitSequenceId(trunkCommit);\n\t\tconst branches = getOrCreate(this.trunkBranches, sequenceId, () => new Set());\n\n\t\tassert(!branches.has(b), 0x670 /* Branch was registered more than once */);\n\t\tbranches.add(b);\n\t}\n\n\tprivate untrackBranch(b: SharedTreeBranch<TEditor, TChangeset>): void {\n\t\tconst trunkCommit =\n\t\t\tfindCommonAncestor(this.trunk.getHead(), b.getHead()) ??\n\t\t\tfail(\"Expected branch to be related to trunk\");\n\t\tconst sequenceId = this.getCommitSequenceId(trunkCommit);\n\t\tconst branches =\n\t\t\tthis.trunkBranches.get(sequenceId) ?? fail(\"Expected branch to be tracked\");\n\n\t\tassert(branches.delete(b), 0x671 /* Expected branch to be tracked */);\n\t\tif (branches.size === 0) {\n\t\t\tthis.trunkBranches.delete(sequenceId);\n\t\t}\n\t}\n\n\t/**\n\t * Updates the `trunkBranches` map to reflect the fact that a new local commit was fast-forwarded to the trunk.\n\t * @param priorTrunkCommit - The trunk head prior to the fast-forward.\n\t * @param newId - The ID of the new trunk head.\n\t */\n\tprivate fastForwardBranches(\n\t\tpriorTrunkCommit: GraphCommit<TChangeset>,\n\t\tnewId: SequenceId,\n\t): void {\n\t\tconst currentId = this.getCommitSequenceId(priorTrunkCommit);\n\t\tconst currentBranches = this.trunkBranches.get(currentId);\n\t\tif (currentBranches !== undefined) {\n\t\t\tconst newBranches = getOrCreate(this.trunkBranches, newId, () => new Set());\n\t\t\tfor (const branch of currentBranches) {\n\t\t\t\tif (branch.getHead() !== priorTrunkCommit) {\n\t\t\t\t\tnewBranches.add(branch);\n\t\t\t\t\tcurrentBranches.delete(branch);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (currentBranches.size === 0) {\n\t\t\t\tthis.trunkBranches.delete(currentId);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Advances the minimum sequence number, and removes all commits from the trunk which lie outside the collaboration window,\n\t * if they are not retained by revertibles or local branches.\n\t * @param minimumSequenceNumber - the sequence number of the newest commit that all peers (including this one) have received and applied to their trunks.\n\t *\n\t * @remarks If there are more than one commit with the same sequence number we assume this refers to the last commit in the batch.\n\t */\n\tpublic advanceMinimumSequenceNumber(minimumSequenceNumber: SeqNumber): void {\n\t\tif (minimumSequenceNumber === this.minimumSequenceNumber) {\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\tminimumSequenceNumber > this.minimumSequenceNumber,\n\t\t\t0x476 /* number must be larger or equal to current minimumSequenceNumber. */,\n\t\t);\n\n\t\tthis.minimumSequenceNumber = minimumSequenceNumber;\n\t\tthis.trimTrunk();\n\t}\n\n\t/**\n\t * Examines the latest known minimum sequence number and the trunk bases of any registered branches to determine\n\t * if any commits on the trunk are unreferenced and unneeded for future computation; those found are evicted from the trunk.\n\t * @returns the number of commits that were removed from the trunk\n\t */\n\tprivate trimTrunk(): void {\n\t\t/** The sequence id of the oldest commit on the trunk that will be retained */\n\t\tlet trunkTailSequenceId: SequenceId = {\n\t\t\tsequenceNumber: this.minimumSequenceNumber,\n\t\t\tindexInBatch: Number.POSITIVE_INFINITY,\n\t\t};\n\t\t// If there are any outstanding registered branches, get the one that is the oldest (has the \"most behind\" trunk base)\n\t\tconst minimumBranchBaseSequenceId = this.trunkBranches.minKey();\n\t\tif (minimumBranchBaseSequenceId !== undefined) {\n\t\t\t// If that branch is behind the minimum sequence id, we only want to evict commits older than it,\n\t\t\t// even if those commits are behind the minimum sequence id\n\t\t\tconst sequenceIdBeforeMinimumBranchBase = decrementSequenceId(\n\t\t\t\tminimumBranchBaseSequenceId,\n\t\t\t);\n\t\t\ttrunkTailSequenceId = minSequenceId(\n\t\t\t\ttrunkTailSequenceId,\n\t\t\t\tsequenceIdBeforeMinimumBranchBase,\n\t\t\t);\n\t\t}\n\n\t\tconst [sequenceId, latestEvicted] = this.getClosestTrunkCommit(\n\t\t\tmaxSequenceId(\n\t\t\t\ttrunkTailSequenceId,\n\t\t\t\tthis.sequenceMap.minKey() ?? minimumPossibleSequenceId,\n\t\t\t),\n\t\t);\n\n\t\t// Don't do any work if the commit found by the search is already the tail of the trunk\n\t\tif (latestEvicted !== this.trunkBase) {\n\t\t\t// The minimum sequence number informs us that all peer branches are at least caught up to the tail commit,\n\t\t\t// so rebase them accordingly. This is necessary to prevent peer branches from referencing any evicted commits.\n\t\t\tfor (const [, branch] of this.peerLocalBranches) {\n\t\t\t\tbranch.rebaseOnto(this.trunk, latestEvicted);\n\t\t\t}\n\n\t\t\t// This mutation is a performance hack. If commits are truly immutable, then changing the trunk's tail requires\n\t\t\t// regenerating the entire commit graph. Instead, we can simply chop off the tail like this if we're certain\n\t\t\t// that there are no outstanding references to any of the commits being removed (other than the references via\n\t\t\t// the trunk). The peer branches have been rebased to the head of the trunk, the local branch is already rebased\n\t\t\t// to the head of the trunk, and all other branches are tracked by `trunkBranches` and known to be ahead of or at\n\t\t\t// `newTrunkBase`. Therefore, no branches should have unique references to any of the commits being evicted here.\n\t\t\t// We mutate the most recent of the evicted commits to become the new trunk base. That way, any other commits that\n\t\t\t// have parent pointers to the latest evicted commit will stay linked, even though that it is no longer part of the trunk.\n\t\t\tconst newTrunkBase = latestEvicted as Mutable<typeof latestEvicted>;\n\t\t\t// The metadata for new trunk base revision needs to be deleted before modifying it.\n\t\t\tthis.trunkMetadata.delete(newTrunkBase.revision);\n\t\t\t// collect the revisions that will be trimmed to send as part of the branch trimmed event\n\t\t\tconst trimmedRevisions: RevisionTag[] = getPathFromBase(\n\t\t\t\tnewTrunkBase,\n\t\t\t\tthis.trunkBase,\n\t\t\t).map((c) => c.revision);\n\t\t\t// Copying the revision of the old trunk base into the new trunk base means we don't need to write out the original\n\t\t\t// revision to summaries. All clients agree that the trunk base always has the same hardcoded revision.\n\t\t\tnewTrunkBase.revision = this.trunkBase.revision;\n\t\t\t// Overwriting the change is not strictly necessary, but done here for consistency (so all trunk bases are deeply equal).\n\t\t\tnewTrunkBase.change = this.trunkBase.change;\n\t\t\t// Dropping the parent field removes (transitively) all references to the evicted commits so they can be garbage collected.\n\t\t\tdelete newTrunkBase.parent;\n\t\t\tthis.trunkBase = newTrunkBase;\n\n\t\t\t// Update any state that is derived from trunk commits\n\t\t\tthis.sequenceMap.editRange(\n\t\t\t\tminimumPossibleSequenceId,\n\t\t\t\tsequenceId,\n\t\t\t\ttrue,\n\t\t\t\t(s, { revision }) => {\n\t\t\t\t\t// Cleanup look-aside data for each evicted commit\n\t\t\t\t\tthis.trunkMetadata.delete(revision);\n\t\t\t\t\t// Delete all evicted commits from `sequenceMap` except for the latest one, which is the new `trunkBase`\n\t\t\t\t\tif (equalSequenceIds(s, sequenceId)) {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\trevision === newTrunkBase.revision,\n\t\t\t\t\t\t\t0x729 /* Expected last evicted commit to be new trunk base */,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn { delete: true };\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst trunkSize = getPathFromBase(this.trunk.getHead(), this.trunkBase).length;\n\t\t\tassert(\n\t\t\t\tthis.sequenceMap.size === trunkSize + 1,\n\t\t\t\t0x744 /* The size of the sequenceMap must have one element more than the trunk */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tthis.trunkMetadata.size === trunkSize,\n\t\t\t\t0x745 /* The size of the trunkMetadata must be the same as the trunk */,\n\t\t\t);\n\n\t\t\tthis._events.emit(\"ancestryTrimmed\", trimmedRevisions);\n\t\t}\n\t}\n\n\tpublic isEmpty(): boolean {\n\t\treturn (\n\t\t\tthis.trunk.getHead() === this.trunkBase &&\n\t\t\tthis.peerLocalBranches.size === 0 &&\n\t\t\tthis.localBranch.getHead() === this.trunk.getHead() &&\n\t\t\tthis.minimumSequenceNumber === minimumPossibleSequenceNumber\n\t\t);\n\t}\n\n\tpublic getSummaryData(): SummaryData<TChangeset> {\n\t\t// The assert below is acceptable at present because summarization only ever occurs on a client with no\n\t\t// local/in-flight changes.\n\t\t// In the future we may wish to relax this constraint. For that to work, the current implementation of\n\t\t// `EditManager` would have to be amended in one of two ways:\n\t\t// A) Changes made by the local session should be represented by a branch in `EditManager.branches`.\n\t\t// B) The contents of such a branch should be computed on demand based on the trunk.\n\t\t// Note that option (A) would be a simple change to `addSequencedChange` whereas (B) would likely require\n\t\t// rebasing trunk changes over the inverse of trunk changes.\n\t\tassert(\n\t\t\tthis.localBranch.getHead() === this.trunk.getHead(),\n\t\t\t0x428 /* Clients with local changes cannot be used to generate summaries */,\n\t\t);\n\n\t\tlet oldestCommitInCollabWindow = this.getClosestTrunkCommit(this.minimumSequenceNumber)[1];\n\t\tassert(\n\t\t\toldestCommitInCollabWindow.parent !== undefined ||\n\t\t\t\toldestCommitInCollabWindow === this.trunkBase,\n\t\t\t0x8c7 /* Expected oldest commit in collab window to have a parent or be the trunk base */,\n\t\t);\n\n\t\t// Path construction is exclusive, so we need to use the parent of the oldest commit in the window if it exists\n\t\toldestCommitInCollabWindow =\n\t\t\toldestCommitInCollabWindow.parent ?? oldestCommitInCollabWindow;\n\n\t\tconst trunk = getPathFromBase(this.trunk.getHead(), oldestCommitInCollabWindow).map((c) => {\n\t\t\tconst metadata =\n\t\t\t\tthis.trunkMetadata.get(c.revision) ?? fail(\"Expected metadata for trunk commit\");\n\t\t\tconst commit: SequencedCommit<TChangeset> = {\n\t\t\t\tchange: c.change,\n\t\t\t\trevision: c.revision,\n\t\t\t\tsequenceNumber: metadata.sequenceId.sequenceNumber,\n\t\t\t\tsessionId: metadata.sessionId,\n\t\t\t};\n\t\t\tif (metadata.sequenceId.indexInBatch !== undefined) {\n\t\t\t\tcommit.indexInBatch = metadata.sequenceId.indexInBatch;\n\t\t\t}\n\t\t\treturn commit;\n\t\t});\n\n\t\tconst peerLocalBranches = new Map<SessionId, SummarySessionBranch<TChangeset>>(\n\t\t\tmapIterable(this.peerLocalBranches.entries(), ([sessionId, branch]) => {\n\t\t\t\tconst branchPath: GraphCommit<TChangeset>[] = [];\n\t\t\t\tconst ancestor =\n\t\t\t\t\tfindCommonAncestor([branch.getHead(), branchPath], this.trunk.getHead()) ??\n\t\t\t\t\tfail(\"Expected branch to be based on trunk\");\n\n\t\t\t\treturn [\n\t\t\t\t\tsessionId,\n\t\t\t\t\t{\n\t\t\t\t\t\tbase: ancestor.revision,\n\t\t\t\t\t\tcommits: branchPath.map((c) => {\n\t\t\t\t\t\t\tconst commit: Commit<TChangeset> = {\n\t\t\t\t\t\t\t\tchange: c.change,\n\t\t\t\t\t\t\t\trevision: c.revision,\n\t\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\treturn commit;\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}),\n\t\t);\n\n\t\treturn { trunk, peerLocalBranches };\n\t}\n\n\tpublic loadSummaryData(data: SummaryData<TChangeset>): void {\n\t\tassert(\n\t\t\tthis.isEmpty(),\n\t\t\t0x68a /* Attempted to load from summary after edit manager was already mutated */,\n\t\t);\n\t\t// Record the tags of each trunk commit as we generate the trunk so they can be looked up quickly\n\t\t// when hydrating the peer branches below\n\t\tconst trunkRevisionCache = new Map<RevisionTag, GraphCommit<TChangeset>>();\n\t\ttrunkRevisionCache.set(this.trunkBase.revision, this.trunkBase);\n\t\tthis.trunk.setHead(\n\t\t\tdata.trunk.reduce((base, c) => {\n\t\t\t\tconst sequenceId: SequenceId =\n\t\t\t\t\tc.indexInBatch === undefined\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tsequenceNumber: c.sequenceNumber,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tsequenceNumber: c.sequenceNumber,\n\t\t\t\t\t\t\t\tindexInBatch: c.indexInBatch,\n\t\t\t\t\t\t };\n\t\t\t\tconst commit = mintCommit(base, c);\n\t\t\t\tthis.sequenceMap.set(sequenceId, commit);\n\t\t\t\tthis.trunkMetadata.set(c.revision, {\n\t\t\t\t\tsequenceId,\n\t\t\t\t\tsessionId: c.sessionId,\n\t\t\t\t});\n\t\t\t\ttrunkRevisionCache.set(c.revision, commit);\n\t\t\t\treturn commit;\n\t\t\t}, this.trunkBase),\n\t\t);\n\n\t\tthis.localBranch.setHead(this.trunk.getHead());\n\n\t\tfor (const [sessionId, branch] of data.peerLocalBranches) {\n\t\t\tconst commit =\n\t\t\t\ttrunkRevisionCache.get(branch.base) ??\n\t\t\t\tfail(\"Expected summary branch to be based off of a revision in the trunk\");\n\n\t\t\tthis.peerLocalBranches.set(\n\t\t\t\tsessionId,\n\t\t\t\tnew SharedTreeBranch(\n\t\t\t\t\tbranch.commits.reduce(mintCommit, commit),\n\t\t\t\t\tthis.changeFamily,\n\t\t\t\t\tthis.mintRevisionTag,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate getCommitSequenceId(commit: GraphCommit<TChangeset>): SequenceId {\n\t\treturn this.trunkMetadata.get(commit.revision)?.sequenceId ?? minimumPossibleSequenceId;\n\t}\n\n\tpublic getTrunkChanges(): readonly TChangeset[] {\n\t\treturn this.getTrunkCommits().map((c) => c.change);\n\t}\n\n\tpublic getTrunkCommits(): readonly GraphCommit<TChangeset>[] {\n\t\treturn getPathFromBase(this.trunk.getHead(), this.trunkBase);\n\t}\n\n\tpublic getTrunkHead(): GraphCommit<TChangeset> {\n\t\treturn this.trunk.getHead();\n\t}\n\n\tpublic getLocalChanges(): readonly TChangeset[] {\n\t\treturn this.getLocalCommits().map((c) => c.change);\n\t}\n\n\tpublic getLocalCommits(): readonly GraphCommit<TChangeset>[] {\n\t\treturn this.localCommits;\n\t}\n\n\t/**\n\t * @returns The length of the longest branch maintained by this EditManager.\n\t * This may be the length of a peer branch or the local branch.\n\t * The length is counted from the lowest common ancestor with the trunk such that a fully sequenced branch would\n\t * have length zero.\n\t */\n\tpublic getLongestBranchLength(): number {\n\t\tlet max = 0;\n\t\tconst trunkHead = this.trunk.getHead();\n\t\tfor (const branch of this.peerLocalBranches.values()) {\n\t\t\tconst branchPath = getPathFromBase(branch.getHead(), trunkHead);\n\t\t\tif (branchPath.length > max) {\n\t\t\t\tmax = branchPath.length;\n\t\t\t}\n\t\t}\n\t\tconst localPath = getPathFromBase(this.localBranch.getHead(), trunkHead);\n\t\treturn Math.max(max, localPath.length);\n\t}\n\n\tpublic addSequencedChange(\n\t\tnewCommit: Commit<TChangeset>,\n\t\tsequenceNumber: SeqNumber,\n\t\treferenceSequenceNumber: SeqNumber,\n\t): void {\n\t\tassert(\n\t\t\tsequenceNumber > this.minimumSequenceNumber,\n\t\t\t0x713 /* Expected change sequence number to exceed the last known minimum sequence number */,\n\t\t);\n\n\t\tconst commitsSequenceNumber = this.getBatch(sequenceNumber);\n\t\tconst sequenceId: SequenceId =\n\t\t\tcommitsSequenceNumber.length === 0\n\t\t\t\t? {\n\t\t\t\t\t\tsequenceNumber,\n\t\t\t\t }\n\t\t\t\t: {\n\t\t\t\t\t\tsequenceNumber,\n\t\t\t\t\t\tindexInBatch: commitsSequenceNumber.length,\n\t\t\t\t };\n\n\t\tif (newCommit.sessionId === this.localSessionId) {\n\t\t\tconst headTrunkCommit = this.trunk.getHead();\n\t\t\tconst firstLocalCommit = this.localCommits.shift();\n\t\t\tassert(\n\t\t\t\tfirstLocalCommit !== undefined,\n\t\t\t\t0x6b5 /* Received a sequenced change from the local session despite having no local changes */,\n\t\t\t);\n\n\t\t\t// The first local branch commit is already rebased over the trunk, so we can push it directly to the trunk.\n\t\t\tthis.pushGraphCommitToTrunk(sequenceId, firstLocalCommit, this.localSessionId);\n\t\t\tthis.fastForwardBranches(headTrunkCommit, sequenceId);\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the revision that the remote change is based on\n\t\tconst [, baseRevisionInTrunk] = this.getClosestTrunkCommit(referenceSequenceNumber);\n\t\t// Rebase that branch over the part of the trunk up to the base revision\n\t\t// This will be a no-op if the sending client has not advanced since the last time we received an edit from it\n\t\tconst peerLocalBranch = getOrCreate(\n\t\t\tthis.peerLocalBranches,\n\t\t\tnewCommit.sessionId,\n\t\t\t() =>\n\t\t\t\tnew SharedTreeBranch(baseRevisionInTrunk, this.changeFamily, this.mintRevisionTag),\n\t\t);\n\t\tpeerLocalBranch.rebaseOnto(this.trunk, baseRevisionInTrunk);\n\n\t\tif (peerLocalBranch.getHead() === this.trunk.getHead()) {\n\t\t\t// If the branch is fully caught up and empty after being rebased, then push to the trunk directly\n\t\t\tthis.pushCommitToTrunk(sequenceId, newCommit);\n\t\t\tpeerLocalBranch.setHead(this.trunk.getHead());\n\t\t} else {\n\t\t\t// Otherwise, rebase the change over the trunk and append it, and append the original change to the peer branch.\n\t\t\tconst newChangeFullyRebased = rebaseChange(\n\t\t\t\tthis.changeFamily.rebaser,\n\t\t\t\tnewCommit,\n\t\t\t\tpeerLocalBranch.getHead(),\n\t\t\t\tthis.trunk.getHead(),\n\t\t\t\tthis.mintRevisionTag,\n\t\t\t);\n\n\t\t\tpeerLocalBranch.apply(newCommit.change, newCommit.revision);\n\t\t\tthis.pushCommitToTrunk(sequenceId, {\n\t\t\t\t...newCommit,\n\t\t\t\tchange: newChangeFullyRebased.change,\n\t\t\t});\n\t\t}\n\n\t\tthis.localBranch.rebaseOnto(this.trunk);\n\t}\n\n\tpublic findLocalCommit(\n\t\trevision: RevisionTag,\n\t): [commit: GraphCommit<TChangeset>, commitsAfter: GraphCommit<TChangeset>[]] {\n\t\tconst commits: GraphCommit<TChangeset>[] = [];\n\t\tconst commit = findAncestor(\n\t\t\t[this.localBranch.getHead(), commits],\n\t\t\t(c) => c.revision === revision,\n\t\t);\n\t\tassert(commit !== undefined, 0x599 /* Expected local branch to contain revision */);\n\t\treturn [commit, commits];\n\t}\n\n\tprivate pushCommitToTrunk(\n\t\tsequenceId: SequenceId,\n\t\tcommit: Commit<TChangeset>,\n\t\tlocal = false,\n\t): void {\n\t\tconst mintedCommit = mintCommit(this.trunk.getHead(), commit);\n\t\tthis.pushGraphCommitToTrunk(sequenceId, mintedCommit, commit.sessionId);\n\t}\n\n\tprivate pushGraphCommitToTrunk(\n\t\tsequenceId: SequenceId,\n\t\tgraphCommit: GraphCommit<TChangeset>,\n\t\tsessionId: SessionId,\n\t): void {\n\t\tthis.trunk.setHead(graphCommit);\n\t\tconst trunkHead = this.trunk.getHead();\n\t\tthis.sequenceMap.set(sequenceId, trunkHead);\n\t\tthis.trunkMetadata.set(trunkHead.revision, { sequenceId, sessionId });\n\t}\n\n\t/**\n\t * Finds the most recent trunk commit that was sequenced at or before the given point.\n\t * @param searchBy - the sequence number or the sequence id to search for\n\t * @remarks Fails if there is no eligible commit.\n\t * @returns the closest commit and its sequence id\n\t */\n\tprivate getClosestTrunkCommit(searchBy: SeqNumber): [SequenceId, GraphCommit<TChangeset>];\n\tprivate getClosestTrunkCommit(searchBy: SequenceId): [SequenceId, GraphCommit<TChangeset>];\n\tprivate getClosestTrunkCommit(\n\t\tsearchBy: SeqNumber | SequenceId,\n\t): [SequenceId, GraphCommit<TChangeset>] {\n\t\tconst sequenceId: SequenceId =\n\t\t\ttypeof searchBy === \"number\"\n\t\t\t\t? {\n\t\t\t\t\t\t// This is to make sure that the correct commit is selected in this 2 scenarios:\n\t\t\t\t\t\t// 1) The commit is unique for that sequence number\n\t\t\t\t\t\t// 2) There are more than one commit for the same sequence number, in this case we need to select the last one.\n\t\t\t\t\t\tsequenceNumber: searchBy,\n\t\t\t\t\t\tindexInBatch: Number.POSITIVE_INFINITY,\n\t\t\t\t }\n\t\t\t\t: searchBy;\n\n\t\tconst commit = this.sequenceMap.getPairOrNextLower(sequenceId);\n\t\tassert(commit !== undefined, 0x746 /* sequence id has been evicted */);\n\t\treturn commit;\n\t}\n\n\tprivate getBatch(sequenceNumber: SeqNumber): [SequenceId, GraphCommit<TChangeset>][] {\n\t\tconst startSequenceId: SequenceId = {\n\t\t\tsequenceNumber,\n\t\t};\n\t\tconst endSequenceId: SequenceId = {\n\t\t\tsequenceNumber: brand((sequenceNumber as number) + 1),\n\t\t};\n\n\t\treturn this.sequenceMap.getRange(startSequenceId, endSequenceId, false);\n\t}\n}\n\n/**\n * The in-memory data that summaries contain\n */\nexport interface SummaryData<TChangeset> {\n\treadonly trunk: readonly SequencedCommit<TChangeset>[];\n\treadonly peerLocalBranches: ReadonlyMap<SessionId, SummarySessionBranch<TChangeset>>;\n}\n\n/**\n * @returns the path from the base of a branch to its head\n */\nfunction getPathFromBase<TCommit extends { parent?: TCommit }>(\n\tbranchHead: TCommit,\n\tbaseBranchHead: TCommit,\n): TCommit[] {\n\tconst path: TCommit[] = [];\n\tassert(\n\t\tfindCommonAncestor([branchHead, path], baseBranchHead) !== undefined,\n\t\t0x573 /* Expected branches to be related */,\n\t);\n\treturn path;\n}\n"]}
|
|
@@ -13,16 +13,12 @@ const stringKey = "String";
|
|
|
13
13
|
* Provides methods for summarizing and loading an `EditManager`
|
|
14
14
|
*/
|
|
15
15
|
class EditManagerSummarizer {
|
|
16
|
-
editManager;
|
|
17
|
-
codec;
|
|
18
|
-
idCompressor;
|
|
19
|
-
schemaAndPolicy;
|
|
20
|
-
key = "EditManager";
|
|
21
16
|
constructor(editManager, codec, idCompressor, schemaAndPolicy) {
|
|
22
17
|
this.editManager = editManager;
|
|
23
18
|
this.codec = codec;
|
|
24
19
|
this.idCompressor = idCompressor;
|
|
25
20
|
this.schemaAndPolicy = schemaAndPolicy;
|
|
21
|
+
this.key = "EditManager";
|
|
26
22
|
}
|
|
27
23
|
getAttachSummary(stringify, fullTree, trackState, telemetryContext) {
|
|
28
24
|
return this.summarizeCore(stringify);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editManagerSummarizer.js","sourceRoot":"","sources":["../../src/shared-tree-core/editManagerSummarizer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAA8D;AAC9D,kEAA6D;AAO7D,0EAAsF;AAetF,MAAM,SAAS,GAAG,QAAQ,CAAC;AAE3B;;GAEG;AACH,MAAa,qBAAqB;
|
|
1
|
+
{"version":3,"file":"editManagerSummarizer.js","sourceRoot":"","sources":["../../src/shared-tree-core/editManagerSummarizer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAA8D;AAC9D,kEAA6D;AAO7D,0EAAsF;AAetF,MAAM,SAAS,GAAG,QAAQ,CAAC;AAE3B;;GAEG;AACH,MAAa,qBAAqB;IAGjC,YACkB,WAIhB,EACgB,KAKhB,EACgB,YAA2B,EAC3B,eAAiC;QAZjC,gBAAW,GAAX,WAAW,CAI3B;QACgB,UAAK,GAAL,KAAK,CAKrB;QACgB,iBAAY,GAAZ,YAAY,CAAe;QAC3B,oBAAe,GAAf,eAAe,CAAkB;QAfnC,QAAG,GAAG,aAAa,CAAC;IAgBjC,CAAC;IAEG,gBAAgB,CACtB,SAAoC,EACpC,QAAkB,EAClB,UAAoB,EACpB,gBAAoC;QAEpC,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK,CAAC,SAAS,CACrB,SAAoC,EACpC,QAAkB,EAClB,UAAoB,EACpB,gBAAoC;QAEpC,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAEO,aAAa,CAAC,SAAoC;QACzD,MAAM,OAAO,GACZ,IAAI,CAAC,eAAe,KAAK,SAAS;YACjC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE;YACnE,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;QACxC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;QACrF,MAAM,UAAU,GAAG,SAAS,CAAC,cAAc,CAAC,CAAC;QAC7C,OAAO,IAAA,kCAAuB,EAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACvD,CAAC;IAEM,SAAS,CAAC,MAAgB;QAChC,wGAAwG;QACxG,0GAA0G;QAC1G,2GAA2G;QAC3G,QAAQ;QACR,OAAO;YACN,OAAO,EAAE,EAAE;SACX,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,IAAI,CAChB,QAAgC,EAChC,KAA2B;QAE3B,MAAM,YAAY,GAAoB,MAAM,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAEzE,gEAAgE;QAChE,wEAAwE;QACxE,gDAAgD;QAChD,IAAA,iBAAM,EACL,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAC1B,KAAK,CAAC,mFAAmF,CACzF,CAAC;QAEF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAA,6BAAc,EAAC,YAAY,EAAE,OAAO,CAAC,CAA2B,CAAC;QACvF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CACD;AA3ED,sDA2EC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { IChannelStorageService } from \"@fluidframework/datastore-definitions/internal\";\nimport type {\n\tIGarbageCollectionData,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { createSingleBlobSummary } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { IJsonCodec } from \"../codec/index.js\";\nimport type { ChangeFamily, ChangeFamilyEditor, SchemaAndPolicy } from \"../core/index.js\";\nimport type { JsonCompatibleReadOnly } from \"../util/index.js\";\n\nimport type { EditManager, SummaryData } from \"./editManager.js\";\nimport type { EditManagerEncodingContext } from \"./editManagerCodecs.js\";\nimport type {\n\tSummarizable,\n\tSummaryElementParser,\n\tSummaryElementStringifier,\n} from \"./sharedTreeCore.js\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nconst stringKey = \"String\";\n\n/**\n * Provides methods for summarizing and loading an `EditManager`\n */\nexport class EditManagerSummarizer<TChangeset> implements Summarizable {\n\tpublic readonly key = \"EditManager\";\n\n\tpublic constructor(\n\t\tprivate readonly editManager: EditManager<\n\t\t\tChangeFamilyEditor,\n\t\t\tTChangeset,\n\t\t\tChangeFamily<ChangeFamilyEditor, TChangeset>\n\t\t>,\n\t\tprivate readonly codec: IJsonCodec<\n\t\t\tSummaryData<TChangeset>,\n\t\t\tJsonCompatibleReadOnly,\n\t\t\tJsonCompatibleReadOnly,\n\t\t\tEditManagerEncodingContext\n\t\t>,\n\t\tprivate readonly idCompressor: IIdCompressor,\n\t\tprivate readonly schemaAndPolicy?: SchemaAndPolicy,\n\t) {}\n\n\tpublic getAttachSummary(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummaryTreeWithStats {\n\t\treturn this.summarizeCore(stringify);\n\t}\n\n\tpublic async summarize(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats> {\n\t\treturn this.summarizeCore(stringify);\n\t}\n\n\tprivate summarizeCore(stringify: SummaryElementStringifier): ISummaryTreeWithStats {\n\t\tconst context: EditManagerEncodingContext =\n\t\t\tthis.schemaAndPolicy !== undefined\n\t\t\t\t? { schema: this.schemaAndPolicy, idCompressor: this.idCompressor }\n\t\t\t\t: { idCompressor: this.idCompressor };\n\t\tconst jsonCompatible = this.codec.encode(this.editManager.getSummaryData(), context);\n\t\tconst dataString = stringify(jsonCompatible);\n\t\treturn createSingleBlobSummary(stringKey, dataString);\n\t}\n\n\tpublic getGCData(fullGC?: boolean): IGarbageCollectionData {\n\t\t// TODO: Properly implement garbage collection. Right now, garbage collection is performed automatically\n\t\t// by the code in SharedObject (from which SharedTreeCore extends). The `runtime.uploadBlob` API delegates\n\t\t// to the `BlobManager`, which automatically populates the summary with ISummaryAttachment entries for each\n\t\t// blob.\n\t\treturn {\n\t\t\tgcNodes: {},\n\t\t};\n\t}\n\n\tpublic async load(\n\t\tservices: IChannelStorageService,\n\t\tparse: SummaryElementParser,\n\t): Promise<void> {\n\t\tconst schemaBuffer: ArrayBufferLike = await services.readBlob(stringKey);\n\n\t\t// After the awaits, validate that the data is in a clean state.\n\t\t// This detects any data that could have been accidentally added through\n\t\t// invalid means and is about to be overwritten.\n\t\tassert(\n\t\t\tthis.editManager.isEmpty(),\n\t\t\t0x42c /* There should not already be stored EditManager data when loading from summary */,\n\t\t);\n\n\t\tconst summary = parse(bufferToString(schemaBuffer, \"utf-8\")) as JsonCompatibleReadOnly;\n\t\tconst data = this.codec.decode(summary, { idCompressor: this.idCompressor });\n\t\tthis.editManager.loadSummaryData(data);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeCore.d.ts","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AAExD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAC7F,OAAO,KAAK,EACX,sCAAsC,EACtC,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EAAE,KAAK,gBAAgB,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAElG,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,mBAAmB,CAAC;AACnE,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,kBAAkB,EAEvB,KAAK,WAAW,EAEhB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,0BAA0B,EAC/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,sBAAsB,EAAS,MAAM,kBAAkB,CAAC;AAEtE,OAAO,EAAE,KAAK,gBAAgB,EAAwB,MAAM,aAAa,CAAC;AAO1E,OAAO,EAAE,KAAK,8BAA8B,EAAsB,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAKjE,MAAM,WAAW,yBAAyB;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC/D,MAAM,EAAE,0BAA0B,CAAC;CACnC;AAED;;;;;GAKG;AACH,qBAAa,cAAc,CAAC,OAAO,SAAS,kBAAkB,EAAE,OAAO,CAAE,SAAQ,YAAY;IAC5F,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgE;IAC5F,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IAExD;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAAwD;IAEhF;;;OAGG;IACH,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAK3B;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAE7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA2B;IAC3D,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAEjE,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,WAAW,CAAC;IAEtD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAE1D;;;;;;;;OAQG;gBAEF,aAAa,EAAE,SAAS,YAAY,EAAE,EACtC,YAAY,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EAC5C,OAAO,EAAE,aAAa,EACtB,aAAa,EAAE,yBAAyB,EAExC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,EAC/B,UAAU,EAAE,kBAAkB,EAC9B,sBAAsB,EAAE,MAAM,EAC9B,MAAM,EAAE,0BAA0B,EAClC,YAAY,EAAE,YAAY,EAC1B,eAAe,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,EAC1C,QAAQ,CAAC,EAAE,8BAA8B,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"sharedTreeCore.d.ts","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,14 +27,6 @@ const summarizablesTreeKey = "indexes";
|
|
|
27
27
|
* TODO: is history policy a detail of what indexes are used, or is there something else to it?
|
|
28
28
|
*/
|
|
29
29
|
class SharedTreeCore extends internal_3.SharedObject {
|
|
30
|
-
editManager;
|
|
31
|
-
summarizables;
|
|
32
|
-
/**
|
|
33
|
-
* The sequence number that this instance is at.
|
|
34
|
-
* This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.
|
|
35
|
-
* Is `undefined` after (and only after) this instance is attached.
|
|
36
|
-
*/
|
|
37
|
-
detachedRevision = editManager_js_1.minimumPossibleSequenceNumber;
|
|
38
30
|
/**
|
|
39
31
|
* Used to edit the state of the tree. Edits will be immediately applied locally to the tree.
|
|
40
32
|
* If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.
|
|
@@ -42,21 +34,6 @@ class SharedTreeCore extends internal_3.SharedObject {
|
|
|
42
34
|
get editor() {
|
|
43
35
|
return this.getLocalBranch().editor;
|
|
44
36
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Used to encode/decode messages sent to/received from the Fluid runtime.
|
|
47
|
-
*
|
|
48
|
-
* @remarks Since there is currently only one format, this can just be cached on the class.
|
|
49
|
-
* With more write formats active, it may make sense to keep around the "usual" format codec
|
|
50
|
-
* (the one for the current persisted configuration) and resolve codecs for different versions
|
|
51
|
-
* as necessary (e.g. an upgrade op came in, or the configuration changed within the collab window
|
|
52
|
-
* and an op needs to be interpreted which isn't written with the current configuration).
|
|
53
|
-
*/
|
|
54
|
-
messageCodec;
|
|
55
|
-
idCompressor;
|
|
56
|
-
resubmitMachine;
|
|
57
|
-
commitEnricher;
|
|
58
|
-
mintRevisionTag;
|
|
59
|
-
schemaAndPolicy;
|
|
60
37
|
/**
|
|
61
38
|
* @param summarizables - Summarizers for all indexes used by this tree
|
|
62
39
|
* @param changeFamily - The change family
|
|
@@ -70,6 +47,12 @@ class SharedTreeCore extends internal_3.SharedObject {
|
|
|
70
47
|
// Base class arguments
|
|
71
48
|
id, runtime, attributes, telemetryContextPrefix, schema, schemaPolicy, resubmitMachine, enricher) {
|
|
72
49
|
super(id, runtime, attributes, telemetryContextPrefix);
|
|
50
|
+
/**
|
|
51
|
+
* The sequence number that this instance is at.
|
|
52
|
+
* This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.
|
|
53
|
+
* Is `undefined` after (and only after) this instance is attached.
|
|
54
|
+
*/
|
|
55
|
+
this.detachedRevision = editManager_js_1.minimumPossibleSequenceNumber;
|
|
73
56
|
this.schemaAndPolicy = {
|
|
74
57
|
schema,
|
|
75
58
|
policy: schemaPolicy,
|
|
@@ -84,6 +67,15 @@ class SharedTreeCore extends internal_3.SharedObject {
|
|
|
84
67
|
*/
|
|
85
68
|
const localSessionId = runtime.idCompressor.localSessionId;
|
|
86
69
|
this.editManager = new editManager_js_1.EditManager(changeFamily, localSessionId, this.mintRevisionTag);
|
|
70
|
+
this.editManager.localBranch.on("transactionStarted", () => {
|
|
71
|
+
this.commitEnricher.startNewTransaction();
|
|
72
|
+
});
|
|
73
|
+
this.editManager.localBranch.on("transactionAborted", () => {
|
|
74
|
+
this.commitEnricher.abortCurrentTransaction();
|
|
75
|
+
});
|
|
76
|
+
this.editManager.localBranch.on("transactionCommitted", () => {
|
|
77
|
+
this.commitEnricher.commitCurrentTransaction();
|
|
78
|
+
});
|
|
87
79
|
this.editManager.localBranch.on("beforeChange", (change) => {
|
|
88
80
|
// Ensure that any previously prepared commits that have not been sent are purged.
|
|
89
81
|
this.commitEnricher.purgePreparedCommits();
|
|
@@ -242,7 +234,7 @@ class SharedTreeCore extends internal_3.SharedObject {
|
|
|
242
234
|
const gcNodes = super.getGCData(fullGC).gcNodes;
|
|
243
235
|
for (const s of this.summarizables) {
|
|
244
236
|
for (const [id, routes] of Object.entries(s.getGCData(fullGC).gcNodes)) {
|
|
245
|
-
gcNodes[id]
|
|
237
|
+
gcNodes[id] ?? (gcNodes[id] = []);
|
|
246
238
|
for (const route of routes) {
|
|
247
239
|
gcNodes[id].push(route);
|
|
248
240
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeCore.js","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tIExperimentalIncrementalSummaryContext,\n\tIGarbageCollectionData,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils/internal\";\nimport { type IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ICodecOptions, IJsonCodec } from \"../codec/index.js\";\nimport {\n\ttype ChangeFamily,\n\ttype ChangeFamilyEditor,\n\ttype GraphCommit,\n\ttype RevisionTag,\n\tRevisionTagCodec,\n\ttype SchemaAndPolicy,\n\ttype SchemaPolicy,\n\ttype TreeStoredSchemaRepository,\n} from \"../core/index.js\";\nimport { type JsonCompatibleReadOnly, brand } from \"../util/index.js\";\n\nimport { type SharedTreeBranch, getChangeReplaceType } from \"./branch.js\";\nimport { EditManager, minimumPossibleSequenceNumber } from \"./editManager.js\";\nimport { makeEditManagerCodec } from \"./editManagerCodecs.js\";\nimport type { SeqNumber } from \"./editManagerFormat.js\";\nimport { EditManagerSummarizer } from \"./editManagerSummarizer.js\";\nimport { type MessageEncodingContext, makeMessageCodec } from \"./messageCodecs.js\";\nimport type { DecodedMessage } from \"./messageTypes.js\";\nimport { type ChangeEnricherReadonlyCheckout, NoOpChangeEnricher } from \"./changeEnricher.js\";\nimport type { ResubmitMachine } from \"./resubmitMachine.js\";\nimport { DefaultResubmitMachine } from \"./defaultResubmitMachine.js\";\nimport { BranchCommitEnricher } from \"./branchCommitEnricher.js\";\n\n// TODO: Organize this to be adjacent to persisted types.\nconst summarizablesTreeKey = \"indexes\";\n\nexport interface ExplicitCoreCodecVersions {\n\teditManager: number;\n\tmessage: number;\n}\n\nexport interface ClonableSchemaAndPolicy extends SchemaAndPolicy {\n\tschema: TreeStoredSchemaRepository;\n}\n\n/**\n * Generic shared tree, which needs to be configured with indexes, field kinds and a history policy to be used.\n *\n * TODO: actually implement\n * TODO: is history policy a detail of what indexes are used, or is there something else to it?\n */\nexport class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends SharedObject {\n\tprivate readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;\n\tprivate readonly summarizables: readonly Summarizable[];\n\n\t/**\n\t * The sequence number that this instance is at.\n\t * This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.\n\t * Is `undefined` after (and only after) this instance is attached.\n\t */\n\tprivate detachedRevision: SeqNumber | undefined = minimumPossibleSequenceNumber;\n\n\t/**\n\t * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.\n\t * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.\n\t */\n\tpublic get editor(): TEditor {\n\t\treturn this.getLocalBranch().editor;\n\t}\n\n\t/**\n\t * Used to encode/decode messages sent to/received from the Fluid runtime.\n\t *\n\t * @remarks Since there is currently only one format, this can just be cached on the class.\n\t * With more write formats active, it may make sense to keep around the \"usual\" format codec\n\t * (the one for the current persisted configuration) and resolve codecs for different versions\n\t * as necessary (e.g. an upgrade op came in, or the configuration changed within the collab window\n\t * and an op needs to be interpreted which isn't written with the current configuration).\n\t */\n\tprivate readonly messageCodec: IJsonCodec<\n\t\tDecodedMessage<TChange>,\n\t\tunknown,\n\t\tunknown,\n\t\tMessageEncodingContext\n\t>;\n\n\tprivate readonly idCompressor: IIdCompressor;\n\n\tprivate readonly resubmitMachine: ResubmitMachine<TChange>;\n\tprotected readonly commitEnricher: BranchCommitEnricher<TChange>;\n\n\tprotected readonly mintRevisionTag: () => RevisionTag;\n\n\tprivate readonly schemaAndPolicy: ClonableSchemaAndPolicy;\n\n\t/**\n\t * @param summarizables - Summarizers for all indexes used by this tree\n\t * @param changeFamily - The change family\n\t * @param editManager - The edit manager\n\t * @param id - The id of the shared object\n\t * @param runtime - The IFluidDataStoreRuntime which contains the shared object\n\t * @param attributes - Attributes of the shared object\n\t * @param telemetryContextPrefix - The property prefix for telemetry pertaining to this object. See {@link ITelemetryContext}\n\t */\n\tpublic constructor(\n\t\tsummarizables: readonly Summarizable[],\n\t\tchangeFamily: ChangeFamily<TEditor, TChange>,\n\t\toptions: ICodecOptions,\n\t\tformatOptions: ExplicitCoreCodecVersions,\n\t\t// Base class arguments\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t\ttelemetryContextPrefix: string,\n\t\tschema: TreeStoredSchemaRepository,\n\t\tschemaPolicy: SchemaPolicy,\n\t\tresubmitMachine?: ResubmitMachine<TChange>,\n\t\tenricher?: ChangeEnricherReadonlyCheckout<TChange>,\n\t) {\n\t\tsuper(id, runtime, attributes, telemetryContextPrefix);\n\n\t\tthis.schemaAndPolicy = {\n\t\t\tschema,\n\t\t\tpolicy: schemaPolicy,\n\t\t};\n\n\t\tassert(\n\t\t\truntime.idCompressor !== undefined,\n\t\t\t0x886 /* IdCompressor must be enabled to use SharedTree */,\n\t\t);\n\t\tthis.idCompressor = runtime.idCompressor;\n\t\tthis.mintRevisionTag = () => this.idCompressor.generateCompressedId();\n\t\t/**\n\t\t * A random ID that uniquely identifies this client in the collab session.\n\t\t * This is sent alongside every op to identify which client the op originated from.\n\t\t * This is used rather than the Fluid client ID because the Fluid client ID is not stable across reconnections.\n\t\t */\n\t\tconst localSessionId = runtime.idCompressor.localSessionId;\n\t\tthis.editManager = new EditManager(changeFamily, localSessionId, this.mintRevisionTag);\n\t\tthis.editManager.localBranch.on(\"beforeChange\", (change) => {\n\t\t\t// Ensure that any previously prepared commits that have not been sent are purged.\n\t\t\tthis.commitEnricher.purgePreparedCommits();\n\t\t\tif (this.detachedRevision !== undefined) {\n\t\t\t\t// Edits submitted before the first attach do not need enrichment because they will not be applied by peers.\n\t\t\t} else if (change.type === \"append\") {\n\t\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tthis.commitEnricher.ingestTransactionCommit(newCommit);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tthis.commitEnricher.prepareCommit(newCommit, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tchange.type === \"replace\" &&\n\t\t\t\tgetChangeReplaceType(change) === \"transactionCommit\" &&\n\t\t\t\t!this.getLocalBranch().isTransacting()\n\t\t\t) {\n\t\t\t\tassert(\n\t\t\t\t\tchange.newCommits.length === 1,\n\t\t\t\t\t\"Unexpected number of commits when committing transaction\",\n\t\t\t\t);\n\t\t\t\tthis.commitEnricher.prepareCommit(change.newCommits[0], true);\n\t\t\t}\n\t\t});\n\t\tthis.editManager.localBranch.on(\"afterChange\", (change) => {\n\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t// We do not submit ops for changes that are part of a transaction.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tchange.type === \"append\" ||\n\t\t\t\t(change.type === \"replace\" && getChangeReplaceType(change) === \"transactionCommit\")\n\t\t\t) {\n\t\t\t\tif (this.detachedRevision !== undefined) {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tthis.submitCommit(newCommit, this.schemaAndPolicy);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tconst prepared = this.commitEnricher.getPreparedCommit(newCommit);\n\t\t\t\t\t\tthis.submitCommit(prepared, this.schemaAndPolicy);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst revisionTagCodec = new RevisionTagCodec(runtime.idCompressor);\n\t\tconst editManagerCodec = makeEditManagerCodec(\n\t\t\tthis.editManager.changeFamily.codecs,\n\t\t\trevisionTagCodec,\n\t\t\toptions,\n\t\t\tformatOptions.editManager,\n\t\t);\n\t\tthis.summarizables = [\n\t\t\tnew EditManagerSummarizer(\n\t\t\t\tthis.editManager,\n\t\t\t\teditManagerCodec,\n\t\t\t\tthis.idCompressor,\n\t\t\t\tthis.schemaAndPolicy,\n\t\t\t),\n\t\t\t...summarizables,\n\t\t];\n\t\tassert(\n\t\t\tnew Set(this.summarizables.map((e) => e.key)).size === this.summarizables.length,\n\t\t\t0x350 /* Index summary element keys must be unique */,\n\t\t);\n\n\t\tthis.messageCodec = makeMessageCodec(\n\t\t\tchangeFamily.codecs,\n\t\t\tnew RevisionTagCodec(runtime.idCompressor),\n\t\t\toptions,\n\t\t\tformatOptions.message,\n\t\t);\n\n\t\tconst changeEnricher = enricher ?? new NoOpChangeEnricher();\n\t\tthis.resubmitMachine =\n\t\t\tresubmitMachine ??\n\t\t\tnew DefaultResubmitMachine(\n\t\t\t\tchangeFamily.rebaser.invert.bind(changeFamily.rebaser),\n\t\t\t\tchangeEnricher,\n\t\t\t);\n\t\tthis.commitEnricher = new BranchCommitEnricher(changeFamily.rebaser, changeEnricher);\n\t}\n\n\t// TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:\n\t// We might want to not subclass it, or override/reimplement most of its functionality.\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tconst summarizableBuilder = new SummaryTreeBuilder();\n\t\t// Merge the summaries of all summarizables together under a single ISummaryTree\n\t\tfor (const s of this.summarizables) {\n\t\t\tsummarizableBuilder.addWithStats(\n\t\t\t\ts.key,\n\t\t\t\ts.getAttachSummary(\n\t\t\t\t\t(contents) => serializer.stringify(contents, this.handle),\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\ttelemetryContext,\n\t\t\t\t\tincrementalSummaryContext,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tbuilder.addWithStats(summarizablesTreeKey, summarizableBuilder.getSummaryTree());\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tprotected async loadCore(services: IChannelStorageService): Promise<void> {\n\t\tconst loadSummaries = this.summarizables.map(async (summaryElement) =>\n\t\t\tsummaryElement.load(\n\t\t\t\tscopeStorageService(services, summarizablesTreeKey, summaryElement.key),\n\t\t\t\t(contents) => this.serializer.parse(contents),\n\t\t\t),\n\t\t);\n\n\t\tawait Promise.all(loadSummaries);\n\t}\n\n\t/**\n\t * Submits an op to the Fluid runtime containing the given commit\n\t * @param commit - the commit to submit\n\t * @returns the submitted commit. This is undefined if the underlying `SharedObject` is not attached,\n\t * and may differ from `commit` due to enrichments like detached tree refreshers.\n\t */\n\tprivate submitCommit(\n\t\tcommit: GraphCommit<TChange>,\n\t\tschemaAndPolicy: ClonableSchemaAndPolicy,\n\t\tisResubmit = false,\n\t): void {\n\t\tassert(\n\t\t\t// Edits should not be submitted until all transactions finish\n\t\t\t!this.getLocalBranch().isTransacting() || isResubmit,\n\t\t\t0x68b /* Unexpected edit submitted during transaction */,\n\t\t);\n\t\tassert(\n\t\t\tthis.isAttached() === (this.detachedRevision === undefined),\n\t\t\t0x95a /* Detached revision should only be set when not attached */,\n\t\t);\n\n\t\t// Edits submitted before the first attach are treated as sequenced because they will be included\n\t\t// in the attach summary that is uploaded to the service.\n\t\t// Until this attach workflow happens, this instance essentially behaves as a centralized data structure.\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tconst newRevision: SeqNumber = brand((this.detachedRevision as number) + 1);\n\t\t\tthis.detachedRevision = newRevision;\n\t\t\tthis.editManager.addSequencedChange(\n\t\t\t\t{ ...commit, sessionId: this.editManager.localSessionId },\n\t\t\t\tnewRevision,\n\t\t\t\tthis.detachedRevision,\n\t\t\t);\n\t\t\tthis.editManager.advanceMinimumSequenceNumber(newRevision);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst message = this.messageCodec.encode(\n\t\t\t{\n\t\t\t\tcommit,\n\t\t\t\tsessionId: this.editManager.localSessionId,\n\t\t\t},\n\t\t\t{\n\t\t\t\tidCompressor: this.idCompressor,\n\t\t\t\tschema: schemaAndPolicy,\n\t\t\t},\n\t\t);\n\t\tthis.submitLocalMessage(message, {\n\t\t\t// Clone the schema to ensure that during resubmit the schema has not been mutated by later changes\n\t\t\tschema: schemaAndPolicy.schema.clone(),\n\t\t\tpolicy: schemaAndPolicy.policy,\n\t\t});\n\t\tthis.resubmitMachine.onCommitSubmitted(commit);\n\t}\n\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst { commit, sessionId } = this.messageCodec.decode(message.contents, {\n\t\t\tidCompressor: this.idCompressor,\n\t\t});\n\n\t\tthis.editManager.addSequencedChange(\n\t\t\t{ ...commit, sessionId },\n\t\t\tbrand(message.sequenceNumber),\n\t\t\tbrand(message.referenceSequenceNumber),\n\t\t);\n\t\tthis.resubmitMachine.onSequencedCommitApplied(local);\n\n\t\tthis.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));\n\t}\n\n\t/**\n\t * @returns the head commit of the root local branch\n\t */\n\tprotected getLocalBranch(): SharedTreeBranch<TEditor, TChange> {\n\t\treturn this.editManager.localBranch;\n\t}\n\n\tprotected onDisconnect(): void {}\n\n\tprotected override didAttach(): void {\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tthis.detachedRevision = undefined;\n\t\t}\n\t}\n\n\tprotected override reSubmitCore(\n\t\tcontent: JsonCompatibleReadOnly,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision },\n\t\t} = this.messageCodec.decode(this.serializer.decode(content), {\n\t\t\tidCompressor: this.idCompressor,\n\t\t});\n\t\tconst [commit] = this.editManager.findLocalCommit(revision);\n\t\t// If a resubmit phase is not already in progress, then this must be the first commit of a new resubmit phase.\n\t\tif (this.resubmitMachine.isInResubmitPhase === false) {\n\t\t\tconst toResubmit = this.editManager.getLocalCommits();\n\t\t\tassert(\n\t\t\t\tcommit === toResubmit[0],\n\t\t\t\t0x95d /* Resubmit phase should start with the oldest local commit */,\n\t\t\t);\n\t\t\tthis.resubmitMachine.prepareForResubmit(toResubmit);\n\t\t}\n\t\tassert(\n\t\t\tisClonableSchemaPolicy(localOpMetadata),\n\t\t\t0x95e /* Local metadata must contain schema and policy. */,\n\t\t);\n\t\tassert(\n\t\t\tthis.resubmitMachine.isInResubmitPhase !== false,\n\t\t\t\"Invalid resubmit outside of resubmit phase\",\n\t\t);\n\t\tconst enrichedCommit = this.resubmitMachine.peekNextCommit();\n\t\tthis.submitCommit(enrichedCommit, localOpMetadata, true);\n\t}\n\n\tprotected applyStashedOp(content: JsonCompatibleReadOnly): void {\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting(),\n\t\t\t0x674 /* Unexpected transaction is open while applying stashed ops */,\n\t\t);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision, change },\n\t\t} = this.messageCodec.decode(content, { idCompressor: this.idCompressor });\n\t\tthis.editManager.localBranch.apply(change, revision);\n\t}\n\n\tpublic override getGCData(fullGC?: boolean): IGarbageCollectionData {\n\t\tconst gcNodes: IGarbageCollectionData[\"gcNodes\"] = super.getGCData(fullGC).gcNodes;\n\t\tfor (const s of this.summarizables) {\n\t\t\tfor (const [id, routes] of Object.entries(s.getGCData(fullGC).gcNodes)) {\n\t\t\t\tgcNodes[id] ??= [];\n\t\t\t\tfor (const route of routes) {\n\t\t\t\t\tgcNodes[id].push(route);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tgcNodes,\n\t\t};\n\t}\n}\n\nfunction isClonableSchemaPolicy(\n\tmaybeSchemaPolicy: unknown,\n): maybeSchemaPolicy is ClonableSchemaAndPolicy {\n\tconst schemaAndPolicy = maybeSchemaPolicy as ClonableSchemaAndPolicy;\n\treturn schemaAndPolicy.schema !== undefined && schemaAndPolicy.policy !== undefined;\n}\n\n/**\n * Specifies the behavior of a component that puts data in a summary.\n */\nexport interface Summarizable {\n\t/**\n\t * Field name in summary json under which this element stores its data.\n\t */\n\treadonly key: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).getAttachSummary}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tgetAttachSummary(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).summarize}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tsummarize(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats>;\n\n\t/**\n\t * {@inheritDoc (ISharedObject:interface).getGCData}\n\t */\n\t// TODO: Change this interface (and the one in ISharedObject, if necessary) to support \"handles within handles\".\n\t// Consider the case of a document with history; the return value here currently grows unboundedly.\n\tgetGCData(fullGC?: boolean): IGarbageCollectionData;\n\n\t/**\n\t * Allows the component to perform custom loading. The storage service is scoped to this component and therefore\n\t * paths in this component will not collide with those in other components, even if they are the same string.\n\t * @param service - Storage used by the component\n\t * @param parse - Parses serialized data from storage into runtime objects for the component\n\t */\n\tload(service: IChannelStorageService, parse: SummaryElementParser): Promise<void>;\n}\n\n/**\n * Serializes the given contents into a string acceptable for storing in summaries, i.e. all\n * Fluid handles have been replaced appropriately by an IFluidSerializer\n */\nexport type SummaryElementStringifier = (contents: unknown) => string;\n\n/**\n * Parses a serialized/summarized string into an object, rehydrating any Fluid handles as necessary\n */\nexport type SummaryElementParser = (contents: string) => unknown;\n\n/**\n * Compose an {@link IChannelStorageService} which prefixes all paths before forwarding them to the original service\n */\nfunction scopeStorageService(\n\tservice: IChannelStorageService,\n\t...pathElements: string[]\n): IChannelStorageService {\n\tconst scope = `${pathElements.join(\"/\")}/`;\n\n\treturn {\n\t\tasync readBlob(path: string): Promise<ArrayBufferLike> {\n\t\t\treturn service.readBlob(`${scope}${path}`);\n\t\t},\n\t\tasync contains(path) {\n\t\t\treturn service.contains(`${scope}${path}`);\n\t\t},\n\t\tasync list(path) {\n\t\t\treturn service.list(`${scope}${path}`);\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sharedTreeCore.js","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tIExperimentalIncrementalSummaryContext,\n\tIGarbageCollectionData,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils/internal\";\nimport { type IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ICodecOptions, IJsonCodec } from \"../codec/index.js\";\nimport {\n\ttype ChangeFamily,\n\ttype ChangeFamilyEditor,\n\ttype GraphCommit,\n\ttype RevisionTag,\n\tRevisionTagCodec,\n\ttype SchemaAndPolicy,\n\ttype SchemaPolicy,\n\ttype TreeStoredSchemaRepository,\n} from \"../core/index.js\";\nimport { type JsonCompatibleReadOnly, brand } from \"../util/index.js\";\n\nimport { type SharedTreeBranch, getChangeReplaceType } from \"./branch.js\";\nimport { EditManager, minimumPossibleSequenceNumber } from \"./editManager.js\";\nimport { makeEditManagerCodec } from \"./editManagerCodecs.js\";\nimport type { SeqNumber } from \"./editManagerFormat.js\";\nimport { EditManagerSummarizer } from \"./editManagerSummarizer.js\";\nimport { type MessageEncodingContext, makeMessageCodec } from \"./messageCodecs.js\";\nimport type { DecodedMessage } from \"./messageTypes.js\";\nimport { type ChangeEnricherReadonlyCheckout, NoOpChangeEnricher } from \"./changeEnricher.js\";\nimport type { ResubmitMachine } from \"./resubmitMachine.js\";\nimport { DefaultResubmitMachine } from \"./defaultResubmitMachine.js\";\nimport { BranchCommitEnricher } from \"./branchCommitEnricher.js\";\n\n// TODO: Organize this to be adjacent to persisted types.\nconst summarizablesTreeKey = \"indexes\";\n\nexport interface ExplicitCoreCodecVersions {\n\teditManager: number;\n\tmessage: number;\n}\n\nexport interface ClonableSchemaAndPolicy extends SchemaAndPolicy {\n\tschema: TreeStoredSchemaRepository;\n}\n\n/**\n * Generic shared tree, which needs to be configured with indexes, field kinds and a history policy to be used.\n *\n * TODO: actually implement\n * TODO: is history policy a detail of what indexes are used, or is there something else to it?\n */\nexport class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends SharedObject {\n\tprivate readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;\n\tprivate readonly summarizables: readonly Summarizable[];\n\n\t/**\n\t * The sequence number that this instance is at.\n\t * This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.\n\t * Is `undefined` after (and only after) this instance is attached.\n\t */\n\tprivate detachedRevision: SeqNumber | undefined = minimumPossibleSequenceNumber;\n\n\t/**\n\t * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.\n\t * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.\n\t */\n\tpublic get editor(): TEditor {\n\t\treturn this.getLocalBranch().editor;\n\t}\n\n\t/**\n\t * Used to encode/decode messages sent to/received from the Fluid runtime.\n\t *\n\t * @remarks Since there is currently only one format, this can just be cached on the class.\n\t * With more write formats active, it may make sense to keep around the \"usual\" format codec\n\t * (the one for the current persisted configuration) and resolve codecs for different versions\n\t * as necessary (e.g. an upgrade op came in, or the configuration changed within the collab window\n\t * and an op needs to be interpreted which isn't written with the current configuration).\n\t */\n\tprivate readonly messageCodec: IJsonCodec<\n\t\tDecodedMessage<TChange>,\n\t\tunknown,\n\t\tunknown,\n\t\tMessageEncodingContext\n\t>;\n\n\tprivate readonly idCompressor: IIdCompressor;\n\n\tprivate readonly resubmitMachine: ResubmitMachine<TChange>;\n\tprotected readonly commitEnricher: BranchCommitEnricher<TChange>;\n\n\tprotected readonly mintRevisionTag: () => RevisionTag;\n\n\tprivate readonly schemaAndPolicy: ClonableSchemaAndPolicy;\n\n\t/**\n\t * @param summarizables - Summarizers for all indexes used by this tree\n\t * @param changeFamily - The change family\n\t * @param editManager - The edit manager\n\t * @param id - The id of the shared object\n\t * @param runtime - The IFluidDataStoreRuntime which contains the shared object\n\t * @param attributes - Attributes of the shared object\n\t * @param telemetryContextPrefix - The property prefix for telemetry pertaining to this object. See {@link ITelemetryContext}\n\t */\n\tpublic constructor(\n\t\tsummarizables: readonly Summarizable[],\n\t\tchangeFamily: ChangeFamily<TEditor, TChange>,\n\t\toptions: ICodecOptions,\n\t\tformatOptions: ExplicitCoreCodecVersions,\n\t\t// Base class arguments\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t\ttelemetryContextPrefix: string,\n\t\tschema: TreeStoredSchemaRepository,\n\t\tschemaPolicy: SchemaPolicy,\n\t\tresubmitMachine?: ResubmitMachine<TChange>,\n\t\tenricher?: ChangeEnricherReadonlyCheckout<TChange>,\n\t) {\n\t\tsuper(id, runtime, attributes, telemetryContextPrefix);\n\n\t\tthis.schemaAndPolicy = {\n\t\t\tschema,\n\t\t\tpolicy: schemaPolicy,\n\t\t};\n\n\t\tassert(\n\t\t\truntime.idCompressor !== undefined,\n\t\t\t0x886 /* IdCompressor must be enabled to use SharedTree */,\n\t\t);\n\t\tthis.idCompressor = runtime.idCompressor;\n\t\tthis.mintRevisionTag = () => this.idCompressor.generateCompressedId();\n\t\t/**\n\t\t * A random ID that uniquely identifies this client in the collab session.\n\t\t * This is sent alongside every op to identify which client the op originated from.\n\t\t * This is used rather than the Fluid client ID because the Fluid client ID is not stable across reconnections.\n\t\t */\n\t\tconst localSessionId = runtime.idCompressor.localSessionId;\n\t\tthis.editManager = new EditManager(changeFamily, localSessionId, this.mintRevisionTag);\n\t\tthis.editManager.localBranch.on(\"transactionStarted\", () => {\n\t\t\tthis.commitEnricher.startNewTransaction();\n\t\t});\n\t\tthis.editManager.localBranch.on(\"transactionAborted\", () => {\n\t\t\tthis.commitEnricher.abortCurrentTransaction();\n\t\t});\n\t\tthis.editManager.localBranch.on(\"transactionCommitted\", () => {\n\t\t\tthis.commitEnricher.commitCurrentTransaction();\n\t\t});\n\t\tthis.editManager.localBranch.on(\"beforeChange\", (change) => {\n\t\t\t// Ensure that any previously prepared commits that have not been sent are purged.\n\t\t\tthis.commitEnricher.purgePreparedCommits();\n\t\t\tif (this.detachedRevision !== undefined) {\n\t\t\t\t// Edits submitted before the first attach do not need enrichment because they will not be applied by peers.\n\t\t\t} else if (change.type === \"append\") {\n\t\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tthis.commitEnricher.ingestTransactionCommit(newCommit);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tthis.commitEnricher.prepareCommit(newCommit, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\tchange.type === \"replace\" &&\n\t\t\t\tgetChangeReplaceType(change) === \"transactionCommit\" &&\n\t\t\t\t!this.getLocalBranch().isTransacting()\n\t\t\t) {\n\t\t\t\tassert(\n\t\t\t\t\tchange.newCommits.length === 1,\n\t\t\t\t\t\"Unexpected number of commits when committing transaction\",\n\t\t\t\t);\n\t\t\t\tthis.commitEnricher.prepareCommit(change.newCommits[0], true);\n\t\t\t}\n\t\t});\n\t\tthis.editManager.localBranch.on(\"afterChange\", (change) => {\n\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t// We do not submit ops for changes that are part of a transaction.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tchange.type === \"append\" ||\n\t\t\t\t(change.type === \"replace\" && getChangeReplaceType(change) === \"transactionCommit\")\n\t\t\t) {\n\t\t\t\tif (this.detachedRevision !== undefined) {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tthis.submitCommit(newCommit, this.schemaAndPolicy);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor (const newCommit of change.newCommits) {\n\t\t\t\t\t\tconst prepared = this.commitEnricher.getPreparedCommit(newCommit);\n\t\t\t\t\t\tthis.submitCommit(prepared, this.schemaAndPolicy);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst revisionTagCodec = new RevisionTagCodec(runtime.idCompressor);\n\t\tconst editManagerCodec = makeEditManagerCodec(\n\t\t\tthis.editManager.changeFamily.codecs,\n\t\t\trevisionTagCodec,\n\t\t\toptions,\n\t\t\tformatOptions.editManager,\n\t\t);\n\t\tthis.summarizables = [\n\t\t\tnew EditManagerSummarizer(\n\t\t\t\tthis.editManager,\n\t\t\t\teditManagerCodec,\n\t\t\t\tthis.idCompressor,\n\t\t\t\tthis.schemaAndPolicy,\n\t\t\t),\n\t\t\t...summarizables,\n\t\t];\n\t\tassert(\n\t\t\tnew Set(this.summarizables.map((e) => e.key)).size === this.summarizables.length,\n\t\t\t0x350 /* Index summary element keys must be unique */,\n\t\t);\n\n\t\tthis.messageCodec = makeMessageCodec(\n\t\t\tchangeFamily.codecs,\n\t\t\tnew RevisionTagCodec(runtime.idCompressor),\n\t\t\toptions,\n\t\t\tformatOptions.message,\n\t\t);\n\n\t\tconst changeEnricher = enricher ?? new NoOpChangeEnricher();\n\t\tthis.resubmitMachine =\n\t\t\tresubmitMachine ??\n\t\t\tnew DefaultResubmitMachine(\n\t\t\t\tchangeFamily.rebaser.invert.bind(changeFamily.rebaser),\n\t\t\t\tchangeEnricher,\n\t\t\t);\n\t\tthis.commitEnricher = new BranchCommitEnricher(changeFamily.rebaser, changeEnricher);\n\t}\n\n\t// TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:\n\t// We might want to not subclass it, or override/reimplement most of its functionality.\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tconst summarizableBuilder = new SummaryTreeBuilder();\n\t\t// Merge the summaries of all summarizables together under a single ISummaryTree\n\t\tfor (const s of this.summarizables) {\n\t\t\tsummarizableBuilder.addWithStats(\n\t\t\t\ts.key,\n\t\t\t\ts.getAttachSummary(\n\t\t\t\t\t(contents) => serializer.stringify(contents, this.handle),\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\ttelemetryContext,\n\t\t\t\t\tincrementalSummaryContext,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tbuilder.addWithStats(summarizablesTreeKey, summarizableBuilder.getSummaryTree());\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tprotected async loadCore(services: IChannelStorageService): Promise<void> {\n\t\tconst loadSummaries = this.summarizables.map(async (summaryElement) =>\n\t\t\tsummaryElement.load(\n\t\t\t\tscopeStorageService(services, summarizablesTreeKey, summaryElement.key),\n\t\t\t\t(contents) => this.serializer.parse(contents),\n\t\t\t),\n\t\t);\n\n\t\tawait Promise.all(loadSummaries);\n\t}\n\n\t/**\n\t * Submits an op to the Fluid runtime containing the given commit\n\t * @param commit - the commit to submit\n\t * @returns the submitted commit. This is undefined if the underlying `SharedObject` is not attached,\n\t * and may differ from `commit` due to enrichments like detached tree refreshers.\n\t */\n\tprivate submitCommit(\n\t\tcommit: GraphCommit<TChange>,\n\t\tschemaAndPolicy: ClonableSchemaAndPolicy,\n\t\tisResubmit = false,\n\t): void {\n\t\tassert(\n\t\t\t// Edits should not be submitted until all transactions finish\n\t\t\t!this.getLocalBranch().isTransacting() || isResubmit,\n\t\t\t0x68b /* Unexpected edit submitted during transaction */,\n\t\t);\n\t\tassert(\n\t\t\tthis.isAttached() === (this.detachedRevision === undefined),\n\t\t\t0x95a /* Detached revision should only be set when not attached */,\n\t\t);\n\n\t\t// Edits submitted before the first attach are treated as sequenced because they will be included\n\t\t// in the attach summary that is uploaded to the service.\n\t\t// Until this attach workflow happens, this instance essentially behaves as a centralized data structure.\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tconst newRevision: SeqNumber = brand((this.detachedRevision as number) + 1);\n\t\t\tthis.detachedRevision = newRevision;\n\t\t\tthis.editManager.addSequencedChange(\n\t\t\t\t{ ...commit, sessionId: this.editManager.localSessionId },\n\t\t\t\tnewRevision,\n\t\t\t\tthis.detachedRevision,\n\t\t\t);\n\t\t\tthis.editManager.advanceMinimumSequenceNumber(newRevision);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst message = this.messageCodec.encode(\n\t\t\t{\n\t\t\t\tcommit,\n\t\t\t\tsessionId: this.editManager.localSessionId,\n\t\t\t},\n\t\t\t{\n\t\t\t\tidCompressor: this.idCompressor,\n\t\t\t\tschema: schemaAndPolicy,\n\t\t\t},\n\t\t);\n\t\tthis.submitLocalMessage(message, {\n\t\t\t// Clone the schema to ensure that during resubmit the schema has not been mutated by later changes\n\t\t\tschema: schemaAndPolicy.schema.clone(),\n\t\t\tpolicy: schemaAndPolicy.policy,\n\t\t});\n\t\tthis.resubmitMachine.onCommitSubmitted(commit);\n\t}\n\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst { commit, sessionId } = this.messageCodec.decode(message.contents, {\n\t\t\tidCompressor: this.idCompressor,\n\t\t});\n\n\t\tthis.editManager.addSequencedChange(\n\t\t\t{ ...commit, sessionId },\n\t\t\tbrand(message.sequenceNumber),\n\t\t\tbrand(message.referenceSequenceNumber),\n\t\t);\n\t\tthis.resubmitMachine.onSequencedCommitApplied(local);\n\n\t\tthis.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));\n\t}\n\n\t/**\n\t * @returns the head commit of the root local branch\n\t */\n\tprotected getLocalBranch(): SharedTreeBranch<TEditor, TChange> {\n\t\treturn this.editManager.localBranch;\n\t}\n\n\tprotected onDisconnect(): void {}\n\n\tprotected override didAttach(): void {\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tthis.detachedRevision = undefined;\n\t\t}\n\t}\n\n\tprotected override reSubmitCore(\n\t\tcontent: JsonCompatibleReadOnly,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision },\n\t\t} = this.messageCodec.decode(this.serializer.decode(content), {\n\t\t\tidCompressor: this.idCompressor,\n\t\t});\n\t\tconst [commit] = this.editManager.findLocalCommit(revision);\n\t\t// If a resubmit phase is not already in progress, then this must be the first commit of a new resubmit phase.\n\t\tif (this.resubmitMachine.isInResubmitPhase === false) {\n\t\t\tconst toResubmit = this.editManager.getLocalCommits();\n\t\t\tassert(\n\t\t\t\tcommit === toResubmit[0],\n\t\t\t\t0x95d /* Resubmit phase should start with the oldest local commit */,\n\t\t\t);\n\t\t\tthis.resubmitMachine.prepareForResubmit(toResubmit);\n\t\t}\n\t\tassert(\n\t\t\tisClonableSchemaPolicy(localOpMetadata),\n\t\t\t0x95e /* Local metadata must contain schema and policy. */,\n\t\t);\n\t\tassert(\n\t\t\tthis.resubmitMachine.isInResubmitPhase !== false,\n\t\t\t\"Invalid resubmit outside of resubmit phase\",\n\t\t);\n\t\tconst enrichedCommit = this.resubmitMachine.peekNextCommit();\n\t\tthis.submitCommit(enrichedCommit, localOpMetadata, true);\n\t}\n\n\tprotected applyStashedOp(content: JsonCompatibleReadOnly): void {\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting(),\n\t\t\t0x674 /* Unexpected transaction is open while applying stashed ops */,\n\t\t);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision, change },\n\t\t} = this.messageCodec.decode(content, { idCompressor: this.idCompressor });\n\t\tthis.editManager.localBranch.apply(change, revision);\n\t}\n\n\tpublic override getGCData(fullGC?: boolean): IGarbageCollectionData {\n\t\tconst gcNodes: IGarbageCollectionData[\"gcNodes\"] = super.getGCData(fullGC).gcNodes;\n\t\tfor (const s of this.summarizables) {\n\t\t\tfor (const [id, routes] of Object.entries(s.getGCData(fullGC).gcNodes)) {\n\t\t\t\tgcNodes[id] ??= [];\n\t\t\t\tfor (const route of routes) {\n\t\t\t\t\tgcNodes[id].push(route);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tgcNodes,\n\t\t};\n\t}\n}\n\nfunction isClonableSchemaPolicy(\n\tmaybeSchemaPolicy: unknown,\n): maybeSchemaPolicy is ClonableSchemaAndPolicy {\n\tconst schemaAndPolicy = maybeSchemaPolicy as ClonableSchemaAndPolicy;\n\treturn schemaAndPolicy.schema !== undefined && schemaAndPolicy.policy !== undefined;\n}\n\n/**\n * Specifies the behavior of a component that puts data in a summary.\n */\nexport interface Summarizable {\n\t/**\n\t * Field name in summary json under which this element stores its data.\n\t */\n\treadonly key: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).getAttachSummary}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tgetAttachSummary(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).summarize}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tsummarize(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats>;\n\n\t/**\n\t * {@inheritDoc (ISharedObject:interface).getGCData}\n\t */\n\t// TODO: Change this interface (and the one in ISharedObject, if necessary) to support \"handles within handles\".\n\t// Consider the case of a document with history; the return value here currently grows unboundedly.\n\tgetGCData(fullGC?: boolean): IGarbageCollectionData;\n\n\t/**\n\t * Allows the component to perform custom loading. The storage service is scoped to this component and therefore\n\t * paths in this component will not collide with those in other components, even if they are the same string.\n\t * @param service - Storage used by the component\n\t * @param parse - Parses serialized data from storage into runtime objects for the component\n\t */\n\tload(service: IChannelStorageService, parse: SummaryElementParser): Promise<void>;\n}\n\n/**\n * Serializes the given contents into a string acceptable for storing in summaries, i.e. all\n * Fluid handles have been replaced appropriately by an IFluidSerializer\n */\nexport type SummaryElementStringifier = (contents: unknown) => string;\n\n/**\n * Parses a serialized/summarized string into an object, rehydrating any Fluid handles as necessary\n */\nexport type SummaryElementParser = (contents: string) => unknown;\n\n/**\n * Compose an {@link IChannelStorageService} which prefixes all paths before forwarding them to the original service\n */\nfunction scopeStorageService(\n\tservice: IChannelStorageService,\n\t...pathElements: string[]\n): IChannelStorageService {\n\tconst scope = `${pathElements.join(\"/\")}/`;\n\n\treturn {\n\t\tasync readBlob(path: string): Promise<ArrayBufferLike> {\n\t\t\treturn service.readBlob(`${scope}${path}`);\n\t\t},\n\t\tasync contains(path) {\n\t\t\treturn service.contains(`${scope}${path}`);\n\t\t},\n\t\tasync list(path) {\n\t\t\treturn service.list(`${scope}${path}`);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -11,8 +11,18 @@ export declare class TransactionEnricher<TChange> {
|
|
|
11
11
|
private readonly rebaser;
|
|
12
12
|
private readonly enricher;
|
|
13
13
|
private readonly transactionCommits;
|
|
14
|
+
/**
|
|
15
|
+
* The number of commits before the start of each active transaction scope.
|
|
16
|
+
* For a stack of `n` transaction scopes, the array will contain `n` integers,
|
|
17
|
+
* where the integer at index `i` is the number of commits made before the start of the `i`th transaction scope
|
|
18
|
+
* (therefore, the first element in the array, if present, is always 0)
|
|
19
|
+
*/
|
|
20
|
+
private readonly transactionScopesStart;
|
|
14
21
|
constructor(rebaser: ChangeRebaser<TChange>, enricher: ChangeEnricherReadonlyCheckout<TChange>);
|
|
15
|
-
|
|
22
|
+
startNewTransaction(): void;
|
|
23
|
+
commitCurrentTransaction(): void;
|
|
24
|
+
abortCurrentTransaction(): void;
|
|
25
|
+
addTransactionStep(commit: GraphCommit<TChange>): void;
|
|
16
26
|
getComposedChange(revision: RevisionTag): TChange;
|
|
17
27
|
}
|
|
18
28
|
//# sourceMappingURL=transactionEnricher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactionEnricher.d.ts","sourceRoot":"","sources":["../../src/shared-tree-core/transactionEnricher.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"transactionEnricher.d.ts","sourceRoot":"","sources":["../../src/shared-tree-core/transactionEnricher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AAE1E;;GAEG;AACH,qBAAa,mBAAmB,CAAC,OAAO;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8B;IACjE;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAgB;gBAGtD,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAC/B,QAAQ,EAAE,8BAA8B,CAAC,OAAO,CAAC;IAM3C,mBAAmB,IAAI,IAAI;IAI3B,wBAAwB,IAAI,IAAI;IAKhC,uBAAuB,IAAI,IAAI;IAM/B,kBAAkB,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI;IAMtD,iBAAiB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO;CAOxD"}
|
|
@@ -5,24 +5,45 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.TransactionEnricher = void 0;
|
|
8
|
+
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
8
9
|
/**
|
|
9
10
|
* Utility for producing an enriched commit out of multiple transaction steps
|
|
10
11
|
*/
|
|
11
12
|
class TransactionEnricher {
|
|
12
|
-
rebaser;
|
|
13
|
-
enricher;
|
|
14
|
-
transactionCommits = [];
|
|
15
13
|
constructor(rebaser, enricher) {
|
|
14
|
+
this.transactionCommits = [];
|
|
15
|
+
/**
|
|
16
|
+
* The number of commits before the start of each active transaction scope.
|
|
17
|
+
* For a stack of `n` transaction scopes, the array will contain `n` integers,
|
|
18
|
+
* where the integer at index `i` is the number of commits made before the start of the `i`th transaction scope
|
|
19
|
+
* (therefore, the first element in the array, if present, is always 0)
|
|
20
|
+
*/
|
|
21
|
+
this.transactionScopesStart = [];
|
|
16
22
|
this.rebaser = rebaser;
|
|
17
23
|
this.enricher = enricher;
|
|
18
24
|
}
|
|
19
|
-
|
|
25
|
+
startNewTransaction() {
|
|
26
|
+
this.transactionScopesStart.push(this.transactionCommits.length);
|
|
27
|
+
}
|
|
28
|
+
commitCurrentTransaction() {
|
|
29
|
+
const commitsCommitted = this.transactionScopesStart.pop();
|
|
30
|
+
(0, internal_1.assert)(commitsCommitted !== undefined, "No transaction to commit");
|
|
31
|
+
}
|
|
32
|
+
abortCurrentTransaction() {
|
|
33
|
+
const scopeStart = this.transactionScopesStart.pop();
|
|
34
|
+
(0, internal_1.assert)(scopeStart !== undefined, "No transaction to abort");
|
|
35
|
+
this.transactionCommits.length = scopeStart;
|
|
36
|
+
}
|
|
37
|
+
addTransactionStep(commit) {
|
|
38
|
+
(0, internal_1.assert)(this.transactionScopesStart.length !== 0, "No transaction to add a step to");
|
|
20
39
|
const change = this.enricher.updateChangeEnrichments(commit.change, commit.revision);
|
|
21
40
|
this.transactionCommits.push({ ...commit, change });
|
|
22
41
|
}
|
|
23
42
|
getComposedChange(revision) {
|
|
43
|
+
(0, internal_1.assert)(this.transactionScopesStart.length === 0, "Transaction not committed");
|
|
24
44
|
const squashed = this.rebaser.compose(this.transactionCommits);
|
|
25
45
|
const tagged = this.rebaser.changeRevision(squashed, revision);
|
|
46
|
+
this.transactionCommits.length = 0;
|
|
26
47
|
return tagged;
|
|
27
48
|
}
|
|
28
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transactionEnricher.js","sourceRoot":"","sources":["../../src/shared-tree-core/transactionEnricher.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"transactionEnricher.js","sourceRoot":"","sources":["../../src/shared-tree-core/transactionEnricher.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAI7D;;GAEG;AACH,MAAa,mBAAmB;IAY/B,YACC,OAA+B,EAC/B,QAAiD;QAXjC,uBAAkB,GAA2B,EAAE,CAAC;QACjE;;;;;WAKG;QACc,2BAAsB,GAAa,EAAE,CAAC;QAMtD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;IAEM,mBAAmB;QACzB,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAClE,CAAC;IAEM,wBAAwB;QAC9B,MAAM,gBAAgB,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,CAAC;QAC3D,IAAA,iBAAM,EAAC,gBAAgB,KAAK,SAAS,EAAE,0BAA0B,CAAC,CAAC;IACpE,CAAC;IAEM,uBAAuB;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,CAAC;QACrD,IAAA,iBAAM,EAAC,UAAU,KAAK,SAAS,EAAE,yBAAyB,CAAC,CAAC;QAC5D,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,UAAU,CAAC;IAC7C,CAAC;IAEM,kBAAkB,CAAC,MAA4B;QACrD,IAAA,iBAAM,EAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,KAAK,CAAC,EAAE,iCAAiC,CAAC,CAAC;QACpF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAEM,iBAAiB,CAAC,QAAqB;QAC7C,IAAA,iBAAM,EAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,KAAK,CAAC,EAAE,2BAA2B,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/D,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC;IACf,CAAC;CACD;AAhDD,kDAgDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ChangeRebaser, GraphCommit, RevisionTag } from \"../core/index.js\";\nimport type { ChangeEnricherReadonlyCheckout } from \"./changeEnricher.js\";\n\n/**\n * Utility for producing an enriched commit out of multiple transaction steps\n */\nexport class TransactionEnricher<TChange> {\n\tprivate readonly rebaser: ChangeRebaser<TChange>;\n\tprivate readonly enricher: ChangeEnricherReadonlyCheckout<TChange>;\n\tprivate readonly transactionCommits: GraphCommit<TChange>[] = [];\n\t/**\n\t * The number of commits before the start of each active transaction scope.\n\t * For a stack of `n` transaction scopes, the array will contain `n` integers,\n\t * where the integer at index `i` is the number of commits made before the start of the `i`th transaction scope\n\t * (therefore, the first element in the array, if present, is always 0)\n\t */\n\tprivate readonly transactionScopesStart: number[] = [];\n\n\tpublic constructor(\n\t\trebaser: ChangeRebaser<TChange>,\n\t\tenricher: ChangeEnricherReadonlyCheckout<TChange>,\n\t) {\n\t\tthis.rebaser = rebaser;\n\t\tthis.enricher = enricher;\n\t}\n\n\tpublic startNewTransaction(): void {\n\t\tthis.transactionScopesStart.push(this.transactionCommits.length);\n\t}\n\n\tpublic commitCurrentTransaction(): void {\n\t\tconst commitsCommitted = this.transactionScopesStart.pop();\n\t\tassert(commitsCommitted !== undefined, \"No transaction to commit\");\n\t}\n\n\tpublic abortCurrentTransaction(): void {\n\t\tconst scopeStart = this.transactionScopesStart.pop();\n\t\tassert(scopeStart !== undefined, \"No transaction to abort\");\n\t\tthis.transactionCommits.length = scopeStart;\n\t}\n\n\tpublic addTransactionStep(commit: GraphCommit<TChange>): void {\n\t\tassert(this.transactionScopesStart.length !== 0, \"No transaction to add a step to\");\n\t\tconst change = this.enricher.updateChangeEnrichments(commit.change, commit.revision);\n\t\tthis.transactionCommits.push({ ...commit, change });\n\t}\n\n\tpublic getComposedChange(revision: RevisionTag): TChange {\n\t\tassert(this.transactionScopesStart.length === 0, \"Transaction not committed\");\n\t\tconst squashed = this.rebaser.compose(this.transactionCommits);\n\t\tconst tagged = this.rebaser.changeRevision(squashed, revision);\n\t\tthis.transactionCommits.length = 0;\n\t\treturn tagged;\n\t}\n}\n"]}
|
|
@@ -10,7 +10,9 @@ const index_js_1 = require("../util/index.js");
|
|
|
10
10
|
* A helper class that organizes the state needed for managing nesting transactions.
|
|
11
11
|
*/
|
|
12
12
|
class TransactionStack {
|
|
13
|
-
|
|
13
|
+
constructor() {
|
|
14
|
+
this.stack = [];
|
|
15
|
+
}
|
|
14
16
|
/**
|
|
15
17
|
* The number of transactions currently ongoing.
|
|
16
18
|
*/
|