@fluidframework/tree 2.74.0-370705 → 2.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +1 -16
- package/.vscode/settings.json +2 -0
- package/CHANGELOG.md +29 -0
- package/api-report/tree.alpha.api.md +39 -17
- package/assertTagging.config.mjs +1 -1
- package/dist/alpha.d.ts +7 -0
- package/dist/codec/codec.d.ts +63 -20
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +50 -24
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/index.d.ts +2 -2
- package/dist/codec/index.d.ts.map +1 -1
- package/dist/codec/index.js +2 -2
- package/dist/codec/index.js.map +1 -1
- package/dist/codec/versioned/codec.d.ts +80 -22
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js +137 -15
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/codec/versioned/index.d.ts +1 -1
- package/dist/codec/versioned/index.d.ts.map +1 -1
- package/dist/codec/versioned/index.js +2 -2
- package/dist/codec/versioned/index.js.map +1 -1
- package/dist/core/change-family/changeFamily.d.ts +1 -4
- package/dist/core/change-family/changeFamily.d.ts.map +1 -1
- package/dist/core/change-family/changeFamily.js.map +1 -1
- package/dist/core/change-family/index.d.ts +1 -1
- package/dist/core/change-family/index.d.ts.map +1 -1
- package/dist/core/change-family/index.js.map +1 -1
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +5 -8
- package/dist/core/index.js.map +1 -1
- package/dist/core/rebase/changeRebaser.d.ts +37 -8
- package/dist/core/rebase/changeRebaser.d.ts.map +1 -1
- package/dist/core/rebase/changeRebaser.js.map +1 -1
- package/dist/core/rebase/index.d.ts +2 -2
- package/dist/core/rebase/index.d.ts.map +1 -1
- package/dist/core/rebase/index.js +1 -3
- package/dist/core/rebase/index.js.map +1 -1
- package/dist/core/rebase/types.d.ts +27 -5
- package/dist/core/rebase/types.d.ts.map +1 -1
- package/dist/core/rebase/types.js +1 -16
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/rebase/utils.d.ts.map +1 -1
- package/dist/core/rebase/utils.js +10 -28
- package/dist/core/rebase/utils.js.map +1 -1
- package/dist/core/schema-stored/schema.d.ts +4 -7
- package/dist/core/schema-stored/schema.d.ts.map +1 -1
- package/dist/core/schema-stored/schema.js +5 -5
- package/dist/core/schema-stored/schema.js.map +1 -1
- package/dist/core/tree/anchorSet.d.ts.map +1 -1
- package/dist/core/tree/anchorSet.js +3 -4
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/core/tree/detachedFieldIndex.d.ts +1 -8
- package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndex.js +12 -65
- package/dist/core/tree/detachedFieldIndex.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecCommon.d.ts +18 -10
- package/dist/core/tree/detachedFieldIndexCodecCommon.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecCommon.js +6 -6
- package/dist/core/tree/detachedFieldIndexCodecCommon.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV1.d.ts +2 -3
- package/dist/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV1.js +4 -5
- package/dist/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV2.d.ts +2 -3
- package/dist/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV2.js +4 -6
- package/dist/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.d.ts +5 -6
- package/dist/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.js +11 -41
- package/dist/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatCommon.d.ts +4 -4
- package/dist/core/tree/detachedFieldIndexFormatCommon.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatCommon.js +2 -2
- package/dist/core/tree/detachedFieldIndexFormatCommon.js.map +1 -1
- package/dist/core/tree/index.d.ts +2 -2
- package/dist/core/tree/index.d.ts.map +1 -1
- package/dist/core/tree/index.js +4 -5
- package/dist/core/tree/index.js.map +1 -1
- package/dist/core/tree/mapTree.js +1 -1
- package/dist/core/tree/mapTree.js.map +1 -1
- package/dist/core/tree/pathTree.d.ts +3 -11
- package/dist/core/tree/pathTree.d.ts.map +1 -1
- package/dist/core/tree/pathTree.js +2 -14
- package/dist/core/tree/pathTree.js.map +1 -1
- package/dist/core/tree/sparseTree.d.ts.map +1 -1
- package/dist/core/tree/sparseTree.js +1 -0
- package/dist/core/tree/sparseTree.js.map +1 -1
- package/dist/core/tree/treeTextFormat.d.ts.map +1 -1
- package/dist/core/tree/treeTextFormat.js +5 -9
- package/dist/core/tree/treeTextFormat.js.map +1 -1
- package/dist/feature-libraries/changeAtomIdBTree.d.ts +10 -0
- package/dist/feature-libraries/changeAtomIdBTree.d.ts.map +1 -0
- package/dist/feature-libraries/changeAtomIdBTree.js +16 -0
- package/dist/feature-libraries/changeAtomIdBTree.js.map +1 -0
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +1 -8
- package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +1 -4
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +6 -6
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +7 -4
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +19 -11
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +3 -3
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format.d.ts +5 -5
- package/dist/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format.js +4 -4
- package/dist/feature-libraries/chunked-forest/codec/format.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +9 -5
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +54 -93
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js +81 -245
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +6 -5
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/default-schema/index.d.ts +1 -2
- package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/index.js +2 -5
- package/dist/feature-libraries/default-schema/index.js.map +1 -1
- package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts +8 -7
- package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/mappedEditBuilder.js +6 -15
- package/dist/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
- package/dist/feature-libraries/deltaUtils.d.ts +0 -1
- package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
- package/dist/feature-libraries/deltaUtils.js +1 -6
- package/dist/feature-libraries/deltaUtils.js.map +1 -1
- package/dist/feature-libraries/flex-tree/context.d.ts +0 -9
- package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js +0 -6
- package/dist/feature-libraries/flex-tree/context.js.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.d.ts +7 -8
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +16 -47
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.d.ts +8 -2
- package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.js +13 -11
- package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +3 -2
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +18 -9
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.d.ts +61 -0
- package/dist/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/{format.js → formatCommon.js} +9 -6
- package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -0
- package/dist/feature-libraries/forest-summary/{format.d.ts → formatV1.d.ts} +6 -14
- package/dist/feature-libraries/forest-summary/formatV1.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/formatV1.js +11 -0
- package/dist/feature-libraries/forest-summary/formatV1.js.map +1 -0
- package/dist/feature-libraries/forest-summary/formatV2.d.ts +51 -0
- package/dist/feature-libraries/forest-summary/formatV2.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/formatV2.js +11 -0
- package/dist/feature-libraries/forest-summary/formatV2.js.map +1 -0
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +7 -15
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +11 -20
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/dist/feature-libraries/forest-summary/index.d.ts +1 -2
- package/dist/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/index.js +3 -5
- package/dist/feature-libraries/forest-summary/index.js.map +1 -1
- package/dist/feature-libraries/forest-summary/summaryFormatCommon.d.ts +35 -0
- package/dist/feature-libraries/forest-summary/summaryFormatCommon.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryFormatCommon.js +43 -0
- package/dist/feature-libraries/forest-summary/summaryFormatCommon.js.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV1ToV2.d.ts +11 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV1ToV2.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV1ToV2.js +14 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV1ToV2.js.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV3.d.ts +18 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV3.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV3.js +21 -0
- package/dist/feature-libraries/forest-summary/summaryFormatV3.js.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts +7 -37
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/summaryTypes.js +23 -45
- package/dist/feature-libraries/forest-summary/summaryTypes.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +5 -4
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +10 -12
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/indexing/anchorTreeIndex.js +6 -6
- package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.js +0 -1
- package/dist/feature-libraries/mapTreeCursor.js.map +1 -1
- package/dist/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/mitigatedChangeFamily.js +12 -3
- package/dist/feature-libraries/mitigatedChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.js +13 -10
- package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +21 -97
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js +7 -4
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +25 -0
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js +59 -0
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -0
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +52 -20
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +13 -7
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +7 -5
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +7 -7
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +41 -9
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +263 -336
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +7 -9
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js +8 -390
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +24 -11
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +27 -55
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +622 -1433
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +3 -4
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js +4 -4
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +14 -48
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +10 -21
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +18 -48
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js +3 -24
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/dist/feature-libraries/node-identifier/mockNodeIdentifierManager.js +1 -1
- package/dist/feature-libraries/node-identifier/mockNodeIdentifierManager.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +4 -4
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/optional-field/index.d.ts +2 -2
- package/dist/feature-libraries/optional-field/index.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/index.js +2 -1
- package/dist/feature-libraries/optional-field/index.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.d.ts +26 -5
- package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +447 -218
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +33 -24
- package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js +28 -57
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecs.js +1 -5
- package/dist/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
- package/dist/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js +15 -4
- package/dist/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/schema-index/codec.d.ts +7 -21
- package/dist/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/codec.js +28 -70
- package/dist/feature-libraries/schema-index/codec.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV1.d.ts +1 -1
- package/dist/feature-libraries/schema-index/formatV2.d.ts +1 -1
- package/dist/feature-libraries/schema-index/index.d.ts +2 -2
- package/dist/feature-libraries/schema-index/index.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/index.js +2 -5
- package/dist/feature-libraries/schema-index/index.js.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts +1 -9
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -12
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/schemaChecker.d.ts.map +1 -1
- package/dist/feature-libraries/schemaChecker.js +11 -6
- package/dist/feature-libraries/schemaChecker.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.d.ts +7 -6
- package/dist/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +264 -84
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/helperTypes.d.ts +10 -14
- package/dist/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/helperTypes.js.map +1 -1
- package/dist/feature-libraries/sequence-field/index.d.ts +3 -2
- package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/index.js +3 -1
- package/dist/feature-libraries/sequence-field/index.js.map +1 -1
- package/dist/feature-libraries/sequence-field/invert.d.ts +3 -3
- package/dist/feature-libraries/sequence-field/invert.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/invert.js +169 -66
- package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
- package/dist/feature-libraries/sequence-field/markQueue.d.ts +2 -2
- package/dist/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +56 -4
- package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.js +93 -8
- package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.d.ts +3 -3
- package/dist/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.js +127 -113
- package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +9 -0
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +1 -0
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js +50 -0
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js.map +1 -0
- package/dist/feature-libraries/sequence-field/replaceRevisions.d.ts +2 -2
- package/dist/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/replaceRevisions.js +49 -27
- package/dist/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +2 -0
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +4 -22
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +187 -358
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js +62 -20
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +115 -17
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/dist/feature-libraries/sequence-field/types.d.ts +59 -30
- package/dist/feature-libraries/sequence-field/types.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/types.js.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.d.ts +24 -15
- package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +334 -127
- package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
- package/dist/feature-libraries/treeCursorUtils.js +7 -7
- package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
- package/dist/feature-libraries/treeTextCursor.js +2 -2
- package/dist/feature-libraries/treeTextCursor.js.map +1 -1
- package/dist/feature-libraries/valueUtilities.d.ts.map +1 -1
- package/dist/feature-libraries/valueUtilities.js +16 -8
- package/dist/feature-libraries/valueUtilities.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/independentView.d.ts.map +1 -1
- package/dist/shared-tree/independentView.js +1 -1
- package/dist/shared-tree/independentView.js.map +1 -1
- package/dist/shared-tree/index.d.ts +1 -1
- package/dist/shared-tree/index.d.ts.map +1 -1
- package/dist/shared-tree/index.js.map +1 -1
- package/dist/shared-tree/schematizeTree.d.ts +4 -4
- package/dist/shared-tree/schematizeTree.d.ts.map +1 -1
- package/dist/shared-tree/schematizeTree.js +1 -2
- package/dist/shared-tree/schematizeTree.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +9 -5
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +56 -41
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +3 -9
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +57 -50
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js +11 -11
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.js +5 -3
- package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.d.ts +7 -6
- package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.js +23 -24
- package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/dist/shared-tree/sharedTreeEditBuilder.d.ts +6 -16
- package/dist/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeEditBuilder.js +7 -14
- package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts +35 -29
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +21 -23
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +17 -12
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +85 -66
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branch.d.ts +5 -4
- package/dist/shared-tree-core/branch.d.ts.map +1 -1
- package/dist/shared-tree-core/branch.js +7 -6
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
- package/dist/shared-tree-core/branchCommitEnricher.js +1 -1
- package/dist/shared-tree-core/branchCommitEnricher.js.map +1 -1
- package/dist/shared-tree-core/editManager.d.ts +2 -2
- package/dist/shared-tree-core/editManager.d.ts.map +1 -1
- package/dist/shared-tree-core/editManager.js +10 -10
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.d.ts +0 -4
- package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.js +13 -16
- package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js +1 -1
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts +9 -44
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.js +8 -8
- package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
- package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.js +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js +3 -3
- package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/dist/shared-tree-core/index.d.ts +3 -2
- package/dist/shared-tree-core/index.d.ts.map +1 -1
- package/dist/shared-tree-core/index.js +2 -3
- package/dist/shared-tree-core/index.js.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.d.ts +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.js +2 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/messageCodecs.d.ts +0 -4
- package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecs.js +15 -19
- package/dist/shared-tree-core/messageCodecs.js.map +1 -1
- package/dist/shared-tree-core/messageFormat.d.ts +10 -50
- package/dist/shared-tree-core/messageFormat.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormat.js +9 -8
- package/dist/shared-tree-core/messageFormat.js.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts +2 -2
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts +1 -1
- package/dist/shared-tree-core/sequenceIdUtils.d.ts.map +1 -1
- package/dist/shared-tree-core/sequenceIdUtils.js +4 -4
- package/dist/shared-tree-core/sequenceIdUtils.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts +0 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +13 -9
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/shared-tree-core/transaction.d.ts +25 -8
- package/dist/shared-tree-core/transaction.d.ts.map +1 -1
- package/dist/shared-tree-core/transaction.js +65 -30
- package/dist/shared-tree-core/transaction.js.map +1 -1
- package/dist/shared-tree-core/transactionEnricher.d.ts +2 -2
- package/dist/shared-tree-core/transactionEnricher.d.ts.map +1 -1
- package/dist/shared-tree-core/transactionEnricher.js +3 -3
- package/dist/shared-tree-core/transactionEnricher.js.map +1 -1
- package/dist/shared-tree-core/versionedSummarizer.d.ts +6 -1
- package/dist/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
- package/dist/shared-tree-core/versionedSummarizer.js +4 -3
- package/dist/shared-tree-core/versionedSummarizer.js.map +1 -1
- package/dist/simple-tree/api/configuration.js +1 -1
- package/dist/simple-tree/api/configuration.js.map +1 -1
- package/dist/simple-tree/api/customTree.d.ts.map +1 -1
- package/dist/simple-tree/api/customTree.js +13 -9
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/discrepancies.d.ts.map +1 -1
- package/dist/simple-tree/api/discrepancies.js +21 -17
- package/dist/simple-tree/api/discrepancies.js.map +1 -1
- package/dist/simple-tree/api/eraseSchemaDetails.d.ts +89 -0
- package/dist/simple-tree/api/eraseSchemaDetails.d.ts.map +1 -0
- package/dist/simple-tree/api/eraseSchemaDetails.js +97 -0
- package/dist/simple-tree/api/eraseSchemaDetails.js.map +1 -0
- package/dist/simple-tree/api/index.d.ts +2 -1
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +5 -1
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +12 -8
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/schemaFromSimple.js +18 -9
- package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaCodec.js +10 -5
- package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +15 -11
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/simpleTreeIndex.js +10 -10
- package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
- package/dist/simple-tree/api/storedSchema.d.ts +1 -1
- package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/storedSchema.js +3 -5
- package/dist/simple-tree/api/storedSchema.js.map +1 -1
- package/dist/simple-tree/api/transactionTypes.d.ts +17 -4
- package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
- package/dist/simple-tree/api/transactionTypes.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +15 -2
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.js +21 -13
- package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/dist/simple-tree/api/verboseTree.js +14 -9
- package/dist/simple-tree/api/verboseTree.js.map +1 -1
- package/dist/simple-tree/core/treeNode.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNode.js +1 -0
- package/dist/simple-tree/core/treeNode.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +6 -3
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts +15 -15
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +28 -74
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/createContext.d.ts.map +1 -1
- package/dist/simple-tree/createContext.js +1 -1
- package/dist/simple-tree/createContext.js.map +1 -1
- package/dist/simple-tree/fieldSchema.d.ts +4 -4
- package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
- package/dist/simple-tree/fieldSchema.js.map +1 -1
- package/dist/simple-tree/getTreeNodeForField.d.ts.map +1 -1
- package/dist/simple-tree/getTreeNodeForField.js +2 -1
- package/dist/simple-tree/getTreeNodeForField.js.map +1 -1
- package/dist/simple-tree/index.d.ts +3 -3
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +5 -3
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.js +9 -6
- package/dist/simple-tree/leafNodeSchema.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +18 -20
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/common.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/common.js +1 -1
- package/dist/simple-tree/node-kinds/common.js.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNode.js +2 -2
- package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.js +21 -22
- package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNode.js +4 -7
- package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/dist/simple-tree/prepareForInsertion.d.ts +47 -54
- package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/dist/simple-tree/prepareForInsertion.js +125 -183
- package/dist/simple-tree/prepareForInsertion.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +12 -8
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +4 -13
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +11 -29
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/dist/tableSchema.d.ts +3 -14
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +2 -2
- package/dist/tableSchema.js.map +1 -1
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +2 -12
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/bTreeUtils.js +1 -1
- package/dist/util/bTreeUtils.js.map +1 -1
- package/dist/util/brand.d.ts +49 -0
- package/dist/util/brand.d.ts.map +1 -1
- package/dist/util/brand.js +47 -1
- package/dist/util/brand.js.map +1 -1
- package/dist/util/breakable.js +7 -9
- package/dist/util/breakable.js.map +1 -1
- package/dist/util/idAllocator.d.ts.map +1 -1
- package/dist/util/idAllocator.js +1 -2
- package/dist/util/idAllocator.js.map +1 -1
- package/dist/util/index.d.ts +2 -2
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +4 -3
- package/dist/util/index.js.map +1 -1
- package/dist/util/nestedMap.d.ts.map +1 -1
- package/dist/util/nestedMap.js +1 -1
- package/dist/util/nestedMap.js.map +1 -1
- package/dist/util/rangeMap.d.ts +12 -24
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +6 -46
- package/dist/util/rangeMap.js.map +1 -1
- package/dist/util/utils.d.ts.map +1 -1
- package/dist/util/utils.js +16 -15
- package/dist/util/utils.js.map +1 -1
- package/docs/main/sequence-field/move-composition.md +46 -0
- package/eslint.config.mts +83 -0
- package/lib/alpha.d.ts +7 -0
- package/lib/codec/codec.d.ts +63 -20
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +44 -18
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/index.d.ts +2 -2
- package/lib/codec/index.d.ts.map +1 -1
- package/lib/codec/index.js +1 -1
- package/lib/codec/index.js.map +1 -1
- package/lib/codec/versioned/codec.d.ts +80 -22
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js +138 -15
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/codec/versioned/index.d.ts +1 -1
- package/lib/codec/versioned/index.d.ts.map +1 -1
- package/lib/codec/versioned/index.js +1 -1
- package/lib/codec/versioned/index.js.map +1 -1
- package/lib/core/change-family/changeFamily.d.ts +1 -4
- package/lib/core/change-family/changeFamily.d.ts.map +1 -1
- package/lib/core/change-family/changeFamily.js.map +1 -1
- package/lib/core/change-family/index.d.ts +1 -1
- package/lib/core/change-family/index.d.ts.map +1 -1
- package/lib/core/change-family/index.js.map +1 -1
- package/lib/core/index.d.ts +3 -3
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +2 -2
- package/lib/core/index.js.map +1 -1
- package/lib/core/rebase/changeRebaser.d.ts +37 -8
- package/lib/core/rebase/changeRebaser.d.ts.map +1 -1
- package/lib/core/rebase/changeRebaser.js.map +1 -1
- package/lib/core/rebase/index.d.ts +2 -2
- package/lib/core/rebase/index.d.ts.map +1 -1
- package/lib/core/rebase/index.js +1 -1
- package/lib/core/rebase/index.js.map +1 -1
- package/lib/core/rebase/types.d.ts +27 -5
- package/lib/core/rebase/types.d.ts.map +1 -1
- package/lib/core/rebase/types.js +0 -13
- package/lib/core/rebase/types.js.map +1 -1
- package/lib/core/rebase/utils.d.ts.map +1 -1
- package/lib/core/rebase/utils.js +10 -28
- package/lib/core/rebase/utils.js.map +1 -1
- package/lib/core/schema-stored/schema.d.ts +4 -7
- package/lib/core/schema-stored/schema.d.ts.map +1 -1
- package/lib/core/schema-stored/schema.js +6 -6
- package/lib/core/schema-stored/schema.js.map +1 -1
- package/lib/core/tree/anchorSet.d.ts.map +1 -1
- package/lib/core/tree/anchorSet.js +3 -4
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/core/tree/detachedFieldIndex.d.ts +1 -8
- package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndex.js +14 -67
- package/lib/core/tree/detachedFieldIndex.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecCommon.d.ts +18 -10
- package/lib/core/tree/detachedFieldIndexCodecCommon.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecCommon.js +4 -4
- package/lib/core/tree/detachedFieldIndexCodecCommon.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV1.d.ts +2 -3
- package/lib/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV1.js +4 -5
- package/lib/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV2.d.ts +2 -3
- package/lib/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV2.js +4 -6
- package/lib/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.d.ts +5 -6
- package/lib/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.js +12 -39
- package/lib/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormatCommon.d.ts +4 -4
- package/lib/core/tree/detachedFieldIndexFormatCommon.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormatCommon.js +3 -3
- package/lib/core/tree/detachedFieldIndexFormatCommon.js.map +1 -1
- package/lib/core/tree/index.d.ts +2 -2
- package/lib/core/tree/index.d.ts.map +1 -1
- package/lib/core/tree/index.js +2 -2
- package/lib/core/tree/index.js.map +1 -1
- package/lib/core/tree/mapTree.js +1 -1
- package/lib/core/tree/mapTree.js.map +1 -1
- package/lib/core/tree/pathTree.d.ts +3 -11
- package/lib/core/tree/pathTree.d.ts.map +1 -1
- package/lib/core/tree/pathTree.js +1 -12
- package/lib/core/tree/pathTree.js.map +1 -1
- package/lib/core/tree/sparseTree.d.ts.map +1 -1
- package/lib/core/tree/sparseTree.js +1 -0
- package/lib/core/tree/sparseTree.js.map +1 -1
- package/lib/core/tree/treeTextFormat.d.ts.map +1 -1
- package/lib/core/tree/treeTextFormat.js +5 -9
- package/lib/core/tree/treeTextFormat.js.map +1 -1
- package/lib/feature-libraries/changeAtomIdBTree.d.ts +10 -0
- package/lib/feature-libraries/changeAtomIdBTree.d.ts.map +1 -0
- package/lib/feature-libraries/changeAtomIdBTree.js +11 -0
- package/lib/feature-libraries/changeAtomIdBTree.js.map +1 -0
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +2 -9
- package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +1 -4
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +6 -6
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +7 -4
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +20 -12
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +3 -3
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format.d.ts +5 -5
- package/lib/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format.js +5 -5
- package/lib/feature-libraries/chunked-forest/codec/format.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +9 -5
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +54 -93
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js +82 -243
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +6 -5
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/default-schema/index.d.ts +1 -2
- package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/index.js +1 -2
- package/lib/feature-libraries/default-schema/index.js.map +1 -1
- package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts +8 -7
- package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/mappedEditBuilder.js +6 -15
- package/lib/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
- package/lib/feature-libraries/deltaUtils.d.ts +0 -1
- package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
- package/lib/feature-libraries/deltaUtils.js +1 -5
- package/lib/feature-libraries/deltaUtils.js.map +1 -1
- package/lib/feature-libraries/flex-tree/context.d.ts +0 -9
- package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js +0 -6
- package/lib/feature-libraries/flex-tree/context.js.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.d.ts +7 -8
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +17 -48
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.d.ts +8 -2
- package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.js +12 -11
- package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +3 -2
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +19 -10
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/forest-summary/formatCommon.d.ts +61 -0
- package/lib/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/{format.js → formatCommon.js} +8 -6
- package/lib/feature-libraries/forest-summary/formatCommon.js.map +1 -0
- package/lib/feature-libraries/forest-summary/{format.d.ts → formatV1.d.ts} +6 -14
- package/lib/feature-libraries/forest-summary/formatV1.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/formatV1.js +8 -0
- package/lib/feature-libraries/forest-summary/formatV1.js.map +1 -0
- package/lib/feature-libraries/forest-summary/formatV2.d.ts +51 -0
- package/lib/feature-libraries/forest-summary/formatV2.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/formatV2.js +8 -0
- package/lib/feature-libraries/forest-summary/formatV2.js.map +1 -0
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +7 -15
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +11 -20
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/lib/feature-libraries/forest-summary/index.d.ts +1 -2
- package/lib/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/index.js +1 -2
- package/lib/feature-libraries/forest-summary/index.js.map +1 -1
- package/lib/feature-libraries/forest-summary/summaryFormatCommon.d.ts +35 -0
- package/lib/feature-libraries/forest-summary/summaryFormatCommon.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryFormatCommon.js +40 -0
- package/lib/feature-libraries/forest-summary/summaryFormatCommon.js.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV1ToV2.d.ts +11 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV1ToV2.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV1ToV2.js +11 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV1ToV2.js.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV3.d.ts +18 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV3.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV3.js +18 -0
- package/lib/feature-libraries/forest-summary/summaryFormatV3.js.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts +7 -37
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/summaryTypes.js +20 -43
- package/lib/feature-libraries/forest-summary/summaryTypes.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +5 -4
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +5 -4
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/indexing/anchorTreeIndex.js +6 -6
- package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.js +1 -2
- package/lib/feature-libraries/mapTreeCursor.js.map +1 -1
- package/lib/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/mitigatedChangeFamily.js +12 -3
- package/lib/feature-libraries/mitigatedChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.js +13 -10
- package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +21 -97
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js +5 -3
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +25 -0
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js +55 -0
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -0
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +52 -20
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +14 -8
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +7 -5
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js +5 -4
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +41 -9
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +248 -334
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +7 -9
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js +10 -392
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +24 -11
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +27 -55
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +549 -1352
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +3 -4
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +14 -48
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js +10 -21
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +18 -48
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js +2 -20
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/lib/feature-libraries/node-identifier/mockNodeIdentifierManager.js +1 -1
- package/lib/feature-libraries/node-identifier/mockNodeIdentifierManager.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +4 -4
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/optional-field/index.d.ts +2 -2
- package/lib/feature-libraries/optional-field/index.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/index.js +1 -1
- package/lib/feature-libraries/optional-field/index.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.d.ts +26 -5
- package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +445 -218
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +33 -24
- package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js +26 -55
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecs.js +1 -5
- package/lib/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
- package/lib/feature-libraries/schema-edits/schemaChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js +16 -5
- package/lib/feature-libraries/schema-edits/schemaChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/schema-index/codec.d.ts +7 -21
- package/lib/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/codec.js +29 -67
- package/lib/feature-libraries/schema-index/codec.js.map +1 -1
- package/lib/feature-libraries/schema-index/formatV1.d.ts +1 -1
- package/lib/feature-libraries/schema-index/formatV2.d.ts +1 -1
- package/lib/feature-libraries/schema-index/index.d.ts +2 -2
- package/lib/feature-libraries/schema-index/index.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/index.js +2 -2
- package/lib/feature-libraries/schema-index/index.js.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts +1 -9
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js +0 -10
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/schemaChecker.d.ts.map +1 -1
- package/lib/feature-libraries/schemaChecker.js +11 -6
- package/lib/feature-libraries/schemaChecker.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.d.ts +7 -6
- package/lib/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +266 -86
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/helperTypes.d.ts +10 -14
- package/lib/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/helperTypes.js.map +1 -1
- package/lib/feature-libraries/sequence-field/index.d.ts +3 -2
- package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/index.js +1 -0
- package/lib/feature-libraries/sequence-field/index.js.map +1 -1
- package/lib/feature-libraries/sequence-field/invert.d.ts +3 -3
- package/lib/feature-libraries/sequence-field/invert.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/invert.js +171 -68
- package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
- package/lib/feature-libraries/sequence-field/markQueue.d.ts +2 -2
- package/lib/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +56 -4
- package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.js +87 -7
- package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.d.ts +3 -3
- package/lib/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.js +129 -115
- package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +9 -0
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +1 -0
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js +46 -0
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js.map +1 -0
- package/lib/feature-libraries/sequence-field/replaceRevisions.d.ts +2 -2
- package/lib/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/replaceRevisions.js +50 -28
- package/lib/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +2 -0
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +4 -22
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +183 -350
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js +63 -21
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +115 -17
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/lib/feature-libraries/sequence-field/types.d.ts +59 -30
- package/lib/feature-libraries/sequence-field/types.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/types.js.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.d.ts +24 -15
- package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +327 -123
- package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
- package/lib/feature-libraries/treeCursorUtils.js +7 -7
- package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
- package/lib/feature-libraries/treeTextCursor.js +2 -2
- package/lib/feature-libraries/treeTextCursor.js.map +1 -1
- package/lib/feature-libraries/valueUtilities.d.ts.map +1 -1
- package/lib/feature-libraries/valueUtilities.js +16 -8
- package/lib/feature-libraries/valueUtilities.js.map +1 -1
- package/lib/index.d.ts +3 -3
- 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.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/independentView.d.ts.map +1 -1
- package/lib/shared-tree/independentView.js +2 -2
- package/lib/shared-tree/independentView.js.map +1 -1
- package/lib/shared-tree/index.d.ts +1 -1
- package/lib/shared-tree/index.d.ts.map +1 -1
- package/lib/shared-tree/index.js.map +1 -1
- package/lib/shared-tree/schematizeTree.d.ts +4 -4
- package/lib/shared-tree/schematizeTree.d.ts.map +1 -1
- package/lib/shared-tree/schematizeTree.js +2 -3
- package/lib/shared-tree/schematizeTree.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +9 -5
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +59 -44
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +3 -9
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +26 -19
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js +11 -11
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.js +6 -4
- package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.d.ts +7 -6
- package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.js +24 -25
- package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/lib/shared-tree/sharedTreeEditBuilder.d.ts +6 -16
- package/lib/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeEditBuilder.js +6 -12
- package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts +35 -29
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +21 -23
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +17 -12
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +89 -70
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branch.d.ts +5 -4
- package/lib/shared-tree-core/branch.d.ts.map +1 -1
- package/lib/shared-tree-core/branch.js +7 -6
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/branchCommitEnricher.d.ts.map +1 -1
- package/lib/shared-tree-core/branchCommitEnricher.js +2 -2
- package/lib/shared-tree-core/branchCommitEnricher.js.map +1 -1
- package/lib/shared-tree-core/editManager.d.ts +2 -2
- package/lib/shared-tree-core/editManager.d.ts.map +1 -1
- package/lib/shared-tree-core/editManager.js +10 -10
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.d.ts +0 -4
- package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.js +13 -15
- package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js +1 -1
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts +9 -44
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatCommons.js +9 -9
- package/lib/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
- package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.js +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js +3 -3
- package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/lib/shared-tree-core/index.d.ts +3 -2
- package/lib/shared-tree-core/index.d.ts.map +1 -1
- package/lib/shared-tree-core/index.js +2 -2
- package/lib/shared-tree-core/index.js.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.d.ts +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.js +2 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/lib/shared-tree-core/messageCodecs.d.ts +0 -4
- package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecs.js +15 -18
- package/lib/shared-tree-core/messageCodecs.js.map +1 -1
- package/lib/shared-tree-core/messageFormat.d.ts +10 -50
- package/lib/shared-tree-core/messageFormat.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormat.js +9 -8
- package/lib/shared-tree-core/messageFormat.js.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts +2 -2
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts +1 -1
- package/lib/shared-tree-core/sequenceIdUtils.d.ts.map +1 -1
- package/lib/shared-tree-core/sequenceIdUtils.js +4 -4
- package/lib/shared-tree-core/sequenceIdUtils.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts +0 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +13 -9
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/shared-tree-core/transaction.d.ts +25 -8
- package/lib/shared-tree-core/transaction.d.ts.map +1 -1
- package/lib/shared-tree-core/transaction.js +67 -32
- package/lib/shared-tree-core/transaction.js.map +1 -1
- package/lib/shared-tree-core/transactionEnricher.d.ts +2 -2
- package/lib/shared-tree-core/transactionEnricher.d.ts.map +1 -1
- package/lib/shared-tree-core/transactionEnricher.js +3 -3
- package/lib/shared-tree-core/transactionEnricher.js.map +1 -1
- package/lib/shared-tree-core/versionedSummarizer.d.ts +6 -1
- package/lib/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
- package/lib/shared-tree-core/versionedSummarizer.js +4 -3
- package/lib/shared-tree-core/versionedSummarizer.js.map +1 -1
- package/lib/simple-tree/api/configuration.js +1 -1
- package/lib/simple-tree/api/configuration.js.map +1 -1
- package/lib/simple-tree/api/customTree.d.ts.map +1 -1
- package/lib/simple-tree/api/customTree.js +13 -9
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/discrepancies.d.ts.map +1 -1
- package/lib/simple-tree/api/discrepancies.js +21 -17
- package/lib/simple-tree/api/discrepancies.js.map +1 -1
- package/lib/simple-tree/api/eraseSchemaDetails.d.ts +89 -0
- package/lib/simple-tree/api/eraseSchemaDetails.d.ts.map +1 -0
- package/lib/simple-tree/api/eraseSchemaDetails.js +92 -0
- package/lib/simple-tree/api/eraseSchemaDetails.js.map +1 -0
- package/lib/simple-tree/api/index.d.ts +2 -1
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -0
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +12 -8
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/schemaFromSimple.js +18 -9
- package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaCodec.js +10 -5
- package/lib/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +15 -11
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/simpleTreeIndex.js +10 -10
- package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
- package/lib/simple-tree/api/storedSchema.d.ts +1 -1
- package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/storedSchema.js +5 -9
- package/lib/simple-tree/api/storedSchema.js.map +1 -1
- package/lib/simple-tree/api/transactionTypes.d.ts +17 -4
- package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
- package/lib/simple-tree/api/transactionTypes.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +15 -2
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.js +21 -13
- package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/lib/simple-tree/api/verboseTree.js +14 -9
- package/lib/simple-tree/api/verboseTree.js.map +1 -1
- package/lib/simple-tree/core/treeNode.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNode.js +1 -0
- package/lib/simple-tree/core/treeNode.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +6 -3
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts +15 -15
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +28 -73
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/createContext.d.ts.map +1 -1
- package/lib/simple-tree/createContext.js +1 -1
- package/lib/simple-tree/createContext.js.map +1 -1
- package/lib/simple-tree/fieldSchema.d.ts +4 -4
- package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
- package/lib/simple-tree/fieldSchema.js.map +1 -1
- package/lib/simple-tree/getTreeNodeForField.d.ts.map +1 -1
- package/lib/simple-tree/getTreeNodeForField.js +2 -1
- package/lib/simple-tree/getTreeNodeForField.js.map +1 -1
- package/lib/simple-tree/index.d.ts +3 -3
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +2 -2
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.js +9 -6
- package/lib/simple-tree/leafNodeSchema.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +19 -21
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/common.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/common.js +2 -2
- package/lib/simple-tree/node-kinds/common.js.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNode.js +2 -2
- package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.js +22 -23
- package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNode.js +4 -7
- package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/lib/simple-tree/prepareForInsertion.d.ts +47 -54
- package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/lib/simple-tree/prepareForInsertion.js +124 -183
- package/lib/simple-tree/prepareForInsertion.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +12 -8
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +4 -13
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +9 -26
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/lib/tableSchema.d.ts +3 -14
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +3 -3
- package/lib/tableSchema.js.map +1 -1
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +3 -13
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/bTreeUtils.js +1 -1
- package/lib/util/bTreeUtils.js.map +1 -1
- package/lib/util/brand.d.ts +49 -0
- package/lib/util/brand.d.ts.map +1 -1
- package/lib/util/brand.js +44 -0
- package/lib/util/brand.js.map +1 -1
- package/lib/util/breakable.js +7 -9
- package/lib/util/breakable.js.map +1 -1
- package/lib/util/idAllocator.d.ts.map +1 -1
- package/lib/util/idAllocator.js +1 -2
- package/lib/util/idAllocator.js.map +1 -1
- package/lib/util/index.d.ts +2 -2
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +2 -2
- package/lib/util/index.js.map +1 -1
- package/lib/util/nestedMap.d.ts.map +1 -1
- package/lib/util/nestedMap.js +1 -1
- package/lib/util/nestedMap.js.map +1 -1
- package/lib/util/rangeMap.d.ts +12 -24
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +5 -44
- package/lib/util/rangeMap.js.map +1 -1
- package/lib/util/utils.d.ts.map +1 -1
- package/lib/util/utils.js +16 -15
- package/lib/util/utils.js.map +1 -1
- package/package.json +33 -32
- package/src/codec/codec.ts +82 -26
- package/src/codec/index.ts +4 -1
- package/src/codec/versioned/codec.ts +340 -22
- package/src/codec/versioned/index.ts +3 -1
- package/src/core/change-family/changeFamily.ts +0 -5
- package/src/core/change-family/index.ts +0 -1
- package/src/core/index.ts +4 -6
- package/src/core/rebase/changeRebaser.ts +41 -12
- package/src/core/rebase/index.ts +2 -2
- package/src/core/rebase/types.ts +32 -26
- package/src/core/rebase/utils.ts +10 -34
- package/src/core/schema-stored/schema.ts +8 -10
- package/src/core/tree/anchorSet.ts +3 -4
- package/src/core/tree/detachedFieldIndex.ts +14 -91
- package/src/core/tree/detachedFieldIndexCodecCommon.ts +4 -8
- package/src/core/tree/detachedFieldIndexCodecV1.ts +3 -7
- package/src/core/tree/detachedFieldIndexCodecV2.ts +5 -9
- package/src/core/tree/detachedFieldIndexCodecs.ts +21 -64
- package/src/core/tree/detachedFieldIndexFormatCommon.ts +4 -7
- package/src/core/tree/index.ts +2 -3
- package/src/core/tree/mapTree.ts +1 -1
- package/src/core/tree/pathTree.ts +4 -16
- package/src/core/tree/sparseTree.ts +1 -0
- package/src/core/tree/treeTextFormat.ts +5 -9
- package/src/feature-libraries/changeAtomIdBTree.ts +24 -0
- package/src/feature-libraries/chunked-forest/basicChunk.ts +2 -8
- package/src/feature-libraries/chunked-forest/chunkTree.ts +1 -6
- package/src/feature-libraries/chunked-forest/chunkedForest.ts +5 -5
- package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +7 -4
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +20 -11
- package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +3 -3
- package/src/feature-libraries/chunked-forest/codec/format.ts +6 -9
- package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +9 -5
- package/src/feature-libraries/chunked-forest/uniformChunk.ts +1 -1
- package/src/feature-libraries/default-schema/defaultEditBuilder.ts +163 -403
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +9 -7
- package/src/feature-libraries/default-schema/index.ts +5 -17
- package/src/feature-libraries/default-schema/mappedEditBuilder.ts +15 -35
- package/src/feature-libraries/deltaUtils.ts +1 -6
- package/src/feature-libraries/flex-tree/context.ts +0 -17
- package/src/feature-libraries/flex-tree/flexTreeTypes.ts +8 -7
- package/src/feature-libraries/flex-tree/lazyField.ts +31 -74
- package/src/feature-libraries/forest-summary/codec.ts +25 -13
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +37 -12
- package/src/feature-libraries/forest-summary/{format.ts → formatCommon.ts} +10 -11
- package/src/feature-libraries/forest-summary/formatV1.ts +12 -0
- package/src/feature-libraries/forest-summary/formatV2.ts +12 -0
- package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +18 -21
- package/src/feature-libraries/forest-summary/index.ts +1 -2
- package/src/feature-libraries/forest-summary/summaryFormatCommon.ts +41 -0
- package/src/feature-libraries/forest-summary/summaryFormatV1ToV2.ts +11 -0
- package/src/feature-libraries/forest-summary/summaryFormatV3.ts +18 -0
- package/src/feature-libraries/forest-summary/summaryTypes.ts +26 -46
- package/src/feature-libraries/index.ts +18 -27
- package/src/feature-libraries/indexing/anchorTreeIndex.ts +5 -5
- package/src/feature-libraries/mapTreeCursor.ts +1 -2
- package/src/feature-libraries/mitigatedChangeFamily.ts +12 -9
- package/src/feature-libraries/modular-schema/comparison.ts +14 -10
- package/src/feature-libraries/modular-schema/crossFieldQueries.ts +44 -142
- package/src/feature-libraries/modular-schema/defaultRevisionReplacer.ts +70 -0
- package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +58 -40
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +23 -13
- package/src/feature-libraries/modular-schema/index.ts +18 -21
- package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +543 -572
- package/src/feature-libraries/modular-schema/modularChangeCodecV2.ts +44 -745
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +37 -51
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +862 -2636
- package/src/feature-libraries/modular-schema/modularChangeFormatV1.ts +3 -4
- package/src/feature-libraries/modular-schema/modularChangeFormatV2.ts +17 -45
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +18 -97
- package/src/feature-libraries/node-identifier/mockNodeIdentifierManager.ts +1 -1
- package/src/feature-libraries/object-forest/objectForest.ts +4 -4
- package/src/feature-libraries/optional-field/index.ts +3 -1
- package/src/feature-libraries/optional-field/optionalField.ts +566 -321
- package/src/feature-libraries/optional-field/optionalFieldChangeTypes.ts +38 -24
- package/src/feature-libraries/optional-field/optionalFieldCodecV2.ts +35 -89
- package/src/feature-libraries/optional-field/optionalFieldCodecs.ts +1 -5
- package/src/feature-libraries/schema-edits/schemaChangeCodecs.ts +19 -5
- package/src/feature-libraries/schema-index/codec.ts +30 -92
- package/src/feature-libraries/schema-index/index.ts +2 -4
- package/src/feature-libraries/schema-index/schemaSummarizer.ts +0 -17
- package/src/feature-libraries/schemaChecker.ts +11 -6
- package/src/feature-libraries/sequence-field/compose.ts +527 -138
- package/src/feature-libraries/sequence-field/helperTypes.ts +19 -34
- package/src/feature-libraries/sequence-field/index.ts +9 -0
- package/src/feature-libraries/sequence-field/invert.ts +229 -103
- package/src/feature-libraries/sequence-field/markQueue.ts +2 -2
- package/src/feature-libraries/sequence-field/moveEffectTable.ts +198 -9
- package/src/feature-libraries/sequence-field/rebase.ts +218 -175
- package/src/feature-libraries/sequence-field/relevantRemovedRoots.ts +57 -0
- package/src/feature-libraries/sequence-field/replaceRevisions.ts +76 -59
- package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +2 -0
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +228 -643
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV3.ts +70 -56
- package/src/feature-libraries/sequence-field/sequenceFieldEditor.ts +27 -25
- package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +135 -22
- package/src/feature-libraries/sequence-field/types.ts +64 -34
- package/src/feature-libraries/sequence-field/utils.ts +382 -150
- package/src/feature-libraries/treeCursorUtils.ts +7 -7
- package/src/feature-libraries/treeTextCursor.ts +2 -2
- package/src/feature-libraries/valueUtilities.ts +16 -8
- package/src/index.ts +7 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/independentView.ts +1 -2
- package/src/shared-tree/index.ts +2 -3
- package/src/shared-tree/schematizeTree.ts +8 -21
- package/src/shared-tree/schematizingTreeView.ts +96 -63
- package/src/shared-tree/sharedTree.ts +29 -29
- package/src/shared-tree/sharedTreeChangeCodecs.ts +12 -15
- package/src/shared-tree/sharedTreeChangeEnricher.ts +4 -4
- package/src/shared-tree/sharedTreeChangeFamily.ts +34 -34
- package/src/shared-tree/sharedTreeEditBuilder.ts +9 -39
- package/src/shared-tree/treeAlpha.ts +60 -51
- package/src/shared-tree/treeCheckout.ts +158 -132
- package/src/shared-tree-core/branch.ts +10 -11
- package/src/shared-tree-core/branchCommitEnricher.ts +3 -8
- package/src/shared-tree-core/editManager.ts +3 -17
- package/src/shared-tree-core/editManagerCodecs.ts +13 -18
- package/src/shared-tree-core/editManagerCodecsVSharedBranches.ts +1 -1
- package/src/shared-tree-core/editManagerFormatCommons.ts +12 -15
- package/src/shared-tree-core/editManagerFormatV1toV4.ts +2 -2
- package/src/shared-tree-core/editManagerSummarizer.ts +3 -3
- package/src/shared-tree-core/index.ts +3 -2
- package/src/shared-tree-core/messageCodecV1ToV4.ts +1 -1
- package/src/shared-tree-core/messageCodecVSharedBranches.ts +2 -1
- package/src/shared-tree-core/messageCodecs.ts +15 -21
- package/src/shared-tree-core/messageFormat.ts +12 -15
- package/src/shared-tree-core/messageFormatV1ToV4.ts +2 -2
- package/src/shared-tree-core/sequenceIdUtils.ts +4 -4
- package/src/shared-tree-core/sharedTreeCore.ts +12 -11
- package/src/shared-tree-core/transaction.ts +115 -56
- package/src/shared-tree-core/transactionEnricher.ts +5 -6
- package/src/shared-tree-core/versionedSummarizer.ts +10 -3
- package/src/simple-tree/api/configuration.ts +1 -1
- package/src/simple-tree/api/customTree.ts +14 -10
- package/src/simple-tree/api/discrepancies.ts +23 -17
- package/src/simple-tree/api/eraseSchemaDetails.ts +123 -0
- package/src/simple-tree/api/index.ts +6 -0
- package/src/simple-tree/api/schemaFactory.ts +11 -7
- package/src/simple-tree/api/schemaFromSimple.ts +18 -9
- package/src/simple-tree/api/simpleSchemaCodec.ts +10 -5
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +17 -13
- package/src/simple-tree/api/simpleTreeIndex.ts +8 -8
- package/src/simple-tree/api/storedSchema.ts +12 -9
- package/src/simple-tree/api/transactionTypes.ts +19 -4
- package/src/simple-tree/api/tree.ts +16 -1
- package/src/simple-tree/api/treeNodeApi.ts +21 -13
- package/src/simple-tree/api/verboseTree.ts +14 -9
- package/src/simple-tree/core/treeNode.ts +1 -0
- package/src/simple-tree/core/treeNodeKernel.ts +6 -3
- package/src/simple-tree/core/unhydratedFlexTree.ts +58 -104
- package/src/simple-tree/createContext.ts +4 -1
- package/src/simple-tree/fieldSchema.ts +4 -6
- package/src/simple-tree/getTreeNodeForField.ts +2 -1
- package/src/simple-tree/index.ts +5 -2
- package/src/simple-tree/leafNodeSchema.ts +8 -5
- package/src/simple-tree/node-kinds/array/arrayNode.ts +28 -30
- package/src/simple-tree/node-kinds/common.ts +5 -2
- package/src/simple-tree/node-kinds/map/mapNode.ts +4 -4
- package/src/simple-tree/node-kinds/object/objectNode.ts +28 -29
- package/src/simple-tree/node-kinds/record/recordNode.ts +11 -13
- package/src/simple-tree/prepareForInsertion.ts +200 -343
- package/src/simple-tree/toStoredSchema.ts +12 -8
- package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +14 -42
- package/src/tableSchema.ts +13 -18
- package/src/treeFactory.ts +5 -14
- package/src/util/bTreeUtils.ts +1 -1
- package/src/util/brand.ts +61 -0
- package/src/util/breakable.ts +9 -9
- package/src/util/idAllocator.ts +1 -2
- package/src/util/index.ts +3 -3
- package/src/util/nestedMap.ts +1 -3
- package/src/util/rangeMap.ts +18 -72
- package/src/util/utils.ts +14 -13
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +0 -36
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +0 -1
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js +0 -126
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js.map +0 -1
- package/dist/feature-libraries/forest-summary/format.d.ts.map +0 -1
- package/dist/feature-libraries/forest-summary/format.js.map +0 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +0 -23
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +0 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +0 -31
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +0 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +0 -12
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +0 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js +0 -57
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js.map +0 -1
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +0 -36
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +0 -1
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js +0 -122
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js.map +0 -1
- package/lib/feature-libraries/forest-summary/format.d.ts.map +0 -1
- package/lib/feature-libraries/forest-summary/format.js.map +0 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +0 -23
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +0 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +0 -27
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +0 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +0 -12
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +0 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js +0 -53
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js.map +0 -1
- package/src/feature-libraries/default-schema/locationBasedEditBuilder.ts +0 -180
- package/src/feature-libraries/optional-field/optionalFieldChangeFormatV3.ts +0 -45
- package/src/feature-libraries/optional-field/optionalFieldCodecV3.ts +0 -94
|
@@ -5,8 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert, fail } from "@fluidframework/core-utils/internal";
|
|
7
7
|
import { BTree } from "@tylerbu/sorted-btree-es6";
|
|
8
|
+
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
8
9
|
|
|
9
|
-
import
|
|
10
|
+
import {
|
|
11
|
+
FluidClientVersion,
|
|
12
|
+
type CodecWriteOptions,
|
|
13
|
+
type ICodecFamily,
|
|
14
|
+
} from "../../codec/index.js";
|
|
10
15
|
import {
|
|
11
16
|
type ChangeEncodingContext,
|
|
12
17
|
type ChangeFamily,
|
|
@@ -22,30 +27,24 @@ import {
|
|
|
22
27
|
EditBuilder,
|
|
23
28
|
type FieldKey,
|
|
24
29
|
type FieldKindIdentifier,
|
|
30
|
+
type FieldUpPath,
|
|
25
31
|
type RevisionInfo,
|
|
26
32
|
type RevisionMetadataSource,
|
|
27
33
|
type RevisionTag,
|
|
28
34
|
type TaggedChange,
|
|
35
|
+
type UpPath,
|
|
29
36
|
makeDetachedNodeId,
|
|
30
|
-
replaceAtomRevisions,
|
|
31
37
|
revisionMetadataSourceFromInfo,
|
|
32
38
|
areEqualChangeAtomIds,
|
|
33
39
|
type ChangeAtomId,
|
|
34
40
|
areEqualChangeAtomIdOpts,
|
|
35
41
|
tagChange,
|
|
36
42
|
makeAnonChange,
|
|
43
|
+
newChangeAtomIdRangeMap,
|
|
37
44
|
type DeltaDetachedNodeChanges,
|
|
38
45
|
type DeltaDetachedNodeRename,
|
|
39
46
|
mapTaggedChange,
|
|
40
|
-
|
|
41
|
-
newChangeAtomIdTransform,
|
|
42
|
-
type ChangeAtomIdRangeMap,
|
|
43
|
-
offsetChangeAtomId,
|
|
44
|
-
type NormalizedUpPath,
|
|
45
|
-
type NormalizedFieldUpPath,
|
|
46
|
-
isDetachedUpPathRoot,
|
|
47
|
-
subtractChangeAtomIds,
|
|
48
|
-
makeChangeAtomId,
|
|
47
|
+
type RevisionReplacer,
|
|
49
48
|
} from "../../core/index.js";
|
|
50
49
|
import {
|
|
51
50
|
type IdAllocationState,
|
|
@@ -61,19 +60,14 @@ import {
|
|
|
61
60
|
type TupleBTree,
|
|
62
61
|
RangeMap,
|
|
63
62
|
balancedReduce,
|
|
64
|
-
type RangeQueryEntry,
|
|
65
|
-
type RangeQueryResultFragment,
|
|
66
63
|
} from "../../util/index.js";
|
|
67
64
|
import type { TreeChunk } from "../chunked-forest/index.js";
|
|
68
65
|
|
|
69
66
|
import {
|
|
70
|
-
type
|
|
67
|
+
type CrossFieldManager,
|
|
71
68
|
type CrossFieldMap,
|
|
72
69
|
CrossFieldTarget,
|
|
73
|
-
|
|
74
|
-
type InvertNodeManager,
|
|
75
|
-
type RebaseDetachedNodeEntry,
|
|
76
|
-
type RebaseNodeManager,
|
|
70
|
+
getFirstFromCrossFieldMap,
|
|
77
71
|
setInCrossFieldMap,
|
|
78
72
|
} from "./crossFieldQueries.js";
|
|
79
73
|
import {
|
|
@@ -84,28 +78,26 @@ import {
|
|
|
84
78
|
import { convertGenericChange, genericFieldKind } from "./genericFieldKind.js";
|
|
85
79
|
import type { GenericChangeset } from "./genericFieldKindTypes.js";
|
|
86
80
|
import {
|
|
87
|
-
type ChangeAtomIdBTree,
|
|
88
|
-
type ChangeAtomIdKey,
|
|
89
81
|
type CrossFieldKey,
|
|
90
82
|
type CrossFieldKeyRange,
|
|
91
83
|
type CrossFieldKeyTable,
|
|
92
|
-
type CrossFieldRangeTable,
|
|
93
84
|
type FieldChange,
|
|
94
85
|
type FieldChangeMap,
|
|
95
86
|
type FieldChangeset,
|
|
96
87
|
type FieldId,
|
|
97
|
-
getFromChangeAtomIdMap,
|
|
98
88
|
type ModularChangeset,
|
|
99
|
-
|
|
89
|
+
newCrossFieldKeyTable,
|
|
90
|
+
type NoChangeConstraint,
|
|
100
91
|
type NodeChangeset,
|
|
101
92
|
type NodeId,
|
|
102
|
-
type NodeLocation,
|
|
103
|
-
rangeQueryChangeAtomIdMap,
|
|
104
|
-
type RebaseVersion,
|
|
105
|
-
type RootNodeTable,
|
|
106
|
-
setInChangeAtomIdMap,
|
|
107
93
|
} from "./modularChangeTypes.js";
|
|
108
94
|
import type { FlexFieldKind } from "./fieldKind.js";
|
|
95
|
+
import {
|
|
96
|
+
getFromChangeAtomIdMap,
|
|
97
|
+
setInChangeAtomIdMap,
|
|
98
|
+
type ChangeAtomIdBTree,
|
|
99
|
+
} from "../changeAtomIdBTree.js";
|
|
100
|
+
import { lt } from "semver-ts";
|
|
109
101
|
|
|
110
102
|
/**
|
|
111
103
|
* Implementation of ChangeFamily which delegates work in a given field to the appropriate FieldKind
|
|
@@ -123,6 +115,7 @@ export class ModularChangeFamily
|
|
|
123
115
|
public constructor(
|
|
124
116
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
125
117
|
public readonly codecs: ICodecFamily<ModularChangeset, ChangeEncodingContext>,
|
|
118
|
+
public readonly codecOptions: CodecWriteOptions,
|
|
126
119
|
) {
|
|
127
120
|
this.fieldKinds = fieldKinds;
|
|
128
121
|
}
|
|
@@ -149,9 +142,9 @@ export class ModularChangeFamily
|
|
|
149
142
|
} {
|
|
150
143
|
// TODO: Handle the case where changes have conflicting field kinds
|
|
151
144
|
const kind =
|
|
152
|
-
change1.fieldKind
|
|
153
|
-
?
|
|
154
|
-
:
|
|
145
|
+
change1.fieldKind === genericFieldKind.identifier
|
|
146
|
+
? change2.fieldKind
|
|
147
|
+
: change1.fieldKind;
|
|
155
148
|
|
|
156
149
|
if (kind === genericFieldKind.identifier) {
|
|
157
150
|
// Both changes are generic
|
|
@@ -190,14 +183,14 @@ export class ModularChangeFamily
|
|
|
190
183
|
}
|
|
191
184
|
|
|
192
185
|
public compose(changes: TaggedChange<ModularChangeset>[]): ModularChangeset {
|
|
193
|
-
const { maxId } = getRevInfoFromTaggedChanges(changes);
|
|
186
|
+
const { revInfos, maxId } = getRevInfoFromTaggedChanges(changes);
|
|
194
187
|
const idState: IdAllocationState = { maxId };
|
|
195
188
|
|
|
196
189
|
const pairwiseDelegate = (
|
|
197
190
|
left: ModularChangeset,
|
|
198
191
|
right: ModularChangeset,
|
|
199
192
|
): ModularChangeset => {
|
|
200
|
-
return this.composePair(left, right, idState);
|
|
193
|
+
return this.composePair(left, right, revInfos, idState);
|
|
201
194
|
};
|
|
202
195
|
|
|
203
196
|
const innerChanges = changes.map((change) => change.change);
|
|
@@ -207,11 +200,10 @@ export class ModularChangeFamily
|
|
|
207
200
|
private composePair(
|
|
208
201
|
change1: ModularChangeset,
|
|
209
202
|
change2: ModularChangeset,
|
|
203
|
+
revInfos: RevisionInfo[],
|
|
210
204
|
idState: IdAllocationState,
|
|
211
205
|
): ModularChangeset {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys, rootNodes } =
|
|
206
|
+
const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys } =
|
|
215
207
|
this.composeAllFields(change1, change2, revInfos, idState);
|
|
216
208
|
|
|
217
209
|
const { allBuilds, allDestroys, allRefreshers } = composeBuildsDestroysAndRefreshers(
|
|
@@ -219,7 +211,12 @@ export class ModularChangeFamily
|
|
|
219
211
|
change2,
|
|
220
212
|
);
|
|
221
213
|
|
|
222
|
-
|
|
214
|
+
// The composed changeset has a "no change" constraint if either change has one
|
|
215
|
+
const noChangeConstraint = change1.noChangeConstraint ?? change2.noChangeConstraint;
|
|
216
|
+
const noChangeConstraintOnRevert =
|
|
217
|
+
change1.noChangeConstraintOnRevert ?? change2.noChangeConstraintOnRevert;
|
|
218
|
+
|
|
219
|
+
return makeModularChangeset({
|
|
223
220
|
fieldChanges,
|
|
224
221
|
nodeChanges,
|
|
225
222
|
nodeToParent,
|
|
@@ -227,15 +224,12 @@ export class ModularChangeFamily
|
|
|
227
224
|
crossFieldKeys,
|
|
228
225
|
maxId: idState.maxId,
|
|
229
226
|
revisions: revInfos,
|
|
230
|
-
|
|
227
|
+
noChangeConstraint,
|
|
228
|
+
noChangeConstraintOnRevert,
|
|
231
229
|
builds: allBuilds,
|
|
232
230
|
destroys: allDestroys,
|
|
233
231
|
refreshers: allRefreshers,
|
|
234
232
|
});
|
|
235
|
-
|
|
236
|
-
// XXX: This is an expensive assert which should be disabled before merging.
|
|
237
|
-
this.validateChangeset(composed);
|
|
238
|
-
return composed;
|
|
239
233
|
}
|
|
240
234
|
|
|
241
235
|
private composeAllFields(
|
|
@@ -265,38 +259,14 @@ export class ModularChangeFamily
|
|
|
265
259
|
mergeTupleBTrees(change1.nodeChanges, change2.nodeChanges),
|
|
266
260
|
);
|
|
267
261
|
|
|
268
|
-
const composedNodeToParent: ChangeAtomIdBTree<
|
|
262
|
+
const composedNodeToParent: ChangeAtomIdBTree<FieldId> = brand(
|
|
269
263
|
mergeTupleBTrees(change1.nodeToParent, change2.nodeToParent),
|
|
270
264
|
);
|
|
271
265
|
const composedNodeAliases: ChangeAtomIdBTree<NodeId> = brand(
|
|
272
266
|
mergeTupleBTrees(change1.nodeAliases, change2.nodeAliases),
|
|
273
267
|
);
|
|
274
268
|
|
|
275
|
-
const
|
|
276
|
-
nodeIdsToCompose: [],
|
|
277
|
-
affectedBaseFields: newTupleBTree(),
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
const movedCrossFieldKeys: CrossFieldKeyTable = newCrossFieldRangeTable();
|
|
281
|
-
const removedCrossFieldKeys: CrossFieldRangeTable<boolean> = newCrossFieldRangeTable();
|
|
282
|
-
|
|
283
|
-
const composedRoots = composeRootTables(
|
|
284
|
-
change1,
|
|
285
|
-
change2,
|
|
286
|
-
composedNodeToParent,
|
|
287
|
-
movedCrossFieldKeys,
|
|
288
|
-
removedCrossFieldKeys,
|
|
289
|
-
pendingCompositions,
|
|
290
|
-
);
|
|
291
|
-
|
|
292
|
-
const crossFieldTable = newComposeTable(
|
|
293
|
-
change1,
|
|
294
|
-
change2,
|
|
295
|
-
composedRoots,
|
|
296
|
-
movedCrossFieldKeys,
|
|
297
|
-
removedCrossFieldKeys,
|
|
298
|
-
pendingCompositions,
|
|
299
|
-
);
|
|
269
|
+
const crossFieldTable = newComposeTable(change1, change2, composedNodeToParent);
|
|
300
270
|
|
|
301
271
|
const composedFields = this.composeFieldMaps(
|
|
302
272
|
change1.fieldChanges,
|
|
@@ -317,32 +287,17 @@ export class ModularChangeFamily
|
|
|
317
287
|
revisionMetadata,
|
|
318
288
|
);
|
|
319
289
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
// Moved nodes are from change2.
|
|
326
|
-
// If there is a corresponding node in change1, then composedNodeToParent will already have the correct entry,
|
|
327
|
-
// because the location of the node is the same in change1 and the composed change
|
|
328
|
-
// (since they have the same input context).
|
|
329
|
-
if (crossFieldTable.newToBaseNodeId.get(nodeId) === undefined) {
|
|
330
|
-
composedNodeToParent.set(nodeId, location);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
290
|
+
// Currently no field kinds require making changes to cross-field keys during composition, so we can just merge the two tables.
|
|
291
|
+
const composedCrossFieldKeys = RangeMap.union(
|
|
292
|
+
change1.crossFieldKeys,
|
|
293
|
+
change2.crossFieldKeys,
|
|
294
|
+
);
|
|
334
295
|
return {
|
|
335
296
|
fieldChanges: composedFields,
|
|
336
297
|
nodeChanges: composedNodeChanges,
|
|
337
298
|
nodeToParent: composedNodeToParent,
|
|
338
299
|
nodeAliases: composedNodeAliases,
|
|
339
|
-
crossFieldKeys:
|
|
340
|
-
change1.crossFieldKeys,
|
|
341
|
-
change2.crossFieldKeys,
|
|
342
|
-
crossFieldTable.movedCrossFieldKeys,
|
|
343
|
-
crossFieldTable.removedCrossFieldKeys,
|
|
344
|
-
),
|
|
345
|
-
rootNodes: composedRoots,
|
|
300
|
+
crossFieldKeys: composedCrossFieldKeys,
|
|
346
301
|
};
|
|
347
302
|
}
|
|
348
303
|
|
|
@@ -354,16 +309,17 @@ export class ModularChangeFamily
|
|
|
354
309
|
): void {
|
|
355
310
|
const context = crossFieldTable.fieldToContext.get(fieldChange);
|
|
356
311
|
assert(context !== undefined, 0x8cc /* Should have context for every invalidated field */);
|
|
357
|
-
const { change1: fieldChange1, change2: fieldChange2, composedChange } = context;
|
|
358
|
-
|
|
359
|
-
crossFieldTable.pendingCompositions.affectedBaseFields.delete(
|
|
360
|
-
fieldIdKeyFromFieldId(context.fieldId),
|
|
361
|
-
);
|
|
312
|
+
const { fieldId, change1: fieldChange1, change2: fieldChange2, composedChange } = context;
|
|
362
313
|
|
|
363
314
|
const rebaser = getChangeHandler(this.fieldKinds, composedChange.fieldKind).rebaser;
|
|
364
315
|
const composeNodes = (child1: NodeId | undefined, child2: NodeId | undefined): NodeId => {
|
|
365
|
-
if (
|
|
366
|
-
|
|
316
|
+
if (
|
|
317
|
+
child1 !== undefined &&
|
|
318
|
+
child2 !== undefined &&
|
|
319
|
+
getFromChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2) === undefined
|
|
320
|
+
) {
|
|
321
|
+
setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
|
|
322
|
+
crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
|
|
367
323
|
}
|
|
368
324
|
|
|
369
325
|
return child1 ?? child2 ?? fail(0xb22 /* Should not compose two undefined nodes */);
|
|
@@ -374,7 +330,7 @@ export class ModularChangeFamily
|
|
|
374
330
|
fieldChange2,
|
|
375
331
|
composeNodes,
|
|
376
332
|
genId,
|
|
377
|
-
new
|
|
333
|
+
new ComposeManager(crossFieldTable, fieldChange, fieldId, false),
|
|
378
334
|
revisionMetadata,
|
|
379
335
|
);
|
|
380
336
|
composedChange.change = brand(amendedChange);
|
|
@@ -386,7 +342,7 @@ export class ModularChangeFamily
|
|
|
386
342
|
* - discovering that two node changesets refer to the same node (`nodeIdsToCompose`)
|
|
387
343
|
* - a previously composed field being invalidated by a cross field effect (`invalidatedFields`)
|
|
388
344
|
* - a field which was copied directly from an input changeset being invalidated by a cross field effect
|
|
389
|
-
* (`affectedBaseFields`)
|
|
345
|
+
* (`affectedBaseFields` and `affectedNewFields`)
|
|
390
346
|
*
|
|
391
347
|
* Updating an element may invalidate further elements. This function runs until there is no more invalidation.
|
|
392
348
|
*/
|
|
@@ -394,59 +350,72 @@ export class ModularChangeFamily
|
|
|
394
350
|
table: ComposeTable,
|
|
395
351
|
composedFields: FieldChangeMap,
|
|
396
352
|
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
397
|
-
composedNodeToParent: ChangeAtomIdBTree<
|
|
353
|
+
composedNodeToParent: ChangeAtomIdBTree<FieldId>,
|
|
398
354
|
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
399
355
|
genId: IdAllocator,
|
|
400
356
|
metadata: RevisionMetadataSource,
|
|
401
357
|
): void {
|
|
402
358
|
const pending = table.pendingCompositions;
|
|
403
|
-
while (
|
|
404
|
-
|
|
359
|
+
while (
|
|
360
|
+
table.invalidatedFields.size > 0 ||
|
|
361
|
+
pending.nodeIdsToCompose.length > 0 ||
|
|
362
|
+
pending.affectedBaseFields.length > 0 ||
|
|
363
|
+
pending.affectedNewFields.length > 0
|
|
364
|
+
) {
|
|
365
|
+
// Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
366
|
+
for (const [id1, id2] of pending.nodeIdsToCompose) {
|
|
367
|
+
this.composeNodesById(
|
|
368
|
+
table.baseChange.nodeChanges,
|
|
369
|
+
table.newChange.nodeChanges,
|
|
370
|
+
composedNodes,
|
|
371
|
+
composedNodeToParent,
|
|
372
|
+
nodeAliases,
|
|
373
|
+
id1,
|
|
374
|
+
id2,
|
|
375
|
+
genId,
|
|
376
|
+
table,
|
|
377
|
+
metadata,
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
pending.nodeIdsToCompose.length = 0;
|
|
382
|
+
|
|
383
|
+
this.composeAffectedFields(
|
|
405
384
|
table,
|
|
385
|
+
table.baseChange,
|
|
386
|
+
true,
|
|
387
|
+
pending.affectedBaseFields,
|
|
388
|
+
composedFields,
|
|
406
389
|
composedNodes,
|
|
407
|
-
composedNodeToParent,
|
|
408
|
-
nodeAliases,
|
|
409
390
|
genId,
|
|
410
391
|
metadata,
|
|
411
392
|
);
|
|
412
393
|
|
|
413
394
|
this.composeAffectedFields(
|
|
414
395
|
table,
|
|
415
|
-
table.
|
|
416
|
-
|
|
396
|
+
table.newChange,
|
|
397
|
+
false,
|
|
398
|
+
pending.affectedNewFields,
|
|
417
399
|
composedFields,
|
|
418
400
|
composedNodes,
|
|
419
401
|
genId,
|
|
420
402
|
metadata,
|
|
421
403
|
);
|
|
404
|
+
|
|
405
|
+
this.processInvalidatedCompositions(table, genId, metadata);
|
|
422
406
|
}
|
|
423
407
|
}
|
|
424
408
|
|
|
425
|
-
private
|
|
409
|
+
private processInvalidatedCompositions(
|
|
426
410
|
table: ComposeTable,
|
|
427
|
-
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
428
|
-
composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
429
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
430
411
|
genId: IdAllocator,
|
|
431
412
|
metadata: RevisionMetadataSource,
|
|
432
413
|
): void {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
table.newChange,
|
|
438
|
-
composedNodes,
|
|
439
|
-
composedNodeToParent,
|
|
440
|
-
nodeAliases,
|
|
441
|
-
id1,
|
|
442
|
-
id2,
|
|
443
|
-
genId,
|
|
444
|
-
table,
|
|
445
|
-
metadata,
|
|
446
|
-
);
|
|
414
|
+
const fieldsToUpdate = table.invalidatedFields;
|
|
415
|
+
table.invalidatedFields = new Set();
|
|
416
|
+
for (const fieldChange of fieldsToUpdate) {
|
|
417
|
+
this.composeInvalidatedField(fieldChange, table, genId, metadata);
|
|
447
418
|
}
|
|
448
|
-
|
|
449
|
-
table.pendingCompositions.nodeIdsToCompose.length = 0;
|
|
450
419
|
}
|
|
451
420
|
|
|
452
421
|
/**
|
|
@@ -463,79 +432,63 @@ export class ModularChangeFamily
|
|
|
463
432
|
private composeAffectedFields(
|
|
464
433
|
table: ComposeTable,
|
|
465
434
|
change: ModularChangeset,
|
|
435
|
+
areBaseFields: boolean,
|
|
466
436
|
affectedFields: BTree<FieldIdKey, true>,
|
|
467
437
|
composedFields: FieldChangeMap,
|
|
468
438
|
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
469
439
|
genId: IdAllocator,
|
|
470
440
|
metadata: RevisionMetadataSource,
|
|
471
441
|
): void {
|
|
472
|
-
const
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
for (const fieldIdKey of fieldsToProcess.keys()) {
|
|
476
|
-
const fieldId = fieldIdFromFieldIdKey(fieldIdKey);
|
|
477
|
-
const fieldChange = fieldChangeFromId(change, fieldId);
|
|
442
|
+
for (const fieldIdKey of affectedFields.keys()) {
|
|
443
|
+
const fieldId = normalizeFieldId(fieldIdFromFieldIdKey(fieldIdKey), change.nodeAliases);
|
|
444
|
+
const fieldChange = fieldChangeFromId(change.fieldChanges, change.nodeChanges, fieldId);
|
|
478
445
|
|
|
479
446
|
if (
|
|
480
447
|
table.fieldToContext.has(fieldChange) ||
|
|
481
448
|
table.newFieldToBaseField.has(fieldChange)
|
|
482
449
|
) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
fieldChange,
|
|
488
|
-
fieldId,
|
|
489
|
-
composedFields,
|
|
490
|
-
composedNodes,
|
|
491
|
-
genId,
|
|
492
|
-
metadata,
|
|
493
|
-
);
|
|
450
|
+
// This function handles fields which were not part of the intersection of the two changesets but which need to be updated anyway.
|
|
451
|
+
// If we've already processed this field then either it is up to date
|
|
452
|
+
// or there is pending inval which will be handled in processInvalidatedCompositions.
|
|
453
|
+
continue;
|
|
494
454
|
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
455
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
composedFields: FieldChangeMap,
|
|
503
|
-
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
504
|
-
genId: IdAllocator,
|
|
505
|
-
metadata: RevisionMetadataSource,
|
|
506
|
-
): void {
|
|
507
|
-
const emptyChange = this.createEmptyFieldChange(baseFieldChange.fieldKind);
|
|
456
|
+
const emptyChange = this.createEmptyFieldChange(fieldChange.fieldKind);
|
|
457
|
+
const [change1, change2] = areBaseFields
|
|
458
|
+
? [fieldChange, emptyChange]
|
|
459
|
+
: [emptyChange, fieldChange];
|
|
508
460
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
461
|
+
const composedField = this.composeFieldChanges(
|
|
462
|
+
fieldId,
|
|
463
|
+
change1,
|
|
464
|
+
change2,
|
|
465
|
+
genId,
|
|
466
|
+
table,
|
|
467
|
+
metadata,
|
|
468
|
+
);
|
|
517
469
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
470
|
+
if (fieldId.nodeId === undefined) {
|
|
471
|
+
composedFields.set(fieldId.field, composedField);
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
522
474
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
table.baseChange.nodeAliases,
|
|
526
|
-
);
|
|
475
|
+
const nodeId =
|
|
476
|
+
getFromChangeAtomIdMap(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId;
|
|
527
477
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
478
|
+
let nodeChangeset = nodeChangeFromId(composedNodes, nodeId);
|
|
479
|
+
if (!table.composedNodes.has(nodeChangeset)) {
|
|
480
|
+
nodeChangeset = cloneNodeChangeset(nodeChangeset);
|
|
481
|
+
setInChangeAtomIdMap(composedNodes, nodeId, nodeChangeset);
|
|
482
|
+
}
|
|
533
483
|
|
|
534
|
-
|
|
535
|
-
|
|
484
|
+
if (nodeChangeset.fieldChanges === undefined) {
|
|
485
|
+
nodeChangeset.fieldChanges = new Map();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
nodeChangeset.fieldChanges.set(fieldId.field, composedField);
|
|
536
489
|
}
|
|
537
490
|
|
|
538
|
-
|
|
491
|
+
affectedFields.clear();
|
|
539
492
|
}
|
|
540
493
|
|
|
541
494
|
private composeFieldMaps(
|
|
@@ -554,29 +507,17 @@ export class ModularChangeFamily
|
|
|
554
507
|
for (const [field, fieldChange1] of change1) {
|
|
555
508
|
const fieldId: FieldId = { nodeId: parentId, field };
|
|
556
509
|
const fieldChange2 = change2.get(field);
|
|
557
|
-
|
|
558
|
-
const cachedComposedFieldChange =
|
|
559
|
-
crossFieldTable.fieldToContext.get(fieldChange1)?.composedChange;
|
|
560
|
-
|
|
561
|
-
if (fieldChange2 === undefined && cachedComposedFieldChange !== undefined) {
|
|
562
|
-
// This can happen if the field was previous processed in `composeFieldWithNoNewChange`.
|
|
563
|
-
// If `change2` does not have a change for this field, then without this check we would
|
|
564
|
-
// lose the composed field change and instead simply have `change1`'s change.
|
|
565
|
-
composedFields.set(field, cachedComposedFieldChange);
|
|
566
|
-
continue;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
510
|
const composedField =
|
|
570
|
-
fieldChange2
|
|
571
|
-
?
|
|
511
|
+
fieldChange2 === undefined
|
|
512
|
+
? fieldChange1
|
|
513
|
+
: this.composeFieldChanges(
|
|
572
514
|
fieldId,
|
|
573
515
|
fieldChange1,
|
|
574
516
|
fieldChange2,
|
|
575
517
|
genId,
|
|
576
518
|
crossFieldTable,
|
|
577
519
|
revisionMetadata,
|
|
578
|
-
)
|
|
579
|
-
: fieldChange1;
|
|
520
|
+
);
|
|
580
521
|
|
|
581
522
|
composedFields.set(field, composedField);
|
|
582
523
|
}
|
|
@@ -597,7 +538,7 @@ export class ModularChangeFamily
|
|
|
597
538
|
* will be added to `crossFieldTable.pendingCompositions.nodeIdsToCompose`.
|
|
598
539
|
*
|
|
599
540
|
* Any fields which had cross-field information sent to them as part of this field composition
|
|
600
|
-
* will be added to `affectedBaseFields` in `crossFieldTable.pendingCompositions`.
|
|
541
|
+
* will be added to either `affectedBaseFields` or `affectedNewFields` in `crossFieldTable.pendingCompositions`.
|
|
601
542
|
*
|
|
602
543
|
* Any composed `FieldChange` which is invalidated by new cross-field information will be added to `crossFieldTable.invalidatedFields`.
|
|
603
544
|
*/
|
|
@@ -616,14 +557,15 @@ export class ModularChangeFamily
|
|
|
616
557
|
change2: change2Normalized,
|
|
617
558
|
} = this.normalizeFieldChanges(change1, change2);
|
|
618
559
|
|
|
619
|
-
const manager = new
|
|
560
|
+
const manager = new ComposeManager(crossFieldTable, change1, fieldId);
|
|
620
561
|
|
|
621
562
|
const composedChange = changeHandler.rebaser.compose(
|
|
622
563
|
change1Normalized,
|
|
623
564
|
change2Normalized,
|
|
624
565
|
(child1, child2) => {
|
|
625
566
|
if (child1 !== undefined && child2 !== undefined) {
|
|
626
|
-
|
|
567
|
+
setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
|
|
568
|
+
crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
|
|
627
569
|
}
|
|
628
570
|
return child1 ?? child2 ?? fail(0xb23 /* Should not compose two undefined nodes */);
|
|
629
571
|
},
|
|
@@ -649,19 +591,19 @@ export class ModularChangeFamily
|
|
|
649
591
|
}
|
|
650
592
|
|
|
651
593
|
private composeNodesById(
|
|
652
|
-
|
|
653
|
-
|
|
594
|
+
nodeChanges1: ChangeAtomIdBTree<NodeChangeset>,
|
|
595
|
+
nodeChanges2: ChangeAtomIdBTree<NodeChangeset>,
|
|
654
596
|
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
655
|
-
composedNodeToParent: ChangeAtomIdBTree<
|
|
656
|
-
|
|
597
|
+
composedNodeToParent: ChangeAtomIdBTree<FieldId>,
|
|
598
|
+
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
657
599
|
id1: NodeId,
|
|
658
600
|
id2: NodeId,
|
|
659
601
|
idAllocator: IdAllocator,
|
|
660
602
|
crossFieldTable: ComposeTable,
|
|
661
603
|
revisionMetadata: RevisionMetadataSource,
|
|
662
604
|
): void {
|
|
663
|
-
const nodeChangeset1 = nodeChangeFromId(
|
|
664
|
-
const nodeChangeset2 = nodeChangeFromId(
|
|
605
|
+
const nodeChangeset1 = nodeChangeFromId(nodeChanges1, id1);
|
|
606
|
+
const nodeChangeset2 = nodeChangeFromId(nodeChanges2, id2);
|
|
665
607
|
const composedNodeChangeset = this.composeNodeChanges(
|
|
666
608
|
id1,
|
|
667
609
|
nodeChangeset1,
|
|
@@ -676,11 +618,13 @@ export class ModularChangeFamily
|
|
|
676
618
|
if (!areEqualChangeAtomIds(id1, id2)) {
|
|
677
619
|
composedNodes.delete([id2.revision, id2.localId]);
|
|
678
620
|
composedNodeToParent.delete([id2.revision, id2.localId]);
|
|
679
|
-
setInChangeAtomIdMap(
|
|
621
|
+
setInChangeAtomIdMap(nodeAliases, id2, id1);
|
|
680
622
|
|
|
681
623
|
// We need to delete id1 to avoid forming a cycle in case id1 already had an alias.
|
|
682
|
-
|
|
624
|
+
nodeAliases.delete([id1.revision, id1.localId]);
|
|
683
625
|
}
|
|
626
|
+
|
|
627
|
+
crossFieldTable.composedNodes.add(composedNodeChangeset);
|
|
684
628
|
}
|
|
685
629
|
|
|
686
630
|
private composeNodeChanges(
|
|
@@ -715,7 +659,7 @@ export class ModularChangeFamily
|
|
|
715
659
|
revisionMetadata,
|
|
716
660
|
);
|
|
717
661
|
|
|
718
|
-
const composedNodeChange:
|
|
662
|
+
const composedNodeChange: NodeChangeset = {};
|
|
719
663
|
|
|
720
664
|
if (composedFieldChanges.size > 0) {
|
|
721
665
|
composedNodeChange.fieldChanges = composedFieldChanges;
|
|
@@ -735,8 +679,8 @@ export class ModularChangeFamily
|
|
|
735
679
|
/**
|
|
736
680
|
* @param change - The change to invert.
|
|
737
681
|
* @param isRollback - Whether the inverted change is meant to rollback a change on a branch as is the case when
|
|
738
|
-
* @param revisionForInvert - The revision for the invert changeset.
|
|
739
682
|
* performing a sandwich rebase.
|
|
683
|
+
* @param revisionForInvert - The revision for the invert changeset.
|
|
740
684
|
*/
|
|
741
685
|
public invert(
|
|
742
686
|
change: TaggedChange<ModularChangeset>,
|
|
@@ -756,6 +700,9 @@ export class ModularChangeFamily
|
|
|
756
700
|
? [{ revision: revisionForInvert, rollbackOf: change.revision }]
|
|
757
701
|
: [{ revision: revisionForInvert }];
|
|
758
702
|
|
|
703
|
+
const noChangeConstraint = change.change.noChangeConstraintOnRevert;
|
|
704
|
+
const noChangeConstraintOnRevert = change.change.noChangeConstraint;
|
|
705
|
+
|
|
759
706
|
if (hasConflicts(change.change)) {
|
|
760
707
|
return makeModularChangeset({
|
|
761
708
|
maxId: change.change.maxId as number,
|
|
@@ -767,14 +714,9 @@ export class ModularChangeFamily
|
|
|
767
714
|
const genId: IdAllocator = idAllocatorFromMaxId(change.change.maxId ?? -1);
|
|
768
715
|
|
|
769
716
|
const crossFieldTable: InvertTable = {
|
|
770
|
-
|
|
771
|
-
entries: newChangeAtomIdRangeMap(),
|
|
717
|
+
...newCrossFieldTable<FieldChange>(),
|
|
772
718
|
originalFieldToContext: new Map(),
|
|
773
|
-
invertRevision: revisionForInvert,
|
|
774
719
|
invertedNodeToParent: brand(change.change.nodeToParent.clone()),
|
|
775
|
-
invalidatedFields: new Set(),
|
|
776
|
-
invertedRoots: invertRootTable(change.change, isRollback),
|
|
777
|
-
attachToDetachId: newChangeAtomIdTransform(),
|
|
778
720
|
};
|
|
779
721
|
const { revInfos: oldRevInfos } = getRevInfoFromTaggedChanges([change]);
|
|
780
722
|
const revisionMetadata = revisionMetadataSourceFromInfo(oldRevInfos);
|
|
@@ -815,7 +757,7 @@ export class ModularChangeFamily
|
|
|
815
757
|
context !== undefined,
|
|
816
758
|
0x851 /* Should have context for every invalidated field */,
|
|
817
759
|
);
|
|
818
|
-
const { invertedField } = context;
|
|
760
|
+
const { invertedField, fieldId } = context;
|
|
819
761
|
|
|
820
762
|
const amendedChange = getChangeHandler(
|
|
821
763
|
this.fieldKinds,
|
|
@@ -825,7 +767,7 @@ export class ModularChangeFamily
|
|
|
825
767
|
isRollback,
|
|
826
768
|
genId,
|
|
827
769
|
revisionForInvert,
|
|
828
|
-
new
|
|
770
|
+
new InvertManager(crossFieldTable, fieldChange, fieldId),
|
|
829
771
|
revisionMetadata,
|
|
830
772
|
);
|
|
831
773
|
invertedField.change = brand(amendedChange);
|
|
@@ -834,19 +776,18 @@ export class ModularChangeFamily
|
|
|
834
776
|
|
|
835
777
|
const crossFieldKeys = this.makeCrossFieldKeyTable(invertedFields, invertedNodes);
|
|
836
778
|
|
|
837
|
-
this.processInvertRenames(crossFieldTable);
|
|
838
|
-
|
|
839
779
|
return makeModularChangeset({
|
|
840
780
|
fieldChanges: invertedFields,
|
|
841
781
|
nodeChanges: invertedNodes,
|
|
842
782
|
nodeToParent: crossFieldTable.invertedNodeToParent,
|
|
843
|
-
rootNodes: crossFieldTable.invertedRoots,
|
|
844
783
|
nodeAliases: change.change.nodeAliases,
|
|
845
784
|
crossFieldKeys,
|
|
846
785
|
maxId: genId.getMaxId(),
|
|
847
786
|
revisions: revInfos,
|
|
848
787
|
constraintViolationCount: change.change.constraintViolationCountOnRevert,
|
|
849
788
|
constraintViolationCountOnRevert: change.change.constraintViolationCount,
|
|
789
|
+
noChangeConstraint,
|
|
790
|
+
noChangeConstraintOnRevert,
|
|
850
791
|
destroys,
|
|
851
792
|
});
|
|
852
793
|
}
|
|
@@ -864,7 +805,7 @@ export class ModularChangeFamily
|
|
|
864
805
|
|
|
865
806
|
for (const [field, fieldChange] of changes) {
|
|
866
807
|
const fieldId = { nodeId: parentId, field };
|
|
867
|
-
const manager = new
|
|
808
|
+
const manager = new InvertManager(crossFieldTable, fieldChange, fieldId);
|
|
868
809
|
const invertedChange = getChangeHandler(
|
|
869
810
|
this.fieldKinds,
|
|
870
811
|
fieldChange.fieldKind,
|
|
@@ -901,7 +842,7 @@ export class ModularChangeFamily
|
|
|
901
842
|
revisionMetadata: RevisionMetadataSource,
|
|
902
843
|
revisionForInvert: RevisionTag,
|
|
903
844
|
): NodeChangeset {
|
|
904
|
-
const inverse:
|
|
845
|
+
const inverse: NodeChangeset = {};
|
|
905
846
|
|
|
906
847
|
// If the node has a constraint, it should be inverted to a node-exist-on-revert constraint. This ensure that if
|
|
907
848
|
// the inverse is inverted again, the original input constraint will be restored.
|
|
@@ -931,17 +872,6 @@ export class ModularChangeFamily
|
|
|
931
872
|
return inverse;
|
|
932
873
|
}
|
|
933
874
|
|
|
934
|
-
private processInvertRenames(table: InvertTable): void {
|
|
935
|
-
for (const {
|
|
936
|
-
start: newAttachId,
|
|
937
|
-
value: originalDetachId,
|
|
938
|
-
length,
|
|
939
|
-
} of table.attachToDetachId.entries()) {
|
|
940
|
-
// Note that the detach location is already set in `invertDetach`.
|
|
941
|
-
addNodeRename(table.invertedRoots, originalDetachId, newAttachId, length, undefined);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
|
|
945
875
|
public rebase(
|
|
946
876
|
taggedChange: TaggedChange<ModularChangeset>,
|
|
947
877
|
potentiallyConflictedOver: TaggedChange<ModularChangeset>,
|
|
@@ -961,41 +891,17 @@ export class ModularChangeFamily
|
|
|
961
891
|
const idState: IdAllocationState = { maxId };
|
|
962
892
|
const genId: IdAllocator = idAllocatorFromState(idState);
|
|
963
893
|
|
|
964
|
-
const affectedBaseFields: TupleBTree<FieldIdKey, boolean> = newTupleBTree();
|
|
965
|
-
const nodesToRebase: [newChangeset: NodeId, baseChangeset: NodeId][] = [];
|
|
966
|
-
|
|
967
|
-
const rebasedNodeToParent: ChangeAtomIdBTree<NodeLocation> = brand(
|
|
968
|
-
change.nodeToParent.clone(),
|
|
969
|
-
);
|
|
970
|
-
|
|
971
|
-
const rebaseVersion = Math.max(
|
|
972
|
-
change.rebaseVersion,
|
|
973
|
-
over.change.rebaseVersion,
|
|
974
|
-
) as RebaseVersion;
|
|
975
|
-
|
|
976
|
-
const rebasedRootNodes = rebaseRoots(
|
|
977
|
-
change,
|
|
978
|
-
over.change,
|
|
979
|
-
affectedBaseFields,
|
|
980
|
-
nodesToRebase,
|
|
981
|
-
rebasedNodeToParent,
|
|
982
|
-
rebaseVersion,
|
|
983
|
-
);
|
|
984
894
|
const crossFieldTable: RebaseTable = {
|
|
985
|
-
|
|
986
|
-
entries: newDetachedEntryMap(),
|
|
895
|
+
...newCrossFieldTable<FieldChange>(),
|
|
987
896
|
newChange: change,
|
|
988
897
|
baseChange: over.change,
|
|
989
898
|
baseFieldToContext: new Map(),
|
|
990
|
-
baseRoots: over.change.rootNodes,
|
|
991
|
-
rebasedRootNodes,
|
|
992
899
|
baseToRebasedNodeId: newTupleBTree(),
|
|
993
900
|
rebasedFields: new Set(),
|
|
994
|
-
rebasedNodeToParent,
|
|
995
|
-
|
|
996
|
-
movedDetaches: newChangeAtomIdRangeMap(),
|
|
901
|
+
rebasedNodeToParent: brand(change.nodeToParent.clone()),
|
|
902
|
+
rebasedCrossFieldKeys: change.crossFieldKeys.clone(),
|
|
997
903
|
nodeIdPairs: [],
|
|
998
|
-
affectedBaseFields,
|
|
904
|
+
affectedBaseFields: newTupleBTree(),
|
|
999
905
|
fieldsWithUnattachedChild: new Set(),
|
|
1000
906
|
};
|
|
1001
907
|
|
|
@@ -1011,14 +917,13 @@ export class ModularChangeFamily
|
|
|
1011
917
|
const rebasedNodes: ChangeAtomIdBTree<NodeChangeset> = brand(change.nodeChanges.clone());
|
|
1012
918
|
|
|
1013
919
|
const rebasedFields = this.rebaseIntersectingFields(
|
|
1014
|
-
nodesToRebase,
|
|
1015
920
|
crossFieldTable,
|
|
1016
921
|
rebasedNodes,
|
|
1017
922
|
genId,
|
|
1018
923
|
rebaseMetadata,
|
|
1019
924
|
);
|
|
1020
925
|
|
|
1021
|
-
this.
|
|
926
|
+
this.rebaseInvalidatedElements(
|
|
1022
927
|
rebasedFields,
|
|
1023
928
|
rebasedNodes,
|
|
1024
929
|
crossFieldTable,
|
|
@@ -1026,78 +931,49 @@ export class ModularChangeFamily
|
|
|
1026
931
|
genId,
|
|
1027
932
|
);
|
|
1028
933
|
|
|
1029
|
-
fixupRebasedDetachLocations(crossFieldTable);
|
|
1030
|
-
|
|
1031
934
|
const constraintState = newConstraintState(change.constraintViolationCount ?? 0);
|
|
1032
935
|
const revertConstraintState = newConstraintState(
|
|
1033
936
|
change.constraintViolationCountOnRevert ?? 0,
|
|
1034
937
|
);
|
|
1035
938
|
|
|
1036
|
-
|
|
939
|
+
let noChangeConstraint = change.noChangeConstraint;
|
|
940
|
+
if (noChangeConstraint !== undefined && !noChangeConstraint.violated) {
|
|
941
|
+
noChangeConstraint = { violated: true };
|
|
942
|
+
constraintState.violationCount += 1;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
this.updateConstraintsForFields(
|
|
1037
946
|
rebasedFields,
|
|
1038
|
-
|
|
1039
|
-
|
|
947
|
+
NodeAttachState.Attached,
|
|
948
|
+
NodeAttachState.Attached,
|
|
1040
949
|
constraintState,
|
|
1041
950
|
revertConstraintState,
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
const fieldsWithRootMoves = getFieldsWithRootMoves(
|
|
1045
|
-
crossFieldTable.rebasedRootNodes,
|
|
1046
|
-
change.nodeAliases,
|
|
1047
|
-
);
|
|
1048
|
-
|
|
1049
|
-
const fieldToRootChanges = getFieldToRootChanges(
|
|
1050
|
-
crossFieldTable.rebasedRootNodes,
|
|
1051
|
-
change.nodeAliases,
|
|
951
|
+
rebasedNodes,
|
|
1052
952
|
);
|
|
1053
953
|
|
|
1054
954
|
const rebased = makeModularChangeset({
|
|
1055
|
-
fieldChanges: this.pruneFieldMap(
|
|
1056
|
-
rebasedFields,
|
|
1057
|
-
undefined,
|
|
1058
|
-
rebasedNodes,
|
|
1059
|
-
crossFieldTable.rebasedNodeToParent,
|
|
1060
|
-
change.nodeAliases,
|
|
1061
|
-
crossFieldTable.rebasedRootNodes,
|
|
1062
|
-
fieldsWithRootMoves,
|
|
1063
|
-
fieldToRootChanges,
|
|
1064
|
-
),
|
|
955
|
+
fieldChanges: this.pruneFieldMap(rebasedFields, rebasedNodes),
|
|
1065
956
|
nodeChanges: rebasedNodes,
|
|
1066
957
|
nodeToParent: crossFieldTable.rebasedNodeToParent,
|
|
1067
|
-
rootNodes: this.pruneRoots(
|
|
1068
|
-
crossFieldTable.rebasedRootNodes,
|
|
1069
|
-
rebasedNodes,
|
|
1070
|
-
crossFieldTable.rebasedNodeToParent,
|
|
1071
|
-
change.nodeAliases,
|
|
1072
|
-
fieldsWithRootMoves,
|
|
1073
|
-
fieldToRootChanges,
|
|
1074
|
-
),
|
|
1075
|
-
// TODO: Do we need to include aliases for node changesets added during rebasing?
|
|
1076
958
|
nodeAliases: change.nodeAliases,
|
|
1077
|
-
crossFieldKeys:
|
|
1078
|
-
change.crossFieldKeys,
|
|
1079
|
-
crossFieldTable.movedDetaches,
|
|
1080
|
-
crossFieldTable.rebasedDetachLocations,
|
|
1081
|
-
),
|
|
959
|
+
crossFieldKeys: crossFieldTable.rebasedCrossFieldKeys,
|
|
1082
960
|
maxId: idState.maxId,
|
|
1083
961
|
revisions: change.revisions,
|
|
1084
962
|
constraintViolationCount: constraintState.violationCount,
|
|
1085
963
|
constraintViolationCountOnRevert: revertConstraintState.violationCount,
|
|
964
|
+
noChangeConstraint,
|
|
965
|
+
noChangeConstraintOnRevert: change.noChangeConstraintOnRevert,
|
|
1086
966
|
builds: change.builds,
|
|
1087
967
|
destroys: change.destroys,
|
|
1088
968
|
refreshers: change.refreshers,
|
|
1089
|
-
rebaseVersion,
|
|
1090
969
|
});
|
|
1091
970
|
|
|
1092
|
-
// XXX: This is an expensive assert which should be disabled before merging.
|
|
1093
|
-
this.validateChangeset(rebased);
|
|
1094
971
|
return rebased;
|
|
1095
972
|
}
|
|
1096
973
|
|
|
1097
974
|
// This performs a first pass on all fields which have both new and base changes.
|
|
1098
975
|
// TODO: Can we also handle additional passes in this method?
|
|
1099
976
|
private rebaseIntersectingFields(
|
|
1100
|
-
rootChanges: [newChangeset: NodeId, baseChangeset: NodeId][],
|
|
1101
977
|
crossFieldTable: RebaseTable,
|
|
1102
978
|
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1103
979
|
genId: IdAllocator,
|
|
@@ -1114,18 +990,6 @@ export class ModularChangeFamily
|
|
|
1114
990
|
metadata,
|
|
1115
991
|
);
|
|
1116
992
|
|
|
1117
|
-
for (const [newChildChange, baseChildChange] of rootChanges) {
|
|
1118
|
-
const rebasedNode = this.rebaseNodeChange(
|
|
1119
|
-
newChildChange,
|
|
1120
|
-
baseChildChange,
|
|
1121
|
-
genId,
|
|
1122
|
-
crossFieldTable,
|
|
1123
|
-
metadata,
|
|
1124
|
-
);
|
|
1125
|
-
|
|
1126
|
-
setInChangeAtomIdMap(rebasedNodes, newChildChange, rebasedNode);
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
993
|
// This loop processes all fields which have both base and new changes.
|
|
1130
994
|
// Note that the call to `rebaseNodeChange` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
1131
995
|
for (const [newId, baseId, _attachState] of crossFieldTable.nodeIdPairs) {
|
|
@@ -1143,150 +1007,146 @@ export class ModularChangeFamily
|
|
|
1143
1007
|
return rebasedFields;
|
|
1144
1008
|
}
|
|
1145
1009
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
baseFieldId: FieldId,
|
|
1149
|
-
crossFieldTable: RebaseTable,
|
|
1010
|
+
// This processes fields which have no new changes but have been invalidated by another field.
|
|
1011
|
+
private rebaseFieldsWithoutNewChanges(
|
|
1150
1012
|
rebasedFields: FieldChangeMap,
|
|
1151
1013
|
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1014
|
+
crossFieldTable: RebaseTable,
|
|
1152
1015
|
genId: IdAllocator,
|
|
1153
1016
|
metadata: RebaseRevisionMetadata,
|
|
1154
|
-
|
|
1155
|
-
/**
|
|
1156
|
-
* The ID of a node in `baseFieldChange` which should be included in the rebased field change.
|
|
1157
|
-
*/
|
|
1158
|
-
baseNodeId?: NodeId,
|
|
1159
1017
|
): void {
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
return areEqualChangeAtomIds(
|
|
1173
|
-
normalizeNodeId(baseChild, crossFieldTable.baseChange.nodeAliases),
|
|
1018
|
+
const baseChange = crossFieldTable.baseChange;
|
|
1019
|
+
for (const [revision, localId, fieldKey] of crossFieldTable.affectedBaseFields.keys()) {
|
|
1020
|
+
const baseNodeId =
|
|
1021
|
+
localId === undefined
|
|
1022
|
+
? undefined
|
|
1023
|
+
: normalizeNodeId({ revision, localId }, baseChange.nodeAliases);
|
|
1024
|
+
|
|
1025
|
+
const baseFieldChange = fieldMapFromNodeId(
|
|
1026
|
+
baseChange.fieldChanges,
|
|
1027
|
+
baseChange.nodeChanges,
|
|
1174
1028
|
baseNodeId,
|
|
1175
|
-
)
|
|
1176
|
-
? baseNodeId
|
|
1177
|
-
: undefined;
|
|
1178
|
-
};
|
|
1179
|
-
|
|
1180
|
-
const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
|
|
1181
|
-
const fieldChange: FieldChange = {
|
|
1182
|
-
...baseFieldChange,
|
|
1183
|
-
change: brand(handler.createEmpty()),
|
|
1184
|
-
};
|
|
1029
|
+
).get(fieldKey);
|
|
1185
1030
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1031
|
+
assert(
|
|
1032
|
+
baseFieldChange !== undefined,
|
|
1033
|
+
0x9c2 /* Cross field key registered for empty field */,
|
|
1034
|
+
);
|
|
1035
|
+
if (crossFieldTable.baseFieldToContext.has(baseFieldChange)) {
|
|
1036
|
+
// This field has already been processed because there were changes to rebase.
|
|
1037
|
+
continue;
|
|
1038
|
+
}
|
|
1190
1039
|
|
|
1191
|
-
|
|
1040
|
+
// This field has no changes in the new changeset, otherwise it would have been added to
|
|
1041
|
+
// `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
|
|
1042
|
+
const rebaseChild = (
|
|
1043
|
+
child: NodeId | undefined,
|
|
1044
|
+
baseChild: NodeId | undefined,
|
|
1045
|
+
stateChange: NodeAttachState | undefined,
|
|
1046
|
+
): NodeId | undefined => {
|
|
1047
|
+
assert(child === undefined, 0x9c3 /* There should be no new changes in this field */);
|
|
1048
|
+
return undefined;
|
|
1049
|
+
};
|
|
1192
1050
|
|
|
1193
|
-
|
|
1194
|
-
fieldChange
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
new RebaseNodeManagerI(crossFieldTable, fieldId),
|
|
1199
|
-
metadata,
|
|
1200
|
-
crossFieldTable.rebaseVersion,
|
|
1201
|
-
);
|
|
1051
|
+
const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
|
|
1052
|
+
const fieldChange: FieldChange = {
|
|
1053
|
+
...baseFieldChange,
|
|
1054
|
+
change: brand(handler.createEmpty()),
|
|
1055
|
+
};
|
|
1202
1056
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1057
|
+
const rebasedNodeId =
|
|
1058
|
+
baseNodeId === undefined
|
|
1059
|
+
? undefined
|
|
1060
|
+
: rebasedNodeIdFromBaseNodeId(crossFieldTable, baseNodeId);
|
|
1207
1061
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1062
|
+
const fieldId: FieldId = { nodeId: rebasedNodeId, field: fieldKey };
|
|
1063
|
+
const rebasedField: unknown = handler.rebaser.rebase(
|
|
1064
|
+
fieldChange.change,
|
|
1065
|
+
baseFieldChange.change,
|
|
1066
|
+
rebaseChild,
|
|
1067
|
+
genId,
|
|
1068
|
+
new RebaseManager(crossFieldTable, baseFieldChange, fieldId),
|
|
1069
|
+
metadata,
|
|
1070
|
+
);
|
|
1215
1071
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1072
|
+
const rebasedFieldChange: FieldChange = {
|
|
1073
|
+
...baseFieldChange,
|
|
1074
|
+
change: brand(rebasedField),
|
|
1075
|
+
};
|
|
1219
1076
|
|
|
1220
|
-
|
|
1077
|
+
// TODO: Deduplicate
|
|
1078
|
+
crossFieldTable.baseFieldToContext.set(baseFieldChange, {
|
|
1079
|
+
newChange: fieldChange,
|
|
1080
|
+
baseChange: baseFieldChange,
|
|
1081
|
+
rebasedChange: rebasedFieldChange,
|
|
1082
|
+
fieldId,
|
|
1083
|
+
baseNodeIds: [],
|
|
1084
|
+
});
|
|
1085
|
+
crossFieldTable.rebasedFields.add(rebasedFieldChange);
|
|
1221
1086
|
|
|
1222
|
-
|
|
1087
|
+
this.attachRebasedField(
|
|
1088
|
+
rebasedFields,
|
|
1089
|
+
rebasedNodes,
|
|
1090
|
+
crossFieldTable,
|
|
1091
|
+
rebasedFieldChange,
|
|
1092
|
+
fieldId,
|
|
1093
|
+
genId,
|
|
1094
|
+
metadata,
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1223
1098
|
|
|
1224
|
-
|
|
1099
|
+
private rebaseInvalidatedElements(
|
|
1100
|
+
rebasedFields: FieldChangeMap,
|
|
1101
|
+
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1102
|
+
table: RebaseTable,
|
|
1103
|
+
metadata: RebaseRevisionMetadata,
|
|
1104
|
+
idAllocator: IdAllocator,
|
|
1105
|
+
): void {
|
|
1106
|
+
this.rebaseFieldsWithoutNewChanges(
|
|
1225
1107
|
rebasedFields,
|
|
1226
1108
|
rebasedNodes,
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
fieldId,
|
|
1230
|
-
genId,
|
|
1109
|
+
table,
|
|
1110
|
+
idAllocator,
|
|
1231
1111
|
metadata,
|
|
1232
1112
|
);
|
|
1113
|
+
|
|
1114
|
+
this.rebaseFieldsWithUnattachedChild(table, metadata, idAllocator);
|
|
1115
|
+
this.rebaseInvalidatedFields(table, metadata, idAllocator);
|
|
1233
1116
|
}
|
|
1234
1117
|
|
|
1235
1118
|
private rebaseInvalidatedFields(
|
|
1236
|
-
rebasedFields: FieldChangeMap,
|
|
1237
|
-
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1238
1119
|
crossFieldTable: RebaseTable,
|
|
1239
1120
|
rebaseMetadata: RebaseRevisionMetadata,
|
|
1240
1121
|
genId: IdAllocator,
|
|
1241
1122
|
): void {
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
fieldIdFromFieldIdKey(baseFieldIdKey),
|
|
1249
|
-
crossFieldTable.baseChange.nodeAliases,
|
|
1250
|
-
);
|
|
1251
|
-
|
|
1252
|
-
const baseField = fieldChangeFromId(crossFieldTable.baseChange, baseFieldId);
|
|
1253
|
-
|
|
1254
|
-
assert(
|
|
1255
|
-
baseField !== undefined,
|
|
1256
|
-
0x9c2 /* Cross field key registered for empty field */,
|
|
1257
|
-
);
|
|
1123
|
+
const fieldsToUpdate = crossFieldTable.invalidatedFields;
|
|
1124
|
+
crossFieldTable.invalidatedFields = new Set();
|
|
1125
|
+
for (const field of fieldsToUpdate) {
|
|
1126
|
+
this.rebaseInvalidatedField(field, crossFieldTable, rebaseMetadata, genId);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1258
1129
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
genId,
|
|
1268
|
-
rebaseMetadata,
|
|
1269
|
-
);
|
|
1270
|
-
} else {
|
|
1271
|
-
this.rebaseInvalidatedField(
|
|
1272
|
-
baseField,
|
|
1273
|
-
crossFieldTable,
|
|
1274
|
-
context,
|
|
1275
|
-
rebaseMetadata,
|
|
1276
|
-
genId,
|
|
1277
|
-
);
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1130
|
+
private rebaseFieldsWithUnattachedChild(
|
|
1131
|
+
table: RebaseTable,
|
|
1132
|
+
metadata: RebaseRevisionMetadata,
|
|
1133
|
+
idAllocator: IdAllocator,
|
|
1134
|
+
): void {
|
|
1135
|
+
for (const field of table.fieldsWithUnattachedChild) {
|
|
1136
|
+
table.invalidatedFields.delete(field);
|
|
1137
|
+
this.rebaseInvalidatedField(field, table, metadata, idAllocator, true);
|
|
1280
1138
|
}
|
|
1281
1139
|
}
|
|
1282
1140
|
|
|
1283
1141
|
private rebaseInvalidatedField(
|
|
1284
1142
|
baseField: FieldChange,
|
|
1285
1143
|
crossFieldTable: RebaseTable,
|
|
1286
|
-
context: RebaseFieldContext,
|
|
1287
1144
|
rebaseMetadata: RebaseRevisionMetadata,
|
|
1288
1145
|
genId: IdAllocator,
|
|
1146
|
+
allowInval = false,
|
|
1289
1147
|
): void {
|
|
1148
|
+
const context = crossFieldTable.baseFieldToContext.get(baseField);
|
|
1149
|
+
assert(context !== undefined, 0x852 /* Every field should have a context */);
|
|
1290
1150
|
const {
|
|
1291
1151
|
changeHandler,
|
|
1292
1152
|
change1: fieldChangeset,
|
|
@@ -1301,28 +1161,25 @@ export class ModularChangeFamily
|
|
|
1301
1161
|
return curr;
|
|
1302
1162
|
}
|
|
1303
1163
|
|
|
1304
|
-
if (base !== undefined
|
|
1305
|
-
|
|
1164
|
+
if (base !== undefined) {
|
|
1165
|
+
for (const id of context.baseNodeIds) {
|
|
1166
|
+
if (areEqualChangeAtomIds(base, id)) {
|
|
1167
|
+
return base;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1306
1170
|
}
|
|
1307
1171
|
|
|
1308
1172
|
return undefined;
|
|
1309
1173
|
};
|
|
1310
1174
|
|
|
1311
|
-
let allowInval = false;
|
|
1312
|
-
if (crossFieldTable.fieldsWithUnattachedChild.has(baseField)) {
|
|
1313
|
-
crossFieldTable.fieldsWithUnattachedChild.delete(baseField);
|
|
1314
|
-
allowInval = true;
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
1175
|
context.rebasedChange.change = brand(
|
|
1318
1176
|
changeHandler.rebaser.rebase(
|
|
1319
1177
|
fieldChangeset,
|
|
1320
1178
|
baseChangeset,
|
|
1321
1179
|
rebaseChild,
|
|
1322
1180
|
genId,
|
|
1323
|
-
new
|
|
1181
|
+
new RebaseManager(crossFieldTable, baseField, context.fieldId, allowInval),
|
|
1324
1182
|
rebaseMetadata,
|
|
1325
|
-
crossFieldTable.rebaseVersion,
|
|
1326
1183
|
),
|
|
1327
1184
|
);
|
|
1328
1185
|
}
|
|
@@ -1342,19 +1199,13 @@ export class ModularChangeFamily
|
|
|
1342
1199
|
}
|
|
1343
1200
|
const rebasedNode = getFromChangeAtomIdMap(rebasedNodes, nodeId);
|
|
1344
1201
|
if (rebasedNode !== undefined) {
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
if (updatedRebasedNode.fieldChanges === undefined) {
|
|
1349
|
-
updatedRebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
|
|
1202
|
+
if (rebasedNode.fieldChanges === undefined) {
|
|
1203
|
+
rebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
|
|
1350
1204
|
return;
|
|
1351
1205
|
}
|
|
1352
1206
|
|
|
1353
|
-
assert(
|
|
1354
|
-
|
|
1355
|
-
0x9c4 /* Expected an empty field */,
|
|
1356
|
-
);
|
|
1357
|
-
updatedRebasedNode.fieldChanges.set(fieldKey, rebasedField);
|
|
1207
|
+
assert(!rebasedNode.fieldChanges.has(fieldKey), 0x9c4 /* Expected an empty field */);
|
|
1208
|
+
rebasedNode.fieldChanges.set(fieldKey, rebasedField);
|
|
1358
1209
|
return;
|
|
1359
1210
|
}
|
|
1360
1211
|
|
|
@@ -1365,14 +1216,14 @@ export class ModularChangeFamily
|
|
|
1365
1216
|
setInChangeAtomIdMap(rebasedNodes, nodeId, newNode);
|
|
1366
1217
|
setInChangeAtomIdMap(table.baseToRebasedNodeId, nodeId, nodeId);
|
|
1367
1218
|
|
|
1368
|
-
const
|
|
1219
|
+
const parentFieldId = getParentFieldId(table.baseChange, nodeId);
|
|
1369
1220
|
|
|
1370
1221
|
this.attachRebasedNode(
|
|
1371
1222
|
rebasedFields,
|
|
1372
1223
|
rebasedNodes,
|
|
1373
1224
|
table,
|
|
1374
1225
|
nodeId,
|
|
1375
|
-
|
|
1226
|
+
parentFieldId,
|
|
1376
1227
|
idAllocator,
|
|
1377
1228
|
metadata,
|
|
1378
1229
|
);
|
|
@@ -1383,100 +1234,65 @@ export class ModularChangeFamily
|
|
|
1383
1234
|
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1384
1235
|
table: RebaseTable,
|
|
1385
1236
|
baseNodeId: NodeId,
|
|
1386
|
-
|
|
1237
|
+
parentFieldIdBase: FieldId,
|
|
1387
1238
|
idAllocator: IdAllocator,
|
|
1388
1239
|
metadata: RebaseRevisionMetadata,
|
|
1389
1240
|
): void {
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
).value;
|
|
1396
|
-
|
|
1397
|
-
const attachField = table.baseChange.crossFieldKeys.getFirst(
|
|
1398
|
-
{ ...renamedRoot, target: CrossFieldTarget.Destination },
|
|
1399
|
-
1,
|
|
1400
|
-
).value;
|
|
1401
|
-
|
|
1402
|
-
if (attachField !== undefined) {
|
|
1403
|
-
// The base change inserts this node into `attachField`, so the rebased change should represent this node there.
|
|
1404
|
-
const normalizedAttachField = normalizeFieldId(
|
|
1405
|
-
attachField,
|
|
1406
|
-
table.baseChange.nodeAliases,
|
|
1407
|
-
);
|
|
1408
|
-
|
|
1409
|
-
const entry: DetachedNodeEntry = table.entries.getFirst(renamedRoot, 1).value ?? {};
|
|
1410
|
-
table.entries.set(renamedRoot, 1, { ...entry, nodeChange: baseNodeId });
|
|
1411
|
-
table.affectedBaseFields.set(fieldIdKeyFromFieldId(normalizedAttachField), true);
|
|
1412
|
-
this.attachRebasedNode(
|
|
1413
|
-
rebasedFields,
|
|
1414
|
-
rebasedNodes,
|
|
1415
|
-
table,
|
|
1416
|
-
baseNodeId,
|
|
1417
|
-
{ field: normalizedAttachField },
|
|
1418
|
-
idAllocator,
|
|
1419
|
-
metadata,
|
|
1420
|
-
);
|
|
1421
|
-
} else {
|
|
1422
|
-
const baseDetachLocation = table.baseChange.rootNodes.detachLocations.getFirst(
|
|
1423
|
-
parentBase.root,
|
|
1424
|
-
1,
|
|
1425
|
-
).value;
|
|
1426
|
-
|
|
1427
|
-
assignRootChange(
|
|
1428
|
-
table.rebasedRootNodes,
|
|
1429
|
-
table.rebasedNodeToParent,
|
|
1430
|
-
renamedRoot,
|
|
1431
|
-
baseNodeId,
|
|
1432
|
-
baseDetachLocation,
|
|
1433
|
-
table.rebaseVersion,
|
|
1434
|
-
);
|
|
1435
|
-
|
|
1436
|
-
// We need to make sure the rebased changeset includes the detach location,
|
|
1437
|
-
// so we add that field to `affectedBaseFields` unless it's already been processed.
|
|
1438
|
-
if (
|
|
1439
|
-
baseDetachLocation !== undefined &&
|
|
1440
|
-
!table.baseFieldToContext.has(
|
|
1441
|
-
fieldChangeFromId(table.baseChange, baseDetachLocation),
|
|
1442
|
-
)
|
|
1443
|
-
) {
|
|
1444
|
-
table.affectedBaseFields.set(fieldIdKeyFromFieldId(baseDetachLocation), true);
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
const parentFieldIdBase = parentBase.field;
|
|
1452
|
-
const baseFieldChange = fieldChangeFromId(table.baseChange, parentFieldIdBase);
|
|
1241
|
+
const baseFieldChange = fieldChangeFromId(
|
|
1242
|
+
table.baseChange.fieldChanges,
|
|
1243
|
+
table.baseChange.nodeChanges,
|
|
1244
|
+
parentFieldIdBase,
|
|
1245
|
+
);
|
|
1453
1246
|
|
|
1454
1247
|
const rebasedFieldId = rebasedFieldIdFromBaseId(table, parentFieldIdBase);
|
|
1455
|
-
setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId,
|
|
1248
|
+
setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId, rebasedFieldId);
|
|
1456
1249
|
|
|
1457
1250
|
const context = table.baseFieldToContext.get(baseFieldChange);
|
|
1458
1251
|
if (context !== undefined) {
|
|
1459
1252
|
// We've already processed this field.
|
|
1460
|
-
// The new child node will be attached in
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
// This is done by checking whether `context.baseNodeIds` already contained `baseNodeId`.
|
|
1464
|
-
if (setInChangeAtomIdMap(context.baseNodeIds, baseNodeId, true)) {
|
|
1465
|
-
table.fieldsWithUnattachedChild.add(baseFieldChange);
|
|
1466
|
-
table.affectedBaseFields.set(fieldIdKeyFromFieldId(parentFieldIdBase), true);
|
|
1467
|
-
}
|
|
1253
|
+
// The new child node will be attached in rebaseFieldsWithUnattachedChild.
|
|
1254
|
+
context.baseNodeIds.push(baseNodeId);
|
|
1255
|
+
table.fieldsWithUnattachedChild.add(baseFieldChange);
|
|
1468
1256
|
return;
|
|
1469
1257
|
}
|
|
1470
1258
|
|
|
1471
|
-
this.
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1259
|
+
const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
|
|
1260
|
+
|
|
1261
|
+
const fieldChange: FieldChange = {
|
|
1262
|
+
...baseFieldChange,
|
|
1263
|
+
change: brand(handler.createEmpty()),
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1266
|
+
const rebasedChangeset = handler.rebaser.rebase(
|
|
1267
|
+
handler.createEmpty(),
|
|
1268
|
+
baseFieldChange.change,
|
|
1269
|
+
(_idNew, idBase) =>
|
|
1270
|
+
idBase !== undefined && areEqualChangeAtomIds(idBase, baseNodeId)
|
|
1271
|
+
? baseNodeId
|
|
1272
|
+
: undefined,
|
|
1273
|
+
idAllocator,
|
|
1274
|
+
new RebaseManager(table, baseFieldChange, rebasedFieldId),
|
|
1275
|
+
metadata,
|
|
1276
|
+
);
|
|
1277
|
+
|
|
1278
|
+
const rebasedField: FieldChange = { ...baseFieldChange, change: brand(rebasedChangeset) };
|
|
1279
|
+
table.rebasedFields.add(rebasedField);
|
|
1280
|
+
table.baseFieldToContext.set(baseFieldChange, {
|
|
1281
|
+
newChange: fieldChange,
|
|
1282
|
+
baseChange: baseFieldChange,
|
|
1283
|
+
rebasedChange: rebasedField,
|
|
1284
|
+
fieldId: rebasedFieldId,
|
|
1285
|
+
baseNodeIds: [],
|
|
1286
|
+
});
|
|
1287
|
+
|
|
1288
|
+
this.attachRebasedField(
|
|
1475
1289
|
rebasedFields,
|
|
1476
1290
|
rebasedNodes,
|
|
1291
|
+
table,
|
|
1292
|
+
rebasedField,
|
|
1293
|
+
rebasedFieldId,
|
|
1477
1294
|
idAllocator,
|
|
1478
1295
|
metadata,
|
|
1479
|
-
baseNodeId,
|
|
1480
1296
|
);
|
|
1481
1297
|
}
|
|
1482
1298
|
|
|
@@ -1515,7 +1331,7 @@ export class ModularChangeFamily
|
|
|
1515
1331
|
change2: baseChangeset,
|
|
1516
1332
|
} = this.normalizeFieldChanges(fieldChange, baseChange);
|
|
1517
1333
|
|
|
1518
|
-
const manager = new
|
|
1334
|
+
const manager = new RebaseManager(crossFieldTable, baseChange, fieldId);
|
|
1519
1335
|
|
|
1520
1336
|
const rebasedField = changeHandler.rebaser.rebase(
|
|
1521
1337
|
fieldChangeset,
|
|
@@ -1524,7 +1340,6 @@ export class ModularChangeFamily
|
|
|
1524
1340
|
genId,
|
|
1525
1341
|
manager,
|
|
1526
1342
|
revisionMetadata,
|
|
1527
|
-
crossFieldTable.rebaseVersion,
|
|
1528
1343
|
);
|
|
1529
1344
|
|
|
1530
1345
|
const rebasedFieldChange: FieldChange = {
|
|
@@ -1539,7 +1354,7 @@ export class ModularChangeFamily
|
|
|
1539
1354
|
newChange: fieldChange,
|
|
1540
1355
|
rebasedChange: rebasedFieldChange,
|
|
1541
1356
|
fieldId,
|
|
1542
|
-
baseNodeIds:
|
|
1357
|
+
baseNodeIds: [],
|
|
1543
1358
|
});
|
|
1544
1359
|
|
|
1545
1360
|
crossFieldTable.rebasedFields.add(rebasedFieldChange);
|
|
@@ -1555,16 +1370,8 @@ export class ModularChangeFamily
|
|
|
1555
1370
|
crossFieldTable: RebaseTable,
|
|
1556
1371
|
revisionMetadata: RebaseRevisionMetadata,
|
|
1557
1372
|
): NodeChangeset {
|
|
1558
|
-
const change = nodeChangeFromId(
|
|
1559
|
-
|
|
1560
|
-
crossFieldTable.newChange.nodeAliases,
|
|
1561
|
-
newId,
|
|
1562
|
-
);
|
|
1563
|
-
const over = nodeChangeFromId(
|
|
1564
|
-
crossFieldTable.baseChange.nodeChanges,
|
|
1565
|
-
crossFieldTable.baseChange.nodeAliases,
|
|
1566
|
-
baseId,
|
|
1567
|
-
);
|
|
1373
|
+
const change = nodeChangeFromId(crossFieldTable.newChange.nodeChanges, newId);
|
|
1374
|
+
const over = nodeChangeFromId(crossFieldTable.baseChange.nodeChanges, baseId);
|
|
1568
1375
|
|
|
1569
1376
|
const baseMap: FieldChangeMap = over?.fieldChanges ?? new Map();
|
|
1570
1377
|
|
|
@@ -1580,7 +1387,7 @@ export class ModularChangeFamily
|
|
|
1580
1387
|
)
|
|
1581
1388
|
: change.fieldChanges;
|
|
1582
1389
|
|
|
1583
|
-
const rebasedChange:
|
|
1390
|
+
const rebasedChange: NodeChangeset = {};
|
|
1584
1391
|
|
|
1585
1392
|
if (fieldChanges !== undefined && fieldChanges.size > 0) {
|
|
1586
1393
|
rebasedChange.fieldChanges = fieldChanges;
|
|
@@ -1598,37 +1405,6 @@ export class ModularChangeFamily
|
|
|
1598
1405
|
return rebasedChange;
|
|
1599
1406
|
}
|
|
1600
1407
|
|
|
1601
|
-
private updateConstraints(
|
|
1602
|
-
rebasedFields: FieldChangeMap,
|
|
1603
|
-
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1604
|
-
rebasedRoots: RootNodeTable,
|
|
1605
|
-
constraintState: ConstraintState,
|
|
1606
|
-
revertConstraintState: ConstraintState,
|
|
1607
|
-
): void {
|
|
1608
|
-
this.updateConstraintsForFields(
|
|
1609
|
-
rebasedFields,
|
|
1610
|
-
NodeAttachState.Attached,
|
|
1611
|
-
NodeAttachState.Attached,
|
|
1612
|
-
constraintState,
|
|
1613
|
-
revertConstraintState,
|
|
1614
|
-
rebasedNodes,
|
|
1615
|
-
);
|
|
1616
|
-
|
|
1617
|
-
for (const [_detachId, nodeId] of rebasedRoots.nodeChanges.entries()) {
|
|
1618
|
-
// XXX: This is incorrect if the rebased changeset attaches the node.
|
|
1619
|
-
// Efficiently computing whether the changeset attaches the node would require maintaining a mapping from node ID to attach ID.
|
|
1620
|
-
const detachedInOutput = true;
|
|
1621
|
-
this.updateConstraintsForNode(
|
|
1622
|
-
nodeId,
|
|
1623
|
-
NodeAttachState.Detached,
|
|
1624
|
-
detachedInOutput ? NodeAttachState.Detached : NodeAttachState.Attached,
|
|
1625
|
-
rebasedNodes,
|
|
1626
|
-
constraintState,
|
|
1627
|
-
revertConstraintState,
|
|
1628
|
-
);
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
1408
|
private updateConstraintsForFields(
|
|
1633
1409
|
fields: FieldChangeMap,
|
|
1634
1410
|
parentInputAttachState: NodeAttachState,
|
|
@@ -1639,18 +1415,20 @@ export class ModularChangeFamily
|
|
|
1639
1415
|
): void {
|
|
1640
1416
|
for (const field of fields.values()) {
|
|
1641
1417
|
const handler = getChangeHandler(this.fieldKinds, field.fieldKind);
|
|
1642
|
-
for (const [nodeId] of handler.getNestedChanges(field.change)) {
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1418
|
+
for (const [nodeId, inputIndex, outputIndex] of handler.getNestedChanges(field.change)) {
|
|
1419
|
+
const isInputDetached = inputIndex === undefined;
|
|
1420
|
+
const inputAttachState =
|
|
1421
|
+
parentInputAttachState === NodeAttachState.Detached || isInputDetached
|
|
1422
|
+
? NodeAttachState.Detached
|
|
1423
|
+
: NodeAttachState.Attached;
|
|
1424
|
+
const isOutputDetached = outputIndex === undefined;
|
|
1646
1425
|
const outputAttachState =
|
|
1647
1426
|
parentOutputAttachState === NodeAttachState.Detached || isOutputDetached
|
|
1648
1427
|
? NodeAttachState.Detached
|
|
1649
1428
|
: NodeAttachState.Attached;
|
|
1650
|
-
|
|
1651
1429
|
this.updateConstraintsForNode(
|
|
1652
1430
|
nodeId,
|
|
1653
|
-
|
|
1431
|
+
inputAttachState,
|
|
1654
1432
|
outputAttachState,
|
|
1655
1433
|
nodes,
|
|
1656
1434
|
constraintState,
|
|
@@ -1668,15 +1446,12 @@ export class ModularChangeFamily
|
|
|
1668
1446
|
constraintState: ConstraintState,
|
|
1669
1447
|
revertConstraintState: ConstraintState,
|
|
1670
1448
|
): void {
|
|
1671
|
-
const node =
|
|
1672
|
-
|
|
1673
|
-
const updatedNode: Mutable<NodeChangeset> = { ...node };
|
|
1674
|
-
setInChangeAtomIdMap(nodes, nodeId, updatedNode);
|
|
1675
|
-
|
|
1449
|
+
const node =
|
|
1450
|
+
nodes.get([nodeId.revision, nodeId.localId]) ?? fail(0xb24 /* Unknown node ID */);
|
|
1676
1451
|
if (node.nodeExistsConstraint !== undefined) {
|
|
1677
1452
|
const isNowViolated = inputAttachState === NodeAttachState.Detached;
|
|
1678
1453
|
if (node.nodeExistsConstraint.violated !== isNowViolated) {
|
|
1679
|
-
|
|
1454
|
+
node.nodeExistsConstraint = {
|
|
1680
1455
|
...node.nodeExistsConstraint,
|
|
1681
1456
|
violated: isNowViolated,
|
|
1682
1457
|
};
|
|
@@ -1686,7 +1461,7 @@ export class ModularChangeFamily
|
|
|
1686
1461
|
if (node.nodeExistsConstraintOnRevert !== undefined) {
|
|
1687
1462
|
const isNowViolated = outputAttachState === NodeAttachState.Detached;
|
|
1688
1463
|
if (node.nodeExistsConstraintOnRevert.violated !== isNowViolated) {
|
|
1689
|
-
|
|
1464
|
+
node.nodeExistsConstraintOnRevert = {
|
|
1690
1465
|
...node.nodeExistsConstraintOnRevert,
|
|
1691
1466
|
violated: isNowViolated,
|
|
1692
1467
|
};
|
|
@@ -1708,13 +1483,7 @@ export class ModularChangeFamily
|
|
|
1708
1483
|
|
|
1709
1484
|
private pruneFieldMap(
|
|
1710
1485
|
changeset: FieldChangeMap | undefined,
|
|
1711
|
-
parentId: NodeId | undefined,
|
|
1712
1486
|
nodeMap: ChangeAtomIdBTree<NodeChangeset>,
|
|
1713
|
-
nodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
1714
|
-
aliases: ChangeAtomIdBTree<NodeId>,
|
|
1715
|
-
roots: RootNodeTable,
|
|
1716
|
-
fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
|
|
1717
|
-
fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
|
|
1718
1487
|
): FieldChangeMap | undefined {
|
|
1719
1488
|
if (changeset === undefined) {
|
|
1720
1489
|
return undefined;
|
|
@@ -1725,48 +1494,10 @@ export class ModularChangeFamily
|
|
|
1725
1494
|
const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
|
|
1726
1495
|
|
|
1727
1496
|
const prunedFieldChangeset = handler.rebaser.prune(fieldChange.change, (nodeId) =>
|
|
1728
|
-
this.pruneNodeChange(
|
|
1729
|
-
nodeId,
|
|
1730
|
-
nodeMap,
|
|
1731
|
-
nodeToParent,
|
|
1732
|
-
aliases,
|
|
1733
|
-
roots,
|
|
1734
|
-
fieldsWithRootMoves,
|
|
1735
|
-
fieldsToRootChanges,
|
|
1736
|
-
),
|
|
1497
|
+
this.pruneNodeChange(nodeId, nodeMap),
|
|
1737
1498
|
);
|
|
1738
1499
|
|
|
1739
|
-
|
|
1740
|
-
const fieldIdKey = fieldIdKeyFromFieldId(fieldId);
|
|
1741
|
-
const rootsWithChanges = fieldsToRootChanges.get(fieldIdKey) ?? [];
|
|
1742
|
-
let hasRootWithNodeChange = false;
|
|
1743
|
-
for (const rootId of rootsWithChanges) {
|
|
1744
|
-
const nodeId =
|
|
1745
|
-
getFromChangeAtomIdMap(roots.nodeChanges, rootId) ?? fail("No root change found");
|
|
1746
|
-
|
|
1747
|
-
const isRootChangeEmpty =
|
|
1748
|
-
this.pruneNodeChange(
|
|
1749
|
-
nodeId,
|
|
1750
|
-
nodeMap,
|
|
1751
|
-
nodeToParent,
|
|
1752
|
-
aliases,
|
|
1753
|
-
roots,
|
|
1754
|
-
fieldsWithRootMoves,
|
|
1755
|
-
fieldsToRootChanges,
|
|
1756
|
-
) === undefined;
|
|
1757
|
-
|
|
1758
|
-
if (isRootChangeEmpty) {
|
|
1759
|
-
roots.nodeChanges.delete([rootId.revision, rootId.localId]);
|
|
1760
|
-
tryRemoveDetachLocation(roots, rootId, 1);
|
|
1761
|
-
} else {
|
|
1762
|
-
hasRootWithNodeChange = true;
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
const hasRootChanges =
|
|
1767
|
-
hasRootWithNodeChange || fieldsWithRootMoves.get(fieldIdKey) === true;
|
|
1768
|
-
|
|
1769
|
-
if (!handler.isEmpty(prunedFieldChangeset) || hasRootChanges) {
|
|
1500
|
+
if (!handler.isEmpty(prunedFieldChangeset)) {
|
|
1770
1501
|
prunedChangeset.set(field, { ...fieldChange, change: brand(prunedFieldChangeset) });
|
|
1771
1502
|
}
|
|
1772
1503
|
}
|
|
@@ -1774,65 +1505,15 @@ export class ModularChangeFamily
|
|
|
1774
1505
|
return prunedChangeset.size > 0 ? prunedChangeset : undefined;
|
|
1775
1506
|
}
|
|
1776
1507
|
|
|
1777
|
-
private pruneRoots(
|
|
1778
|
-
roots: RootNodeTable,
|
|
1779
|
-
nodeMap: ChangeAtomIdBTree<NodeChangeset>,
|
|
1780
|
-
nodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
1781
|
-
aliases: ChangeAtomIdBTree<NodeId>,
|
|
1782
|
-
fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
|
|
1783
|
-
fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
|
|
1784
|
-
): RootNodeTable {
|
|
1785
|
-
const pruned: RootNodeTable = { ...roots, nodeChanges: newTupleBTree() };
|
|
1786
|
-
for (const [rootIdKey, nodeId] of roots.nodeChanges.entries()) {
|
|
1787
|
-
const rootId: ChangeAtomId = { revision: rootIdKey[0], localId: rootIdKey[1] };
|
|
1788
|
-
const hasDetachLocation = roots.detachLocations.getFirst(rootId, 1).value !== undefined;
|
|
1789
|
-
|
|
1790
|
-
// If the root has a detach location it should be pruned by recursion when pruning the field it was detached from.
|
|
1791
|
-
const prunedId = hasDetachLocation
|
|
1792
|
-
? nodeId
|
|
1793
|
-
: this.pruneNodeChange(
|
|
1794
|
-
nodeId,
|
|
1795
|
-
nodeMap,
|
|
1796
|
-
nodeToParent,
|
|
1797
|
-
aliases,
|
|
1798
|
-
roots,
|
|
1799
|
-
fieldsWithRootMoves,
|
|
1800
|
-
fieldsToRootChanges,
|
|
1801
|
-
);
|
|
1802
|
-
|
|
1803
|
-
if (prunedId !== undefined) {
|
|
1804
|
-
pruned.nodeChanges.set(rootIdKey, prunedId);
|
|
1805
|
-
}
|
|
1806
|
-
|
|
1807
|
-
tryRemoveDetachLocation(pruned, rootId, 1);
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
|
-
return pruned;
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
1508
|
private pruneNodeChange(
|
|
1814
1509
|
nodeId: NodeId,
|
|
1815
|
-
|
|
1816
|
-
nodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
1817
|
-
aliases: ChangeAtomIdBTree<NodeId>,
|
|
1818
|
-
roots: RootNodeTable,
|
|
1819
|
-
fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
|
|
1820
|
-
fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
|
|
1510
|
+
nodeMap: ChangeAtomIdBTree<NodeChangeset>,
|
|
1821
1511
|
): NodeId | undefined {
|
|
1822
|
-
const changeset = nodeChangeFromId(
|
|
1512
|
+
const changeset = nodeChangeFromId(nodeMap, nodeId);
|
|
1823
1513
|
const prunedFields =
|
|
1824
|
-
changeset.fieldChanges
|
|
1825
|
-
?
|
|
1826
|
-
|
|
1827
|
-
nodeId,
|
|
1828
|
-
nodes,
|
|
1829
|
-
nodeToParent,
|
|
1830
|
-
aliases,
|
|
1831
|
-
roots,
|
|
1832
|
-
fieldsWithRootMoves,
|
|
1833
|
-
fieldsToRootChanges,
|
|
1834
|
-
)
|
|
1835
|
-
: undefined;
|
|
1514
|
+
changeset.fieldChanges === undefined
|
|
1515
|
+
? undefined
|
|
1516
|
+
: this.pruneFieldMap(changeset.fieldChanges, nodeMap);
|
|
1836
1517
|
|
|
1837
1518
|
const prunedChange = { ...changeset, fieldChanges: prunedFields };
|
|
1838
1519
|
if (prunedChange.fieldChanges === undefined) {
|
|
@@ -1840,116 +1521,78 @@ export class ModularChangeFamily
|
|
|
1840
1521
|
}
|
|
1841
1522
|
|
|
1842
1523
|
if (isEmptyNodeChangeset(prunedChange)) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
// TODO: Shouldn't we also delete all aliases associated with this node?
|
|
1846
|
-
nodes.delete(nodeIdKey);
|
|
1847
|
-
nodeToParent.delete(nodeIdKey);
|
|
1524
|
+
nodeMap.delete([nodeId.revision, nodeId.localId]);
|
|
1848
1525
|
return undefined;
|
|
1849
1526
|
} else {
|
|
1850
|
-
setInChangeAtomIdMap(
|
|
1527
|
+
setInChangeAtomIdMap(nodeMap, nodeId, prunedChange);
|
|
1851
1528
|
return nodeId;
|
|
1852
1529
|
}
|
|
1853
1530
|
}
|
|
1854
1531
|
|
|
1532
|
+
public getRevisions(change: ModularChangeset): Set<RevisionTag | undefined> {
|
|
1533
|
+
const aggregated: Set<RevisionTag | undefined> = new Set();
|
|
1534
|
+
for (const revInfo of change.revisions ?? [{ revision: undefined }]) {
|
|
1535
|
+
aggregated.add(revInfo.revision);
|
|
1536
|
+
}
|
|
1537
|
+
return aggregated;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1855
1540
|
public changeRevision(
|
|
1856
1541
|
change: ModularChangeset,
|
|
1857
|
-
|
|
1858
|
-
rollbackOf?: RevisionTag,
|
|
1542
|
+
replacer: RevisionReplacer,
|
|
1859
1543
|
): ModularChangeset {
|
|
1860
|
-
const
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
: change.revisions.map((revInfo) => revInfo.revision),
|
|
1544
|
+
const updatedFields = this.replaceFieldMapRevisions(change.fieldChanges, replacer);
|
|
1545
|
+
const updatedNodes = replaceIdMapRevisions(change.nodeChanges, replacer, (nodeChangeset) =>
|
|
1546
|
+
this.replaceNodeChangesetRevisions(nodeChangeset, replacer),
|
|
1864
1547
|
);
|
|
1865
|
-
const
|
|
1866
|
-
change.
|
|
1867
|
-
|
|
1868
|
-
|
|
1548
|
+
const updatedNodeToParent = replaceIdMapRevisions(
|
|
1549
|
+
change.nodeToParent,
|
|
1550
|
+
replacer,
|
|
1551
|
+
(fieldId) =>
|
|
1552
|
+
replaceFieldIdRevision(normalizeFieldId(fieldId, change.nodeAliases), replacer),
|
|
1869
1553
|
);
|
|
1870
1554
|
|
|
1871
|
-
const updatedNodes: ChangeAtomIdBTree<NodeChangeset> = newTupleBTree();
|
|
1872
|
-
for (const [[revision, id], nodeChangeset] of change.nodeChanges.entries()) {
|
|
1873
|
-
updatedNodes.set(
|
|
1874
|
-
[replaceRevision(revision, oldRevisions, newRevision), id],
|
|
1875
|
-
this.replaceNodeChangesetRevisions(nodeChangeset, oldRevisions, newRevision),
|
|
1876
|
-
);
|
|
1877
|
-
}
|
|
1878
|
-
|
|
1879
|
-
const updatedNodeToParent: ChangeAtomIdBTree<NodeLocation> = newTupleBTree();
|
|
1880
|
-
for (const [[revision, id], location] of change.nodeToParent.entries()) {
|
|
1881
|
-
updatedNodeToParent.set(
|
|
1882
|
-
[replaceRevision(revision, oldRevisions, newRevision), id],
|
|
1883
|
-
replaceNodeLocationRevision(
|
|
1884
|
-
normalizeNodeLocation(location, change.nodeAliases),
|
|
1885
|
-
oldRevisions,
|
|
1886
|
-
newRevision,
|
|
1887
|
-
),
|
|
1888
|
-
);
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
1555
|
const updated: Mutable<ModularChangeset> = {
|
|
1892
1556
|
...change,
|
|
1893
1557
|
fieldChanges: updatedFields,
|
|
1894
1558
|
nodeChanges: updatedNodes,
|
|
1895
1559
|
nodeToParent: updatedNodeToParent,
|
|
1896
|
-
rootNodes: replaceRootTableRevision(
|
|
1897
|
-
change.rootNodes,
|
|
1898
|
-
oldRevisions,
|
|
1899
|
-
newRevision,
|
|
1900
|
-
change.nodeAliases,
|
|
1901
|
-
),
|
|
1902
1560
|
|
|
1903
1561
|
// We've updated all references to old node IDs, so we no longer need an alias table.
|
|
1904
1562
|
nodeAliases: newTupleBTree(),
|
|
1905
|
-
crossFieldKeys:
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
normalizeFieldId(id, change.nodeAliases),
|
|
1910
|
-
oldRevisions,
|
|
1911
|
-
newRevision,
|
|
1912
|
-
),
|
|
1563
|
+
crossFieldKeys: replaceCrossFieldKeyTableRevisions(
|
|
1564
|
+
change.crossFieldKeys,
|
|
1565
|
+
replacer,
|
|
1566
|
+
change.nodeAliases,
|
|
1913
1567
|
),
|
|
1914
1568
|
};
|
|
1915
1569
|
|
|
1916
1570
|
if (change.builds !== undefined) {
|
|
1917
|
-
updated.builds = replaceIdMapRevisions(change.builds,
|
|
1571
|
+
updated.builds = replaceIdMapRevisions(change.builds, replacer);
|
|
1918
1572
|
}
|
|
1919
1573
|
|
|
1920
1574
|
if (change.destroys !== undefined) {
|
|
1921
|
-
updated.destroys = replaceIdMapRevisions(change.destroys,
|
|
1575
|
+
updated.destroys = replaceIdMapRevisions(change.destroys, replacer);
|
|
1922
1576
|
}
|
|
1923
1577
|
|
|
1924
1578
|
if (change.refreshers !== undefined) {
|
|
1925
|
-
updated.refreshers = replaceIdMapRevisions(change.refreshers,
|
|
1579
|
+
updated.refreshers = replaceIdMapRevisions(change.refreshers, replacer);
|
|
1926
1580
|
}
|
|
1927
1581
|
|
|
1928
|
-
|
|
1929
|
-
const revInfo: Mutable<RevisionInfo> = { revision: newRevision };
|
|
1930
|
-
if (rollbackOf !== undefined) {
|
|
1931
|
-
revInfo.rollbackOf = rollbackOf;
|
|
1932
|
-
}
|
|
1933
|
-
|
|
1934
|
-
updated.revisions = [revInfo];
|
|
1935
|
-
} else {
|
|
1936
|
-
delete updated.revisions;
|
|
1937
|
-
}
|
|
1582
|
+
updated.revisions = [{ revision: replacer.updatedRevision }];
|
|
1938
1583
|
|
|
1939
1584
|
return updated;
|
|
1940
1585
|
}
|
|
1941
1586
|
|
|
1942
1587
|
private replaceNodeChangesetRevisions(
|
|
1943
1588
|
nodeChangeset: NodeChangeset,
|
|
1944
|
-
|
|
1945
|
-
newRevision: RevisionTag | undefined,
|
|
1589
|
+
replacer: RevisionReplacer,
|
|
1946
1590
|
): NodeChangeset {
|
|
1947
1591
|
const updated = { ...nodeChangeset };
|
|
1948
1592
|
if (nodeChangeset.fieldChanges !== undefined) {
|
|
1949
1593
|
updated.fieldChanges = this.replaceFieldMapRevisions(
|
|
1950
1594
|
nodeChangeset.fieldChanges,
|
|
1951
|
-
|
|
1952
|
-
newRevision,
|
|
1595
|
+
replacer,
|
|
1953
1596
|
);
|
|
1954
1597
|
}
|
|
1955
1598
|
|
|
@@ -1958,15 +1601,14 @@ export class ModularChangeFamily
|
|
|
1958
1601
|
|
|
1959
1602
|
private replaceFieldMapRevisions(
|
|
1960
1603
|
fields: FieldChangeMap,
|
|
1961
|
-
|
|
1962
|
-
newRevision: RevisionTag | undefined,
|
|
1604
|
+
replacer: RevisionReplacer,
|
|
1963
1605
|
): FieldChangeMap {
|
|
1964
1606
|
const updatedFields: FieldChangeMap = new Map();
|
|
1965
1607
|
for (const [field, fieldChange] of fields) {
|
|
1966
1608
|
const updatedFieldChange = getChangeHandler(
|
|
1967
1609
|
this.fieldKinds,
|
|
1968
1610
|
fieldChange.fieldKind,
|
|
1969
|
-
).rebaser.replaceRevisions(fieldChange.change,
|
|
1611
|
+
).rebaser.replaceRevisions(fieldChange.change, replacer);
|
|
1970
1612
|
|
|
1971
1613
|
updatedFields.set(field, { ...fieldChange, change: brand(updatedFieldChange) });
|
|
1972
1614
|
}
|
|
@@ -1978,7 +1620,7 @@ export class ModularChangeFamily
|
|
|
1978
1620
|
fields: FieldChangeMap,
|
|
1979
1621
|
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1980
1622
|
): CrossFieldKeyTable {
|
|
1981
|
-
const keys: CrossFieldKeyTable =
|
|
1623
|
+
const keys: CrossFieldKeyTable = newCrossFieldKeyTable();
|
|
1982
1624
|
this.populateCrossFieldKeyTableForFieldMap(keys, fields, undefined);
|
|
1983
1625
|
nodes.forEachPair(([revision, localId], node) => {
|
|
1984
1626
|
if (node.fieldChanges !== undefined) {
|
|
@@ -2008,9 +1650,10 @@ export class ModularChangeFamily
|
|
|
2008
1650
|
}
|
|
2009
1651
|
|
|
2010
1652
|
public buildEditor(
|
|
1653
|
+
mintRevisionTag: () => RevisionTag,
|
|
2011
1654
|
changeReceiver: (change: TaggedChange<ModularChangeset>) => void,
|
|
2012
1655
|
): ModularEditBuilder {
|
|
2013
|
-
return new ModularEditBuilder(this, this.fieldKinds, changeReceiver);
|
|
1656
|
+
return new ModularEditBuilder(this, this.fieldKinds, changeReceiver, this.codecOptions);
|
|
2014
1657
|
}
|
|
2015
1658
|
|
|
2016
1659
|
private createEmptyFieldChange(fieldKind: FieldKindIdentifier): FieldChange {
|
|
@@ -2019,102 +1662,60 @@ export class ModularChangeFamily
|
|
|
2019
1662
|
}
|
|
2020
1663
|
|
|
2021
1664
|
public validateChangeset(change: ModularChangeset): void {
|
|
2022
|
-
|
|
2023
|
-
change.nodeToParent.clone(),
|
|
2024
|
-
);
|
|
2025
|
-
|
|
2026
|
-
const unreachableCFKs = change.crossFieldKeys.clone();
|
|
2027
|
-
|
|
2028
|
-
this.validateFieldChanges(
|
|
2029
|
-
change,
|
|
2030
|
-
change.fieldChanges,
|
|
2031
|
-
undefined,
|
|
2032
|
-
unreachableNodes,
|
|
2033
|
-
unreachableCFKs,
|
|
2034
|
-
);
|
|
1665
|
+
let numNodes = this.validateFieldChanges(change, change.fieldChanges, undefined);
|
|
2035
1666
|
|
|
2036
1667
|
for (const [[revision, localId], node] of change.nodeChanges.entries()) {
|
|
2037
1668
|
if (node.fieldChanges === undefined) {
|
|
2038
1669
|
continue;
|
|
2039
1670
|
}
|
|
2040
1671
|
|
|
2041
|
-
const nodeId =
|
|
2042
|
-
this.validateFieldChanges(
|
|
2043
|
-
change,
|
|
2044
|
-
node.fieldChanges,
|
|
2045
|
-
nodeId,
|
|
2046
|
-
unreachableNodes,
|
|
2047
|
-
unreachableCFKs,
|
|
2048
|
-
);
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
2052
|
-
const detachId: ChangeAtomId = { revision: detachIdKey[0], localId: detachIdKey[1] };
|
|
2053
|
-
const location = getNodeParent(change, nodeId);
|
|
2054
|
-
assert(areEqualChangeAtomIdOpts(location.root, detachId), "Inconsistent node location");
|
|
2055
|
-
|
|
2056
|
-
const normalizedNodeId = normalizeNodeId(nodeId, change.nodeAliases);
|
|
2057
|
-
unreachableNodes.delete([normalizedNodeId.revision, normalizedNodeId.localId]);
|
|
1672
|
+
const nodeId: NodeId = { revision, localId };
|
|
1673
|
+
const numChildren = this.validateFieldChanges(change, node.fieldChanges, nodeId);
|
|
2058
1674
|
|
|
2059
|
-
|
|
2060
|
-
change.nodeChanges,
|
|
2061
|
-
change.nodeAliases,
|
|
2062
|
-
nodeId,
|
|
2063
|
-
).fieldChanges;
|
|
2064
|
-
|
|
2065
|
-
if (fieldChanges !== undefined) {
|
|
2066
|
-
this.validateFieldChanges(
|
|
2067
|
-
change,
|
|
2068
|
-
fieldChanges,
|
|
2069
|
-
normalizedNodeId,
|
|
2070
|
-
unreachableNodes,
|
|
2071
|
-
unreachableCFKs,
|
|
2072
|
-
);
|
|
2073
|
-
}
|
|
1675
|
+
numNodes += numChildren;
|
|
2074
1676
|
}
|
|
2075
1677
|
|
|
2076
|
-
assert(
|
|
2077
|
-
|
|
1678
|
+
assert(
|
|
1679
|
+
numNodes === change.nodeChanges.size,
|
|
1680
|
+
0xa4d /* Node table contains unparented nodes */,
|
|
1681
|
+
);
|
|
2078
1682
|
}
|
|
2079
1683
|
|
|
2080
1684
|
/**
|
|
2081
|
-
* Asserts that each
|
|
2082
|
-
*
|
|
1685
|
+
* Asserts that each child and cross field key in each field has a correct entry in
|
|
1686
|
+
* `nodeToParent` or `crossFieldKeyTable`.
|
|
2083
1687
|
* @returns the number of children found.
|
|
2084
1688
|
*/
|
|
2085
1689
|
private validateFieldChanges(
|
|
2086
1690
|
change: ModularChangeset,
|
|
2087
1691
|
fieldChanges: FieldChangeMap,
|
|
2088
1692
|
nodeParent: NodeId | undefined,
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
): void {
|
|
1693
|
+
): number {
|
|
1694
|
+
let numChildren = 0;
|
|
2092
1695
|
for (const [field, fieldChange] of fieldChanges.entries()) {
|
|
2093
1696
|
const fieldId = { nodeId: nodeParent, field };
|
|
2094
1697
|
const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
|
|
2095
1698
|
for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
|
|
2096
|
-
const parentFieldId =
|
|
1699
|
+
const parentFieldId = getParentFieldId(change, child);
|
|
2097
1700
|
assert(
|
|
2098
|
-
|
|
1701
|
+
areEqualFieldIds(parentFieldId, fieldId),
|
|
2099
1702
|
0xa4e /* Inconsistent node parentage */,
|
|
2100
1703
|
);
|
|
2101
|
-
|
|
2102
|
-
unreachableNodes.delete([child.revision, child.localId]);
|
|
1704
|
+
numChildren += 1;
|
|
2103
1705
|
}
|
|
2104
1706
|
|
|
2105
1707
|
for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
|
|
2106
1708
|
const fields = getFieldsForCrossFieldKey(change, keyRange.key, keyRange.count);
|
|
2107
|
-
assert(
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
areEqualFieldIds(
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
}
|
|
2114
|
-
|
|
2115
|
-
unreachableCFKs.delete(keyRange.key, keyRange.count);
|
|
1709
|
+
assert(
|
|
1710
|
+
fields.length === 1 &&
|
|
1711
|
+
fields[0] !== undefined &&
|
|
1712
|
+
areEqualFieldIds(fields[0], fieldId),
|
|
1713
|
+
0xa4f /* Inconsistent cross field keys */,
|
|
1714
|
+
);
|
|
2116
1715
|
}
|
|
2117
1716
|
}
|
|
1717
|
+
|
|
1718
|
+
return numChildren;
|
|
2118
1719
|
}
|
|
2119
1720
|
|
|
2120
1721
|
private getEffectiveChange(change: ModularChangeset): ModularChangeset {
|
|
@@ -2130,8 +1731,7 @@ export class ModularChangeFamily
|
|
|
2130
1731
|
private muteChange(change: ModularChangeset): ModularChangeset {
|
|
2131
1732
|
const muted: Mutable<ModularChangeset> = {
|
|
2132
1733
|
...change,
|
|
2133
|
-
|
|
2134
|
-
crossFieldKeys: newCrossFieldRangeTable(),
|
|
1734
|
+
crossFieldKeys: newCrossFieldKeyTable(),
|
|
2135
1735
|
fieldChanges: this.muteFieldChanges(change.fieldChanges),
|
|
2136
1736
|
nodeChanges: brand(change.nodeChanges.mapValues((v) => this.muteNodeChange(v))),
|
|
2137
1737
|
};
|
|
@@ -2163,34 +1763,43 @@ export class ModularChangeFamily
|
|
|
2163
1763
|
}
|
|
2164
1764
|
}
|
|
2165
1765
|
|
|
2166
|
-
function
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
):
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
1766
|
+
function replaceCrossFieldKeyTableRevisions(
|
|
1767
|
+
table: CrossFieldKeyTable,
|
|
1768
|
+
replacer: RevisionReplacer,
|
|
1769
|
+
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
1770
|
+
): CrossFieldKeyTable {
|
|
1771
|
+
const updated: CrossFieldKeyTable = newCrossFieldKeyTable();
|
|
1772
|
+
for (const entry of table.entries()) {
|
|
1773
|
+
const key = entry.start;
|
|
1774
|
+
const updatedKey: CrossFieldKey = replacer.getUpdatedAtomId(key);
|
|
1775
|
+
|
|
1776
|
+
const field = entry.value;
|
|
1777
|
+
const normalizedFieldId = normalizeFieldId(field, nodeAliases);
|
|
1778
|
+
const updatedNodeId =
|
|
1779
|
+
normalizedFieldId.nodeId === undefined
|
|
1780
|
+
? undefined
|
|
1781
|
+
: replacer.getUpdatedAtomId(normalizedFieldId.nodeId);
|
|
1782
|
+
|
|
1783
|
+
const updatedValue: FieldId = {
|
|
1784
|
+
...normalizedFieldId,
|
|
1785
|
+
nodeId: updatedNodeId,
|
|
1786
|
+
};
|
|
1787
|
+
|
|
1788
|
+
updated.set(updatedKey, entry.length, updatedValue);
|
|
1789
|
+
}
|
|
2177
1790
|
|
|
2178
|
-
|
|
2179
|
-
revision: RevisionTag | undefined,
|
|
2180
|
-
oldRevisions: Set<RevisionTag | undefined>,
|
|
2181
|
-
newRevision: RevisionTag | undefined,
|
|
2182
|
-
): RevisionTag | undefined {
|
|
2183
|
-
return oldRevisions.has(revision) ? newRevision : revision;
|
|
1791
|
+
return updated;
|
|
2184
1792
|
}
|
|
2185
1793
|
|
|
2186
1794
|
function replaceIdMapRevisions<T>(
|
|
2187
1795
|
map: ChangeAtomIdBTree<T>,
|
|
2188
|
-
|
|
2189
|
-
|
|
1796
|
+
replacer: RevisionReplacer,
|
|
1797
|
+
valueMapper: (value: T) => T = (value) => value,
|
|
2190
1798
|
): ChangeAtomIdBTree<T> {
|
|
2191
1799
|
const updated: ChangeAtomIdBTree<T> = newTupleBTree();
|
|
2192
|
-
for (const [[revision,
|
|
2193
|
-
|
|
1800
|
+
for (const [[revision, localId], value] of map.entries()) {
|
|
1801
|
+
const newAtom = replacer.getUpdatedAtomId({ revision, localId });
|
|
1802
|
+
updated.set([newAtom.revision, newAtom.localId], valueMapper(value));
|
|
2194
1803
|
}
|
|
2195
1804
|
|
|
2196
1805
|
return updated;
|
|
@@ -2266,20 +1875,6 @@ function composeBuildsDestroysAndRefreshers(
|
|
|
2266
1875
|
}
|
|
2267
1876
|
}
|
|
2268
1877
|
|
|
2269
|
-
// It's possible to have a build and a refresher for the same root because an attach operation need not be performed in the same changeset as the corresponding build.
|
|
2270
|
-
if (change1.builds !== undefined && change2.refreshers !== undefined) {
|
|
2271
|
-
for (const [key, chunk] of change2.refreshers.entries()) {
|
|
2272
|
-
assert(chunk.topLevelLength === 1, "Expected refresher chunk to have length 1");
|
|
2273
|
-
const match = change1.builds.getPairOrNextLower(key);
|
|
2274
|
-
if (match !== undefined) {
|
|
2275
|
-
const [buildKey, buildChunk] = match;
|
|
2276
|
-
if (buildKey[0] === key[0] && buildKey[1] + buildChunk.topLevelLength > key[1]) {
|
|
2277
|
-
allRefreshers.delete(key);
|
|
2278
|
-
}
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
}
|
|
2282
|
-
|
|
2283
1878
|
return { allBuilds, allDestroys, allRefreshers };
|
|
2284
1879
|
}
|
|
2285
1880
|
|
|
@@ -2311,77 +1906,27 @@ export function* relevantRemovedRoots(
|
|
|
2311
1906
|
change: ModularChangeset,
|
|
2312
1907
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
2313
1908
|
): Iterable<DeltaDetachedNodeId> {
|
|
2314
|
-
|
|
2315
|
-
addAttachesToSet(change, rootIds);
|
|
2316
|
-
addRenamesToSet(change, rootIds);
|
|
2317
|
-
|
|
2318
|
-
for (const [[revision, localId]] of change.rootNodes.nodeChanges.entries()) {
|
|
2319
|
-
rootIds.set({ revision, localId }, 1, true);
|
|
2320
|
-
}
|
|
2321
|
-
|
|
2322
|
-
for (const entry of rootIds.entries()) {
|
|
2323
|
-
for (let offset = 0; offset < entry.length; offset++) {
|
|
2324
|
-
const detachId = offsetChangeAtomId(entry.start, offset);
|
|
2325
|
-
yield makeDetachedNodeId(detachId.revision, detachId.localId);
|
|
2326
|
-
}
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
|
|
2330
|
-
export function* getBuildIds(change: ModularChangeset): Iterable<DeltaDetachedNodeId> {
|
|
2331
|
-
if (change.builds !== undefined) {
|
|
2332
|
-
for (const [[revision, localId]] of change.builds.entries()) {
|
|
2333
|
-
yield makeDetachedNodeId(revision, localId);
|
|
2334
|
-
}
|
|
2335
|
-
}
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
|
-
function addAttachesToSet(
|
|
2339
|
-
change: ModularChangeset,
|
|
2340
|
-
rootIds: ChangeAtomIdRangeMap<boolean>,
|
|
2341
|
-
): void {
|
|
2342
|
-
// This includes each attach which does not have a corresponding detach.
|
|
2343
|
-
for (const entry of change.crossFieldKeys.entries()) {
|
|
2344
|
-
if (entry.start.target !== CrossFieldTarget.Destination) {
|
|
2345
|
-
continue;
|
|
2346
|
-
}
|
|
2347
|
-
|
|
2348
|
-
for (const detachIdEntry of change.rootNodes.newToOldId.getAll2(
|
|
2349
|
-
entry.start,
|
|
2350
|
-
entry.length,
|
|
2351
|
-
)) {
|
|
2352
|
-
const detachId =
|
|
2353
|
-
detachIdEntry.value ?? offsetChangeAtomId(entry.start, detachIdEntry.offset);
|
|
2354
|
-
for (const detachEntry of change.crossFieldKeys.getAll2(
|
|
2355
|
-
{ ...detachId, target: CrossFieldTarget.Source },
|
|
2356
|
-
detachIdEntry.length,
|
|
2357
|
-
)) {
|
|
2358
|
-
if (detachEntry.value === undefined) {
|
|
2359
|
-
rootIds.set(
|
|
2360
|
-
offsetChangeAtomId(detachId, detachEntry.offset),
|
|
2361
|
-
detachEntry.length,
|
|
2362
|
-
true,
|
|
2363
|
-
);
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
1909
|
+
yield* relevantRemovedRootsFromFields(change.fieldChanges, change.nodeChanges, fieldKinds);
|
|
2368
1910
|
}
|
|
2369
1911
|
|
|
2370
|
-
function
|
|
2371
|
-
change:
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
1912
|
+
function* relevantRemovedRootsFromFields(
|
|
1913
|
+
change: FieldChangeMap,
|
|
1914
|
+
nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
|
|
1915
|
+
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
1916
|
+
): Iterable<DeltaDetachedNodeId> {
|
|
1917
|
+
for (const [_, fieldChange] of change) {
|
|
1918
|
+
const handler = getChangeHandler(fieldKinds, fieldChange.fieldKind);
|
|
1919
|
+
const delegate = function* (node: NodeId): Iterable<DeltaDetachedNodeId> {
|
|
1920
|
+
const nodeChangeset = nodeChangeFromId(nodeChanges, node);
|
|
1921
|
+
if (nodeChangeset.fieldChanges !== undefined) {
|
|
1922
|
+
yield* relevantRemovedRootsFromFields(
|
|
1923
|
+
nodeChangeset.fieldChanges,
|
|
1924
|
+
nodeChanges,
|
|
1925
|
+
fieldKinds,
|
|
1926
|
+
);
|
|
2383
1927
|
}
|
|
2384
|
-
}
|
|
1928
|
+
};
|
|
1929
|
+
yield* handler.relevantRemovedRoots(fieldChange.change, delegate);
|
|
2385
1930
|
}
|
|
2386
1931
|
}
|
|
2387
1932
|
|
|
@@ -2441,6 +1986,9 @@ export function updateRefreshers(
|
|
|
2441
1986
|
const {
|
|
2442
1987
|
fieldChanges,
|
|
2443
1988
|
nodeChanges,
|
|
1989
|
+
nodeToParent,
|
|
1990
|
+
nodeAliases,
|
|
1991
|
+
crossFieldKeys,
|
|
2444
1992
|
maxId,
|
|
2445
1993
|
revisions,
|
|
2446
1994
|
constraintViolationCount,
|
|
@@ -2452,10 +2000,9 @@ export function updateRefreshers(
|
|
|
2452
2000
|
return makeModularChangeset({
|
|
2453
2001
|
fieldChanges,
|
|
2454
2002
|
nodeChanges,
|
|
2455
|
-
nodeToParent
|
|
2456
|
-
nodeAliases
|
|
2457
|
-
|
|
2458
|
-
crossFieldKeys: change.crossFieldKeys,
|
|
2003
|
+
nodeToParent,
|
|
2004
|
+
nodeAliases,
|
|
2005
|
+
crossFieldKeys,
|
|
2459
2006
|
maxId: maxId as number,
|
|
2460
2007
|
revisions,
|
|
2461
2008
|
constraintViolationCount,
|
|
@@ -2478,42 +2025,18 @@ export function intoDelta(
|
|
|
2478
2025
|
): DeltaRoot {
|
|
2479
2026
|
const change = taggedChange.change;
|
|
2480
2027
|
const rootDelta: Mutable<DeltaRoot> = {};
|
|
2028
|
+
const global: DeltaDetachedNodeChanges[] = [];
|
|
2029
|
+
const rename: DeltaDetachedNodeRename[] = [];
|
|
2481
2030
|
|
|
2482
2031
|
if (!hasConflicts(change)) {
|
|
2483
2032
|
// If there are no constraint violations, then tree changes apply.
|
|
2484
2033
|
const fieldDeltas = intoDeltaImpl(
|
|
2485
2034
|
change.fieldChanges,
|
|
2486
2035
|
change.nodeChanges,
|
|
2487
|
-
change.nodeAliases,
|
|
2488
2036
|
fieldKinds,
|
|
2037
|
+
global,
|
|
2038
|
+
rename,
|
|
2489
2039
|
);
|
|
2490
|
-
|
|
2491
|
-
const global: DeltaDetachedNodeChanges[] = [];
|
|
2492
|
-
for (const [[major, minor], nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
2493
|
-
global.push({
|
|
2494
|
-
id: { major, minor },
|
|
2495
|
-
fields: deltaFromNodeChange(
|
|
2496
|
-
nodeChangeFromId(change.nodeChanges, change.nodeAliases, nodeId),
|
|
2497
|
-
change.nodeChanges,
|
|
2498
|
-
change.nodeAliases,
|
|
2499
|
-
fieldKinds,
|
|
2500
|
-
),
|
|
2501
|
-
});
|
|
2502
|
-
}
|
|
2503
|
-
|
|
2504
|
-
const rename: DeltaDetachedNodeRename[] = [];
|
|
2505
|
-
for (const {
|
|
2506
|
-
start: oldId,
|
|
2507
|
-
value: newId,
|
|
2508
|
-
length,
|
|
2509
|
-
} of change.rootNodes.oldToNewId.entries()) {
|
|
2510
|
-
rename.push({
|
|
2511
|
-
count: length,
|
|
2512
|
-
oldId: makeDetachedNodeId(oldId.revision, oldId.localId),
|
|
2513
|
-
newId: makeDetachedNodeId(newId.revision, newId.localId),
|
|
2514
|
-
});
|
|
2515
|
-
}
|
|
2516
|
-
|
|
2517
2040
|
if (fieldDeltas.size > 0) {
|
|
2518
2041
|
rootDelta.fields = fieldDeltas;
|
|
2519
2042
|
}
|
|
@@ -2542,7 +2065,6 @@ export function intoDelta(
|
|
|
2542
2065
|
if (change.refreshers && change.refreshers.size > 0) {
|
|
2543
2066
|
rootDelta.refreshers = copyDetachedNodes(change.refreshers);
|
|
2544
2067
|
}
|
|
2545
|
-
|
|
2546
2068
|
return rootDelta;
|
|
2547
2069
|
}
|
|
2548
2070
|
|
|
@@ -2568,22 +2090,29 @@ function copyDetachedNodes(
|
|
|
2568
2090
|
function intoDeltaImpl(
|
|
2569
2091
|
change: FieldChangeMap,
|
|
2570
2092
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
|
|
2571
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
2572
2093
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
2094
|
+
global: DeltaDetachedNodeChanges[],
|
|
2095
|
+
rename: DeltaDetachedNodeRename[],
|
|
2573
2096
|
): Map<FieldKey, DeltaFieldChanges> {
|
|
2574
2097
|
const delta: Map<FieldKey, DeltaFieldChanges> = new Map();
|
|
2575
2098
|
|
|
2576
2099
|
for (const [field, fieldChange] of change) {
|
|
2577
|
-
const
|
|
2100
|
+
const {
|
|
2101
|
+
local: fieldChanges,
|
|
2102
|
+
global: fieldGlobal,
|
|
2103
|
+
rename: fieldRename,
|
|
2104
|
+
} = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(
|
|
2578
2105
|
fieldChange.change,
|
|
2579
2106
|
(childChange): DeltaFieldMap => {
|
|
2580
|
-
const nodeChange = nodeChangeFromId(nodeChanges,
|
|
2581
|
-
return deltaFromNodeChange(nodeChange, nodeChanges,
|
|
2107
|
+
const nodeChange = nodeChangeFromId(nodeChanges, childChange);
|
|
2108
|
+
return deltaFromNodeChange(nodeChange, nodeChanges, fieldKinds, global, rename);
|
|
2582
2109
|
},
|
|
2583
2110
|
);
|
|
2584
|
-
if (
|
|
2585
|
-
delta.set(field,
|
|
2111
|
+
if (fieldChanges !== undefined && fieldChanges.length > 0) {
|
|
2112
|
+
delta.set(field, fieldChanges);
|
|
2586
2113
|
}
|
|
2114
|
+
fieldGlobal?.forEach((c) => global.push(c));
|
|
2115
|
+
fieldRename?.forEach((r) => rename.push(r));
|
|
2587
2116
|
}
|
|
2588
2117
|
return delta;
|
|
2589
2118
|
}
|
|
@@ -2591,11 +2120,12 @@ function intoDeltaImpl(
|
|
|
2591
2120
|
function deltaFromNodeChange(
|
|
2592
2121
|
change: NodeChangeset,
|
|
2593
2122
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
|
|
2594
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
2595
2123
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
2124
|
+
global: DeltaDetachedNodeChanges[],
|
|
2125
|
+
rename: DeltaDetachedNodeRename[],
|
|
2596
2126
|
): DeltaFieldMap {
|
|
2597
2127
|
if (change.fieldChanges !== undefined) {
|
|
2598
|
-
return intoDeltaImpl(change.fieldChanges, nodeChanges,
|
|
2128
|
+
return intoDeltaImpl(change.fieldChanges, nodeChanges, fieldKinds, global, rename);
|
|
2599
2129
|
}
|
|
2600
2130
|
// TODO: update the API to allow undefined to be returned here
|
|
2601
2131
|
return new Map();
|
|
@@ -2660,21 +2190,19 @@ export function getChangeHandler(
|
|
|
2660
2190
|
return getFieldKind(fieldKinds, kind).changeHandler;
|
|
2661
2191
|
}
|
|
2662
2192
|
|
|
2663
|
-
|
|
2664
|
-
|
|
2193
|
+
// TODO: TFieldData could instead just be a numeric ID generated by the CrossFieldTable
|
|
2194
|
+
// The CrossFieldTable could have a generic field ID to context table
|
|
2195
|
+
interface CrossFieldTable<TFieldData> {
|
|
2196
|
+
srcTable: CrossFieldMap<unknown>;
|
|
2197
|
+
dstTable: CrossFieldMap<unknown>;
|
|
2198
|
+
srcDependents: CrossFieldMap<TFieldData>;
|
|
2199
|
+
dstDependents: CrossFieldMap<TFieldData>;
|
|
2200
|
+
invalidatedFields: Set<TFieldData>;
|
|
2201
|
+
}
|
|
2665
2202
|
|
|
2666
|
-
|
|
2667
|
-
entries: CrossFieldMap<NodeId>;
|
|
2203
|
+
interface InvertTable extends CrossFieldTable<FieldChange> {
|
|
2668
2204
|
originalFieldToContext: Map<FieldChange, InvertContext>;
|
|
2669
|
-
invertedNodeToParent: ChangeAtomIdBTree<
|
|
2670
|
-
invertRevision: RevisionTag;
|
|
2671
|
-
invalidatedFields: Set<FieldChange>;
|
|
2672
|
-
invertedRoots: RootNodeTable;
|
|
2673
|
-
|
|
2674
|
-
/**
|
|
2675
|
-
* Maps from attach ID in the inverted changeset to the corresponding detach ID in the base changeset.
|
|
2676
|
-
*/
|
|
2677
|
-
attachToDetachId: ChangeAtomIdRangeMap<ChangeAtomId>;
|
|
2205
|
+
invertedNodeToParent: ChangeAtomIdBTree<FieldId>;
|
|
2678
2206
|
}
|
|
2679
2207
|
|
|
2680
2208
|
interface InvertContext {
|
|
@@ -2682,11 +2210,7 @@ interface InvertContext {
|
|
|
2682
2210
|
invertedField: FieldChange;
|
|
2683
2211
|
}
|
|
2684
2212
|
|
|
2685
|
-
interface RebaseTable {
|
|
2686
|
-
readonly rebaseVersion: RebaseVersion;
|
|
2687
|
-
|
|
2688
|
-
// Entries are keyed on attach ID
|
|
2689
|
-
readonly entries: CrossFieldMap<RebaseDetachedNodeEntry>;
|
|
2213
|
+
interface RebaseTable extends CrossFieldTable<FieldChange> {
|
|
2690
2214
|
readonly baseChange: ModularChangeset;
|
|
2691
2215
|
readonly newChange: ModularChangeset;
|
|
2692
2216
|
|
|
@@ -2695,13 +2219,10 @@ interface RebaseTable {
|
|
|
2695
2219
|
* to the context for the field.
|
|
2696
2220
|
*/
|
|
2697
2221
|
readonly baseFieldToContext: Map<FieldChange, RebaseFieldContext>;
|
|
2698
|
-
readonly baseRoots: RootNodeTable;
|
|
2699
2222
|
readonly baseToRebasedNodeId: ChangeAtomIdBTree<NodeId>;
|
|
2700
2223
|
readonly rebasedFields: Set<FieldChange>;
|
|
2701
|
-
readonly rebasedNodeToParent: ChangeAtomIdBTree<
|
|
2702
|
-
readonly
|
|
2703
|
-
readonly movedDetaches: ChangeAtomIdRangeMap<boolean>;
|
|
2704
|
-
readonly rebasedRootNodes: RootNodeTable;
|
|
2224
|
+
readonly rebasedNodeToParent: ChangeAtomIdBTree<FieldId>;
|
|
2225
|
+
readonly rebasedCrossFieldKeys: CrossFieldKeyTable;
|
|
2705
2226
|
|
|
2706
2227
|
/**
|
|
2707
2228
|
* List of unprocessed (newId, baseId) pairs encountered so far.
|
|
@@ -2715,7 +2236,7 @@ interface RebaseTable {
|
|
|
2715
2236
|
readonly fieldsWithUnattachedChild: Set<FieldChange>;
|
|
2716
2237
|
}
|
|
2717
2238
|
|
|
2718
|
-
|
|
2239
|
+
type FieldIdKey = [RevisionTag | undefined, ChangesetLocalId | undefined, FieldKey];
|
|
2719
2240
|
|
|
2720
2241
|
interface RebaseFieldContext {
|
|
2721
2242
|
baseChange: FieldChange;
|
|
@@ -2727,43 +2248,32 @@ interface RebaseFieldContext {
|
|
|
2727
2248
|
* The set of node IDs in the base changeset which should be included in the rebased field,
|
|
2728
2249
|
* even if there is no corresponding node changeset in the new change.
|
|
2729
2250
|
*/
|
|
2730
|
-
baseNodeIds:
|
|
2251
|
+
baseNodeIds: NodeId[];
|
|
2731
2252
|
}
|
|
2732
2253
|
|
|
2733
2254
|
function newComposeTable(
|
|
2734
2255
|
baseChange: ModularChangeset,
|
|
2735
2256
|
newChange: ModularChangeset,
|
|
2736
|
-
|
|
2737
|
-
movedCrossFieldKeys: CrossFieldKeyTable,
|
|
2738
|
-
removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
|
|
2739
|
-
pendingCompositions: PendingCompositions,
|
|
2257
|
+
composedNodeToParent: ChangeAtomIdBTree<FieldId>,
|
|
2740
2258
|
): ComposeTable {
|
|
2741
2259
|
return {
|
|
2742
|
-
|
|
2743
|
-
baseChange.rebaseVersion,
|
|
2744
|
-
newChange.rebaseVersion,
|
|
2745
|
-
) as RebaseVersion,
|
|
2746
|
-
entries: newDetachedEntryMap(),
|
|
2260
|
+
...newCrossFieldTable<FieldChange>(),
|
|
2747
2261
|
baseChange,
|
|
2748
2262
|
newChange,
|
|
2749
2263
|
fieldToContext: new Map(),
|
|
2750
2264
|
newFieldToBaseField: new Map(),
|
|
2751
2265
|
newToBaseNodeId: newTupleBTree(),
|
|
2752
2266
|
composedNodes: new Set(),
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2267
|
+
composedNodeToParent,
|
|
2268
|
+
pendingCompositions: {
|
|
2269
|
+
nodeIdsToCompose: [],
|
|
2270
|
+
affectedBaseFields: newTupleBTree(),
|
|
2271
|
+
affectedNewFields: newTupleBTree(),
|
|
2272
|
+
},
|
|
2759
2273
|
};
|
|
2760
2274
|
}
|
|
2761
2275
|
|
|
2762
|
-
interface ComposeTable {
|
|
2763
|
-
readonly rebaseVersion: RebaseVersion;
|
|
2764
|
-
|
|
2765
|
-
// Entries are keyed on detach ID
|
|
2766
|
-
readonly entries: ChangeAtomIdRangeMap<DetachedNodeEntry>;
|
|
2276
|
+
interface ComposeTable extends CrossFieldTable<FieldChange> {
|
|
2767
2277
|
readonly baseChange: ModularChangeset;
|
|
2768
2278
|
readonly newChange: ModularChangeset;
|
|
2769
2279
|
|
|
@@ -2774,11 +2284,7 @@ interface ComposeTable {
|
|
|
2774
2284
|
readonly newFieldToBaseField: Map<FieldChange, FieldChange>;
|
|
2775
2285
|
readonly newToBaseNodeId: ChangeAtomIdBTree<NodeId>;
|
|
2776
2286
|
readonly composedNodes: Set<NodeChangeset>;
|
|
2777
|
-
readonly
|
|
2778
|
-
readonly composedRootNodes: RootNodeTable;
|
|
2779
|
-
readonly movedCrossFieldKeys: CrossFieldKeyTable;
|
|
2780
|
-
readonly removedCrossFieldKeys: CrossFieldRangeTable<boolean>;
|
|
2781
|
-
readonly renamesToDelete: ChangeAtomIdRangeMap<boolean>;
|
|
2287
|
+
readonly composedNodeToParent: ChangeAtomIdBTree<FieldId>;
|
|
2782
2288
|
readonly pendingCompositions: PendingCompositions;
|
|
2783
2289
|
}
|
|
2784
2290
|
|
|
@@ -2793,6 +2299,11 @@ interface PendingCompositions {
|
|
|
2793
2299
|
* The set of fields in the base changeset which have been affected by a cross field effect.
|
|
2794
2300
|
*/
|
|
2795
2301
|
readonly affectedBaseFields: BTree<FieldIdKey, true>;
|
|
2302
|
+
|
|
2303
|
+
/**
|
|
2304
|
+
* The set of fields in the new changeset which have been affected by a cross field effect.
|
|
2305
|
+
*/
|
|
2306
|
+
readonly affectedNewFields: BTree<FieldIdKey, true>;
|
|
2796
2307
|
}
|
|
2797
2308
|
|
|
2798
2309
|
interface ComposeFieldContext {
|
|
@@ -2805,6 +2316,16 @@ interface ComposeFieldContext {
|
|
|
2805
2316
|
composedChange: FieldChange;
|
|
2806
2317
|
}
|
|
2807
2318
|
|
|
2319
|
+
function newCrossFieldTable<T>(): CrossFieldTable<T> {
|
|
2320
|
+
return {
|
|
2321
|
+
srcTable: newChangeAtomIdRangeMap(),
|
|
2322
|
+
dstTable: newChangeAtomIdRangeMap(),
|
|
2323
|
+
srcDependents: newChangeAtomIdRangeMap(),
|
|
2324
|
+
dstDependents: newChangeAtomIdRangeMap(),
|
|
2325
|
+
invalidatedFields: new Set(),
|
|
2326
|
+
};
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2808
2329
|
interface ConstraintState {
|
|
2809
2330
|
violationCount: number;
|
|
2810
2331
|
}
|
|
@@ -2815,703 +2336,291 @@ function newConstraintState(violationCount: number): ConstraintState {
|
|
|
2815
2336
|
};
|
|
2816
2337
|
}
|
|
2817
2338
|
|
|
2818
|
-
class
|
|
2339
|
+
abstract class CrossFieldManagerI<T> implements CrossFieldManager {
|
|
2819
2340
|
public constructor(
|
|
2820
|
-
|
|
2821
|
-
private readonly
|
|
2341
|
+
protected readonly crossFieldTable: CrossFieldTable<T>,
|
|
2342
|
+
private readonly currentFieldKey: T,
|
|
2343
|
+
protected readonly allowInval = true,
|
|
2822
2344
|
) {}
|
|
2823
2345
|
|
|
2824
|
-
public
|
|
2825
|
-
|
|
2346
|
+
public set(
|
|
2347
|
+
target: CrossFieldTarget,
|
|
2348
|
+
revision: RevisionTag | undefined,
|
|
2349
|
+
id: ChangesetLocalId,
|
|
2826
2350
|
count: number,
|
|
2827
|
-
|
|
2828
|
-
|
|
2351
|
+
newValue: unknown,
|
|
2352
|
+
invalidateDependents: boolean,
|
|
2829
2353
|
): void {
|
|
2830
|
-
if (
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
const attachFieldEntry = this.table.change.crossFieldKeys.getFirst(
|
|
2840
|
-
{ target: CrossFieldTarget.Destination, ...attachEntry.value },
|
|
2841
|
-
count,
|
|
2842
|
-
);
|
|
2843
|
-
|
|
2844
|
-
if (attachFieldEntry.value !== undefined) {
|
|
2845
|
-
setInCrossFieldMap(this.table.entries, attachEntry.value, count, nodeChange);
|
|
2846
|
-
this.table.invalidatedFields.add(
|
|
2847
|
-
fieldChangeFromId(this.table.change, attachFieldEntry.value),
|
|
2848
|
-
);
|
|
2849
|
-
} else {
|
|
2850
|
-
assignRootChange(
|
|
2851
|
-
this.table.invertedRoots,
|
|
2852
|
-
this.table.invertedNodeToParent,
|
|
2853
|
-
attachEntry.value,
|
|
2854
|
-
nodeChange,
|
|
2855
|
-
this.fieldId,
|
|
2856
|
-
this.table.change.rebaseVersion,
|
|
2354
|
+
if (invalidateDependents && this.allowInval) {
|
|
2355
|
+
const lastChangedId = (id as number) + count - 1;
|
|
2356
|
+
let firstId = id;
|
|
2357
|
+
while (firstId <= lastChangedId) {
|
|
2358
|
+
const dependentEntry = getFirstFromCrossFieldMap(
|
|
2359
|
+
this.getDependents(target),
|
|
2360
|
+
revision,
|
|
2361
|
+
firstId,
|
|
2362
|
+
lastChangedId - firstId + 1,
|
|
2857
2363
|
);
|
|
2364
|
+
if (dependentEntry.value !== undefined) {
|
|
2365
|
+
this.crossFieldTable.invalidatedFields.add(dependentEntry.value);
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
firstId = brand(firstId + dependentEntry.length);
|
|
2858
2369
|
}
|
|
2859
2370
|
}
|
|
2371
|
+
setInCrossFieldMap(this.getMap(target), revision, id, count, newValue);
|
|
2372
|
+
}
|
|
2860
2373
|
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2374
|
+
public get(
|
|
2375
|
+
target: CrossFieldTarget,
|
|
2376
|
+
revision: RevisionTag | undefined,
|
|
2377
|
+
id: ChangesetLocalId,
|
|
2378
|
+
count: number,
|
|
2379
|
+
addDependency: boolean,
|
|
2380
|
+
): RangeQueryResult<ChangeAtomId, unknown> {
|
|
2381
|
+
if (addDependency) {
|
|
2382
|
+
// We assume that if there is already an entry for this ID it is because
|
|
2383
|
+
// a field handler has called compose on the same node multiple times.
|
|
2384
|
+
// In this case we only want to update the latest version, so we overwrite the dependency.
|
|
2385
|
+
setInCrossFieldMap(
|
|
2386
|
+
this.getDependents(target),
|
|
2387
|
+
revision,
|
|
2388
|
+
id,
|
|
2865
2389
|
count,
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
this.table.attachToDetachId.set(newAttachId, count, detachId);
|
|
2869
|
-
this.table.invertedRoots.detachLocations.set(detachId, count, this.fieldId);
|
|
2870
|
-
}
|
|
2871
|
-
}
|
|
2390
|
+
this.currentFieldKey,
|
|
2391
|
+
);
|
|
2872
2392
|
}
|
|
2393
|
+
return getFirstFromCrossFieldMap(this.getMap(target), revision, id, count);
|
|
2873
2394
|
}
|
|
2874
2395
|
|
|
2875
|
-
public
|
|
2876
|
-
|
|
2396
|
+
public abstract onMoveIn(id: NodeId): void;
|
|
2397
|
+
|
|
2398
|
+
public abstract moveKey(
|
|
2399
|
+
target: CrossFieldTarget,
|
|
2400
|
+
revision: RevisionTag | undefined,
|
|
2401
|
+
id: ChangesetLocalId,
|
|
2877
2402
|
count: number,
|
|
2878
|
-
):
|
|
2879
|
-
let countToProcess = count;
|
|
2403
|
+
): void;
|
|
2880
2404
|
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2405
|
+
private getMap(target: CrossFieldTarget): CrossFieldMap<unknown> {
|
|
2406
|
+
return target === CrossFieldTarget.Source
|
|
2407
|
+
? this.crossFieldTable.srcTable
|
|
2408
|
+
: this.crossFieldTable.dstTable;
|
|
2409
|
+
}
|
|
2886
2410
|
|
|
2887
|
-
|
|
2411
|
+
private getDependents(target: CrossFieldTarget): CrossFieldMap<T> {
|
|
2412
|
+
return target === CrossFieldTarget.Source
|
|
2413
|
+
? this.crossFieldTable.srcDependents
|
|
2414
|
+
: this.crossFieldTable.dstDependents;
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2888
2417
|
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2418
|
+
class InvertManager extends CrossFieldManagerI<FieldChange> {
|
|
2419
|
+
public constructor(
|
|
2420
|
+
table: InvertTable,
|
|
2421
|
+
field: FieldChange,
|
|
2422
|
+
private readonly fieldId: FieldId,
|
|
2423
|
+
allowInval = true,
|
|
2424
|
+
) {
|
|
2425
|
+
super(table, field, allowInval);
|
|
2426
|
+
}
|
|
2895
2427
|
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
result = { ...moveEntry, value: { nodeChange: moveEntry.value } };
|
|
2900
|
-
} else {
|
|
2901
|
-
// This node is detached in the input context of the original change.
|
|
2902
|
-
const nodeIdEntry = rangeQueryChangeAtomIdMap(
|
|
2903
|
-
this.table.change.rootNodes.nodeChanges,
|
|
2904
|
-
detachIdEntry.value,
|
|
2905
|
-
countToProcess,
|
|
2906
|
-
);
|
|
2428
|
+
public override onMoveIn(id: ChangeAtomId): void {
|
|
2429
|
+
setInChangeAtomIdMap(this.table.invertedNodeToParent, id, this.fieldId);
|
|
2430
|
+
}
|
|
2907
2431
|
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2432
|
+
public override moveKey(
|
|
2433
|
+
target: CrossFieldTarget,
|
|
2434
|
+
revision: RevisionTag | undefined,
|
|
2435
|
+
id: ChangesetLocalId,
|
|
2436
|
+
count: number,
|
|
2437
|
+
): void {
|
|
2438
|
+
assert(false, 0x9c5 /* Keys should not be moved manually during invert */);
|
|
2439
|
+
}
|
|
2914
2440
|
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
field: this.fieldId,
|
|
2918
|
-
});
|
|
2919
|
-
}
|
|
2920
|
-
return result;
|
|
2441
|
+
private get table(): InvertTable {
|
|
2442
|
+
return this.crossFieldTable as InvertTable;
|
|
2921
2443
|
}
|
|
2922
2444
|
}
|
|
2923
2445
|
|
|
2924
|
-
class
|
|
2446
|
+
class RebaseManager extends CrossFieldManagerI<FieldChange> {
|
|
2925
2447
|
public constructor(
|
|
2926
|
-
|
|
2448
|
+
table: RebaseTable,
|
|
2449
|
+
currentField: FieldChange,
|
|
2927
2450
|
private readonly fieldId: FieldId,
|
|
2928
|
-
|
|
2929
|
-
) {
|
|
2930
|
-
|
|
2931
|
-
public getNewChangesForBaseAttach(
|
|
2932
|
-
baseAttachId: ChangeAtomId,
|
|
2933
|
-
count: number,
|
|
2934
|
-
): RangeQueryResult<RebaseDetachedNodeEntry | undefined> {
|
|
2935
|
-
let countToProcess = count;
|
|
2936
|
-
|
|
2937
|
-
const detachEntry = firstDetachIdFromAttachId(
|
|
2938
|
-
this.table.baseChange.rootNodes,
|
|
2939
|
-
baseAttachId,
|
|
2940
|
-
countToProcess,
|
|
2941
|
-
);
|
|
2942
|
-
|
|
2943
|
-
countToProcess = detachEntry.length;
|
|
2944
|
-
|
|
2945
|
-
const nodeEntry = rangeQueryChangeAtomIdMap(
|
|
2946
|
-
this.table.newChange.rootNodes.nodeChanges,
|
|
2947
|
-
detachEntry.value,
|
|
2948
|
-
countToProcess,
|
|
2949
|
-
);
|
|
2950
|
-
|
|
2951
|
-
countToProcess = nodeEntry.length;
|
|
2952
|
-
const newNodeId = nodeEntry.value;
|
|
2953
|
-
|
|
2954
|
-
const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(
|
|
2955
|
-
detachEntry.value,
|
|
2956
|
-
countToProcess,
|
|
2957
|
-
);
|
|
2958
|
-
|
|
2959
|
-
countToProcess = newRenameEntry.length;
|
|
2960
|
-
|
|
2961
|
-
let result: RangeQueryResult<DetachedNodeEntry | undefined>;
|
|
2962
|
-
// eslint-disable-next-line unicorn/prefer-ternary
|
|
2963
|
-
if (newNodeId !== undefined || newRenameEntry.value !== undefined) {
|
|
2964
|
-
result = {
|
|
2965
|
-
...newRenameEntry,
|
|
2966
|
-
value: { detachId: newRenameEntry.value, nodeChange: newNodeId },
|
|
2967
|
-
};
|
|
2968
|
-
} else {
|
|
2969
|
-
// This handles the case where the base changeset has moved these nodes,
|
|
2970
|
-
// meaning they were attached in the input context of the base changeset.
|
|
2971
|
-
result = this.table.entries.getFirst(baseAttachId, countToProcess);
|
|
2972
|
-
}
|
|
2973
|
-
|
|
2974
|
-
// TODO: Consider moving these two checks into a separate method so that this function has no side effects.
|
|
2975
|
-
if (result.value?.detachId !== undefined) {
|
|
2976
|
-
this.table.rebasedDetachLocations.set(
|
|
2977
|
-
result.value.detachId,
|
|
2978
|
-
result.length,
|
|
2979
|
-
this.fieldId,
|
|
2980
|
-
);
|
|
2981
|
-
}
|
|
2982
|
-
|
|
2983
|
-
if (result.value?.nodeChange !== undefined) {
|
|
2984
|
-
setInChangeAtomIdMap(this.table.rebasedNodeToParent, result.value.nodeChange, {
|
|
2985
|
-
field: this.fieldId,
|
|
2986
|
-
});
|
|
2987
|
-
}
|
|
2988
|
-
|
|
2989
|
-
return result;
|
|
2451
|
+
allowInval = true,
|
|
2452
|
+
) {
|
|
2453
|
+
super(table, currentField, allowInval);
|
|
2990
2454
|
}
|
|
2991
2455
|
|
|
2992
|
-
public
|
|
2993
|
-
|
|
2456
|
+
public override set(
|
|
2457
|
+
target: CrossFieldTarget,
|
|
2458
|
+
revision: RevisionTag | undefined,
|
|
2459
|
+
id: ChangesetLocalId,
|
|
2994
2460
|
count: number,
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
cellRename?: ChangeAtomId,
|
|
2461
|
+
newValue: unknown,
|
|
2462
|
+
invalidateDependents: boolean,
|
|
2998
2463
|
): void {
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
this.table.baseChange,
|
|
3010
|
-
{ ...baseAttachId, target: CrossFieldTarget.Destination },
|
|
3011
|
-
countToProcess,
|
|
3012
|
-
);
|
|
3013
|
-
countToProcess = attachFieldEntry.length;
|
|
2464
|
+
if (invalidateDependents && this.allowInval) {
|
|
2465
|
+
const newFieldIds = getFieldsForCrossFieldKey(
|
|
2466
|
+
this.table.newChange,
|
|
2467
|
+
{
|
|
2468
|
+
target,
|
|
2469
|
+
revision,
|
|
2470
|
+
localId: id,
|
|
2471
|
+
},
|
|
2472
|
+
count,
|
|
2473
|
+
);
|
|
3014
2474
|
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
countToProcess = detachedMoveEntry.length;
|
|
3020
|
-
|
|
3021
|
-
const destinationField = attachFieldEntry.value ?? detachedMoveEntry.value;
|
|
3022
|
-
if (destinationField !== undefined) {
|
|
3023
|
-
// The base detach is part of a move (or move of detach location) in the base changeset.
|
|
3024
|
-
setInCrossFieldMap(this.table.entries, baseAttachId, countToProcess, {
|
|
3025
|
-
nodeChange,
|
|
3026
|
-
detachId: newDetachId,
|
|
3027
|
-
cellRename,
|
|
3028
|
-
});
|
|
2475
|
+
assert(
|
|
2476
|
+
newFieldIds.length === 0,
|
|
2477
|
+
0x9c6 /* TODO: Modifying a cross-field key from the new changeset is currently unsupported */,
|
|
2478
|
+
);
|
|
3029
2479
|
|
|
3030
|
-
|
|
3031
|
-
this.
|
|
3032
|
-
|
|
3033
|
-
|
|
2480
|
+
const baseFieldIds = getFieldsForCrossFieldKey(
|
|
2481
|
+
this.table.baseChange,
|
|
2482
|
+
{
|
|
2483
|
+
target,
|
|
2484
|
+
revision,
|
|
2485
|
+
localId: id,
|
|
2486
|
+
},
|
|
2487
|
+
count,
|
|
2488
|
+
);
|
|
3034
2489
|
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
this.table.rebasedRootNodes,
|
|
3040
|
-
this.table.rebasedNodeToParent,
|
|
3041
|
-
baseAttachId,
|
|
3042
|
-
nodeChange,
|
|
3043
|
-
this.fieldId,
|
|
3044
|
-
this.table.rebaseVersion,
|
|
3045
|
-
);
|
|
3046
|
-
}
|
|
2490
|
+
assert(
|
|
2491
|
+
baseFieldIds.length > 0,
|
|
2492
|
+
0x9c7 /* Cross field key not registered in base or new change */,
|
|
2493
|
+
);
|
|
3047
2494
|
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
newDetachId,
|
|
3053
|
-
countToProcess,
|
|
3054
|
-
this.fieldId,
|
|
2495
|
+
for (const baseFieldId of baseFieldIds) {
|
|
2496
|
+
this.table.affectedBaseFields.set(
|
|
2497
|
+
[baseFieldId.nodeId?.revision, baseFieldId.nodeId?.localId, baseFieldId.field],
|
|
2498
|
+
true,
|
|
3055
2499
|
);
|
|
3056
2500
|
}
|
|
3057
2501
|
}
|
|
3058
2502
|
|
|
3059
|
-
|
|
3060
|
-
this.table.movedDetaches.set(newDetachId, countToProcess, true);
|
|
3061
|
-
}
|
|
3062
|
-
|
|
3063
|
-
if (countToProcess < count) {
|
|
3064
|
-
const remainingCount = count - countToProcess;
|
|
3065
|
-
|
|
3066
|
-
const nextDetachId =
|
|
3067
|
-
newDetachId !== undefined
|
|
3068
|
-
? offsetChangeAtomId(newDetachId, countToProcess)
|
|
3069
|
-
: undefined;
|
|
3070
|
-
|
|
3071
|
-
this.rebaseOverDetach(
|
|
3072
|
-
offsetChangeAtomId(baseDetachId, countToProcess),
|
|
3073
|
-
remainingCount,
|
|
3074
|
-
nextDetachId,
|
|
3075
|
-
nodeChange,
|
|
3076
|
-
);
|
|
3077
|
-
}
|
|
3078
|
-
}
|
|
3079
|
-
|
|
3080
|
-
public addDetach(id: ChangeAtomId, count: number): void {
|
|
3081
|
-
this.table.rebasedDetachLocations.set(id, count, this.fieldId);
|
|
3082
|
-
}
|
|
3083
|
-
|
|
3084
|
-
public removeDetach(id: ChangeAtomId, count: number): void {
|
|
3085
|
-
this.table.movedDetaches.set(id, count, true);
|
|
3086
|
-
}
|
|
3087
|
-
|
|
3088
|
-
public doesBaseAttachNodes(
|
|
3089
|
-
id: ChangeAtomId,
|
|
3090
|
-
count: number,
|
|
3091
|
-
): RangeQueryEntry<ChangeAtomId, boolean> {
|
|
3092
|
-
let countToProcess = count;
|
|
3093
|
-
const attachEntry = getFirstAttachField(
|
|
3094
|
-
this.table.baseChange.crossFieldKeys,
|
|
3095
|
-
id,
|
|
3096
|
-
countToProcess,
|
|
3097
|
-
);
|
|
3098
|
-
|
|
3099
|
-
countToProcess = attachEntry.length;
|
|
3100
|
-
return { start: id, value: attachEntry.value !== undefined, length: countToProcess };
|
|
2503
|
+
super.set(target, revision, id, count, newValue, invalidateDependents);
|
|
3101
2504
|
}
|
|
3102
2505
|
|
|
3103
|
-
public
|
|
3104
|
-
id
|
|
3105
|
-
count: number,
|
|
3106
|
-
): RangeQueryResult<ChangeAtomId | undefined> {
|
|
3107
|
-
return this.table.baseChange.rootNodes.oldToNewId.getFirst(id, count);
|
|
2506
|
+
public override onMoveIn(id: ChangeAtomId): void {
|
|
2507
|
+
setInChangeAtomIdMap(this.table.rebasedNodeToParent, id, this.fieldId);
|
|
3108
2508
|
}
|
|
3109
2509
|
|
|
3110
|
-
public
|
|
3111
|
-
|
|
2510
|
+
public override moveKey(
|
|
2511
|
+
target: CrossFieldTarget,
|
|
2512
|
+
revision: RevisionTag | undefined,
|
|
2513
|
+
id: ChangesetLocalId,
|
|
3112
2514
|
count: number,
|
|
3113
|
-
):
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
countToProcess,
|
|
3119
|
-
);
|
|
3120
|
-
|
|
3121
|
-
const attachEntry = getFirstAttachField(
|
|
3122
|
-
this.table.baseChange.crossFieldKeys,
|
|
3123
|
-
baseRenameTo,
|
|
3124
|
-
countToProcess,
|
|
2515
|
+
): void {
|
|
2516
|
+
this.table.rebasedCrossFieldKeys.set(
|
|
2517
|
+
{ target, revision, localId: id },
|
|
2518
|
+
count,
|
|
2519
|
+
this.fieldId,
|
|
3125
2520
|
);
|
|
3126
|
-
|
|
3127
|
-
countToProcess = attachEntry.length;
|
|
3128
|
-
if (attachEntry.value !== undefined) {
|
|
3129
|
-
// These nodes are attached in the output context of the base changeset.
|
|
3130
|
-
return { value: undefined, length: countToProcess };
|
|
3131
|
-
}
|
|
3132
|
-
|
|
3133
|
-
countToProcess = inputEntry.length;
|
|
3134
|
-
const inputId = inputEntry.value;
|
|
3135
|
-
|
|
3136
|
-
const moveEntry = this.table.entries.getFirst(inputId, countToProcess);
|
|
3137
|
-
|
|
3138
|
-
countToProcess = moveEntry.length;
|
|
3139
|
-
if (moveEntry.value !== undefined) {
|
|
3140
|
-
return { ...moveEntry, value: moveEntry.value.cellRename ?? moveEntry.value.detachId };
|
|
3141
|
-
}
|
|
3142
|
-
|
|
3143
|
-
return this.table.newChange.rootNodes.oldToNewId.getFirst(inputId, countToProcess);
|
|
3144
|
-
}
|
|
3145
|
-
|
|
3146
|
-
private invalidateBaseFields(fields: FieldId[]): void {
|
|
3147
|
-
if (this.allowInval) {
|
|
3148
|
-
for (const fieldId of fields) {
|
|
3149
|
-
this.table.affectedBaseFields.set(fieldIdKeyFromFieldId(fieldId), true);
|
|
3150
|
-
}
|
|
3151
|
-
}
|
|
3152
2521
|
}
|
|
3153
|
-
}
|
|
3154
|
-
|
|
3155
|
-
function assignRootChange(
|
|
3156
|
-
table: RootNodeTable,
|
|
3157
|
-
nodeToParent: ChangeAtomIdBTree<NodeLocation> | undefined,
|
|
3158
|
-
detachId: ChangeAtomId,
|
|
3159
|
-
nodeId: NodeId,
|
|
3160
|
-
detachLocation: FieldId | undefined,
|
|
3161
|
-
rebaseVersion: RebaseVersion,
|
|
3162
|
-
): void {
|
|
3163
|
-
assert(
|
|
3164
|
-
rebaseVersion >= 2 || detachLocation !== undefined,
|
|
3165
|
-
"All root changes need a detach location to support compatibility with older client versions",
|
|
3166
|
-
);
|
|
3167
|
-
|
|
3168
|
-
setInChangeAtomIdMap(table.nodeChanges, detachId, nodeId);
|
|
3169
2522
|
|
|
3170
|
-
|
|
3171
|
-
|
|
2523
|
+
private get table(): RebaseTable {
|
|
2524
|
+
return this.crossFieldTable as RebaseTable;
|
|
3172
2525
|
}
|
|
3173
|
-
|
|
3174
|
-
table.detachLocations.set(detachId, 1, detachLocation);
|
|
3175
2526
|
}
|
|
3176
2527
|
|
|
3177
|
-
|
|
2528
|
+
// TODO: Deduplicate this with RebaseTable
|
|
2529
|
+
class ComposeManager extends CrossFieldManagerI<FieldChange> {
|
|
3178
2530
|
public constructor(
|
|
3179
|
-
|
|
2531
|
+
table: ComposeTable,
|
|
2532
|
+
currentField: FieldChange,
|
|
3180
2533
|
private readonly fieldId: FieldId,
|
|
3181
|
-
|
|
3182
|
-
) {
|
|
3183
|
-
|
|
3184
|
-
public getNewChangesForBaseDetach(
|
|
3185
|
-
baseDetachId: ChangeAtomId,
|
|
3186
|
-
count: number,
|
|
3187
|
-
): RangeQueryResult<DetachedNodeEntry | undefined> {
|
|
3188
|
-
let countToProcess = count;
|
|
3189
|
-
|
|
3190
|
-
const baseAttachEntry = getFirstFieldForCrossFieldKey(
|
|
3191
|
-
this.table.baseChange,
|
|
3192
|
-
{ target: CrossFieldTarget.Destination, ...baseDetachId },
|
|
3193
|
-
countToProcess,
|
|
3194
|
-
);
|
|
3195
|
-
|
|
3196
|
-
countToProcess = baseAttachEntry.length;
|
|
3197
|
-
|
|
3198
|
-
let result: RangeQueryResult<DetachedNodeEntry | undefined>;
|
|
3199
|
-
if (baseAttachEntry.value !== undefined) {
|
|
3200
|
-
// The base detach was part of a move.
|
|
3201
|
-
// We check if we've previously seen a node change at the move destination.
|
|
3202
|
-
const entry = this.table.entries.getFirst(baseDetachId, countToProcess);
|
|
3203
|
-
result = { value: entry.value, length: entry.length };
|
|
3204
|
-
} else {
|
|
3205
|
-
// The detached nodes are still detached in the new change's input context.
|
|
3206
|
-
const rootEntry = rangeQueryChangeAtomIdMap(
|
|
3207
|
-
this.table.newChange.rootNodes.nodeChanges,
|
|
3208
|
-
baseDetachId,
|
|
3209
|
-
countToProcess,
|
|
3210
|
-
);
|
|
3211
|
-
|
|
3212
|
-
countToProcess = rootEntry.length;
|
|
3213
|
-
|
|
3214
|
-
const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(
|
|
3215
|
-
baseDetachId,
|
|
3216
|
-
countToProcess,
|
|
3217
|
-
);
|
|
3218
|
-
|
|
3219
|
-
countToProcess = newRenameEntry.length;
|
|
3220
|
-
|
|
3221
|
-
result = {
|
|
3222
|
-
value: { nodeChange: rootEntry.value, detachId: newRenameEntry.value },
|
|
3223
|
-
length: countToProcess,
|
|
3224
|
-
};
|
|
3225
|
-
}
|
|
3226
|
-
|
|
3227
|
-
// TODO: Consider moving this to a separate method so that this method can be side-effect free.
|
|
3228
|
-
if (result.value?.nodeChange !== undefined) {
|
|
3229
|
-
setInChangeAtomIdMap(this.table.movedNodeToParent, result.value.nodeChange, {
|
|
3230
|
-
field: this.fieldId,
|
|
3231
|
-
});
|
|
3232
|
-
}
|
|
3233
|
-
|
|
3234
|
-
return result;
|
|
2534
|
+
allowInval = true,
|
|
2535
|
+
) {
|
|
2536
|
+
super(table, currentField, allowInval);
|
|
3235
2537
|
}
|
|
3236
2538
|
|
|
3237
|
-
public
|
|
3238
|
-
|
|
3239
|
-
|
|
2539
|
+
public override set(
|
|
2540
|
+
target: CrossFieldTarget,
|
|
2541
|
+
revision: RevisionTag | undefined,
|
|
2542
|
+
id: ChangesetLocalId,
|
|
3240
2543
|
count: number,
|
|
2544
|
+
newValue: unknown,
|
|
2545
|
+
invalidateDependents: boolean,
|
|
3241
2546
|
): void {
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
// Both changes can have the same ID if they came from inverse changesets.
|
|
3253
|
-
// If the new detach is part of a move,
|
|
3254
|
-
// then both input changesets contain the attach cross-field key for this ID.
|
|
3255
|
-
// The new attach may still exist in the composed changeset so we do not remove it here.
|
|
3256
|
-
// The new attach will typically cancel with a base detach,
|
|
3257
|
-
// in which case the cross-field key will be removed in `composeDetachAttach`.
|
|
3258
|
-
const hasNewAttachWithBaseAttachId =
|
|
3259
|
-
areEqualChangeAtomIds(baseAttachId, newDetachId) && newAttachEntry.value !== undefined;
|
|
3260
|
-
|
|
3261
|
-
if (!hasNewAttachWithBaseAttachId) {
|
|
3262
|
-
this.table.removedCrossFieldKeys.set(
|
|
3263
|
-
{ ...baseAttachId, target: CrossFieldTarget.Destination },
|
|
3264
|
-
countToProcess,
|
|
3265
|
-
true,
|
|
2547
|
+
if (invalidateDependents && this.allowInval) {
|
|
2548
|
+
const newFieldIds = getFieldsForCrossFieldKey(
|
|
2549
|
+
this.table.newChange,
|
|
2550
|
+
{
|
|
2551
|
+
target,
|
|
2552
|
+
revision,
|
|
2553
|
+
localId: id,
|
|
2554
|
+
},
|
|
2555
|
+
count,
|
|
3266
2556
|
);
|
|
3267
|
-
}
|
|
3268
|
-
|
|
3269
|
-
const baseDetachEntry = getFirstDetachField(
|
|
3270
|
-
this.table.baseChange.crossFieldKeys,
|
|
3271
|
-
baseAttachId,
|
|
3272
|
-
countToProcess,
|
|
3273
|
-
);
|
|
3274
|
-
|
|
3275
|
-
countToProcess = baseDetachEntry.length;
|
|
3276
|
-
|
|
3277
|
-
const baseRootIdEntry = firstDetachIdFromAttachId(
|
|
3278
|
-
this.table.baseChange.rootNodes,
|
|
3279
|
-
baseAttachId,
|
|
3280
|
-
countToProcess,
|
|
3281
|
-
);
|
|
3282
|
-
countToProcess = baseRootIdEntry.length;
|
|
3283
|
-
|
|
3284
|
-
const baseDetachId = baseRootIdEntry.value;
|
|
3285
|
-
|
|
3286
|
-
if (baseDetachEntry.value !== undefined) {
|
|
3287
|
-
// The base change moves these nodes.
|
|
3288
|
-
const prevEntry =
|
|
3289
|
-
this.table.entries.getFirst(baseAttachId, baseDetachEntry.length).value ?? {};
|
|
3290
2557
|
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
2558
|
+
if (newFieldIds.length > 0) {
|
|
2559
|
+
for (const newFieldId of newFieldIds) {
|
|
2560
|
+
this.table.pendingCompositions.affectedNewFields.set(
|
|
2561
|
+
[newFieldId.nodeId?.revision, newFieldId.nodeId?.localId, newFieldId.field],
|
|
2562
|
+
true,
|
|
2563
|
+
);
|
|
2564
|
+
}
|
|
2565
|
+
} else {
|
|
2566
|
+
const baseFieldIds = getFieldsForCrossFieldKey(
|
|
2567
|
+
this.table.baseChange,
|
|
2568
|
+
{
|
|
2569
|
+
target,
|
|
2570
|
+
revision,
|
|
2571
|
+
localId: id,
|
|
2572
|
+
},
|
|
2573
|
+
count,
|
|
3302
2574
|
);
|
|
3303
|
-
}
|
|
3304
2575
|
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
baseDetachEntry.value,
|
|
3309
|
-
);
|
|
3310
|
-
|
|
3311
|
-
this.invalidateBaseFields([baseDetachEntry.value]);
|
|
3312
|
-
} else {
|
|
3313
|
-
const baseDetachLocationEntry = this.table.baseChange.rootNodes.detachLocations.getFirst(
|
|
3314
|
-
baseDetachId,
|
|
3315
|
-
countToProcess,
|
|
3316
|
-
);
|
|
3317
|
-
countToProcess = baseDetachLocationEntry.length;
|
|
3318
|
-
|
|
3319
|
-
// These nodes were detached in the base change's input context,
|
|
3320
|
-
// so the net effect of the two changes is a rename.
|
|
3321
|
-
appendNodeRename(
|
|
3322
|
-
this.table.composedRootNodes,
|
|
3323
|
-
baseAttachId,
|
|
3324
|
-
newDetachId,
|
|
3325
|
-
baseDetachEntry.length,
|
|
3326
|
-
this.table.baseChange.rootNodes,
|
|
3327
|
-
baseDetachLocationEntry.value ?? this.fieldId,
|
|
3328
|
-
);
|
|
3329
|
-
|
|
3330
|
-
this.table.removedCrossFieldKeys.set(
|
|
3331
|
-
{ ...newDetachId, target: CrossFieldTarget.Source },
|
|
3332
|
-
countToProcess,
|
|
3333
|
-
true,
|
|
3334
|
-
);
|
|
3335
|
-
}
|
|
3336
|
-
|
|
3337
|
-
if (newAttachEntry.value === undefined) {
|
|
3338
|
-
const newOutputDetachLocationEntry =
|
|
3339
|
-
this.table.newChange.rootNodes.outputDetachLocations.getFirst(
|
|
3340
|
-
newDetachId,
|
|
3341
|
-
countToProcess,
|
|
2576
|
+
assert(
|
|
2577
|
+
baseFieldIds.length > 0,
|
|
2578
|
+
0x9c8 /* Cross field key not registered in base or new change */,
|
|
3342
2579
|
);
|
|
3343
2580
|
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
);
|
|
3351
|
-
}
|
|
3352
|
-
|
|
3353
|
-
if (countToProcess < count) {
|
|
3354
|
-
const remainingCount = count - countToProcess;
|
|
3355
|
-
this.composeAttachDetach(
|
|
3356
|
-
offsetChangeAtomId(baseAttachId, countToProcess),
|
|
3357
|
-
offsetChangeAtomId(newDetachId, countToProcess),
|
|
3358
|
-
remainingCount,
|
|
3359
|
-
);
|
|
3360
|
-
}
|
|
3361
|
-
}
|
|
3362
|
-
|
|
3363
|
-
public sendNewChangesToBaseSourceLocation(
|
|
3364
|
-
baseAttachId: ChangeAtomId,
|
|
3365
|
-
newChanges: NodeId,
|
|
3366
|
-
): void {
|
|
3367
|
-
const { value: baseDetachId } = firstDetachIdFromAttachId(
|
|
3368
|
-
this.table.baseChange.rootNodes,
|
|
3369
|
-
baseAttachId,
|
|
3370
|
-
1,
|
|
3371
|
-
);
|
|
3372
|
-
|
|
3373
|
-
const detachFields = getFieldsForCrossFieldKey(
|
|
3374
|
-
this.table.baseChange,
|
|
3375
|
-
{
|
|
3376
|
-
...baseDetachId,
|
|
3377
|
-
target: CrossFieldTarget.Source,
|
|
3378
|
-
},
|
|
3379
|
-
1,
|
|
3380
|
-
);
|
|
3381
|
-
|
|
3382
|
-
if (detachFields.length > 0) {
|
|
3383
|
-
// The base attach is part of a move in the base changeset.
|
|
3384
|
-
const prevEntry = this.table.entries.getFirst(baseDetachId, 1).value ?? {};
|
|
3385
|
-
this.table.entries.set(baseDetachId, 1, { ...prevEntry, nodeChange: newChanges });
|
|
3386
|
-
|
|
3387
|
-
if (newChanges !== undefined) {
|
|
3388
|
-
this.invalidateBaseFields(detachFields);
|
|
3389
|
-
}
|
|
3390
|
-
} else {
|
|
3391
|
-
const baseNodeId = getFromChangeAtomIdMap(
|
|
3392
|
-
this.table.baseChange.rootNodes.nodeChanges,
|
|
3393
|
-
baseDetachId,
|
|
3394
|
-
);
|
|
3395
|
-
|
|
3396
|
-
if (baseNodeId !== undefined) {
|
|
3397
|
-
addNodesToCompose(this.table, baseNodeId, newChanges);
|
|
3398
|
-
} else {
|
|
3399
|
-
assignRootChange(
|
|
3400
|
-
this.table.composedRootNodes,
|
|
3401
|
-
this.table.movedNodeToParent,
|
|
3402
|
-
baseDetachId,
|
|
3403
|
-
newChanges,
|
|
3404
|
-
this.fieldId,
|
|
3405
|
-
this.table.rebaseVersion,
|
|
3406
|
-
);
|
|
2581
|
+
for (const baseFieldId of baseFieldIds) {
|
|
2582
|
+
this.table.pendingCompositions.affectedBaseFields.set(
|
|
2583
|
+
[baseFieldId.nodeId?.revision, baseFieldId.nodeId?.localId, baseFieldId.field],
|
|
2584
|
+
true,
|
|
2585
|
+
);
|
|
2586
|
+
}
|
|
3407
2587
|
}
|
|
3408
2588
|
}
|
|
3409
|
-
}
|
|
3410
2589
|
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
newAttachId: ChangeAtomId,
|
|
3414
|
-
count: number,
|
|
3415
|
-
): RangeQueryResult<boolean> {
|
|
3416
|
-
const renamedDetachEntry = firstAttachIdFromDetachId(
|
|
3417
|
-
this.table.composedRootNodes,
|
|
3418
|
-
baseDetachId,
|
|
3419
|
-
count,
|
|
3420
|
-
);
|
|
2590
|
+
super.set(target, revision, id, count, newValue, invalidateDependents);
|
|
2591
|
+
}
|
|
3421
2592
|
|
|
3422
|
-
|
|
3423
|
-
|
|
2593
|
+
public override onMoveIn(id: ChangeAtomId): void {
|
|
2594
|
+
setInChangeAtomIdMap(this.table.composedNodeToParent, id, this.fieldId);
|
|
3424
2595
|
}
|
|
3425
2596
|
|
|
3426
|
-
public
|
|
3427
|
-
|
|
3428
|
-
|
|
2597
|
+
public override moveKey(
|
|
2598
|
+
target: CrossFieldTarget,
|
|
2599
|
+
revision: RevisionTag | undefined,
|
|
2600
|
+
id: ChangesetLocalId,
|
|
3429
2601
|
count: number,
|
|
3430
|
-
composeToPin: boolean,
|
|
3431
2602
|
): void {
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
const countToProcess = areSameEntry.length;
|
|
3435
|
-
if (areSameEntry.value) {
|
|
3436
|
-
// These nodes have been moved back to their original location, so the composed changeset should not have any renames for them.
|
|
3437
|
-
// Note that deleting the rename from `this.table.composedRootNodes` would change the result of this method
|
|
3438
|
-
// if it were rerun due to the field being invalidated, so we instead record that the rename should be deleted later.
|
|
3439
|
-
this.table.renamesToDelete.set(baseDetachId, countToProcess, true);
|
|
3440
|
-
}
|
|
3441
|
-
|
|
3442
|
-
if (composeToPin) {
|
|
3443
|
-
this.table.movedCrossFieldKeys.set(
|
|
3444
|
-
{ target: CrossFieldTarget.Source, ...newAttachId },
|
|
3445
|
-
countToProcess,
|
|
3446
|
-
this.fieldId,
|
|
3447
|
-
);
|
|
3448
|
-
|
|
3449
|
-
if (!areEqualChangeAtomIds(baseDetachId, newAttachId)) {
|
|
3450
|
-
// The pin will have `newAttachId` as both its detach and attach ID.
|
|
3451
|
-
// So we remove `baseDetachId` unless that is equal to the pin's detach ID.
|
|
3452
|
-
this.table.removedCrossFieldKeys.set(
|
|
3453
|
-
{ target: CrossFieldTarget.Source, ...baseDetachId },
|
|
3454
|
-
countToProcess,
|
|
3455
|
-
true,
|
|
3456
|
-
);
|
|
3457
|
-
}
|
|
3458
|
-
|
|
3459
|
-
// Note that while change2 should already have this key, change1 may have a rollback for the same ID in a different location.
|
|
3460
|
-
// In that case, change1's attach should be canceled out by a detach from change2.
|
|
3461
|
-
// Here we make sure that the composed change has the correct location (this field) for the attach ID.
|
|
3462
|
-
this.table.movedCrossFieldKeys.set(
|
|
3463
|
-
{ target: CrossFieldTarget.Destination, ...newAttachId },
|
|
3464
|
-
countToProcess,
|
|
3465
|
-
this.fieldId,
|
|
3466
|
-
);
|
|
3467
|
-
} else {
|
|
3468
|
-
this.table.removedCrossFieldKeys.set(
|
|
3469
|
-
{ target: CrossFieldTarget.Source, ...baseDetachId },
|
|
3470
|
-
countToProcess,
|
|
3471
|
-
true,
|
|
3472
|
-
);
|
|
3473
|
-
|
|
3474
|
-
this.table.removedCrossFieldKeys.set(
|
|
3475
|
-
{ target: CrossFieldTarget.Destination, ...newAttachId },
|
|
3476
|
-
countToProcess,
|
|
3477
|
-
true,
|
|
3478
|
-
);
|
|
3479
|
-
}
|
|
3480
|
-
|
|
3481
|
-
if (countToProcess < count) {
|
|
3482
|
-
this.composeAttachDetach(
|
|
3483
|
-
offsetChangeAtomId(baseDetachId, countToProcess),
|
|
3484
|
-
offsetChangeAtomId(newAttachId, countToProcess),
|
|
3485
|
-
count - countToProcess,
|
|
3486
|
-
);
|
|
3487
|
-
}
|
|
2603
|
+
throw new Error("Moving cross-field keys during compose is currently unsupported");
|
|
3488
2604
|
}
|
|
3489
2605
|
|
|
3490
|
-
private
|
|
3491
|
-
|
|
3492
|
-
for (const fieldId of fields) {
|
|
3493
|
-
this.table.pendingCompositions.affectedBaseFields.set(
|
|
3494
|
-
fieldIdKeyFromFieldId(fieldId),
|
|
3495
|
-
true,
|
|
3496
|
-
);
|
|
3497
|
-
}
|
|
3498
|
-
}
|
|
2606
|
+
private get table(): ComposeTable {
|
|
2607
|
+
return this.crossFieldTable as ComposeTable;
|
|
3499
2608
|
}
|
|
3500
2609
|
}
|
|
3501
2610
|
|
|
3502
2611
|
function makeModularChangeset(
|
|
3503
2612
|
props: {
|
|
3504
|
-
rebaseVersion?: RebaseVersion;
|
|
3505
2613
|
fieldChanges?: FieldChangeMap;
|
|
3506
2614
|
nodeChanges?: ChangeAtomIdBTree<NodeChangeset>;
|
|
3507
|
-
|
|
3508
|
-
nodeToParent?: ChangeAtomIdBTree<NodeLocation>;
|
|
2615
|
+
nodeToParent?: ChangeAtomIdBTree<FieldId>;
|
|
3509
2616
|
nodeAliases?: ChangeAtomIdBTree<NodeId>;
|
|
3510
2617
|
crossFieldKeys?: CrossFieldKeyTable;
|
|
3511
2618
|
maxId: number;
|
|
3512
2619
|
revisions?: readonly RevisionInfo[];
|
|
3513
2620
|
constraintViolationCount?: number;
|
|
3514
2621
|
constraintViolationCountOnRevert?: number;
|
|
2622
|
+
noChangeConstraint?: NoChangeConstraint;
|
|
2623
|
+
noChangeConstraintOnRevert?: NoChangeConstraint;
|
|
3515
2624
|
builds?: ChangeAtomIdBTree<TreeChunk>;
|
|
3516
2625
|
destroys?: ChangeAtomIdBTree<number>;
|
|
3517
2626
|
refreshers?: ChangeAtomIdBTree<TreeChunk>;
|
|
@@ -3520,13 +2629,11 @@ function makeModularChangeset(
|
|
|
3520
2629
|
},
|
|
3521
2630
|
): ModularChangeset {
|
|
3522
2631
|
const changeset: Mutable<ModularChangeset> = {
|
|
3523
|
-
rebaseVersion: props.rebaseVersion ?? 1,
|
|
3524
2632
|
fieldChanges: props.fieldChanges ?? new Map(),
|
|
3525
2633
|
nodeChanges: props.nodeChanges ?? newTupleBTree(),
|
|
3526
|
-
rootNodes: props.rootNodes ?? newRootTable(),
|
|
3527
2634
|
nodeToParent: props.nodeToParent ?? newTupleBTree(),
|
|
3528
2635
|
nodeAliases: props.nodeAliases ?? newTupleBTree(),
|
|
3529
|
-
crossFieldKeys: props.crossFieldKeys ??
|
|
2636
|
+
crossFieldKeys: props.crossFieldKeys ?? newCrossFieldKeyTable(),
|
|
3530
2637
|
};
|
|
3531
2638
|
|
|
3532
2639
|
if (props.revisions !== undefined && props.revisions.length > 0) {
|
|
@@ -3544,6 +2651,12 @@ function makeModularChangeset(
|
|
|
3544
2651
|
) {
|
|
3545
2652
|
changeset.constraintViolationCountOnRevert = props.constraintViolationCountOnRevert;
|
|
3546
2653
|
}
|
|
2654
|
+
if (props.noChangeConstraint !== undefined) {
|
|
2655
|
+
changeset.noChangeConstraint = props.noChangeConstraint;
|
|
2656
|
+
}
|
|
2657
|
+
if (props.noChangeConstraintOnRevert !== undefined) {
|
|
2658
|
+
changeset.noChangeConstraintOnRevert = props.noChangeConstraintOnRevert;
|
|
2659
|
+
}
|
|
3547
2660
|
if (props.builds !== undefined && props.builds.size > 0) {
|
|
3548
2661
|
changeset.builds = props.builds;
|
|
3549
2662
|
}
|
|
@@ -3553,25 +2666,23 @@ function makeModularChangeset(
|
|
|
3553
2666
|
if (props.refreshers !== undefined && props.refreshers.size > 0) {
|
|
3554
2667
|
changeset.refreshers = props.refreshers;
|
|
3555
2668
|
}
|
|
3556
|
-
|
|
3557
2669
|
return changeset;
|
|
3558
2670
|
}
|
|
3559
2671
|
|
|
3560
2672
|
export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
3561
2673
|
private transactionDepth: number = 0;
|
|
3562
2674
|
private idAllocator: IdAllocator;
|
|
2675
|
+
private readonly codecOptions: CodecWriteOptions;
|
|
3563
2676
|
|
|
3564
2677
|
public constructor(
|
|
3565
2678
|
family: ChangeFamily<ChangeFamilyEditor, ModularChangeset>,
|
|
3566
2679
|
private readonly fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
3567
2680
|
changeReceiver: (change: TaggedChange<ModularChangeset>) => void,
|
|
2681
|
+
codecOptions: CodecWriteOptions,
|
|
3568
2682
|
) {
|
|
3569
2683
|
super(family, changeReceiver);
|
|
3570
2684
|
this.idAllocator = idAllocatorFromMaxId();
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
public isInTransaction(): boolean {
|
|
3574
|
-
return this.transactionDepth > 0;
|
|
2685
|
+
this.codecOptions = codecOptions;
|
|
3575
2686
|
}
|
|
3576
2687
|
|
|
3577
2688
|
public override enterTransaction(): void {
|
|
@@ -3628,7 +2739,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3628
2739
|
* @param revision - the revision of the change
|
|
3629
2740
|
*/
|
|
3630
2741
|
public submitChange(
|
|
3631
|
-
field:
|
|
2742
|
+
field: FieldUpPath,
|
|
3632
2743
|
fieldKind: FieldKindIdentifier,
|
|
3633
2744
|
change: FieldChangeset,
|
|
3634
2745
|
revision: RevisionTag,
|
|
@@ -3642,8 +2753,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3642
2753
|
fieldChange: { fieldKind, change },
|
|
3643
2754
|
nodeChanges: newTupleBTree(),
|
|
3644
2755
|
nodeToParent: newTupleBTree(),
|
|
3645
|
-
crossFieldKeys:
|
|
3646
|
-
rootNodes: newRootTable(),
|
|
2756
|
+
crossFieldKeys: newCrossFieldKeyTable(),
|
|
3647
2757
|
idAllocator: this.idAllocator,
|
|
3648
2758
|
localCrossFieldKeys,
|
|
3649
2759
|
revision,
|
|
@@ -3665,7 +2775,6 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3665
2775
|
? makeModularChangeset({
|
|
3666
2776
|
maxId: this.idAllocator.getMaxId(),
|
|
3667
2777
|
builds: change.builds,
|
|
3668
|
-
rootNodes: renameTableFromRenameDescriptions(change.renames ?? []),
|
|
3669
2778
|
revisions: [{ revision: change.revision }],
|
|
3670
2779
|
})
|
|
3671
2780
|
: buildModularChangesetFromField({
|
|
@@ -3676,8 +2785,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3676
2785
|
},
|
|
3677
2786
|
nodeChanges: newTupleBTree(),
|
|
3678
2787
|
nodeToParent: newTupleBTree(),
|
|
3679
|
-
crossFieldKeys:
|
|
3680
|
-
rootNodes: newRootTable(),
|
|
2788
|
+
crossFieldKeys: newCrossFieldKeyTable(),
|
|
3681
2789
|
idAllocator: this.idAllocator,
|
|
3682
2790
|
localCrossFieldKeys: getChangeHandler(
|
|
3683
2791
|
this.fieldKinds,
|
|
@@ -3687,7 +2795,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3687
2795
|
}),
|
|
3688
2796
|
);
|
|
3689
2797
|
});
|
|
3690
|
-
const revInfo =
|
|
2798
|
+
const revInfo = [...revisions].map((revision) => ({ revision }));
|
|
3691
2799
|
const composedChange: Mutable<ModularChangeset> = {
|
|
3692
2800
|
...this.changeFamily.rebaser.compose(changeMaps),
|
|
3693
2801
|
revisions: revInfo,
|
|
@@ -3704,7 +2812,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3704
2812
|
return brand(this.idAllocator.allocate(count));
|
|
3705
2813
|
}
|
|
3706
2814
|
|
|
3707
|
-
public addNodeExistsConstraint(path:
|
|
2815
|
+
public addNodeExistsConstraint(path: UpPath, revision: RevisionTag): void {
|
|
3708
2816
|
const nodeChange: NodeChangeset = {
|
|
3709
2817
|
nodeExistsConstraint: { violated: false },
|
|
3710
2818
|
};
|
|
@@ -3716,8 +2824,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3716
2824
|
nodeChange,
|
|
3717
2825
|
nodeChanges: newTupleBTree(),
|
|
3718
2826
|
nodeToParent: newTupleBTree(),
|
|
3719
|
-
crossFieldKeys:
|
|
3720
|
-
rootNodes: newRootTable(),
|
|
2827
|
+
crossFieldKeys: newCrossFieldKeyTable(),
|
|
3721
2828
|
idAllocator: this.idAllocator,
|
|
3722
2829
|
revision,
|
|
3723
2830
|
}),
|
|
@@ -3726,7 +2833,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3726
2833
|
);
|
|
3727
2834
|
}
|
|
3728
2835
|
|
|
3729
|
-
public addNodeExistsConstraintOnRevert(path:
|
|
2836
|
+
public addNodeExistsConstraintOnRevert(path: UpPath, revision: RevisionTag): void {
|
|
3730
2837
|
const nodeChange: NodeChangeset = {
|
|
3731
2838
|
nodeExistsConstraintOnRevert: { violated: false },
|
|
3732
2839
|
};
|
|
@@ -3738,8 +2845,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3738
2845
|
nodeChange,
|
|
3739
2846
|
nodeChanges: newTupleBTree(),
|
|
3740
2847
|
nodeToParent: newTupleBTree(),
|
|
3741
|
-
crossFieldKeys:
|
|
3742
|
-
rootNodes: newRootTable(),
|
|
2848
|
+
crossFieldKeys: newCrossFieldKeyTable(),
|
|
3743
2849
|
idAllocator: this.idAllocator,
|
|
3744
2850
|
revision,
|
|
3745
2851
|
}),
|
|
@@ -3747,15 +2853,44 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
3747
2853
|
),
|
|
3748
2854
|
);
|
|
3749
2855
|
}
|
|
2856
|
+
|
|
2857
|
+
public addNoChangeConstraint(revision: RevisionTag): void {
|
|
2858
|
+
if (lt(this.codecOptions.minVersionForCollab, FluidClientVersion.v2_80)) {
|
|
2859
|
+
throw new UsageError(
|
|
2860
|
+
`No change constraints require min client version of at least ${FluidClientVersion.v2_80}`,
|
|
2861
|
+
);
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2864
|
+
const changeset = makeModularChangeset({
|
|
2865
|
+
maxId: -1,
|
|
2866
|
+
noChangeConstraint: { violated: false },
|
|
2867
|
+
});
|
|
2868
|
+
|
|
2869
|
+
this.applyChange(tagChange(changeset, revision));
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2872
|
+
public addNoChangeConstraintOnRevert(revision: RevisionTag): void {
|
|
2873
|
+
if (lt(this.codecOptions.minVersionForCollab, FluidClientVersion.v2_80)) {
|
|
2874
|
+
throw new UsageError(
|
|
2875
|
+
`No change constraints require min client version of at least ${FluidClientVersion.v2_80}`,
|
|
2876
|
+
);
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
const changeset = makeModularChangeset({
|
|
2880
|
+
maxId: -1,
|
|
2881
|
+
noChangeConstraintOnRevert: { violated: false },
|
|
2882
|
+
});
|
|
2883
|
+
|
|
2884
|
+
this.applyChange(tagChange(changeset, revision));
|
|
2885
|
+
}
|
|
3750
2886
|
}
|
|
3751
2887
|
|
|
3752
|
-
|
|
3753
|
-
path:
|
|
2888
|
+
function buildModularChangesetFromField(props: {
|
|
2889
|
+
path: FieldUpPath;
|
|
3754
2890
|
fieldChange: FieldChange;
|
|
3755
2891
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
|
|
3756
|
-
nodeToParent: ChangeAtomIdBTree<
|
|
2892
|
+
nodeToParent: ChangeAtomIdBTree<FieldId>;
|
|
3757
2893
|
crossFieldKeys: CrossFieldKeyTable;
|
|
3758
|
-
rootNodes: RootNodeTable;
|
|
3759
2894
|
localCrossFieldKeys?: CrossFieldKeyRange[];
|
|
3760
2895
|
revision: RevisionTag;
|
|
3761
2896
|
idAllocator?: IdAllocator;
|
|
@@ -3767,7 +2902,6 @@ export function buildModularChangesetFromField(props: {
|
|
|
3767
2902
|
nodeChanges,
|
|
3768
2903
|
nodeToParent,
|
|
3769
2904
|
crossFieldKeys,
|
|
3770
|
-
rootNodes,
|
|
3771
2905
|
idAllocator = idAllocatorFromMaxId(),
|
|
3772
2906
|
localCrossFieldKeys = [],
|
|
3773
2907
|
childId,
|
|
@@ -3776,17 +2910,14 @@ export function buildModularChangesetFromField(props: {
|
|
|
3776
2910
|
const fieldChanges: FieldChangeMap = new Map([[path.field, fieldChange]]);
|
|
3777
2911
|
|
|
3778
2912
|
if (path.parent === undefined) {
|
|
3779
|
-
const field = { nodeId: undefined, field: path.field };
|
|
3780
2913
|
for (const { key, count } of localCrossFieldKeys) {
|
|
3781
|
-
crossFieldKeys.set(key, count, field);
|
|
2914
|
+
crossFieldKeys.set(key, count, { nodeId: undefined, field: path.field });
|
|
3782
2915
|
}
|
|
3783
2916
|
|
|
3784
2917
|
if (childId !== undefined) {
|
|
3785
2918
|
setInChangeAtomIdMap(nodeToParent, childId, {
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
field: path.field,
|
|
3789
|
-
},
|
|
2919
|
+
nodeId: undefined,
|
|
2920
|
+
field: path.field,
|
|
3790
2921
|
});
|
|
3791
2922
|
}
|
|
3792
2923
|
|
|
@@ -3795,7 +2926,6 @@ export function buildModularChangesetFromField(props: {
|
|
|
3795
2926
|
nodeChanges,
|
|
3796
2927
|
nodeToParent,
|
|
3797
2928
|
crossFieldKeys,
|
|
3798
|
-
rootNodes,
|
|
3799
2929
|
maxId: idAllocator.getMaxId(),
|
|
3800
2930
|
revisions: [{ revision }],
|
|
3801
2931
|
});
|
|
@@ -3806,7 +2936,6 @@ export function buildModularChangesetFromField(props: {
|
|
|
3806
2936
|
};
|
|
3807
2937
|
|
|
3808
2938
|
const parentId: NodeId = { localId: brand(idAllocator.allocate()), revision };
|
|
3809
|
-
const fieldId = { nodeId: parentId, field: path.field };
|
|
3810
2939
|
|
|
3811
2940
|
for (const { key, count } of localCrossFieldKeys) {
|
|
3812
2941
|
crossFieldKeys.set(key, count, { nodeId: parentId, field: path.field });
|
|
@@ -3814,7 +2943,8 @@ export function buildModularChangesetFromField(props: {
|
|
|
3814
2943
|
|
|
3815
2944
|
if (childId !== undefined) {
|
|
3816
2945
|
setInChangeAtomIdMap(nodeToParent, childId, {
|
|
3817
|
-
|
|
2946
|
+
nodeId: parentId,
|
|
2947
|
+
field: path.field,
|
|
3818
2948
|
});
|
|
3819
2949
|
}
|
|
3820
2950
|
|
|
@@ -3824,7 +2954,6 @@ export function buildModularChangesetFromField(props: {
|
|
|
3824
2954
|
nodeChanges,
|
|
3825
2955
|
nodeToParent,
|
|
3826
2956
|
crossFieldKeys,
|
|
3827
|
-
rootNodes,
|
|
3828
2957
|
idAllocator,
|
|
3829
2958
|
revision,
|
|
3830
2959
|
nodeId: parentId,
|
|
@@ -3832,58 +2961,45 @@ export function buildModularChangesetFromField(props: {
|
|
|
3832
2961
|
}
|
|
3833
2962
|
|
|
3834
2963
|
function buildModularChangesetFromNode(props: {
|
|
3835
|
-
path:
|
|
2964
|
+
path: UpPath;
|
|
3836
2965
|
nodeChange: NodeChangeset;
|
|
3837
2966
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
|
|
3838
|
-
nodeToParent: ChangeAtomIdBTree<
|
|
2967
|
+
nodeToParent: ChangeAtomIdBTree<FieldId>;
|
|
3839
2968
|
crossFieldKeys: CrossFieldKeyTable;
|
|
3840
|
-
rootNodes: RootNodeTable;
|
|
3841
2969
|
idAllocator: IdAllocator;
|
|
3842
2970
|
revision: RevisionTag;
|
|
3843
2971
|
nodeId?: NodeId;
|
|
3844
2972
|
}): ModularChangeset {
|
|
3845
2973
|
const {
|
|
3846
2974
|
path,
|
|
3847
|
-
|
|
2975
|
+
idAllocator,
|
|
2976
|
+
revision,
|
|
2977
|
+
nodeChanges,
|
|
2978
|
+
nodeChange,
|
|
2979
|
+
nodeId = { localId: brand(idAllocator.allocate()), revision },
|
|
3848
2980
|
} = props;
|
|
3849
|
-
setInChangeAtomIdMap(
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
nodeChanges: props.nodeChanges,
|
|
3859
|
-
nodeToParent: props.nodeToParent,
|
|
3860
|
-
crossFieldKeys: props.crossFieldKeys,
|
|
3861
|
-
maxId: props.idAllocator.getMaxId(),
|
|
3862
|
-
revisions: [{ revision: props.revision }],
|
|
3863
|
-
});
|
|
3864
|
-
} else {
|
|
3865
|
-
const fieldChangeset = genericFieldKind.changeHandler.editor.buildChildChanges([
|
|
3866
|
-
[path.parentIndex, nodeId],
|
|
3867
|
-
]);
|
|
3868
|
-
|
|
3869
|
-
const fieldChange: FieldChange = {
|
|
3870
|
-
fieldKind: genericFieldKind.identifier,
|
|
3871
|
-
change: fieldChangeset,
|
|
3872
|
-
};
|
|
2981
|
+
setInChangeAtomIdMap(nodeChanges, nodeId, nodeChange);
|
|
2982
|
+
const fieldChangeset = genericFieldKind.changeHandler.editor.buildChildChanges([
|
|
2983
|
+
[path.parentIndex, nodeId],
|
|
2984
|
+
]);
|
|
2985
|
+
|
|
2986
|
+
const fieldChange: FieldChange = {
|
|
2987
|
+
fieldKind: genericFieldKind.identifier,
|
|
2988
|
+
change: fieldChangeset,
|
|
2989
|
+
};
|
|
3873
2990
|
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
}
|
|
2991
|
+
return buildModularChangesetFromField({
|
|
2992
|
+
...props,
|
|
2993
|
+
path: { parent: path.parent, field: path.parentField },
|
|
2994
|
+
fieldChange,
|
|
2995
|
+
localCrossFieldKeys: [],
|
|
2996
|
+
childId: nodeId,
|
|
2997
|
+
});
|
|
3882
2998
|
}
|
|
3883
2999
|
|
|
3884
3000
|
export interface FieldEditDescription {
|
|
3885
3001
|
type: "field";
|
|
3886
|
-
field:
|
|
3002
|
+
field: FieldUpPath;
|
|
3887
3003
|
fieldKind: FieldKindIdentifier;
|
|
3888
3004
|
change: FieldChangeset;
|
|
3889
3005
|
revision: RevisionTag;
|
|
@@ -3893,23 +3009,6 @@ export interface GlobalEditDescription {
|
|
|
3893
3009
|
type: "global";
|
|
3894
3010
|
revision: RevisionTag;
|
|
3895
3011
|
builds?: ChangeAtomIdBTree<TreeChunk>;
|
|
3896
|
-
renames?: RenameDescription[];
|
|
3897
|
-
}
|
|
3898
|
-
|
|
3899
|
-
export interface RenameDescription {
|
|
3900
|
-
count: number;
|
|
3901
|
-
oldId: ChangeAtomId;
|
|
3902
|
-
newId: ChangeAtomId;
|
|
3903
|
-
detachLocation: FieldId | undefined;
|
|
3904
|
-
}
|
|
3905
|
-
|
|
3906
|
-
function renameTableFromRenameDescriptions(renames: RenameDescription[]): RootNodeTable {
|
|
3907
|
-
const table = newRootTable();
|
|
3908
|
-
for (const rename of renames) {
|
|
3909
|
-
addNodeRename(table, rename.oldId, rename.newId, rename.count, rename.detachLocation);
|
|
3910
|
-
}
|
|
3911
|
-
|
|
3912
|
-
return table;
|
|
3913
3012
|
}
|
|
3914
3013
|
|
|
3915
3014
|
export type EditDescription = FieldEditDescription | GlobalEditDescription;
|
|
@@ -3920,10 +3019,31 @@ function getRevInfoFromTaggedChanges(changes: TaggedChange<ModularChangeset>[]):
|
|
|
3920
3019
|
} {
|
|
3921
3020
|
let maxId = -1;
|
|
3922
3021
|
const revInfos: RevisionInfo[] = [];
|
|
3022
|
+
const revisions = new Set<RevisionTag>();
|
|
3923
3023
|
for (const taggedChange of changes) {
|
|
3924
3024
|
const change = taggedChange.change;
|
|
3925
3025
|
maxId = Math.max(change.maxId ?? -1, maxId);
|
|
3926
|
-
|
|
3026
|
+
const infosToAdd = revisionInfoFromTaggedChange(taggedChange);
|
|
3027
|
+
for (const info of infosToAdd) {
|
|
3028
|
+
if (!revisions.has(info.revision)) {
|
|
3029
|
+
revisions.add(info.revision);
|
|
3030
|
+
revInfos.push(info);
|
|
3031
|
+
}
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
const rolledBackRevisions: RevisionTag[] = [];
|
|
3036
|
+
for (const info of revInfos) {
|
|
3037
|
+
if (info.rollbackOf !== undefined) {
|
|
3038
|
+
rolledBackRevisions.push(info.rollbackOf);
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
|
|
3042
|
+
rolledBackRevisions.reverse();
|
|
3043
|
+
for (const revision of rolledBackRevisions) {
|
|
3044
|
+
if (!revisions.has(revision)) {
|
|
3045
|
+
revInfos.push({ revision });
|
|
3046
|
+
}
|
|
3927
3047
|
}
|
|
3928
3048
|
|
|
3929
3049
|
return { maxId: brand(maxId), revInfos };
|
|
@@ -3945,28 +3065,25 @@ function revisionInfoFromTaggedChange(
|
|
|
3945
3065
|
return revInfos;
|
|
3946
3066
|
}
|
|
3947
3067
|
|
|
3948
|
-
function fieldChangeFromId(
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
fieldId.nodeId,
|
|
3955
|
-
);
|
|
3068
|
+
function fieldChangeFromId(
|
|
3069
|
+
fields: FieldChangeMap,
|
|
3070
|
+
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
3071
|
+
id: FieldId,
|
|
3072
|
+
): FieldChange {
|
|
3073
|
+
const fieldMap = fieldMapFromNodeId(fields, nodes, id.nodeId);
|
|
3956
3074
|
return fieldMap.get(id.field) ?? fail(0xb25 /* No field exists for the given ID */);
|
|
3957
3075
|
}
|
|
3958
3076
|
|
|
3959
3077
|
function fieldMapFromNodeId(
|
|
3960
3078
|
rootFieldMap: FieldChangeMap,
|
|
3961
3079
|
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
3962
|
-
aliases: ChangeAtomIdBTree<NodeId>,
|
|
3963
3080
|
nodeId: NodeId | undefined,
|
|
3964
3081
|
): FieldChangeMap {
|
|
3965
3082
|
if (nodeId === undefined) {
|
|
3966
3083
|
return rootFieldMap;
|
|
3967
3084
|
}
|
|
3968
3085
|
|
|
3969
|
-
const node = nodeChangeFromId(nodes,
|
|
3086
|
+
const node = nodeChangeFromId(nodes, nodeId);
|
|
3970
3087
|
assert(node.fieldChanges !== undefined, 0x9c9 /* Expected node to have field changes */);
|
|
3971
3088
|
return node.fieldChanges;
|
|
3972
3089
|
}
|
|
@@ -3983,26 +3100,17 @@ function rebasedNodeIdFromBaseNodeId(table: RebaseTable, baseId: NodeId): NodeId
|
|
|
3983
3100
|
return getFromChangeAtomIdMap(table.baseToRebasedNodeId, baseId) ?? baseId;
|
|
3984
3101
|
}
|
|
3985
3102
|
|
|
3986
|
-
function nodeChangeFromId(
|
|
3987
|
-
nodes
|
|
3988
|
-
aliases: ChangeAtomIdBTree<NodeId>,
|
|
3989
|
-
id: NodeId,
|
|
3990
|
-
): NodeChangeset {
|
|
3991
|
-
const normalizedId = normalizeNodeId(id, aliases);
|
|
3992
|
-
const node = getFromChangeAtomIdMap(nodes, normalizedId);
|
|
3103
|
+
function nodeChangeFromId(nodes: ChangeAtomIdBTree<NodeChangeset>, id: NodeId): NodeChangeset {
|
|
3104
|
+
const node = getFromChangeAtomIdMap(nodes, id);
|
|
3993
3105
|
assert(node !== undefined, 0x9ca /* Unknown node ID */);
|
|
3994
3106
|
return node;
|
|
3995
3107
|
}
|
|
3996
3108
|
|
|
3997
3109
|
function fieldIdFromFieldIdKey([revision, localId, field]: FieldIdKey): FieldId {
|
|
3998
|
-
const nodeId = localId
|
|
3110
|
+
const nodeId = localId === undefined ? undefined : { revision, localId };
|
|
3999
3111
|
return { nodeId, field };
|
|
4000
3112
|
}
|
|
4001
3113
|
|
|
4002
|
-
function fieldIdKeyFromFieldId(fieldId: FieldId): FieldIdKey {
|
|
4003
|
-
return [fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field];
|
|
4004
|
-
}
|
|
4005
|
-
|
|
4006
3114
|
function cloneNodeChangeset(nodeChangeset: NodeChangeset): NodeChangeset {
|
|
4007
3115
|
if (nodeChangeset.fieldChanges !== undefined) {
|
|
4008
3116
|
return { ...nodeChangeset, fieldChanges: new Map(nodeChangeset.fieldChanges) };
|
|
@@ -4011,41 +3119,21 @@ function cloneNodeChangeset(nodeChangeset: NodeChangeset): NodeChangeset {
|
|
|
4011
3119
|
return { ...nodeChangeset };
|
|
4012
3120
|
}
|
|
4013
3121
|
|
|
4014
|
-
function
|
|
4015
|
-
location: NodeLocation,
|
|
4016
|
-
oldRevisions: Set<RevisionTag | undefined>,
|
|
4017
|
-
newRevision: RevisionTag | undefined,
|
|
4018
|
-
): NodeLocation {
|
|
4019
|
-
return location.field !== undefined
|
|
4020
|
-
? { field: replaceFieldIdRevision(location.field, oldRevisions, newRevision) }
|
|
4021
|
-
: { root: replaceAtomRevisions(location.root, oldRevisions, newRevision) };
|
|
4022
|
-
}
|
|
4023
|
-
|
|
4024
|
-
function replaceFieldIdRevision(
|
|
4025
|
-
fieldId: FieldId,
|
|
4026
|
-
oldRevisions: Set<RevisionTag | undefined>,
|
|
4027
|
-
newRevision: RevisionTag | undefined,
|
|
4028
|
-
): FieldId {
|
|
3122
|
+
function replaceFieldIdRevision(fieldId: FieldId, replacer: RevisionReplacer): FieldId {
|
|
4029
3123
|
if (fieldId.nodeId === undefined) {
|
|
4030
3124
|
return fieldId;
|
|
4031
3125
|
}
|
|
4032
3126
|
|
|
4033
3127
|
return {
|
|
4034
3128
|
...fieldId,
|
|
4035
|
-
nodeId:
|
|
3129
|
+
nodeId: replacer.getUpdatedAtomId(fieldId.nodeId),
|
|
4036
3130
|
};
|
|
4037
3131
|
}
|
|
4038
3132
|
|
|
4039
|
-
export function
|
|
4040
|
-
const
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
if (location.field !== undefined) {
|
|
4045
|
-
return { field: normalizeFieldId(location.field, changeset.nodeAliases) };
|
|
4046
|
-
}
|
|
4047
|
-
|
|
4048
|
-
return location;
|
|
3133
|
+
export function getParentFieldId(changeset: ModularChangeset, nodeId: NodeId): FieldId {
|
|
3134
|
+
const parentId = getFromChangeAtomIdMap(changeset.nodeToParent, nodeId);
|
|
3135
|
+
assert(parentId !== undefined, 0x9cb /* Parent field should be defined */);
|
|
3136
|
+
return normalizeFieldId(parentId, changeset.nodeAliases);
|
|
4049
3137
|
}
|
|
4050
3138
|
|
|
4051
3139
|
function getFieldsForCrossFieldKey(
|
|
@@ -4058,49 +3146,21 @@ function getFieldsForCrossFieldKey(
|
|
|
4058
3146
|
.map(({ value: fieldId }) => normalizeFieldId(fieldId, changeset.nodeAliases));
|
|
4059
3147
|
}
|
|
4060
3148
|
|
|
4061
|
-
function getFirstFieldForCrossFieldKey(
|
|
4062
|
-
changeset: ModularChangeset,
|
|
4063
|
-
key: CrossFieldKey,
|
|
4064
|
-
count: number,
|
|
4065
|
-
): RangeQueryResult<FieldId | undefined> {
|
|
4066
|
-
const result = changeset.crossFieldKeys.getFirst(key, count);
|
|
4067
|
-
if (result.value === undefined) {
|
|
4068
|
-
return result;
|
|
4069
|
-
}
|
|
4070
|
-
|
|
4071
|
-
return { ...result, value: normalizeFieldId(result.value, changeset.nodeAliases) };
|
|
4072
|
-
}
|
|
4073
|
-
|
|
4074
|
-
function normalizeNodeLocation(
|
|
4075
|
-
location: NodeLocation,
|
|
4076
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
4077
|
-
): NodeLocation {
|
|
4078
|
-
if (location.field !== undefined) {
|
|
4079
|
-
return { field: normalizeFieldId(location.field, nodeAliases) };
|
|
4080
|
-
}
|
|
4081
|
-
|
|
4082
|
-
return location;
|
|
4083
|
-
}
|
|
4084
|
-
|
|
4085
3149
|
// This is only exported for use in test utilities.
|
|
4086
3150
|
export function normalizeFieldId(
|
|
4087
3151
|
fieldId: FieldId,
|
|
4088
3152
|
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
4089
3153
|
): FieldId {
|
|
4090
|
-
return fieldId.nodeId
|
|
4091
|
-
?
|
|
4092
|
-
: fieldId;
|
|
3154
|
+
return fieldId.nodeId === undefined
|
|
3155
|
+
? fieldId
|
|
3156
|
+
: { ...fieldId, nodeId: normalizeNodeId(fieldId.nodeId, nodeAliases) };
|
|
4093
3157
|
}
|
|
4094
3158
|
|
|
4095
3159
|
/**
|
|
4096
3160
|
* @returns The canonical form of nodeId, according to nodeAliases
|
|
4097
3161
|
*/
|
|
4098
|
-
|
|
4099
|
-
nodeId: NodeId,
|
|
4100
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
4101
|
-
): NodeId {
|
|
3162
|
+
function normalizeNodeId(nodeId: NodeId, nodeAliases: ChangeAtomIdBTree<NodeId>): NodeId {
|
|
4102
3163
|
let currentId = nodeId;
|
|
4103
|
-
let cycleProbeId: NodeId | undefined = nodeId;
|
|
4104
3164
|
|
|
4105
3165
|
// eslint-disable-next-line no-constant-condition
|
|
4106
3166
|
while (true) {
|
|
@@ -4110,16 +3170,6 @@ export function normalizeNodeId(
|
|
|
4110
3170
|
}
|
|
4111
3171
|
|
|
4112
3172
|
currentId = dealiased;
|
|
4113
|
-
|
|
4114
|
-
if (cycleProbeId !== undefined) {
|
|
4115
|
-
cycleProbeId = getFromChangeAtomIdMap(nodeAliases, cycleProbeId);
|
|
4116
|
-
}
|
|
4117
|
-
|
|
4118
|
-
if (cycleProbeId !== undefined) {
|
|
4119
|
-
cycleProbeId = getFromChangeAtomIdMap(nodeAliases, cycleProbeId);
|
|
4120
|
-
}
|
|
4121
|
-
|
|
4122
|
-
assert(!areEqualChangeAtomIdOpts(cycleProbeId, currentId), "Alias cycle detected");
|
|
4123
3173
|
}
|
|
4124
3174
|
}
|
|
4125
3175
|
|
|
@@ -4130,8 +3180,7 @@ function hasConflicts(change: ModularChangeset): boolean {
|
|
|
4130
3180
|
interface ModularChangesetContent {
|
|
4131
3181
|
fieldChanges: FieldChangeMap;
|
|
4132
3182
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
|
|
4133
|
-
nodeToParent: ChangeAtomIdBTree<
|
|
4134
|
-
rootNodes: RootNodeTable;
|
|
3183
|
+
nodeToParent: ChangeAtomIdBTree<FieldId>;
|
|
4135
3184
|
nodeAliases: ChangeAtomIdBTree<NodeId>;
|
|
4136
3185
|
crossFieldKeys: CrossFieldKeyTable;
|
|
4137
3186
|
}
|
|
@@ -4139,826 +3188,3 @@ interface ModularChangesetContent {
|
|
|
4139
3188
|
function areEqualFieldIds(a: FieldId, b: FieldId): boolean {
|
|
4140
3189
|
return areEqualChangeAtomIdOpts(a.nodeId, b.nodeId) && a.field === b.field;
|
|
4141
3190
|
}
|
|
4142
|
-
|
|
4143
|
-
function firstAttachIdFromDetachId(
|
|
4144
|
-
roots: RootNodeTable,
|
|
4145
|
-
detachId: ChangeAtomId,
|
|
4146
|
-
count: number,
|
|
4147
|
-
): RangeQueryResult<ChangeAtomId> {
|
|
4148
|
-
const result = roots.oldToNewId.getFirst(detachId, count);
|
|
4149
|
-
return { ...result, value: result.value ?? detachId };
|
|
4150
|
-
}
|
|
4151
|
-
|
|
4152
|
-
function firstDetachIdFromAttachId(
|
|
4153
|
-
roots: RootNodeTable,
|
|
4154
|
-
attachId: ChangeAtomId,
|
|
4155
|
-
count: number,
|
|
4156
|
-
): RangeQueryEntry<ChangeAtomId, ChangeAtomId> {
|
|
4157
|
-
const result = roots.newToOldId.getFirst(attachId, count);
|
|
4158
|
-
return { ...result, start: attachId, value: result.value ?? attachId };
|
|
4159
|
-
}
|
|
4160
|
-
|
|
4161
|
-
function rebaseCrossFieldKeys(
|
|
4162
|
-
sourceTable: CrossFieldKeyTable,
|
|
4163
|
-
movedDetaches: ChangeAtomIdRangeMap<boolean>,
|
|
4164
|
-
newDetachLocations: ChangeAtomIdRangeMap<FieldId>,
|
|
4165
|
-
): CrossFieldKeyTable {
|
|
4166
|
-
const rebasedTable = sourceTable.clone();
|
|
4167
|
-
for (const entry of movedDetaches.entries()) {
|
|
4168
|
-
rebasedTable.delete({ ...entry.start, target: CrossFieldTarget.Source }, entry.length);
|
|
4169
|
-
}
|
|
4170
|
-
|
|
4171
|
-
for (const entry of newDetachLocations.entries()) {
|
|
4172
|
-
rebasedTable.set(
|
|
4173
|
-
{ ...entry.start, target: CrossFieldTarget.Source },
|
|
4174
|
-
entry.length,
|
|
4175
|
-
entry.value,
|
|
4176
|
-
);
|
|
4177
|
-
}
|
|
4178
|
-
|
|
4179
|
-
return rebasedTable;
|
|
4180
|
-
}
|
|
4181
|
-
|
|
4182
|
-
export function newRootTable(): RootNodeTable {
|
|
4183
|
-
return {
|
|
4184
|
-
newToOldId: newChangeAtomIdTransform(),
|
|
4185
|
-
oldToNewId: newChangeAtomIdTransform(),
|
|
4186
|
-
nodeChanges: newTupleBTree(),
|
|
4187
|
-
detachLocations: newChangeAtomIdRangeMap(),
|
|
4188
|
-
outputDetachLocations: newChangeAtomIdRangeMap(),
|
|
4189
|
-
};
|
|
4190
|
-
}
|
|
4191
|
-
|
|
4192
|
-
function rebaseRoots(
|
|
4193
|
-
change: ModularChangeset,
|
|
4194
|
-
base: ModularChangeset,
|
|
4195
|
-
affectedBaseFields: TupleBTree<FieldIdKey, boolean>,
|
|
4196
|
-
nodesToRebase: [newChangeset: NodeId, baseChangeset: NodeId][],
|
|
4197
|
-
rebasedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
4198
|
-
rebaseVersion: RebaseVersion,
|
|
4199
|
-
): RootNodeTable {
|
|
4200
|
-
const rebasedRoots = newRootTable();
|
|
4201
|
-
for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
|
|
4202
|
-
rebaseRename(change.rootNodes, rebasedRoots, renameEntry, base, affectedBaseFields);
|
|
4203
|
-
}
|
|
4204
|
-
|
|
4205
|
-
for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
4206
|
-
const changes = base.rootNodes.nodeChanges.get(detachIdKey);
|
|
4207
|
-
if (changes !== undefined) {
|
|
4208
|
-
nodesToRebase.push([nodeId, changes]);
|
|
4209
|
-
}
|
|
4210
|
-
|
|
4211
|
-
const detachId = makeChangeAtomId(detachIdKey[1], detachIdKey[0]);
|
|
4212
|
-
const attachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
|
|
4213
|
-
const baseAttachEntry = base.crossFieldKeys.getFirst(
|
|
4214
|
-
{ target: CrossFieldTarget.Destination, ...attachId },
|
|
4215
|
-
1,
|
|
4216
|
-
);
|
|
4217
|
-
if (baseAttachEntry.value !== undefined) {
|
|
4218
|
-
affectedBaseFields.set(fieldIdKeyFromFieldId(baseAttachEntry.value), true);
|
|
4219
|
-
rebasedNodeToParent.delete(detachIdKey);
|
|
4220
|
-
} else {
|
|
4221
|
-
const renamedDetachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
|
|
4222
|
-
const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(
|
|
4223
|
-
renamedDetachId,
|
|
4224
|
-
1,
|
|
4225
|
-
).value;
|
|
4226
|
-
|
|
4227
|
-
if (baseOutputDetachLocation !== undefined) {
|
|
4228
|
-
affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
|
|
4229
|
-
}
|
|
4230
|
-
|
|
4231
|
-
const detachLocation =
|
|
4232
|
-
baseOutputDetachLocation ??
|
|
4233
|
-
change.rootNodes.detachLocations.getFirst(detachId, 1).value;
|
|
4234
|
-
|
|
4235
|
-
// Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
|
|
4236
|
-
// We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
|
|
4237
|
-
assignRootChange(
|
|
4238
|
-
rebasedRoots,
|
|
4239
|
-
rebasedNodeToParent,
|
|
4240
|
-
renamedDetachId,
|
|
4241
|
-
nodeId,
|
|
4242
|
-
detachLocation,
|
|
4243
|
-
rebaseVersion,
|
|
4244
|
-
);
|
|
4245
|
-
}
|
|
4246
|
-
}
|
|
4247
|
-
|
|
4248
|
-
for (const entry of change.rootNodes.outputDetachLocations.entries()) {
|
|
4249
|
-
rebasedRoots.outputDetachLocations.set(entry.start, entry.length, entry.value);
|
|
4250
|
-
}
|
|
4251
|
-
|
|
4252
|
-
return rebasedRoots;
|
|
4253
|
-
}
|
|
4254
|
-
|
|
4255
|
-
function rebaseRename(
|
|
4256
|
-
newRoots: RootNodeTable,
|
|
4257
|
-
rebasedRoots: RootNodeTable,
|
|
4258
|
-
renameEntry: RangeQueryEntry<ChangeAtomId, ChangeAtomId>,
|
|
4259
|
-
base: ModularChangeset,
|
|
4260
|
-
affectedBaseFields: TupleBTree<FieldIdKey, boolean>,
|
|
4261
|
-
): void {
|
|
4262
|
-
let count = renameEntry.length;
|
|
4263
|
-
const baseRenameEntry = firstAttachIdFromDetachId(base.rootNodes, renameEntry.start, count);
|
|
4264
|
-
count = baseRenameEntry.length;
|
|
4265
|
-
|
|
4266
|
-
const baseAttachEntry = base.crossFieldKeys.getFirst(
|
|
4267
|
-
{
|
|
4268
|
-
...baseRenameEntry.value,
|
|
4269
|
-
target: CrossFieldTarget.Destination,
|
|
4270
|
-
},
|
|
4271
|
-
count,
|
|
4272
|
-
);
|
|
4273
|
-
|
|
4274
|
-
count = baseAttachEntry.length;
|
|
4275
|
-
|
|
4276
|
-
if (baseAttachEntry.value !== undefined) {
|
|
4277
|
-
// This rename represents an intention to detach these nodes.
|
|
4278
|
-
// The rebased change should have a detach in the field where the base change attaches the nodes,
|
|
4279
|
-
// so we need to ensure that field is processed.
|
|
4280
|
-
affectedBaseFields.set(
|
|
4281
|
-
fieldIdKeyFromFieldId(normalizeFieldId(baseAttachEntry.value, base.nodeAliases)),
|
|
4282
|
-
true,
|
|
4283
|
-
);
|
|
4284
|
-
} else {
|
|
4285
|
-
const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(
|
|
4286
|
-
baseRenameEntry.value,
|
|
4287
|
-
1,
|
|
4288
|
-
).value;
|
|
4289
|
-
|
|
4290
|
-
if (baseOutputDetachLocation !== undefined) {
|
|
4291
|
-
affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
|
|
4292
|
-
}
|
|
4293
|
-
|
|
4294
|
-
const detachEntry = newRoots.detachLocations.getFirst(renameEntry.start, count);
|
|
4295
|
-
count = detachEntry.length;
|
|
4296
|
-
|
|
4297
|
-
const detachLocation = baseOutputDetachLocation ?? detachEntry.value;
|
|
4298
|
-
|
|
4299
|
-
// Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
|
|
4300
|
-
// We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
|
|
4301
|
-
addNodeRename(
|
|
4302
|
-
rebasedRoots,
|
|
4303
|
-
baseRenameEntry.value,
|
|
4304
|
-
renameEntry.value,
|
|
4305
|
-
count,
|
|
4306
|
-
detachLocation,
|
|
4307
|
-
);
|
|
4308
|
-
}
|
|
4309
|
-
|
|
4310
|
-
const countRemaining = renameEntry.length - count;
|
|
4311
|
-
if (countRemaining > 0) {
|
|
4312
|
-
rebaseRename(
|
|
4313
|
-
newRoots,
|
|
4314
|
-
rebasedRoots,
|
|
4315
|
-
{
|
|
4316
|
-
start: offsetChangeAtomId(renameEntry.start, count),
|
|
4317
|
-
value: offsetChangeAtomId(renameEntry.value, count),
|
|
4318
|
-
length: countRemaining,
|
|
4319
|
-
},
|
|
4320
|
-
base,
|
|
4321
|
-
affectedBaseFields,
|
|
4322
|
-
);
|
|
4323
|
-
}
|
|
4324
|
-
}
|
|
4325
|
-
|
|
4326
|
-
/**
|
|
4327
|
-
* For each root detach location, replaces any node ID from the base changeset
|
|
4328
|
-
* with the corresponding ID in the new changeset.
|
|
4329
|
-
*/
|
|
4330
|
-
function fixupRebasedDetachLocations(table: RebaseTable): void {
|
|
4331
|
-
for (const {
|
|
4332
|
-
start,
|
|
4333
|
-
length,
|
|
4334
|
-
value: detachLocation,
|
|
4335
|
-
} of table.rebasedRootNodes.detachLocations.entries()) {
|
|
4336
|
-
const normalizedDetachLocation = normalizeFieldId(
|
|
4337
|
-
detachLocation,
|
|
4338
|
-
table.baseChange.nodeAliases,
|
|
4339
|
-
);
|
|
4340
|
-
|
|
4341
|
-
if (normalizedDetachLocation.nodeId !== undefined) {
|
|
4342
|
-
const rebasedNodeId = getFromChangeAtomIdMap(
|
|
4343
|
-
table.baseToRebasedNodeId,
|
|
4344
|
-
normalizedDetachLocation.nodeId,
|
|
4345
|
-
);
|
|
4346
|
-
|
|
4347
|
-
if (rebasedNodeId !== undefined) {
|
|
4348
|
-
table.rebasedRootNodes.detachLocations.set(start, length, {
|
|
4349
|
-
...normalizedDetachLocation,
|
|
4350
|
-
nodeId: rebasedNodeId,
|
|
4351
|
-
});
|
|
4352
|
-
}
|
|
4353
|
-
}
|
|
4354
|
-
}
|
|
4355
|
-
}
|
|
4356
|
-
|
|
4357
|
-
function addNodesToCompose(table: ComposeTable, id1: NodeId, id2: NodeId): void {
|
|
4358
|
-
const normalizedId1 = normalizeNodeId(id1, table.baseChange.nodeAliases);
|
|
4359
|
-
const normalizedId2 = normalizeNodeId(id2, table.newChange.nodeAliases);
|
|
4360
|
-
if (getFromChangeAtomIdMap(table.newToBaseNodeId, normalizedId2) === undefined) {
|
|
4361
|
-
setInChangeAtomIdMap(table.newToBaseNodeId, normalizedId2, normalizedId1);
|
|
4362
|
-
table.pendingCompositions.nodeIdsToCompose.push([normalizedId1, normalizedId2]);
|
|
4363
|
-
}
|
|
4364
|
-
}
|
|
4365
|
-
|
|
4366
|
-
function composeRevInfos(
|
|
4367
|
-
revisions1: readonly RevisionInfo[] | undefined,
|
|
4368
|
-
revisions2: readonly RevisionInfo[] | undefined,
|
|
4369
|
-
): RevisionInfo[] {
|
|
4370
|
-
const result: RevisionInfo[] = [...(revisions1 ?? []), ...(revisions2 ?? [])];
|
|
4371
|
-
return result;
|
|
4372
|
-
}
|
|
4373
|
-
|
|
4374
|
-
function composeCrossFieldKeyTables(
|
|
4375
|
-
table1: CrossFieldKeyTable,
|
|
4376
|
-
table2: CrossFieldKeyTable,
|
|
4377
|
-
movedCrossFieldKeys: CrossFieldKeyTable,
|
|
4378
|
-
removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
|
|
4379
|
-
): CrossFieldKeyTable {
|
|
4380
|
-
const composedTable = RangeMap.union(table1, table2);
|
|
4381
|
-
for (const entry of movedCrossFieldKeys.entries()) {
|
|
4382
|
-
composedTable.set(entry.start, entry.length, entry.value);
|
|
4383
|
-
}
|
|
4384
|
-
|
|
4385
|
-
for (const entry of removedCrossFieldKeys.entries()) {
|
|
4386
|
-
composedTable.delete(entry.start, entry.length);
|
|
4387
|
-
}
|
|
4388
|
-
|
|
4389
|
-
return composedTable;
|
|
4390
|
-
}
|
|
4391
|
-
|
|
4392
|
-
function composeRootTables(
|
|
4393
|
-
change1: ModularChangeset,
|
|
4394
|
-
change2: ModularChangeset,
|
|
4395
|
-
composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
4396
|
-
movedCrossFieldKeys: CrossFieldKeyTable,
|
|
4397
|
-
removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
|
|
4398
|
-
pendingCompositions: PendingCompositions,
|
|
4399
|
-
): RootNodeTable {
|
|
4400
|
-
const composedTable = cloneRootTable(change1.rootNodes);
|
|
4401
|
-
|
|
4402
|
-
for (const renameEntry of change2.rootNodes.oldToNewId.entries()) {
|
|
4403
|
-
composeRename(
|
|
4404
|
-
change1,
|
|
4405
|
-
change2,
|
|
4406
|
-
composedTable,
|
|
4407
|
-
renameEntry.start,
|
|
4408
|
-
renameEntry.value,
|
|
4409
|
-
renameEntry.length,
|
|
4410
|
-
movedCrossFieldKeys,
|
|
4411
|
-
removedCrossFieldKeys,
|
|
4412
|
-
pendingCompositions,
|
|
4413
|
-
);
|
|
4414
|
-
}
|
|
4415
|
-
|
|
4416
|
-
for (const [[revision2, id2], nodeId2] of change2.rootNodes.nodeChanges.entries()) {
|
|
4417
|
-
const detachId2 = { revision: revision2, localId: id2 };
|
|
4418
|
-
const detachId1 = firstDetachIdFromAttachId(change1.rootNodes, detachId2, 1).value;
|
|
4419
|
-
const nodeId1 = getFromChangeAtomIdMap(change1.rootNodes.nodeChanges, detachId1);
|
|
4420
|
-
|
|
4421
|
-
if (nodeId1 !== undefined) {
|
|
4422
|
-
pendingCompositions.nodeIdsToCompose.push([nodeId1, nodeId2]);
|
|
4423
|
-
} else {
|
|
4424
|
-
const fieldId = getFieldsForCrossFieldKey(
|
|
4425
|
-
change1,
|
|
4426
|
-
{ ...detachId1, target: CrossFieldTarget.Source },
|
|
4427
|
-
1,
|
|
4428
|
-
)[0];
|
|
4429
|
-
|
|
4430
|
-
if (fieldId !== undefined) {
|
|
4431
|
-
// In this case, this node is attached in the input context of change1,
|
|
4432
|
-
// and is represented in detachFieldId.
|
|
4433
|
-
pendingCompositions.affectedBaseFields.set(
|
|
4434
|
-
[fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field],
|
|
4435
|
-
true,
|
|
4436
|
-
);
|
|
4437
|
-
} else {
|
|
4438
|
-
assignRootChange(
|
|
4439
|
-
composedTable,
|
|
4440
|
-
composedNodeToParent,
|
|
4441
|
-
detachId1,
|
|
4442
|
-
nodeId2,
|
|
4443
|
-
change1.rootNodes.detachLocations.getFirst(detachId1, 1).value ??
|
|
4444
|
-
change2.rootNodes.detachLocations.getFirst(detachId2, 1).value,
|
|
4445
|
-
Math.max(change1.rebaseVersion, change2.rebaseVersion) as RebaseVersion,
|
|
4446
|
-
);
|
|
4447
|
-
}
|
|
4448
|
-
}
|
|
4449
|
-
}
|
|
4450
|
-
|
|
4451
|
-
for (const outputDetachEntry of change1.rootNodes.outputDetachLocations.entries()) {
|
|
4452
|
-
composeOutputDetachLocation(
|
|
4453
|
-
outputDetachEntry.start,
|
|
4454
|
-
outputDetachEntry.length,
|
|
4455
|
-
outputDetachEntry.value,
|
|
4456
|
-
change2,
|
|
4457
|
-
composedTable,
|
|
4458
|
-
);
|
|
4459
|
-
}
|
|
4460
|
-
|
|
4461
|
-
for (const entry of change2.rootNodes.outputDetachLocations.entries()) {
|
|
4462
|
-
composedTable.outputDetachLocations.set(entry.start, entry.length, entry.value);
|
|
4463
|
-
}
|
|
4464
|
-
|
|
4465
|
-
return composedTable;
|
|
4466
|
-
}
|
|
4467
|
-
|
|
4468
|
-
function composeOutputDetachLocation(
|
|
4469
|
-
outputDetachId1: ChangeAtomId,
|
|
4470
|
-
count: number,
|
|
4471
|
-
detachLocation: FieldId,
|
|
4472
|
-
change2: ModularChangeset,
|
|
4473
|
-
composedTable: RootNodeTable,
|
|
4474
|
-
): void {
|
|
4475
|
-
let countToProcess = count;
|
|
4476
|
-
const renameEntry = firstAttachIdFromDetachId(
|
|
4477
|
-
change2.rootNodes,
|
|
4478
|
-
outputDetachId1,
|
|
4479
|
-
countToProcess,
|
|
4480
|
-
);
|
|
4481
|
-
countToProcess = renameEntry.length;
|
|
4482
|
-
|
|
4483
|
-
const attachEntry = getFirstAttachField(
|
|
4484
|
-
change2.crossFieldKeys,
|
|
4485
|
-
renameEntry.value,
|
|
4486
|
-
countToProcess,
|
|
4487
|
-
);
|
|
4488
|
-
countToProcess = attachEntry.length;
|
|
4489
|
-
|
|
4490
|
-
composedTable.outputDetachLocations.delete(outputDetachId1, countToProcess);
|
|
4491
|
-
|
|
4492
|
-
if (attachEntry.value === undefined) {
|
|
4493
|
-
// We update the key for the detach location to the renamed ID of the root in the composed output context.
|
|
4494
|
-
composedTable.outputDetachLocations.set(renameEntry.value, countToProcess, detachLocation);
|
|
4495
|
-
} else {
|
|
4496
|
-
// These nodes are attached by `change2` and thus attached in the composed output context,
|
|
4497
|
-
// so there should be no output detach location.
|
|
4498
|
-
}
|
|
4499
|
-
|
|
4500
|
-
const countRemaining = count - countToProcess;
|
|
4501
|
-
if (countRemaining > 0) {
|
|
4502
|
-
composeOutputDetachLocation(
|
|
4503
|
-
offsetChangeAtomId(outputDetachId1, countToProcess),
|
|
4504
|
-
countRemaining,
|
|
4505
|
-
detachLocation,
|
|
4506
|
-
change2,
|
|
4507
|
-
composedTable,
|
|
4508
|
-
);
|
|
4509
|
-
}
|
|
4510
|
-
}
|
|
4511
|
-
|
|
4512
|
-
function composeRename(
|
|
4513
|
-
change1: ModularChangeset,
|
|
4514
|
-
change2: ModularChangeset,
|
|
4515
|
-
mergedTable: RootNodeTable,
|
|
4516
|
-
oldId: ChangeAtomId,
|
|
4517
|
-
newId: ChangeAtomId,
|
|
4518
|
-
count: number,
|
|
4519
|
-
movedCrossFieldKeys: CrossFieldKeyTable,
|
|
4520
|
-
removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
|
|
4521
|
-
pendingCompositions: PendingCompositions,
|
|
4522
|
-
): void {
|
|
4523
|
-
let countToProcess = count;
|
|
4524
|
-
const detachEntry = getFirstDetachField(change1.crossFieldKeys, oldId, countToProcess);
|
|
4525
|
-
countToProcess = detachEntry.length;
|
|
4526
|
-
|
|
4527
|
-
if (detachEntry.value !== undefined) {
|
|
4528
|
-
// `change1` detached these nodes,
|
|
4529
|
-
// so we invalidate the detach location so that the detach's ID can be replaced with the new ID.
|
|
4530
|
-
pendingCompositions.affectedBaseFields.set(fieldIdKeyFromFieldId(detachEntry.value), true);
|
|
4531
|
-
|
|
4532
|
-
if (!areEqualChangeAtomIds(oldId, newId)) {
|
|
4533
|
-
// `change1`'s detach will be replaced by `change2`'s detach, so we update the cross-field keys.
|
|
4534
|
-
removedCrossFieldKeys.set(
|
|
4535
|
-
{ ...oldId, target: CrossFieldTarget.Source },
|
|
4536
|
-
countToProcess,
|
|
4537
|
-
true,
|
|
4538
|
-
);
|
|
4539
|
-
}
|
|
4540
|
-
|
|
4541
|
-
movedCrossFieldKeys.set(
|
|
4542
|
-
{ ...newId, target: CrossFieldTarget.Source },
|
|
4543
|
-
countToProcess,
|
|
4544
|
-
detachEntry.value,
|
|
4545
|
-
);
|
|
4546
|
-
} else {
|
|
4547
|
-
// `change1` may also have a rename to `renameEntry.value`, in which case it must refer to a different node.
|
|
4548
|
-
// That node must have been attached by `change1` and detached by `change2`.
|
|
4549
|
-
// The final rename for that node will be created in `composeAttachDetach`.
|
|
4550
|
-
// We delete any such rename for now to avoid colliding with the rename currently being processed.
|
|
4551
|
-
deleteNodeRenameTo(mergedTable, newId, countToProcess);
|
|
4552
|
-
|
|
4553
|
-
// The nodes were detached before `change`, so we append this rename.
|
|
4554
|
-
appendNodeRename(
|
|
4555
|
-
mergedTable,
|
|
4556
|
-
oldId,
|
|
4557
|
-
newId,
|
|
4558
|
-
countToProcess,
|
|
4559
|
-
change1.rootNodes,
|
|
4560
|
-
change2.rootNodes.detachLocations.getFirst(oldId, countToProcess).value,
|
|
4561
|
-
);
|
|
4562
|
-
}
|
|
4563
|
-
|
|
4564
|
-
if (countToProcess < count) {
|
|
4565
|
-
composeRename(
|
|
4566
|
-
change1,
|
|
4567
|
-
change2,
|
|
4568
|
-
mergedTable,
|
|
4569
|
-
offsetChangeAtomId(oldId, countToProcess),
|
|
4570
|
-
offsetChangeAtomId(newId, countToProcess),
|
|
4571
|
-
count - countToProcess,
|
|
4572
|
-
movedCrossFieldKeys,
|
|
4573
|
-
removedCrossFieldKeys,
|
|
4574
|
-
pendingCompositions,
|
|
4575
|
-
);
|
|
4576
|
-
}
|
|
4577
|
-
}
|
|
4578
|
-
|
|
4579
|
-
export function cloneRootTable(table: RootNodeTable): RootNodeTable {
|
|
4580
|
-
return {
|
|
4581
|
-
oldToNewId: table.oldToNewId.clone(),
|
|
4582
|
-
newToOldId: table.newToOldId.clone(),
|
|
4583
|
-
nodeChanges: brand(table.nodeChanges.clone()),
|
|
4584
|
-
detachLocations: table.detachLocations.clone(),
|
|
4585
|
-
outputDetachLocations: table.outputDetachLocations.clone(),
|
|
4586
|
-
};
|
|
4587
|
-
}
|
|
4588
|
-
|
|
4589
|
-
function invertRootTable(change: ModularChangeset, isRollback: boolean): RootNodeTable {
|
|
4590
|
-
const invertedRoots: RootNodeTable = newRootTable();
|
|
4591
|
-
for (const [[revision, localId], nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
4592
|
-
const detachId: ChangeAtomId = { revision, localId };
|
|
4593
|
-
const renamedId = firstAttachIdFromDetachId(change.rootNodes, detachId, 1).value;
|
|
4594
|
-
|
|
4595
|
-
// This checks whether `change` attaches this node.
|
|
4596
|
-
// If it does, the node is not detached in the input context of the inverse, and so should not be included in the root table.
|
|
4597
|
-
if (
|
|
4598
|
-
change.crossFieldKeys.getFirst({ ...renamedId, target: CrossFieldTarget.Destination }, 1)
|
|
4599
|
-
.value === undefined
|
|
4600
|
-
) {
|
|
4601
|
-
assignRootChange(
|
|
4602
|
-
invertedRoots,
|
|
4603
|
-
undefined,
|
|
4604
|
-
renamedId,
|
|
4605
|
-
nodeId,
|
|
4606
|
-
change.rootNodes.detachLocations.getFirst(detachId, 1).value,
|
|
4607
|
-
change.rebaseVersion,
|
|
4608
|
-
);
|
|
4609
|
-
}
|
|
4610
|
-
}
|
|
4611
|
-
|
|
4612
|
-
if (isRollback) {
|
|
4613
|
-
// We only invert renames of nodes which are not attached or detached by this changeset.
|
|
4614
|
-
// When we invert an attach we will create a detach which incorporates the rename.
|
|
4615
|
-
for (const {
|
|
4616
|
-
start: oldId,
|
|
4617
|
-
value: newId,
|
|
4618
|
-
length,
|
|
4619
|
-
} of change.rootNodes.oldToNewId.entries()) {
|
|
4620
|
-
invertRename(change, invertedRoots, oldId, newId, length);
|
|
4621
|
-
}
|
|
4622
|
-
}
|
|
4623
|
-
|
|
4624
|
-
return invertedRoots;
|
|
4625
|
-
}
|
|
4626
|
-
|
|
4627
|
-
function invertRename(
|
|
4628
|
-
change: ModularChangeset,
|
|
4629
|
-
invertedRoots: RootNodeTable,
|
|
4630
|
-
oldId: ChangeAtomId,
|
|
4631
|
-
newId: ChangeAtomId,
|
|
4632
|
-
length: number,
|
|
4633
|
-
): void {
|
|
4634
|
-
for (const detachEntry of doesChangeDetachNodes(change.crossFieldKeys, newId, length)) {
|
|
4635
|
-
assert(
|
|
4636
|
-
!detachEntry.value,
|
|
4637
|
-
"A changeset should not have a rename and detach for the same node.",
|
|
4638
|
-
);
|
|
4639
|
-
}
|
|
4640
|
-
|
|
4641
|
-
let countProcessed = length;
|
|
4642
|
-
const attachEntry = getFirstAttachField(change.crossFieldKeys, newId, countProcessed);
|
|
4643
|
-
countProcessed = attachEntry.length;
|
|
4644
|
-
if (attachEntry.value === undefined) {
|
|
4645
|
-
const outputDetachEntry = change.rootNodes.outputDetachLocations.getFirst(
|
|
4646
|
-
newId,
|
|
4647
|
-
countProcessed,
|
|
4648
|
-
);
|
|
4649
|
-
countProcessed = outputDetachEntry.length;
|
|
4650
|
-
|
|
4651
|
-
const inputDetachEntry = change.rootNodes.detachLocations.getFirst(oldId, countProcessed);
|
|
4652
|
-
countProcessed = inputDetachEntry.length;
|
|
4653
|
-
|
|
4654
|
-
addNodeRename(
|
|
4655
|
-
invertedRoots,
|
|
4656
|
-
newId,
|
|
4657
|
-
oldId,
|
|
4658
|
-
countProcessed,
|
|
4659
|
-
outputDetachEntry.value ?? inputDetachEntry.value,
|
|
4660
|
-
);
|
|
4661
|
-
}
|
|
4662
|
-
|
|
4663
|
-
if (countProcessed < length) {
|
|
4664
|
-
invertRename(
|
|
4665
|
-
change,
|
|
4666
|
-
invertedRoots,
|
|
4667
|
-
offsetChangeAtomId(oldId, countProcessed),
|
|
4668
|
-
offsetChangeAtomId(newId, countProcessed),
|
|
4669
|
-
length - countProcessed,
|
|
4670
|
-
);
|
|
4671
|
-
}
|
|
4672
|
-
}
|
|
4673
|
-
|
|
4674
|
-
function doesChangeAttachNodes(
|
|
4675
|
-
table: CrossFieldKeyTable,
|
|
4676
|
-
id: ChangeAtomId,
|
|
4677
|
-
count: number,
|
|
4678
|
-
): RangeQueryResultFragment<boolean>[] {
|
|
4679
|
-
return table
|
|
4680
|
-
.getAll2({ ...id, target: CrossFieldTarget.Destination }, count)
|
|
4681
|
-
.map((entry) => ({ ...entry, value: entry.value !== undefined }));
|
|
4682
|
-
}
|
|
4683
|
-
|
|
4684
|
-
function doesChangeDetachNodes(
|
|
4685
|
-
table: CrossFieldKeyTable,
|
|
4686
|
-
id: ChangeAtomId,
|
|
4687
|
-
count: number,
|
|
4688
|
-
): RangeQueryResultFragment<boolean>[] {
|
|
4689
|
-
return table
|
|
4690
|
-
.getAll2({ ...id, target: CrossFieldTarget.Source }, count)
|
|
4691
|
-
.map((entry) => ({ ...entry, value: entry.value !== undefined }));
|
|
4692
|
-
}
|
|
4693
|
-
|
|
4694
|
-
export function getFirstDetachField(
|
|
4695
|
-
table: CrossFieldKeyTable,
|
|
4696
|
-
id: ChangeAtomId,
|
|
4697
|
-
count: number,
|
|
4698
|
-
): RangeQueryResult<FieldId | undefined> {
|
|
4699
|
-
return table.getFirst({ target: CrossFieldTarget.Source, ...id }, count);
|
|
4700
|
-
}
|
|
4701
|
-
|
|
4702
|
-
export function getFirstAttachField(
|
|
4703
|
-
table: CrossFieldKeyTable,
|
|
4704
|
-
id: ChangeAtomId,
|
|
4705
|
-
count: number,
|
|
4706
|
-
): RangeQueryResult<FieldId | undefined> {
|
|
4707
|
-
return table.getFirst({ target: CrossFieldTarget.Destination, ...id }, count);
|
|
4708
|
-
}
|
|
4709
|
-
|
|
4710
|
-
export function addNodeRename(
|
|
4711
|
-
table: RootNodeTable,
|
|
4712
|
-
oldId: ChangeAtomId,
|
|
4713
|
-
newId: ChangeAtomId,
|
|
4714
|
-
count: number,
|
|
4715
|
-
detachLocation: FieldId | undefined,
|
|
4716
|
-
): void {
|
|
4717
|
-
if (areEqualChangeAtomIds(oldId, newId)) {
|
|
4718
|
-
return;
|
|
4719
|
-
}
|
|
4720
|
-
|
|
4721
|
-
for (const entry of table.oldToNewId.getAll2(oldId, count)) {
|
|
4722
|
-
assert(
|
|
4723
|
-
entry.value === undefined ||
|
|
4724
|
-
areEqualChangeAtomIds(entry.value, offsetChangeAtomId(newId, entry.offset)),
|
|
4725
|
-
"Rename collision detected",
|
|
4726
|
-
);
|
|
4727
|
-
}
|
|
4728
|
-
|
|
4729
|
-
for (const entry of table.newToOldId.getAll2(newId, count)) {
|
|
4730
|
-
assert(
|
|
4731
|
-
entry.value === undefined ||
|
|
4732
|
-
areEqualChangeAtomIds(entry.value, offsetChangeAtomId(oldId, entry.offset)),
|
|
4733
|
-
"Rename collision detected",
|
|
4734
|
-
);
|
|
4735
|
-
}
|
|
4736
|
-
|
|
4737
|
-
table.oldToNewId.set(oldId, count, newId);
|
|
4738
|
-
table.newToOldId.set(newId, count, oldId);
|
|
4739
|
-
|
|
4740
|
-
if (detachLocation !== undefined) {
|
|
4741
|
-
table.detachLocations.set(oldId, count, detachLocation);
|
|
4742
|
-
}
|
|
4743
|
-
}
|
|
4744
|
-
|
|
4745
|
-
/**
|
|
4746
|
-
* Deletes any renames from `id`.
|
|
4747
|
-
*/
|
|
4748
|
-
function deleteNodeRenameFrom(roots: RootNodeTable, id: ChangeAtomId, count: number): void {
|
|
4749
|
-
for (const entry of roots.oldToNewId.getAll(id, count)) {
|
|
4750
|
-
deleteNodeRenameEntry(roots, entry.start, entry.value, entry.length);
|
|
4751
|
-
}
|
|
4752
|
-
}
|
|
4753
|
-
|
|
4754
|
-
/**
|
|
4755
|
-
* Deletes any renames to `id`.
|
|
4756
|
-
*/
|
|
4757
|
-
function deleteNodeRenameTo(roots: RootNodeTable, id: ChangeAtomId, count: number): void {
|
|
4758
|
-
for (const entry of roots.newToOldId.getAll(id, count)) {
|
|
4759
|
-
deleteNodeRenameEntry(roots, entry.value, entry.start, entry.length);
|
|
4760
|
-
}
|
|
4761
|
-
}
|
|
4762
|
-
|
|
4763
|
-
function appendNodeRename(
|
|
4764
|
-
composedTable: RootNodeTable,
|
|
4765
|
-
oldId: ChangeAtomId,
|
|
4766
|
-
newId: ChangeAtomId,
|
|
4767
|
-
count: number,
|
|
4768
|
-
change1Table: RootNodeTable,
|
|
4769
|
-
detachLocation: FieldId | undefined,
|
|
4770
|
-
): void {
|
|
4771
|
-
let countToProcess = count;
|
|
4772
|
-
const rename1Entry = change1Table.newToOldId.getFirst(oldId, countToProcess);
|
|
4773
|
-
countToProcess = rename1Entry.length;
|
|
4774
|
-
|
|
4775
|
-
if (rename1Entry.value !== undefined) {
|
|
4776
|
-
deleteNodeRenameFrom(composedTable, rename1Entry.value, countToProcess);
|
|
4777
|
-
}
|
|
4778
|
-
|
|
4779
|
-
addNodeRename(
|
|
4780
|
-
composedTable,
|
|
4781
|
-
rename1Entry.value ?? oldId,
|
|
4782
|
-
newId,
|
|
4783
|
-
countToProcess,
|
|
4784
|
-
detachLocation,
|
|
4785
|
-
);
|
|
4786
|
-
|
|
4787
|
-
tryRemoveDetachLocation(composedTable, newId, countToProcess);
|
|
4788
|
-
|
|
4789
|
-
if (countToProcess < count) {
|
|
4790
|
-
const countRemaining = count - countToProcess;
|
|
4791
|
-
appendNodeRename(
|
|
4792
|
-
composedTable,
|
|
4793
|
-
offsetChangeAtomId(oldId, countToProcess),
|
|
4794
|
-
offsetChangeAtomId(newId, countToProcess),
|
|
4795
|
-
countRemaining,
|
|
4796
|
-
change1Table,
|
|
4797
|
-
detachLocation,
|
|
4798
|
-
);
|
|
4799
|
-
}
|
|
4800
|
-
}
|
|
4801
|
-
|
|
4802
|
-
function tryRemoveDetachLocation(
|
|
4803
|
-
roots: RootNodeTable,
|
|
4804
|
-
rootId: ChangeAtomId,
|
|
4805
|
-
count: number,
|
|
4806
|
-
): void {
|
|
4807
|
-
let countProcessed = count;
|
|
4808
|
-
const renameEntry = roots.oldToNewId.getFirst(rootId, countProcessed);
|
|
4809
|
-
countProcessed = renameEntry.length;
|
|
4810
|
-
|
|
4811
|
-
const outputDetachEntry = roots.outputDetachLocations.getFirst(rootId, countProcessed);
|
|
4812
|
-
countProcessed = outputDetachEntry.length;
|
|
4813
|
-
|
|
4814
|
-
const nodeChangeEntry = rangeQueryChangeAtomIdMap(roots.nodeChanges, rootId, countProcessed);
|
|
4815
|
-
countProcessed = nodeChangeEntry.length;
|
|
4816
|
-
|
|
4817
|
-
if (
|
|
4818
|
-
nodeChangeEntry.value === undefined &&
|
|
4819
|
-
renameEntry.value === undefined &&
|
|
4820
|
-
outputDetachEntry.value === undefined
|
|
4821
|
-
) {
|
|
4822
|
-
roots.detachLocations.delete(rootId, countProcessed);
|
|
4823
|
-
}
|
|
4824
|
-
|
|
4825
|
-
const countRemaining = count - countProcessed;
|
|
4826
|
-
if (countRemaining > 0) {
|
|
4827
|
-
tryRemoveDetachLocation(roots, offsetChangeAtomId(rootId, countProcessed), countRemaining);
|
|
4828
|
-
}
|
|
4829
|
-
}
|
|
4830
|
-
|
|
4831
|
-
/**
|
|
4832
|
-
* Deletes the entry renaming the ID range of length `count` from `oldId` to `newId`.
|
|
4833
|
-
* This function assumes that such an entry exists.
|
|
4834
|
-
*/
|
|
4835
|
-
function deleteNodeRenameEntry(
|
|
4836
|
-
roots: RootNodeTable,
|
|
4837
|
-
oldId: ChangeAtomId,
|
|
4838
|
-
newId: ChangeAtomId,
|
|
4839
|
-
count: number,
|
|
4840
|
-
): void {
|
|
4841
|
-
roots.oldToNewId.delete(oldId, count);
|
|
4842
|
-
roots.newToOldId.delete(newId, count);
|
|
4843
|
-
}
|
|
4844
|
-
|
|
4845
|
-
function replaceRootTableRevision(
|
|
4846
|
-
table: RootNodeTable,
|
|
4847
|
-
oldRevisions: Set<RevisionTag | undefined>,
|
|
4848
|
-
newRevision: RevisionTag | undefined,
|
|
4849
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
4850
|
-
): RootNodeTable {
|
|
4851
|
-
const oldToNewId = table.oldToNewId.mapEntries(
|
|
4852
|
-
(id) => replaceAtomRevisions(id, oldRevisions, newRevision),
|
|
4853
|
-
(id) => replaceAtomRevisions(id, oldRevisions, newRevision),
|
|
4854
|
-
);
|
|
4855
|
-
|
|
4856
|
-
const newToOldId = table.newToOldId.mapEntries(
|
|
4857
|
-
(id) => replaceAtomRevisions(id, oldRevisions, newRevision),
|
|
4858
|
-
(id) => replaceAtomRevisions(id, oldRevisions, newRevision),
|
|
4859
|
-
);
|
|
4860
|
-
|
|
4861
|
-
const nodeChanges: ChangeAtomIdBTree<NodeId> = newTupleBTree(
|
|
4862
|
-
[...table.nodeChanges.entries()].map(([[revision, id], nodeId]) => [
|
|
4863
|
-
[oldRevisions.has(revision) ? newRevision : revision, id],
|
|
4864
|
-
replaceAtomRevisions(normalizeNodeId(nodeId, nodeAliases), oldRevisions, newRevision),
|
|
4865
|
-
]),
|
|
4866
|
-
);
|
|
4867
|
-
|
|
4868
|
-
const detachLocations = table.detachLocations.mapEntries(
|
|
4869
|
-
(id) => replaceAtomRevisions(id, oldRevisions, newRevision),
|
|
4870
|
-
(fieldId) =>
|
|
4871
|
-
replaceFieldIdRevision(
|
|
4872
|
-
normalizeFieldId(fieldId, nodeAliases),
|
|
4873
|
-
oldRevisions,
|
|
4874
|
-
newRevision,
|
|
4875
|
-
),
|
|
4876
|
-
);
|
|
4877
|
-
|
|
4878
|
-
const outputDetachLocations = table.outputDetachLocations.mapEntries(
|
|
4879
|
-
(id) => replaceAtomRevisions(id, oldRevisions, newRevision),
|
|
4880
|
-
(fieldId) =>
|
|
4881
|
-
replaceFieldIdRevision(
|
|
4882
|
-
normalizeFieldId(fieldId, nodeAliases),
|
|
4883
|
-
oldRevisions,
|
|
4884
|
-
newRevision,
|
|
4885
|
-
),
|
|
4886
|
-
);
|
|
4887
|
-
|
|
4888
|
-
return { oldToNewId, newToOldId, nodeChanges, detachLocations, outputDetachLocations };
|
|
4889
|
-
}
|
|
4890
|
-
|
|
4891
|
-
function newDetachedEntryMap(): ChangeAtomIdRangeMap<DetachedNodeEntry> {
|
|
4892
|
-
return new RangeMap(offsetChangeAtomId, subtractChangeAtomIds, offsetDetachedNodeEntry);
|
|
4893
|
-
}
|
|
4894
|
-
|
|
4895
|
-
function offsetDetachedNodeEntry(entry: DetachedNodeEntry, count: number): DetachedNodeEntry {
|
|
4896
|
-
assert(
|
|
4897
|
-
count <= 1 || entry.nodeChange === undefined,
|
|
4898
|
-
"Cannot split an entry with a node change",
|
|
4899
|
-
);
|
|
4900
|
-
|
|
4901
|
-
return entry.detachId !== undefined
|
|
4902
|
-
? { ...entry, detachId: offsetChangeAtomId(entry.detachId, count) }
|
|
4903
|
-
: entry;
|
|
4904
|
-
}
|
|
4905
|
-
|
|
4906
|
-
function getFieldsWithRootMoves(
|
|
4907
|
-
roots: RootNodeTable,
|
|
4908
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
4909
|
-
): TupleBTree<FieldIdKey, boolean> {
|
|
4910
|
-
const fields: TupleBTree<FieldIdKey, boolean> = newTupleBTree();
|
|
4911
|
-
for (const { start: rootId, value: fieldId, length } of roots.detachLocations.entries()) {
|
|
4912
|
-
let isRootMoved = false;
|
|
4913
|
-
for (const renameEntry of roots.oldToNewId.getAll2(rootId, length)) {
|
|
4914
|
-
if (renameEntry.value !== undefined) {
|
|
4915
|
-
isRootMoved = true;
|
|
4916
|
-
}
|
|
4917
|
-
}
|
|
4918
|
-
|
|
4919
|
-
for (const outputDetachEntry of roots.outputDetachLocations.getAll2(rootId, length)) {
|
|
4920
|
-
if (outputDetachEntry.value !== undefined) {
|
|
4921
|
-
isRootMoved = true;
|
|
4922
|
-
}
|
|
4923
|
-
}
|
|
4924
|
-
|
|
4925
|
-
if (isRootMoved) {
|
|
4926
|
-
fields.set(fieldIdKeyFromFieldId(normalizeFieldId(fieldId, nodeAliases)), true);
|
|
4927
|
-
}
|
|
4928
|
-
}
|
|
4929
|
-
|
|
4930
|
-
return fields;
|
|
4931
|
-
}
|
|
4932
|
-
|
|
4933
|
-
function getFieldToRootChanges(
|
|
4934
|
-
roots: RootNodeTable,
|
|
4935
|
-
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
4936
|
-
): TupleBTree<FieldIdKey, ChangeAtomId[]> {
|
|
4937
|
-
const fields: TupleBTree<FieldIdKey, ChangeAtomId[]> = newTupleBTree();
|
|
4938
|
-
for (const rootIdKey of roots.nodeChanges.keys()) {
|
|
4939
|
-
const rootId: ChangeAtomId = { revision: rootIdKey[0], localId: rootIdKey[1] };
|
|
4940
|
-
const detachLocation = roots.detachLocations.getFirst(rootId, 1).value;
|
|
4941
|
-
if (detachLocation !== undefined) {
|
|
4942
|
-
const fieldIdKey = fieldIdKeyFromFieldId(normalizeFieldId(detachLocation, nodeAliases));
|
|
4943
|
-
let rootsInField = fields.get(fieldIdKey);
|
|
4944
|
-
if (rootsInField === undefined) {
|
|
4945
|
-
rootsInField = [];
|
|
4946
|
-
fields.set(fieldIdKey, rootsInField);
|
|
4947
|
-
}
|
|
4948
|
-
|
|
4949
|
-
rootsInField.push(rootId);
|
|
4950
|
-
}
|
|
4951
|
-
}
|
|
4952
|
-
|
|
4953
|
-
return fields;
|
|
4954
|
-
}
|
|
4955
|
-
|
|
4956
|
-
function muteRootChanges(roots: RootNodeTable): RootNodeTable {
|
|
4957
|
-
return {
|
|
4958
|
-
oldToNewId: newChangeAtomIdTransform(),
|
|
4959
|
-
newToOldId: newChangeAtomIdTransform(),
|
|
4960
|
-
nodeChanges: brand(roots.nodeChanges.clone()),
|
|
4961
|
-
detachLocations: roots.detachLocations.clone(),
|
|
4962
|
-
outputDetachLocations: newChangeAtomIdRangeMap(),
|
|
4963
|
-
};
|
|
4964
|
-
}
|