@fluidframework/tree 2.74.0-365691 → 2.74.0-370705
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/.vscode/settings.json +2 -2
- package/api-report/tree.alpha.api.md +119 -85
- package/api-report/tree.beta.api.md +0 -1
- package/api-report/tree.legacy.beta.api.md +0 -1
- package/api-report/tree.legacy.public.api.md +0 -1
- package/api-report/tree.public.api.md +0 -1
- package/dist/alpha.d.ts +3 -2
- package/dist/codec/codec.d.ts +14 -1
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +11 -0
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/versioned/codec.d.ts +1 -1
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/codec/versioned/format.d.ts +4 -1
- package/dist/codec/versioned/format.d.ts.map +1 -1
- package/dist/codec/versioned/format.js +4 -1
- package/dist/codec/versioned/format.js.map +1 -1
- package/dist/core/change-family/changeFamily.d.ts +4 -1
- 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 +7 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/rebase/changeRebaser.d.ts +6 -1
- 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 +1 -1
- package/dist/core/rebase/index.d.ts.map +1 -1
- package/dist/core/rebase/index.js +2 -1
- package/dist/core/rebase/index.js.map +1 -1
- package/dist/core/rebase/types.d.ts +2 -1
- package/dist/core/rebase/types.d.ts.map +1 -1
- package/dist/core/rebase/types.js +5 -1
- 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 +25 -7
- package/dist/core/rebase/utils.js.map +1 -1
- package/dist/core/tree/detachedFieldIndex.d.ts +40 -13
- package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndex.js +21 -12
- package/dist/core/tree/detachedFieldIndex.js.map +1 -1
- package/dist/core/tree/index.d.ts +4 -3
- package/dist/core/tree/index.d.ts.map +1 -1
- package/dist/core/tree/index.js +6 -2
- package/dist/core/tree/index.js.map +1 -1
- package/dist/core/tree/pathTree.d.ts +11 -3
- package/dist/core/tree/pathTree.d.ts.map +1 -1
- package/dist/core/tree/pathTree.js +14 -2
- package/dist/core/tree/pathTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +7 -0
- 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 +4 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts +14 -6
- package/dist/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +7 -2
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +91 -42
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js +238 -69
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +4 -4
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +33 -28
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/default-schema/index.d.ts +2 -1
- package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/index.js +5 -2
- package/dist/feature-libraries/default-schema/index.js.map +1 -1
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +36 -0
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +1 -0
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js +126 -0
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js.map +1 -0
- package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts +7 -6
- package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/mappedEditBuilder.js +15 -0
- package/dist/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
- package/dist/feature-libraries/deltaUtils.d.ts +1 -0
- package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
- package/dist/feature-libraries/deltaUtils.js +6 -1
- package/dist/feature-libraries/deltaUtils.js.map +1 -1
- package/dist/feature-libraries/detachedFieldIndexSummarizer.d.ts +30 -8
- package/dist/feature-libraries/detachedFieldIndexSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/detachedFieldIndexSummarizer.js +41 -11
- package/dist/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/dist/feature-libraries/flex-tree/context.d.ts +9 -0
- package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js +6 -0
- 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 +8 -7
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +37 -8
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.d.ts +2 -2
- package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.js +4 -4
- package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +9 -13
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +21 -26
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/forest-summary/format.d.ts +41 -5
- package/dist/feature-libraries/forest-summary/format.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/format.js +7 -7
- package/dist/feature-libraries/forest-summary/format.js.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +11 -9
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +16 -29
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/dist/feature-libraries/forest-summary/index.d.ts +2 -1
- package/dist/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/index.js +3 -2
- package/dist/feature-libraries/forest-summary/index.js.map +1 -1
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts +47 -0
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryTypes.js +57 -0
- package/dist/feature-libraries/forest-summary/summaryTypes.js.map +1 -0
- package/dist/feature-libraries/index.d.ts +4 -4
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +8 -3
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.js +1 -0
- 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 +2 -2
- package/dist/feature-libraries/mitigatedChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.d.ts +18 -2
- package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.js +54 -3
- package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +97 -21
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js +4 -7
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +20 -52
- 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/fieldKind.d.ts +25 -13
- package/dist/feature-libraries/modular-schema/fieldKind.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldKind.js +0 -21
- package/dist/feature-libraries/modular-schema/fieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +7 -10
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindCodecs.js +2 -2
- package/dist/feature-libraries/modular-schema/genericFieldKindCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +6 -6
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +13 -8
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +17 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +388 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +17 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js +413 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +8 -284
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +49 -15
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1306 -465
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/{modularChangeFormat.d.ts → modularChangeFormatV1.d.ts} +2 -2
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/{modularChangeFormat.js → modularChangeFormatV1.js} +5 -5
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +146 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +32 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +50 -10
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js +24 -3
- package/dist/feature-libraries/modular-schema/modularChangeTypes.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 +1 -2
- package/dist/feature-libraries/optional-field/index.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.d.ts +5 -26
- package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +217 -451
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +23 -0
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +1 -0
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +31 -0
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +1 -0
- package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +24 -33
- 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 +57 -28
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +12 -0
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +1 -0
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js +57 -0
- package/dist/feature-libraries/optional-field/optionalFieldCodecV3.js.map +1 -0
- package/dist/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecs.js +5 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts +27 -8
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js +42 -16
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.d.ts +6 -7
- package/dist/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +80 -256
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/helperTypes.d.ts +14 -10
- 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 +2 -3
- package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/index.js +1 -3
- 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 +65 -167
- 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 +4 -56
- package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.js +7 -86
- 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 +106 -112
- package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/dist/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/replaceRevisions.js +16 -33
- 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 +0 -2
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +22 -4
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +358 -179
- 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 +20 -60
- 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 +3 -2
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +14 -109
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/dist/feature-libraries/sequence-field/types.d.ts +30 -59
- 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 +15 -24
- package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +111 -299
- package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/independentView.d.ts +1 -1
- package/dist/shared-tree/independentView.d.ts.map +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 +2 -1
- package/dist/shared-tree/schematizeTree.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +1 -5
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +32 -33
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +11 -5
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +14 -4
- 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 +1 -0
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.d.ts +20 -8
- package/dist/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.js +26 -12
- package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.d.ts +5 -5
- package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.js +10 -4
- package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/dist/shared-tree/sharedTreeEditBuilder.d.ts +16 -6
- package/dist/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeEditBuilder.js +14 -7
- package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +1 -1
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +12 -10
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +66 -17
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branch.d.ts +3 -2
- package/dist/shared-tree-core/branch.d.ts.map +1 -1
- package/dist/shared-tree-core/branch.js +4 -3
- package/dist/shared-tree-core/branch.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 +9 -9
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.d.ts +4 -0
- package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.js +16 -6
- package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/{lib/shared-tree-core/editManagerCodecsV5.d.ts → dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts} +3 -3
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{editManagerCodecsV5.js → editManagerCodecsVSharedBranches.js} +7 -7
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts +20 -6
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.js +22 -7
- 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 -0
- package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/dist/shared-tree-core/{editManagerFormatV5.d.ts → editManagerFormatVSharedBranches.d.ts} +3 -3
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{editManagerFormatV5.js → editManagerFormatVSharedBranches.js} +2 -2
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/editManagerSummarizer.d.ts +29 -9
- package/dist/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js +41 -13
- package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/dist/shared-tree-core/index.d.ts +5 -3
- package/dist/shared-tree-core/index.d.ts.map +1 -1
- package/dist/shared-tree-core/index.js +8 -1
- 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/{lib/shared-tree-core/messageCodecV5.d.ts → dist/shared-tree-core/messageCodecVSharedBranches.d.ts} +2 -2
- package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{messageCodecV5.js → messageCodecVSharedBranches.js} +6 -6
- package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/messageCodecs.d.ts +4 -0
- package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecs.js +16 -6
- package/dist/shared-tree-core/messageCodecs.js.map +1 -1
- package/dist/shared-tree-core/messageFormat.d.ts +20 -6
- package/dist/shared-tree-core/messageFormat.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormat.js +22 -7
- package/dist/shared-tree-core/messageFormat.js.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts +3 -2
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js +8 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/{messageFormatV5.d.ts → messageFormatVSharedBranches.d.ts} +5 -7
- package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{messageFormatV5.js → messageFormatVSharedBranches.js} +3 -2
- package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/sharedTreeCore.d.ts +14 -47
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +30 -18
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/shared-tree-core/summaryTypes.d.ts +94 -0
- package/dist/shared-tree-core/summaryTypes.d.ts.map +1 -0
- package/dist/shared-tree-core/summaryTypes.js +47 -0
- package/dist/shared-tree-core/summaryTypes.js.map +1 -0
- package/dist/shared-tree-core/versionedSummarizer.d.ts +67 -0
- package/dist/shared-tree-core/versionedSummarizer.d.ts.map +1 -0
- package/dist/shared-tree-core/versionedSummarizer.js +63 -0
- package/dist/shared-tree-core/versionedSummarizer.js.map +1 -0
- package/dist/simple-tree/api/configuration.d.ts +3 -26
- package/dist/simple-tree/api/configuration.d.ts.map +1 -1
- package/dist/simple-tree/api/configuration.js +10 -21
- package/dist/simple-tree/api/configuration.js.map +1 -1
- package/dist/simple-tree/api/dirtyIndex.d.ts +11 -0
- package/dist/simple-tree/api/dirtyIndex.d.ts.map +1 -1
- package/dist/simple-tree/api/dirtyIndex.js +7 -0
- package/dist/simple-tree/api/dirtyIndex.js.map +1 -1
- package/dist/simple-tree/api/discrepancies.d.ts +1 -1
- package/dist/simple-tree/api/discrepancies.d.ts.map +1 -1
- package/dist/simple-tree/api/discrepancies.js.map +1 -1
- package/dist/simple-tree/api/getSimpleSchema.d.ts +3 -3
- package/dist/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/getSimpleSchema.js +9 -3
- package/dist/simple-tree/api/getSimpleSchema.js.map +1 -1
- package/dist/simple-tree/api/incrementalAllowedTypes.d.ts +1 -1
- package/dist/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -1
- package/dist/simple-tree/api/incrementalAllowedTypes.js +7 -0
- package/dist/simple-tree/api/incrementalAllowedTypes.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +3 -4
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +4 -5
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.d.ts +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +5 -5
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.js +0 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/dist/simple-tree/api/schemaFromSimple.d.ts +6 -1
- package/dist/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFromSimple.js +5 -0
- package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/dist/simple-tree/api/schemaStatics.d.ts +12 -12
- package/dist/simple-tree/api/simpleSchemaCodec.d.ts +15 -3
- package/dist/simple-tree/api/simpleSchemaCodec.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaCodec.js +18 -6
- package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts +8 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js +13 -8
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.d.ts +3 -3
- package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
- package/dist/simple-tree/core/allowedTypes.d.ts +2 -2
- package/dist/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/dist/simple-tree/core/allowedTypes.js.map +1 -1
- package/dist/simple-tree/core/index.d.ts +1 -1
- package/dist/simple-tree/core/index.d.ts.map +1 -1
- package/dist/simple-tree/core/index.js +2 -3
- package/dist/simple-tree/core/index.js.map +1 -1
- package/dist/simple-tree/core/toStored.d.ts +17 -15
- package/dist/simple-tree/core/toStored.d.ts.map +1 -1
- package/dist/simple-tree/core/toStored.js +5 -40
- package/dist/simple-tree/core/toStored.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 +59 -8
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/core/walkSchema.d.ts.map +1 -1
- package/dist/simple-tree/core/walkSchema.js +4 -0
- package/dist/simple-tree/core/walkSchema.js.map +1 -1
- package/dist/simple-tree/createContext.d.ts.map +1 -1
- package/dist/simple-tree/createContext.js +20 -5
- package/dist/simple-tree/createContext.js.map +1 -1
- package/dist/simple-tree/fieldSchema.d.ts +7 -7
- package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
- package/dist/simple-tree/fieldSchema.js.map +1 -1
- package/dist/simple-tree/index.d.ts +8 -7
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +15 -12
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.d.ts +5 -5
- package/dist/simple-tree/leafNodeSchema.d.ts.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 +5 -3
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNodeTypes.d.ts +3 -3
- package/dist/simple-tree/node-kinds/array/arrayNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNodeTypes.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.d.ts.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/map/mapNodeTypes.d.ts +3 -3
- package/dist/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNodeTypes.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 +18 -18
- package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts +2 -2
- package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNodeTypes.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 -2
- package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNodeTypes.d.ts +3 -3
- package/dist/simple-tree/node-kinds/record/recordNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
- package/dist/simple-tree/prepareForInsertion.d.ts +54 -47
- package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/dist/simple-tree/prepareForInsertion.js +183 -125
- package/dist/simple-tree/prepareForInsertion.js.map +1 -1
- package/dist/simple-tree/simpleSchema.d.ts +55 -23
- package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/simpleSchema.js +17 -0
- package/dist/simple-tree/simpleSchema.js.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.d.ts +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.d.ts.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.js +8 -1
- package/dist/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts +58 -11
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +205 -30
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/dist/simple-tree/treeSchema.d.ts +23 -0
- package/dist/simple-tree/treeSchema.d.ts.map +1 -0
- package/dist/simple-tree/treeSchema.js +25 -0
- package/dist/simple-tree/treeSchema.js.map +1 -0
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +13 -4
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +29 -11
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/dist/tableSchema.d.ts +117 -63
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +159 -58
- package/dist/tableSchema.js.map +1 -1
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +17 -3
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/index.d.ts +2 -1
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +4 -1
- package/dist/util/index.js.map +1 -1
- package/dist/util/rangeMap.d.ts +24 -12
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +46 -6
- package/dist/util/rangeMap.js.map +1 -1
- package/dist/util/readSnapshotBlob.d.ts +13 -0
- package/dist/util/readSnapshotBlob.d.ts.map +1 -0
- package/dist/util/readSnapshotBlob.js +18 -0
- package/dist/util/readSnapshotBlob.js.map +1 -0
- package/lib/alpha.d.ts +3 -2
- package/lib/codec/codec.d.ts +14 -1
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +11 -0
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/versioned/codec.d.ts +1 -1
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/codec/versioned/format.d.ts +4 -1
- package/lib/codec/versioned/format.d.ts.map +1 -1
- package/lib/codec/versioned/format.js +4 -1
- package/lib/codec/versioned/format.js.map +1 -1
- package/lib/core/change-family/changeFamily.d.ts +4 -1
- 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 +6 -1
- 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 +1 -1
- 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 +2 -1
- package/lib/core/rebase/types.d.ts.map +1 -1
- package/lib/core/rebase/types.js +3 -0
- 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 +25 -7
- package/lib/core/rebase/utils.js.map +1 -1
- package/lib/core/tree/detachedFieldIndex.d.ts +40 -13
- package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndex.js +22 -13
- package/lib/core/tree/detachedFieldIndex.js.map +1 -1
- package/lib/core/tree/index.d.ts +4 -3
- package/lib/core/tree/index.d.ts.map +1 -1
- package/lib/core/tree/index.js +3 -2
- package/lib/core/tree/index.js.map +1 -1
- package/lib/core/tree/pathTree.d.ts +11 -3
- package/lib/core/tree/pathTree.d.ts.map +1 -1
- package/lib/core/tree/pathTree.js +12 -1
- package/lib/core/tree/pathTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +8 -1
- 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 +4 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts +14 -6
- package/lib/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +7 -2
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +91 -42
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js +236 -70
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +4 -4
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +34 -29
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/default-schema/index.d.ts +2 -1
- package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/index.js +2 -1
- package/lib/feature-libraries/default-schema/index.js.map +1 -1
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +36 -0
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +1 -0
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js +122 -0
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js.map +1 -0
- package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts +7 -6
- package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/mappedEditBuilder.js +15 -0
- package/lib/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
- package/lib/feature-libraries/deltaUtils.d.ts +1 -0
- package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
- package/lib/feature-libraries/deltaUtils.js +5 -1
- package/lib/feature-libraries/deltaUtils.js.map +1 -1
- package/lib/feature-libraries/detachedFieldIndexSummarizer.d.ts +30 -8
- package/lib/feature-libraries/detachedFieldIndexSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/detachedFieldIndexSummarizer.js +38 -8
- package/lib/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/lib/feature-libraries/flex-tree/context.d.ts +9 -0
- package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js +6 -0
- 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 +8 -7
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +38 -9
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.d.ts +2 -2
- package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.js +5 -5
- package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +9 -13
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +17 -22
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/forest-summary/format.d.ts +41 -5
- package/lib/feature-libraries/forest-summary/format.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/format.js +3 -3
- package/lib/feature-libraries/forest-summary/format.js.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +11 -9
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +13 -26
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/lib/feature-libraries/forest-summary/index.d.ts +2 -1
- package/lib/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/index.js +2 -1
- package/lib/feature-libraries/forest-summary/index.js.map +1 -1
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts +47 -0
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryTypes.js +53 -0
- package/lib/feature-libraries/forest-summary/summaryTypes.js.map +1 -0
- package/lib/feature-libraries/index.d.ts +4 -4
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +3 -3
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.js +2 -1
- 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 +2 -2
- package/lib/feature-libraries/mitigatedChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.d.ts +18 -2
- package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.js +55 -5
- package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +97 -21
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js +3 -5
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +20 -52
- 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/fieldKind.d.ts +25 -13
- package/lib/feature-libraries/modular-schema/fieldKind.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldKind.js +0 -21
- package/lib/feature-libraries/modular-schema/fieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +7 -10
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindCodecs.js +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +6 -6
- 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 +17 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +384 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +17 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js +409 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +9 -285
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +49 -15
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1291 -458
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/{modularChangeFormat.d.ts → modularChangeFormatV1.d.ts} +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/{modularChangeFormat.js → modularChangeFormatV1.js} +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +146 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js +29 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +50 -10
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js +20 -2
- package/lib/feature-libraries/modular-schema/modularChangeTypes.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 +5 -26
- package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +217 -449
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts +23 -0
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.d.ts.map +1 -0
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js +27 -0
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV3.js.map +1 -0
- package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +24 -33
- 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 +55 -26
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts +12 -0
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.d.ts.map +1 -0
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js +53 -0
- package/lib/feature-libraries/optional-field/optionalFieldCodecV3.js.map +1 -0
- package/lib/feature-libraries/optional-field/optionalFieldCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecs.js +5 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecs.js.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts +27 -8
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js +38 -12
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.d.ts +6 -7
- package/lib/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +82 -258
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/helperTypes.d.ts +14 -10
- 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 +2 -3
- package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/index.js +0 -1
- 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 +67 -169
- 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 +4 -56
- package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.js +6 -80
- 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 +108 -114
- package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/lib/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/replaceRevisions.js +16 -33
- 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 +0 -2
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +22 -4
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +350 -175
- 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 +21 -61
- 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 +3 -2
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +14 -109
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/lib/feature-libraries/sequence-field/types.d.ts +30 -59
- 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 +15 -24
- package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +107 -292
- package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/independentView.d.ts +1 -1
- package/lib/shared-tree/independentView.d.ts.map +1 -1
- 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 +3 -2
- package/lib/shared-tree/schematizeTree.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +1 -5
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +35 -36
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +11 -5
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +14 -4
- 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 +1 -0
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.d.ts +20 -8
- package/lib/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.js +27 -13
- package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.d.ts +5 -5
- package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.js +11 -5
- package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/lib/shared-tree/sharedTreeEditBuilder.d.ts +16 -6
- package/lib/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeEditBuilder.js +12 -6
- package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +2 -2
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +12 -10
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +69 -20
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branch.d.ts +3 -2
- package/lib/shared-tree-core/branch.d.ts.map +1 -1
- package/lib/shared-tree-core/branch.js +4 -3
- package/lib/shared-tree-core/branch.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 +9 -9
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.d.ts +4 -0
- package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.js +14 -5
- package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/{dist/shared-tree-core/editManagerCodecsV5.d.ts → lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts} +3 -3
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{editManagerCodecsV5.js → editManagerCodecsVSharedBranches.js} +4 -4
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts +20 -6
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatCommons.js +22 -7
- 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 -0
- package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/lib/shared-tree-core/{editManagerFormatV5.d.ts → editManagerFormatVSharedBranches.d.ts} +3 -3
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{editManagerFormatV5.js → editManagerFormatVSharedBranches.js} +2 -2
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/editManagerSummarizer.d.ts +29 -9
- package/lib/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js +39 -11
- package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/lib/shared-tree-core/index.d.ts +5 -3
- package/lib/shared-tree-core/index.d.ts.map +1 -1
- package/lib/shared-tree-core/index.js +4 -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/{dist/shared-tree-core/messageCodecV5.d.ts → lib/shared-tree-core/messageCodecVSharedBranches.d.ts} +2 -2
- package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{messageCodecV5.js → messageCodecVSharedBranches.js} +3 -3
- package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/messageCodecs.d.ts +4 -0
- package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecs.js +14 -5
- package/lib/shared-tree-core/messageCodecs.js.map +1 -1
- package/lib/shared-tree-core/messageFormat.d.ts +20 -6
- package/lib/shared-tree-core/messageFormat.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormat.js +22 -7
- package/lib/shared-tree-core/messageFormat.js.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts +3 -2
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js +8 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/lib/shared-tree-core/{messageFormatV5.d.ts → messageFormatVSharedBranches.d.ts} +5 -7
- package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{messageFormatV5.js → messageFormatVSharedBranches.js} +3 -2
- package/lib/shared-tree-core/messageFormatVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/sharedTreeCore.d.ts +14 -47
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +28 -16
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/shared-tree-core/summaryTypes.d.ts +94 -0
- package/lib/shared-tree-core/summaryTypes.d.ts.map +1 -0
- package/lib/shared-tree-core/summaryTypes.js +43 -0
- package/lib/shared-tree-core/summaryTypes.js.map +1 -0
- package/lib/shared-tree-core/versionedSummarizer.d.ts +67 -0
- package/lib/shared-tree-core/versionedSummarizer.d.ts.map +1 -0
- package/lib/shared-tree-core/versionedSummarizer.js +59 -0
- package/lib/shared-tree-core/versionedSummarizer.js.map +1 -0
- package/lib/simple-tree/api/configuration.d.ts +3 -26
- package/lib/simple-tree/api/configuration.d.ts.map +1 -1
- package/lib/simple-tree/api/configuration.js +14 -25
- package/lib/simple-tree/api/configuration.js.map +1 -1
- package/lib/simple-tree/api/dirtyIndex.d.ts +11 -0
- package/lib/simple-tree/api/dirtyIndex.d.ts.map +1 -1
- package/lib/simple-tree/api/dirtyIndex.js +7 -0
- package/lib/simple-tree/api/dirtyIndex.js.map +1 -1
- package/lib/simple-tree/api/discrepancies.d.ts +1 -1
- package/lib/simple-tree/api/discrepancies.d.ts.map +1 -1
- package/lib/simple-tree/api/discrepancies.js.map +1 -1
- package/lib/simple-tree/api/getSimpleSchema.d.ts +3 -3
- package/lib/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/getSimpleSchema.js +9 -3
- package/lib/simple-tree/api/getSimpleSchema.js.map +1 -1
- package/lib/simple-tree/api/incrementalAllowedTypes.d.ts +1 -1
- package/lib/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -1
- package/lib/simple-tree/api/incrementalAllowedTypes.js +8 -1
- package/lib/simple-tree/api/incrementalAllowedTypes.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +3 -4
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +2 -3
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.d.ts +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +5 -5
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.js +0 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/lib/simple-tree/api/schemaFromSimple.d.ts +6 -1
- package/lib/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFromSimple.js +5 -0
- package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/lib/simple-tree/api/schemaStatics.d.ts +12 -12
- package/lib/simple-tree/api/simpleSchemaCodec.d.ts +15 -3
- package/lib/simple-tree/api/simpleSchemaCodec.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaCodec.js +15 -3
- package/lib/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts +8 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.js +15 -10
- package/lib/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.d.ts +3 -3
- package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
- package/lib/simple-tree/core/allowedTypes.d.ts +2 -2
- package/lib/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/lib/simple-tree/core/allowedTypes.js.map +1 -1
- package/lib/simple-tree/core/index.d.ts +1 -1
- package/lib/simple-tree/core/index.d.ts.map +1 -1
- package/lib/simple-tree/core/index.js +1 -1
- package/lib/simple-tree/core/index.js.map +1 -1
- package/lib/simple-tree/core/toStored.d.ts +17 -15
- package/lib/simple-tree/core/toStored.d.ts.map +1 -1
- package/lib/simple-tree/core/toStored.js +4 -37
- package/lib/simple-tree/core/toStored.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 +58 -8
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/core/walkSchema.d.ts.map +1 -1
- package/lib/simple-tree/core/walkSchema.js +5 -1
- package/lib/simple-tree/core/walkSchema.js.map +1 -1
- package/lib/simple-tree/createContext.d.ts.map +1 -1
- package/lib/simple-tree/createContext.js +20 -5
- package/lib/simple-tree/createContext.js.map +1 -1
- package/lib/simple-tree/fieldSchema.d.ts +7 -7
- package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
- package/lib/simple-tree/fieldSchema.js.map +1 -1
- package/lib/simple-tree/index.d.ts +8 -7
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +6 -5
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.d.ts +5 -5
- package/lib/simple-tree/leafNodeSchema.d.ts.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 +6 -4
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNodeTypes.d.ts +3 -3
- package/lib/simple-tree/node-kinds/array/arrayNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNodeTypes.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.d.ts.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/map/mapNodeTypes.d.ts +3 -3
- package/lib/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNodeTypes.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 +19 -19
- package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts +2 -2
- package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNodeTypes.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 -2
- package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNodeTypes.d.ts +3 -3
- package/lib/simple-tree/node-kinds/record/recordNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
- package/lib/simple-tree/prepareForInsertion.d.ts +54 -47
- package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/lib/simple-tree/prepareForInsertion.js +183 -124
- package/lib/simple-tree/prepareForInsertion.js.map +1 -1
- package/lib/simple-tree/simpleSchema.d.ts +55 -23
- package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/simpleSchema.js +16 -1
- package/lib/simple-tree/simpleSchema.js.map +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.d.ts +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.d.ts.map +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.js +8 -1
- package/lib/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts +58 -11
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +204 -31
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/lib/simple-tree/treeSchema.d.ts +23 -0
- package/lib/simple-tree/treeSchema.d.ts.map +1 -0
- package/lib/simple-tree/treeSchema.js +21 -0
- package/lib/simple-tree/treeSchema.js.map +1 -0
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +13 -4
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +26 -9
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/lib/tableSchema.d.ts +117 -63
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +160 -59
- package/lib/tableSchema.js.map +1 -1
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +18 -4
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/index.d.ts +2 -1
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +2 -1
- package/lib/util/index.js.map +1 -1
- package/lib/util/rangeMap.d.ts +24 -12
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +44 -5
- package/lib/util/rangeMap.js.map +1 -1
- package/lib/util/readSnapshotBlob.d.ts +13 -0
- package/lib/util/readSnapshotBlob.d.ts.map +1 -0
- package/lib/util/readSnapshotBlob.js +14 -0
- package/lib/util/readSnapshotBlob.js.map +1 -0
- package/package.json +21 -21
- package/src/codec/codec.ts +15 -1
- package/src/codec/versioned/codec.ts +1 -1
- package/src/codec/versioned/format.ts +4 -1
- package/src/core/change-family/changeFamily.ts +5 -0
- package/src/core/change-family/index.ts +1 -0
- package/src/core/index.ts +7 -2
- package/src/core/rebase/changeRebaser.ts +6 -1
- package/src/core/rebase/index.ts +1 -0
- package/src/core/rebase/types.ts +8 -1
- package/src/core/rebase/utils.ts +31 -7
- package/src/core/tree/detachedFieldIndex.ts +71 -14
- package/src/core/tree/index.ts +9 -3
- package/src/core/tree/pathTree.ts +16 -4
- package/src/feature-libraries/chunked-forest/basicChunk.ts +7 -1
- package/src/feature-libraries/chunked-forest/chunkTree.ts +6 -1
- package/src/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.ts +15 -7
- package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +9 -9
- package/src/feature-libraries/default-schema/defaultEditBuilder.ts +398 -127
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +35 -38
- package/src/feature-libraries/default-schema/index.ts +17 -5
- package/src/feature-libraries/default-schema/locationBasedEditBuilder.ts +180 -0
- package/src/feature-libraries/default-schema/mappedEditBuilder.ts +35 -9
- package/src/feature-libraries/deltaUtils.ts +6 -1
- package/src/feature-libraries/detachedFieldIndexSummarizer.ts +62 -15
- package/src/feature-libraries/flex-tree/context.ts +17 -0
- package/src/feature-libraries/flex-tree/flexTreeTypes.ts +7 -8
- package/src/feature-libraries/flex-tree/lazyField.ts +66 -24
- package/src/feature-libraries/forest-summary/codec.ts +8 -8
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +45 -37
- package/src/feature-libraries/forest-summary/format.ts +4 -4
- package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +23 -39
- package/src/feature-libraries/forest-summary/index.ts +2 -1
- package/src/feature-libraries/forest-summary/summaryTypes.ts +61 -0
- package/src/feature-libraries/index.ts +23 -9
- package/src/feature-libraries/mapTreeCursor.ts +2 -1
- package/src/feature-libraries/mitigatedChangeFamily.ts +3 -1
- package/src/feature-libraries/modular-schema/comparison.ts +63 -5
- package/src/feature-libraries/modular-schema/crossFieldQueries.ts +142 -44
- package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +36 -57
- package/src/feature-libraries/modular-schema/fieldKind.ts +24 -40
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +10 -19
- package/src/feature-libraries/modular-schema/genericFieldKindCodecs.ts +1 -1
- package/src/feature-libraries/modular-schema/index.ts +22 -15
- package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +732 -0
- package/src/feature-libraries/modular-schema/modularChangeCodecV2.ts +790 -0
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +29 -499
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +2547 -739
- package/src/feature-libraries/modular-schema/{modularChangeFormat.ts → modularChangeFormatV1.ts} +2 -1
- package/src/feature-libraries/modular-schema/modularChangeFormatV2.ts +62 -0
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +98 -10
- package/src/feature-libraries/optional-field/index.ts +1 -3
- package/src/feature-libraries/optional-field/optionalField.ts +317 -574
- package/src/feature-libraries/optional-field/optionalFieldChangeFormatV3.ts +45 -0
- package/src/feature-libraries/optional-field/optionalFieldChangeTypes.ts +24 -38
- package/src/feature-libraries/optional-field/optionalFieldCodecV2.ts +89 -35
- package/src/feature-libraries/optional-field/optionalFieldCodecV3.ts +94 -0
- package/src/feature-libraries/optional-field/optionalFieldCodecs.ts +5 -1
- package/src/feature-libraries/schema-index/schemaSummarizer.ts +59 -18
- package/src/feature-libraries/sequence-field/compose.ts +134 -519
- package/src/feature-libraries/sequence-field/helperTypes.ts +34 -19
- package/src/feature-libraries/sequence-field/index.ts +0 -9
- package/src/feature-libraries/sequence-field/invert.ts +103 -228
- package/src/feature-libraries/sequence-field/markQueue.ts +2 -2
- package/src/feature-libraries/sequence-field/moveEffectTable.ts +8 -191
- package/src/feature-libraries/sequence-field/rebase.ts +168 -203
- package/src/feature-libraries/sequence-field/replaceRevisions.ts +31 -52
- package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +0 -2
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +643 -220
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV3.ts +56 -68
- package/src/feature-libraries/sequence-field/sequenceFieldEditor.ts +25 -27
- package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +19 -129
- package/src/feature-libraries/sequence-field/types.ts +34 -64
- package/src/feature-libraries/sequence-field/utils.ts +133 -346
- package/src/index.ts +3 -2
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/independentView.ts +1 -1
- package/src/shared-tree/index.ts +3 -2
- package/src/shared-tree/schematizeTree.ts +21 -8
- package/src/shared-tree/schematizingTreeView.ts +50 -68
- package/src/shared-tree/sharedTree.ts +39 -12
- package/src/shared-tree/sharedTreeChangeCodecs.ts +5 -1
- package/src/shared-tree/sharedTreeChangeEnricher.ts +33 -11
- package/src/shared-tree/sharedTreeChangeFamily.ts +15 -5
- package/src/shared-tree/sharedTreeEditBuilder.ts +47 -13
- package/src/shared-tree/treeAlpha.ts +2 -3
- package/src/shared-tree/treeCheckout.ts +104 -31
- package/src/shared-tree-core/branch.ts +8 -2
- package/src/shared-tree-core/editManager.ts +16 -2
- package/src/shared-tree-core/editManagerCodecs.ts +17 -5
- package/src/shared-tree-core/{editManagerCodecsV5.ts → editManagerCodecsVSharedBranches.ts} +3 -3
- package/src/shared-tree-core/editManagerFormatCommons.ts +22 -7
- package/src/shared-tree-core/editManagerFormatV1toV4.ts +3 -1
- package/src/shared-tree-core/{editManagerFormatV5.ts → editManagerFormatVSharedBranches.ts} +2 -2
- package/src/shared-tree-core/editManagerSummarizer.ts +58 -16
- package/src/shared-tree-core/index.ts +11 -3
- package/src/shared-tree-core/messageCodecV1ToV4.ts +2 -1
- package/src/shared-tree-core/{messageCodecV5.ts → messageCodecVSharedBranches.ts} +3 -3
- package/src/shared-tree-core/messageCodecs.ts +17 -5
- package/src/shared-tree-core/messageFormat.ts +22 -7
- package/src/shared-tree-core/messageFormatV1ToV4.ts +16 -2
- package/src/shared-tree-core/{messageFormatV5.ts → messageFormatVSharedBranches.ts} +4 -6
- package/src/shared-tree-core/sharedTreeCore.ts +67 -76
- package/src/shared-tree-core/summaryTypes.ts +122 -0
- package/src/shared-tree-core/versionedSummarizer.ts +107 -0
- package/src/simple-tree/api/configuration.ts +21 -68
- package/src/simple-tree/api/dirtyIndex.ts +11 -0
- package/src/simple-tree/api/discrepancies.ts +1 -1
- package/src/simple-tree/api/getSimpleSchema.ts +13 -6
- package/src/simple-tree/api/incrementalAllowedTypes.ts +15 -3
- package/src/simple-tree/api/index.ts +3 -4
- package/src/simple-tree/api/schemaCompatibilityTester.ts +1 -1
- package/src/simple-tree/api/schemaFactoryAlpha.ts +2 -2
- package/src/simple-tree/api/schemaFactoryRecursive.ts +0 -2
- package/src/simple-tree/api/schemaFromSimple.ts +11 -5
- package/src/simple-tree/api/simpleSchemaCodec.ts +17 -3
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +1 -1
- package/src/simple-tree/api/snapshotCompatibilityChecker.ts +18 -10
- package/src/simple-tree/api/typesUnsafe.ts +7 -3
- package/src/simple-tree/core/allowedTypes.ts +3 -3
- package/src/simple-tree/core/index.ts +2 -2
- package/src/simple-tree/core/toStored.ts +22 -55
- package/src/simple-tree/core/unhydratedFlexTree.ts +87 -36
- package/src/simple-tree/core/walkSchema.ts +6 -0
- package/src/simple-tree/createContext.ts +26 -11
- package/src/simple-tree/fieldSchema.ts +16 -7
- package/src/simple-tree/index.ts +12 -11
- package/src/simple-tree/node-kinds/array/arrayNode.ts +12 -7
- package/src/simple-tree/node-kinds/array/arrayNodeTypes.ts +3 -3
- package/src/simple-tree/node-kinds/common.ts +2 -5
- package/src/simple-tree/node-kinds/map/mapNode.ts +9 -6
- package/src/simple-tree/node-kinds/map/mapNodeTypes.ts +3 -3
- package/src/simple-tree/node-kinds/object/objectNode.ts +26 -26
- package/src/simple-tree/node-kinds/object/objectNodeTypes.ts +6 -2
- package/src/simple-tree/node-kinds/record/recordNode.ts +15 -11
- package/src/simple-tree/node-kinds/record/recordNodeTypes.ts +3 -3
- package/src/simple-tree/prepareForInsertion.ts +343 -200
- package/src/simple-tree/simpleSchema.ts +79 -32
- package/src/simple-tree/simpleSchemaFormatV1.ts +9 -1
- package/src/simple-tree/toStoredSchema.ts +319 -61
- package/src/simple-tree/treeSchema.ts +54 -0
- package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +42 -14
- package/src/tableSchema.ts +485 -166
- package/src/treeFactory.ts +19 -5
- package/src/util/index.ts +5 -0
- package/src/util/rangeMap.ts +72 -18
- package/src/util/readSnapshotBlob.ts +23 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +0 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormat.js.map +0 -1
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +0 -9
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +0 -1
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js +0 -50
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js.map +0 -1
- package/dist/shared-tree-core/editManagerCodecsV5.d.ts.map +0 -1
- package/dist/shared-tree-core/editManagerCodecsV5.js.map +0 -1
- package/dist/shared-tree-core/editManagerFormatV5.d.ts.map +0 -1
- package/dist/shared-tree-core/editManagerFormatV5.js.map +0 -1
- package/dist/shared-tree-core/messageCodecV5.d.ts.map +0 -1
- package/dist/shared-tree-core/messageCodecV5.js.map +0 -1
- package/dist/shared-tree-core/messageFormatV5.d.ts.map +0 -1
- package/dist/shared-tree-core/messageFormatV5.js.map +0 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts +0 -40
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +0 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js +0 -177
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js.map +0 -1
- package/docs/main/sequence-field/move-composition.md +0 -46
- package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +0 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormat.js.map +0 -1
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +0 -9
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +0 -1
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js +0 -46
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js.map +0 -1
- package/lib/shared-tree-core/editManagerCodecsV5.d.ts.map +0 -1
- package/lib/shared-tree-core/editManagerCodecsV5.js.map +0 -1
- package/lib/shared-tree-core/editManagerFormatV5.d.ts.map +0 -1
- package/lib/shared-tree-core/editManagerFormatV5.js.map +0 -1
- package/lib/shared-tree-core/messageCodecV5.d.ts.map +0 -1
- package/lib/shared-tree-core/messageCodecV5.js.map +0 -1
- package/lib/shared-tree-core/messageFormatV5.d.ts.map +0 -1
- package/lib/shared-tree-core/messageFormatV5.js.map +0 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts +0 -40
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +0 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js +0 -171
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js.map +0 -1
- package/src/feature-libraries/sequence-field/relevantRemovedRoots.ts +0 -57
- package/src/simple-tree/api/viewSchemaToSimpleSchema.ts +0 -209
|
@@ -22,12 +22,10 @@ import {
|
|
|
22
22
|
EditBuilder,
|
|
23
23
|
type FieldKey,
|
|
24
24
|
type FieldKindIdentifier,
|
|
25
|
-
type FieldUpPath,
|
|
26
25
|
type RevisionInfo,
|
|
27
26
|
type RevisionMetadataSource,
|
|
28
27
|
type RevisionTag,
|
|
29
28
|
type TaggedChange,
|
|
30
|
-
type UpPath,
|
|
31
29
|
makeDetachedNodeId,
|
|
32
30
|
replaceAtomRevisions,
|
|
33
31
|
revisionMetadataSourceFromInfo,
|
|
@@ -36,10 +34,18 @@ import {
|
|
|
36
34
|
areEqualChangeAtomIdOpts,
|
|
37
35
|
tagChange,
|
|
38
36
|
makeAnonChange,
|
|
39
|
-
newChangeAtomIdRangeMap,
|
|
40
37
|
type DeltaDetachedNodeChanges,
|
|
41
38
|
type DeltaDetachedNodeRename,
|
|
42
39
|
mapTaggedChange,
|
|
40
|
+
newChangeAtomIdRangeMap,
|
|
41
|
+
newChangeAtomIdTransform,
|
|
42
|
+
type ChangeAtomIdRangeMap,
|
|
43
|
+
offsetChangeAtomId,
|
|
44
|
+
type NormalizedUpPath,
|
|
45
|
+
type NormalizedFieldUpPath,
|
|
46
|
+
isDetachedUpPathRoot,
|
|
47
|
+
subtractChangeAtomIds,
|
|
48
|
+
makeChangeAtomId,
|
|
43
49
|
} from "../../core/index.js";
|
|
44
50
|
import {
|
|
45
51
|
type IdAllocationState,
|
|
@@ -55,14 +61,19 @@ import {
|
|
|
55
61
|
type TupleBTree,
|
|
56
62
|
RangeMap,
|
|
57
63
|
balancedReduce,
|
|
64
|
+
type RangeQueryEntry,
|
|
65
|
+
type RangeQueryResultFragment,
|
|
58
66
|
} from "../../util/index.js";
|
|
59
67
|
import type { TreeChunk } from "../chunked-forest/index.js";
|
|
60
68
|
|
|
61
69
|
import {
|
|
62
|
-
type
|
|
70
|
+
type ComposeNodeManager,
|
|
63
71
|
type CrossFieldMap,
|
|
64
72
|
CrossFieldTarget,
|
|
65
|
-
|
|
73
|
+
type DetachedNodeEntry,
|
|
74
|
+
type InvertNodeManager,
|
|
75
|
+
type RebaseDetachedNodeEntry,
|
|
76
|
+
type RebaseNodeManager,
|
|
66
77
|
setInCrossFieldMap,
|
|
67
78
|
} from "./crossFieldQueries.js";
|
|
68
79
|
import {
|
|
@@ -74,17 +85,25 @@ import { convertGenericChange, genericFieldKind } from "./genericFieldKind.js";
|
|
|
74
85
|
import type { GenericChangeset } from "./genericFieldKindTypes.js";
|
|
75
86
|
import {
|
|
76
87
|
type ChangeAtomIdBTree,
|
|
88
|
+
type ChangeAtomIdKey,
|
|
77
89
|
type CrossFieldKey,
|
|
78
90
|
type CrossFieldKeyRange,
|
|
79
91
|
type CrossFieldKeyTable,
|
|
92
|
+
type CrossFieldRangeTable,
|
|
80
93
|
type FieldChange,
|
|
81
94
|
type FieldChangeMap,
|
|
82
95
|
type FieldChangeset,
|
|
83
96
|
type FieldId,
|
|
97
|
+
getFromChangeAtomIdMap,
|
|
84
98
|
type ModularChangeset,
|
|
85
|
-
|
|
99
|
+
newCrossFieldRangeTable,
|
|
86
100
|
type NodeChangeset,
|
|
87
101
|
type NodeId,
|
|
102
|
+
type NodeLocation,
|
|
103
|
+
rangeQueryChangeAtomIdMap,
|
|
104
|
+
type RebaseVersion,
|
|
105
|
+
type RootNodeTable,
|
|
106
|
+
setInChangeAtomIdMap,
|
|
88
107
|
} from "./modularChangeTypes.js";
|
|
89
108
|
import type { FlexFieldKind } from "./fieldKind.js";
|
|
90
109
|
|
|
@@ -171,14 +190,14 @@ export class ModularChangeFamily
|
|
|
171
190
|
}
|
|
172
191
|
|
|
173
192
|
public compose(changes: TaggedChange<ModularChangeset>[]): ModularChangeset {
|
|
174
|
-
const {
|
|
193
|
+
const { maxId } = getRevInfoFromTaggedChanges(changes);
|
|
175
194
|
const idState: IdAllocationState = { maxId };
|
|
176
195
|
|
|
177
196
|
const pairwiseDelegate = (
|
|
178
197
|
left: ModularChangeset,
|
|
179
198
|
right: ModularChangeset,
|
|
180
199
|
): ModularChangeset => {
|
|
181
|
-
return this.composePair(left, right,
|
|
200
|
+
return this.composePair(left, right, idState);
|
|
182
201
|
};
|
|
183
202
|
|
|
184
203
|
const innerChanges = changes.map((change) => change.change);
|
|
@@ -188,10 +207,11 @@ export class ModularChangeFamily
|
|
|
188
207
|
private composePair(
|
|
189
208
|
change1: ModularChangeset,
|
|
190
209
|
change2: ModularChangeset,
|
|
191
|
-
revInfos: RevisionInfo[],
|
|
192
210
|
idState: IdAllocationState,
|
|
193
211
|
): ModularChangeset {
|
|
194
|
-
const
|
|
212
|
+
const revInfos = composeRevInfos(change1.revisions, change2.revisions);
|
|
213
|
+
|
|
214
|
+
const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys, rootNodes } =
|
|
195
215
|
this.composeAllFields(change1, change2, revInfos, idState);
|
|
196
216
|
|
|
197
217
|
const { allBuilds, allDestroys, allRefreshers } = composeBuildsDestroysAndRefreshers(
|
|
@@ -199,7 +219,7 @@ export class ModularChangeFamily
|
|
|
199
219
|
change2,
|
|
200
220
|
);
|
|
201
221
|
|
|
202
|
-
|
|
222
|
+
const composed = makeModularChangeset({
|
|
203
223
|
fieldChanges,
|
|
204
224
|
nodeChanges,
|
|
205
225
|
nodeToParent,
|
|
@@ -207,10 +227,15 @@ export class ModularChangeFamily
|
|
|
207
227
|
crossFieldKeys,
|
|
208
228
|
maxId: idState.maxId,
|
|
209
229
|
revisions: revInfos,
|
|
230
|
+
rootNodes,
|
|
210
231
|
builds: allBuilds,
|
|
211
232
|
destroys: allDestroys,
|
|
212
233
|
refreshers: allRefreshers,
|
|
213
234
|
});
|
|
235
|
+
|
|
236
|
+
// XXX: This is an expensive assert which should be disabled before merging.
|
|
237
|
+
this.validateChangeset(composed);
|
|
238
|
+
return composed;
|
|
214
239
|
}
|
|
215
240
|
|
|
216
241
|
private composeAllFields(
|
|
@@ -240,14 +265,38 @@ export class ModularChangeFamily
|
|
|
240
265
|
mergeTupleBTrees(change1.nodeChanges, change2.nodeChanges),
|
|
241
266
|
);
|
|
242
267
|
|
|
243
|
-
const composedNodeToParent: ChangeAtomIdBTree<
|
|
268
|
+
const composedNodeToParent: ChangeAtomIdBTree<NodeLocation> = brand(
|
|
244
269
|
mergeTupleBTrees(change1.nodeToParent, change2.nodeToParent),
|
|
245
270
|
);
|
|
246
271
|
const composedNodeAliases: ChangeAtomIdBTree<NodeId> = brand(
|
|
247
272
|
mergeTupleBTrees(change1.nodeAliases, change2.nodeAliases),
|
|
248
273
|
);
|
|
249
274
|
|
|
250
|
-
const
|
|
275
|
+
const pendingCompositions: PendingCompositions = {
|
|
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
|
+
);
|
|
251
300
|
|
|
252
301
|
const composedFields = this.composeFieldMaps(
|
|
253
302
|
change1.fieldChanges,
|
|
@@ -268,17 +317,32 @@ export class ModularChangeFamily
|
|
|
268
317
|
revisionMetadata,
|
|
269
318
|
);
|
|
270
319
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
)
|
|
320
|
+
for (const entry of crossFieldTable.renamesToDelete.entries()) {
|
|
321
|
+
deleteNodeRenameFrom(crossFieldTable.composedRootNodes, entry.start, entry.length);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
for (const [nodeId, location] of crossFieldTable.movedNodeToParent.entries()) {
|
|
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
|
+
|
|
276
334
|
return {
|
|
277
335
|
fieldChanges: composedFields,
|
|
278
336
|
nodeChanges: composedNodeChanges,
|
|
279
337
|
nodeToParent: composedNodeToParent,
|
|
280
338
|
nodeAliases: composedNodeAliases,
|
|
281
|
-
crossFieldKeys:
|
|
339
|
+
crossFieldKeys: composeCrossFieldKeyTables(
|
|
340
|
+
change1.crossFieldKeys,
|
|
341
|
+
change2.crossFieldKeys,
|
|
342
|
+
crossFieldTable.movedCrossFieldKeys,
|
|
343
|
+
crossFieldTable.removedCrossFieldKeys,
|
|
344
|
+
),
|
|
345
|
+
rootNodes: composedRoots,
|
|
282
346
|
};
|
|
283
347
|
}
|
|
284
348
|
|
|
@@ -290,17 +354,16 @@ export class ModularChangeFamily
|
|
|
290
354
|
): void {
|
|
291
355
|
const context = crossFieldTable.fieldToContext.get(fieldChange);
|
|
292
356
|
assert(context !== undefined, 0x8cc /* Should have context for every invalidated field */);
|
|
293
|
-
const {
|
|
357
|
+
const { change1: fieldChange1, change2: fieldChange2, composedChange } = context;
|
|
358
|
+
|
|
359
|
+
crossFieldTable.pendingCompositions.affectedBaseFields.delete(
|
|
360
|
+
fieldIdKeyFromFieldId(context.fieldId),
|
|
361
|
+
);
|
|
294
362
|
|
|
295
363
|
const rebaser = getChangeHandler(this.fieldKinds, composedChange.fieldKind).rebaser;
|
|
296
364
|
const composeNodes = (child1: NodeId | undefined, child2: NodeId | undefined): NodeId => {
|
|
297
|
-
if (
|
|
298
|
-
child1
|
|
299
|
-
child2 !== undefined &&
|
|
300
|
-
getFromChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2) === undefined
|
|
301
|
-
) {
|
|
302
|
-
setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
|
|
303
|
-
crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
|
|
365
|
+
if (child1 !== undefined && child2 !== undefined) {
|
|
366
|
+
addNodesToCompose(crossFieldTable, child1, child2);
|
|
304
367
|
}
|
|
305
368
|
|
|
306
369
|
return child1 ?? child2 ?? fail(0xb22 /* Should not compose two undefined nodes */);
|
|
@@ -311,7 +374,7 @@ export class ModularChangeFamily
|
|
|
311
374
|
fieldChange2,
|
|
312
375
|
composeNodes,
|
|
313
376
|
genId,
|
|
314
|
-
new
|
|
377
|
+
new ComposeNodeManagerI(crossFieldTable, context.fieldId, false),
|
|
315
378
|
revisionMetadata,
|
|
316
379
|
);
|
|
317
380
|
composedChange.change = brand(amendedChange);
|
|
@@ -323,7 +386,7 @@ export class ModularChangeFamily
|
|
|
323
386
|
* - discovering that two node changesets refer to the same node (`nodeIdsToCompose`)
|
|
324
387
|
* - a previously composed field being invalidated by a cross field effect (`invalidatedFields`)
|
|
325
388
|
* - a field which was copied directly from an input changeset being invalidated by a cross field effect
|
|
326
|
-
* (`affectedBaseFields`
|
|
389
|
+
* (`affectedBaseFields`)
|
|
327
390
|
*
|
|
328
391
|
* Updating an element may invalidate further elements. This function runs until there is no more invalidation.
|
|
329
392
|
*/
|
|
@@ -331,72 +394,59 @@ export class ModularChangeFamily
|
|
|
331
394
|
table: ComposeTable,
|
|
332
395
|
composedFields: FieldChangeMap,
|
|
333
396
|
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
334
|
-
composedNodeToParent: ChangeAtomIdBTree<
|
|
397
|
+
composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
335
398
|
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
336
399
|
genId: IdAllocator,
|
|
337
400
|
metadata: RevisionMetadataSource,
|
|
338
401
|
): void {
|
|
339
402
|
const pending = table.pendingCompositions;
|
|
340
|
-
while (
|
|
341
|
-
|
|
342
|
-
pending.nodeIdsToCompose.length > 0 ||
|
|
343
|
-
pending.affectedBaseFields.length > 0 ||
|
|
344
|
-
pending.affectedNewFields.length > 0
|
|
345
|
-
) {
|
|
346
|
-
// Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
347
|
-
for (const [id1, id2] of pending.nodeIdsToCompose) {
|
|
348
|
-
this.composeNodesById(
|
|
349
|
-
table.baseChange.nodeChanges,
|
|
350
|
-
table.newChange.nodeChanges,
|
|
351
|
-
composedNodes,
|
|
352
|
-
composedNodeToParent,
|
|
353
|
-
nodeAliases,
|
|
354
|
-
id1,
|
|
355
|
-
id2,
|
|
356
|
-
genId,
|
|
357
|
-
table,
|
|
358
|
-
metadata,
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
pending.nodeIdsToCompose.length = 0;
|
|
363
|
-
|
|
364
|
-
this.composeAffectedFields(
|
|
403
|
+
while (pending.nodeIdsToCompose.length > 0 || pending.affectedBaseFields.length > 0) {
|
|
404
|
+
this.processPendingNodeCompositions(
|
|
365
405
|
table,
|
|
366
|
-
table.baseChange,
|
|
367
|
-
true,
|
|
368
|
-
pending.affectedBaseFields,
|
|
369
|
-
composedFields,
|
|
370
406
|
composedNodes,
|
|
407
|
+
composedNodeToParent,
|
|
408
|
+
nodeAliases,
|
|
371
409
|
genId,
|
|
372
410
|
metadata,
|
|
373
411
|
);
|
|
374
412
|
|
|
375
413
|
this.composeAffectedFields(
|
|
376
414
|
table,
|
|
377
|
-
table.
|
|
378
|
-
|
|
379
|
-
pending.affectedNewFields,
|
|
415
|
+
table.baseChange,
|
|
416
|
+
pending.affectedBaseFields,
|
|
380
417
|
composedFields,
|
|
381
418
|
composedNodes,
|
|
382
419
|
genId,
|
|
383
420
|
metadata,
|
|
384
421
|
);
|
|
385
|
-
|
|
386
|
-
this.processInvalidatedCompositions(table, genId, metadata);
|
|
387
422
|
}
|
|
388
423
|
}
|
|
389
424
|
|
|
390
|
-
private
|
|
425
|
+
private processPendingNodeCompositions(
|
|
391
426
|
table: ComposeTable,
|
|
427
|
+
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
428
|
+
composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
429
|
+
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
392
430
|
genId: IdAllocator,
|
|
393
431
|
metadata: RevisionMetadataSource,
|
|
394
432
|
): void {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
433
|
+
// Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
434
|
+
for (const [id1, id2] of table.pendingCompositions.nodeIdsToCompose) {
|
|
435
|
+
this.composeNodesById(
|
|
436
|
+
table.baseChange,
|
|
437
|
+
table.newChange,
|
|
438
|
+
composedNodes,
|
|
439
|
+
composedNodeToParent,
|
|
440
|
+
nodeAliases,
|
|
441
|
+
id1,
|
|
442
|
+
id2,
|
|
443
|
+
genId,
|
|
444
|
+
table,
|
|
445
|
+
metadata,
|
|
446
|
+
);
|
|
399
447
|
}
|
|
448
|
+
|
|
449
|
+
table.pendingCompositions.nodeIdsToCompose.length = 0;
|
|
400
450
|
}
|
|
401
451
|
|
|
402
452
|
/**
|
|
@@ -413,63 +463,79 @@ export class ModularChangeFamily
|
|
|
413
463
|
private composeAffectedFields(
|
|
414
464
|
table: ComposeTable,
|
|
415
465
|
change: ModularChangeset,
|
|
416
|
-
areBaseFields: boolean,
|
|
417
466
|
affectedFields: BTree<FieldIdKey, true>,
|
|
418
467
|
composedFields: FieldChangeMap,
|
|
419
468
|
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
420
469
|
genId: IdAllocator,
|
|
421
470
|
metadata: RevisionMetadataSource,
|
|
422
471
|
): void {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
472
|
+
const fieldsToProcess = affectedFields.clone();
|
|
473
|
+
affectedFields.clear();
|
|
474
|
+
|
|
475
|
+
for (const fieldIdKey of fieldsToProcess.keys()) {
|
|
476
|
+
const fieldId = fieldIdFromFieldIdKey(fieldIdKey);
|
|
477
|
+
const fieldChange = fieldChangeFromId(change, fieldId);
|
|
426
478
|
|
|
427
479
|
if (
|
|
428
480
|
table.fieldToContext.has(fieldChange) ||
|
|
429
481
|
table.newFieldToBaseField.has(fieldChange)
|
|
430
482
|
) {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
483
|
+
this.composeInvalidatedField(fieldChange, table, genId, metadata);
|
|
484
|
+
} else {
|
|
485
|
+
this.composeFieldWithNoNewChange(
|
|
486
|
+
table,
|
|
487
|
+
fieldChange,
|
|
488
|
+
fieldId,
|
|
489
|
+
composedFields,
|
|
490
|
+
composedNodes,
|
|
491
|
+
genId,
|
|
492
|
+
metadata,
|
|
493
|
+
);
|
|
435
494
|
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
436
497
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
table,
|
|
448
|
-
metadata,
|
|
449
|
-
);
|
|
498
|
+
private composeFieldWithNoNewChange(
|
|
499
|
+
table: ComposeTable,
|
|
500
|
+
baseFieldChange: FieldChange,
|
|
501
|
+
fieldId: FieldId,
|
|
502
|
+
composedFields: FieldChangeMap,
|
|
503
|
+
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
504
|
+
genId: IdAllocator,
|
|
505
|
+
metadata: RevisionMetadataSource,
|
|
506
|
+
): void {
|
|
507
|
+
const emptyChange = this.createEmptyFieldChange(baseFieldChange.fieldKind);
|
|
450
508
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
509
|
+
const composedField = this.composeFieldChanges(
|
|
510
|
+
fieldId,
|
|
511
|
+
baseFieldChange,
|
|
512
|
+
emptyChange,
|
|
513
|
+
genId,
|
|
514
|
+
table,
|
|
515
|
+
metadata,
|
|
516
|
+
);
|
|
455
517
|
|
|
456
|
-
|
|
457
|
-
|
|
518
|
+
if (fieldId.nodeId === undefined) {
|
|
519
|
+
composedFields.set(fieldId.field, composedField);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
458
522
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
523
|
+
const nodeId = normalizeNodeId(
|
|
524
|
+
getFromChangeAtomIdMap(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId,
|
|
525
|
+
table.baseChange.nodeAliases,
|
|
526
|
+
);
|
|
464
527
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
528
|
+
// We clone the node changeset before mutating it, as it may be from one of the input changesets.
|
|
529
|
+
const nodeChangeset: Mutable<NodeChangeset> = cloneNodeChangeset(
|
|
530
|
+
nodeChangeFromId(composedNodes, table.baseChange.nodeAliases, nodeId),
|
|
531
|
+
);
|
|
532
|
+
setInChangeAtomIdMap(composedNodes, nodeId, nodeChangeset);
|
|
468
533
|
|
|
469
|
-
|
|
534
|
+
if (nodeChangeset.fieldChanges === undefined) {
|
|
535
|
+
nodeChangeset.fieldChanges = new Map();
|
|
470
536
|
}
|
|
471
537
|
|
|
472
|
-
|
|
538
|
+
nodeChangeset.fieldChanges.set(fieldId.field, composedField);
|
|
473
539
|
}
|
|
474
540
|
|
|
475
541
|
private composeFieldMaps(
|
|
@@ -488,6 +554,18 @@ export class ModularChangeFamily
|
|
|
488
554
|
for (const [field, fieldChange1] of change1) {
|
|
489
555
|
const fieldId: FieldId = { nodeId: parentId, field };
|
|
490
556
|
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
|
+
|
|
491
569
|
const composedField =
|
|
492
570
|
fieldChange2 !== undefined
|
|
493
571
|
? this.composeFieldChanges(
|
|
@@ -519,7 +597,7 @@ export class ModularChangeFamily
|
|
|
519
597
|
* will be added to `crossFieldTable.pendingCompositions.nodeIdsToCompose`.
|
|
520
598
|
*
|
|
521
599
|
* Any fields which had cross-field information sent to them as part of this field composition
|
|
522
|
-
* will be added to
|
|
600
|
+
* will be added to `affectedBaseFields` in `crossFieldTable.pendingCompositions`.
|
|
523
601
|
*
|
|
524
602
|
* Any composed `FieldChange` which is invalidated by new cross-field information will be added to `crossFieldTable.invalidatedFields`.
|
|
525
603
|
*/
|
|
@@ -538,15 +616,14 @@ export class ModularChangeFamily
|
|
|
538
616
|
change2: change2Normalized,
|
|
539
617
|
} = this.normalizeFieldChanges(change1, change2);
|
|
540
618
|
|
|
541
|
-
const manager = new
|
|
619
|
+
const manager = new ComposeNodeManagerI(crossFieldTable, fieldId);
|
|
542
620
|
|
|
543
621
|
const composedChange = changeHandler.rebaser.compose(
|
|
544
622
|
change1Normalized,
|
|
545
623
|
change2Normalized,
|
|
546
624
|
(child1, child2) => {
|
|
547
625
|
if (child1 !== undefined && child2 !== undefined) {
|
|
548
|
-
|
|
549
|
-
crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
|
|
626
|
+
addNodesToCompose(crossFieldTable, child1, child2);
|
|
550
627
|
}
|
|
551
628
|
return child1 ?? child2 ?? fail(0xb23 /* Should not compose two undefined nodes */);
|
|
552
629
|
},
|
|
@@ -572,19 +649,19 @@ export class ModularChangeFamily
|
|
|
572
649
|
}
|
|
573
650
|
|
|
574
651
|
private composeNodesById(
|
|
575
|
-
|
|
576
|
-
|
|
652
|
+
change1: ModularChangeset,
|
|
653
|
+
change2: ModularChangeset,
|
|
577
654
|
composedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
578
|
-
composedNodeToParent: ChangeAtomIdBTree<
|
|
579
|
-
|
|
655
|
+
composedNodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
656
|
+
composedAliases: ChangeAtomIdBTree<NodeId>,
|
|
580
657
|
id1: NodeId,
|
|
581
658
|
id2: NodeId,
|
|
582
659
|
idAllocator: IdAllocator,
|
|
583
660
|
crossFieldTable: ComposeTable,
|
|
584
661
|
revisionMetadata: RevisionMetadataSource,
|
|
585
662
|
): void {
|
|
586
|
-
const nodeChangeset1 = nodeChangeFromId(
|
|
587
|
-
const nodeChangeset2 = nodeChangeFromId(
|
|
663
|
+
const nodeChangeset1 = nodeChangeFromId(change1.nodeChanges, change1.nodeAliases, id1);
|
|
664
|
+
const nodeChangeset2 = nodeChangeFromId(change2.nodeChanges, change2.nodeAliases, id2);
|
|
588
665
|
const composedNodeChangeset = this.composeNodeChanges(
|
|
589
666
|
id1,
|
|
590
667
|
nodeChangeset1,
|
|
@@ -599,13 +676,11 @@ export class ModularChangeFamily
|
|
|
599
676
|
if (!areEqualChangeAtomIds(id1, id2)) {
|
|
600
677
|
composedNodes.delete([id2.revision, id2.localId]);
|
|
601
678
|
composedNodeToParent.delete([id2.revision, id2.localId]);
|
|
602
|
-
setInChangeAtomIdMap(
|
|
679
|
+
setInChangeAtomIdMap(composedAliases, id2, id1);
|
|
603
680
|
|
|
604
681
|
// We need to delete id1 to avoid forming a cycle in case id1 already had an alias.
|
|
605
|
-
|
|
682
|
+
composedAliases.delete([id1.revision, id1.localId]);
|
|
606
683
|
}
|
|
607
|
-
|
|
608
|
-
crossFieldTable.composedNodes.add(composedNodeChangeset);
|
|
609
684
|
}
|
|
610
685
|
|
|
611
686
|
private composeNodeChanges(
|
|
@@ -640,7 +715,7 @@ export class ModularChangeFamily
|
|
|
640
715
|
revisionMetadata,
|
|
641
716
|
);
|
|
642
717
|
|
|
643
|
-
const composedNodeChange: NodeChangeset = {};
|
|
718
|
+
const composedNodeChange: Mutable<NodeChangeset> = {};
|
|
644
719
|
|
|
645
720
|
if (composedFieldChanges.size > 0) {
|
|
646
721
|
composedNodeChange.fieldChanges = composedFieldChanges;
|
|
@@ -692,9 +767,14 @@ export class ModularChangeFamily
|
|
|
692
767
|
const genId: IdAllocator = idAllocatorFromMaxId(change.change.maxId ?? -1);
|
|
693
768
|
|
|
694
769
|
const crossFieldTable: InvertTable = {
|
|
695
|
-
|
|
770
|
+
change: change.change,
|
|
771
|
+
entries: newChangeAtomIdRangeMap(),
|
|
696
772
|
originalFieldToContext: new Map(),
|
|
773
|
+
invertRevision: revisionForInvert,
|
|
697
774
|
invertedNodeToParent: brand(change.change.nodeToParent.clone()),
|
|
775
|
+
invalidatedFields: new Set(),
|
|
776
|
+
invertedRoots: invertRootTable(change.change, isRollback),
|
|
777
|
+
attachToDetachId: newChangeAtomIdTransform(),
|
|
698
778
|
};
|
|
699
779
|
const { revInfos: oldRevInfos } = getRevInfoFromTaggedChanges([change]);
|
|
700
780
|
const revisionMetadata = revisionMetadataSourceFromInfo(oldRevInfos);
|
|
@@ -735,7 +815,7 @@ export class ModularChangeFamily
|
|
|
735
815
|
context !== undefined,
|
|
736
816
|
0x851 /* Should have context for every invalidated field */,
|
|
737
817
|
);
|
|
738
|
-
const { invertedField
|
|
818
|
+
const { invertedField } = context;
|
|
739
819
|
|
|
740
820
|
const amendedChange = getChangeHandler(
|
|
741
821
|
this.fieldKinds,
|
|
@@ -745,7 +825,7 @@ export class ModularChangeFamily
|
|
|
745
825
|
isRollback,
|
|
746
826
|
genId,
|
|
747
827
|
revisionForInvert,
|
|
748
|
-
new
|
|
828
|
+
new InvertNodeManagerI(crossFieldTable, context.fieldId),
|
|
749
829
|
revisionMetadata,
|
|
750
830
|
);
|
|
751
831
|
invertedField.change = brand(amendedChange);
|
|
@@ -754,10 +834,13 @@ export class ModularChangeFamily
|
|
|
754
834
|
|
|
755
835
|
const crossFieldKeys = this.makeCrossFieldKeyTable(invertedFields, invertedNodes);
|
|
756
836
|
|
|
837
|
+
this.processInvertRenames(crossFieldTable);
|
|
838
|
+
|
|
757
839
|
return makeModularChangeset({
|
|
758
840
|
fieldChanges: invertedFields,
|
|
759
841
|
nodeChanges: invertedNodes,
|
|
760
842
|
nodeToParent: crossFieldTable.invertedNodeToParent,
|
|
843
|
+
rootNodes: crossFieldTable.invertedRoots,
|
|
761
844
|
nodeAliases: change.change.nodeAliases,
|
|
762
845
|
crossFieldKeys,
|
|
763
846
|
maxId: genId.getMaxId(),
|
|
@@ -781,7 +864,7 @@ export class ModularChangeFamily
|
|
|
781
864
|
|
|
782
865
|
for (const [field, fieldChange] of changes) {
|
|
783
866
|
const fieldId = { nodeId: parentId, field };
|
|
784
|
-
const manager = new
|
|
867
|
+
const manager = new InvertNodeManagerI(crossFieldTable, fieldId);
|
|
785
868
|
const invertedChange = getChangeHandler(
|
|
786
869
|
this.fieldKinds,
|
|
787
870
|
fieldChange.fieldKind,
|
|
@@ -818,7 +901,7 @@ export class ModularChangeFamily
|
|
|
818
901
|
revisionMetadata: RevisionMetadataSource,
|
|
819
902
|
revisionForInvert: RevisionTag,
|
|
820
903
|
): NodeChangeset {
|
|
821
|
-
const inverse: NodeChangeset = {};
|
|
904
|
+
const inverse: Mutable<NodeChangeset> = {};
|
|
822
905
|
|
|
823
906
|
// If the node has a constraint, it should be inverted to a node-exist-on-revert constraint. This ensure that if
|
|
824
907
|
// the inverse is inverted again, the original input constraint will be restored.
|
|
@@ -848,6 +931,17 @@ export class ModularChangeFamily
|
|
|
848
931
|
return inverse;
|
|
849
932
|
}
|
|
850
933
|
|
|
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
|
+
|
|
851
945
|
public rebase(
|
|
852
946
|
taggedChange: TaggedChange<ModularChangeset>,
|
|
853
947
|
potentiallyConflictedOver: TaggedChange<ModularChangeset>,
|
|
@@ -867,17 +961,41 @@ export class ModularChangeFamily
|
|
|
867
961
|
const idState: IdAllocationState = { maxId };
|
|
868
962
|
const genId: IdAllocator = idAllocatorFromState(idState);
|
|
869
963
|
|
|
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
|
+
);
|
|
870
984
|
const crossFieldTable: RebaseTable = {
|
|
871
|
-
|
|
985
|
+
rebaseVersion,
|
|
986
|
+
entries: newDetachedEntryMap(),
|
|
872
987
|
newChange: change,
|
|
873
988
|
baseChange: over.change,
|
|
874
989
|
baseFieldToContext: new Map(),
|
|
990
|
+
baseRoots: over.change.rootNodes,
|
|
991
|
+
rebasedRootNodes,
|
|
875
992
|
baseToRebasedNodeId: newTupleBTree(),
|
|
876
993
|
rebasedFields: new Set(),
|
|
877
|
-
rebasedNodeToParent
|
|
878
|
-
|
|
994
|
+
rebasedNodeToParent,
|
|
995
|
+
rebasedDetachLocations: newChangeAtomIdRangeMap(),
|
|
996
|
+
movedDetaches: newChangeAtomIdRangeMap(),
|
|
879
997
|
nodeIdPairs: [],
|
|
880
|
-
affectedBaseFields
|
|
998
|
+
affectedBaseFields,
|
|
881
999
|
fieldsWithUnattachedChild: new Set(),
|
|
882
1000
|
};
|
|
883
1001
|
|
|
@@ -893,13 +1011,14 @@ export class ModularChangeFamily
|
|
|
893
1011
|
const rebasedNodes: ChangeAtomIdBTree<NodeChangeset> = brand(change.nodeChanges.clone());
|
|
894
1012
|
|
|
895
1013
|
const rebasedFields = this.rebaseIntersectingFields(
|
|
1014
|
+
nodesToRebase,
|
|
896
1015
|
crossFieldTable,
|
|
897
1016
|
rebasedNodes,
|
|
898
1017
|
genId,
|
|
899
1018
|
rebaseMetadata,
|
|
900
1019
|
);
|
|
901
1020
|
|
|
902
|
-
this.
|
|
1021
|
+
this.rebaseInvalidatedFields(
|
|
903
1022
|
rebasedFields,
|
|
904
1023
|
rebasedNodes,
|
|
905
1024
|
crossFieldTable,
|
|
@@ -907,25 +1026,59 @@ export class ModularChangeFamily
|
|
|
907
1026
|
genId,
|
|
908
1027
|
);
|
|
909
1028
|
|
|
1029
|
+
fixupRebasedDetachLocations(crossFieldTable);
|
|
1030
|
+
|
|
910
1031
|
const constraintState = newConstraintState(change.constraintViolationCount ?? 0);
|
|
911
1032
|
const revertConstraintState = newConstraintState(
|
|
912
1033
|
change.constraintViolationCountOnRevert ?? 0,
|
|
913
1034
|
);
|
|
914
|
-
|
|
1035
|
+
|
|
1036
|
+
this.updateConstraints(
|
|
915
1037
|
rebasedFields,
|
|
916
|
-
|
|
917
|
-
|
|
1038
|
+
rebasedNodes,
|
|
1039
|
+
rebasedRootNodes,
|
|
918
1040
|
constraintState,
|
|
919
1041
|
revertConstraintState,
|
|
920
|
-
|
|
1042
|
+
);
|
|
1043
|
+
|
|
1044
|
+
const fieldsWithRootMoves = getFieldsWithRootMoves(
|
|
1045
|
+
crossFieldTable.rebasedRootNodes,
|
|
1046
|
+
change.nodeAliases,
|
|
1047
|
+
);
|
|
1048
|
+
|
|
1049
|
+
const fieldToRootChanges = getFieldToRootChanges(
|
|
1050
|
+
crossFieldTable.rebasedRootNodes,
|
|
1051
|
+
change.nodeAliases,
|
|
921
1052
|
);
|
|
922
1053
|
|
|
923
1054
|
const rebased = makeModularChangeset({
|
|
924
|
-
fieldChanges: this.pruneFieldMap(
|
|
1055
|
+
fieldChanges: this.pruneFieldMap(
|
|
1056
|
+
rebasedFields,
|
|
1057
|
+
undefined,
|
|
1058
|
+
rebasedNodes,
|
|
1059
|
+
crossFieldTable.rebasedNodeToParent,
|
|
1060
|
+
change.nodeAliases,
|
|
1061
|
+
crossFieldTable.rebasedRootNodes,
|
|
1062
|
+
fieldsWithRootMoves,
|
|
1063
|
+
fieldToRootChanges,
|
|
1064
|
+
),
|
|
925
1065
|
nodeChanges: rebasedNodes,
|
|
926
1066
|
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?
|
|
927
1076
|
nodeAliases: change.nodeAliases,
|
|
928
|
-
crossFieldKeys:
|
|
1077
|
+
crossFieldKeys: rebaseCrossFieldKeys(
|
|
1078
|
+
change.crossFieldKeys,
|
|
1079
|
+
crossFieldTable.movedDetaches,
|
|
1080
|
+
crossFieldTable.rebasedDetachLocations,
|
|
1081
|
+
),
|
|
929
1082
|
maxId: idState.maxId,
|
|
930
1083
|
revisions: change.revisions,
|
|
931
1084
|
constraintViolationCount: constraintState.violationCount,
|
|
@@ -933,14 +1086,18 @@ export class ModularChangeFamily
|
|
|
933
1086
|
builds: change.builds,
|
|
934
1087
|
destroys: change.destroys,
|
|
935
1088
|
refreshers: change.refreshers,
|
|
1089
|
+
rebaseVersion,
|
|
936
1090
|
});
|
|
937
1091
|
|
|
1092
|
+
// XXX: This is an expensive assert which should be disabled before merging.
|
|
1093
|
+
this.validateChangeset(rebased);
|
|
938
1094
|
return rebased;
|
|
939
1095
|
}
|
|
940
1096
|
|
|
941
1097
|
// This performs a first pass on all fields which have both new and base changes.
|
|
942
1098
|
// TODO: Can we also handle additional passes in this method?
|
|
943
1099
|
private rebaseIntersectingFields(
|
|
1100
|
+
rootChanges: [newChangeset: NodeId, baseChangeset: NodeId][],
|
|
944
1101
|
crossFieldTable: RebaseTable,
|
|
945
1102
|
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
946
1103
|
genId: IdAllocator,
|
|
@@ -957,6 +1114,18 @@ export class ModularChangeFamily
|
|
|
957
1114
|
metadata,
|
|
958
1115
|
);
|
|
959
1116
|
|
|
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
|
+
|
|
960
1129
|
// This loop processes all fields which have both base and new changes.
|
|
961
1130
|
// Note that the call to `rebaseNodeChange` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
962
1131
|
for (const [newId, baseId, _attachState] of crossFieldTable.nodeIdPairs) {
|
|
@@ -974,146 +1143,150 @@ export class ModularChangeFamily
|
|
|
974
1143
|
return rebasedFields;
|
|
975
1144
|
}
|
|
976
1145
|
|
|
977
|
-
|
|
978
|
-
|
|
1146
|
+
private rebaseFieldWithoutNewChanges(
|
|
1147
|
+
baseFieldChange: FieldChange,
|
|
1148
|
+
baseFieldId: FieldId,
|
|
1149
|
+
crossFieldTable: RebaseTable,
|
|
979
1150
|
rebasedFields: FieldChangeMap,
|
|
980
1151
|
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
981
|
-
crossFieldTable: RebaseTable,
|
|
982
1152
|
genId: IdAllocator,
|
|
983
1153
|
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,
|
|
984
1159
|
): void {
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1160
|
+
// This field has no changes in the new changeset, otherwise it would have been added to
|
|
1161
|
+
// `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
|
|
1162
|
+
const rebaseChild = (
|
|
1163
|
+
child: NodeId | undefined,
|
|
1164
|
+
baseChild: NodeId | undefined,
|
|
1165
|
+
stateChange: NodeAttachState | undefined,
|
|
1166
|
+
): NodeId | undefined => {
|
|
1167
|
+
assert(child === undefined, 0x9c3 /* There should be no new changes in this field */);
|
|
1168
|
+
if (baseChild === undefined || baseNodeId === undefined) {
|
|
1169
|
+
return undefined;
|
|
1170
|
+
}
|
|
991
1171
|
|
|
992
|
-
|
|
993
|
-
baseChange.
|
|
994
|
-
baseChange.nodeChanges,
|
|
1172
|
+
return areEqualChangeAtomIds(
|
|
1173
|
+
normalizeNodeId(baseChild, crossFieldTable.baseChange.nodeAliases),
|
|
995
1174
|
baseNodeId,
|
|
996
|
-
)
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
0x9c2 /* Cross field key registered for empty field */,
|
|
1001
|
-
);
|
|
1002
|
-
if (crossFieldTable.baseFieldToContext.has(baseFieldChange)) {
|
|
1003
|
-
// This field has already been processed because there were changes to rebase.
|
|
1004
|
-
continue;
|
|
1005
|
-
}
|
|
1175
|
+
)
|
|
1176
|
+
? baseNodeId
|
|
1177
|
+
: undefined;
|
|
1178
|
+
};
|
|
1006
1179
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
stateChange: NodeAttachState | undefined,
|
|
1013
|
-
): NodeId | undefined => {
|
|
1014
|
-
assert(child === undefined, 0x9c3 /* There should be no new changes in this field */);
|
|
1015
|
-
return undefined;
|
|
1016
|
-
};
|
|
1180
|
+
const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
|
|
1181
|
+
const fieldChange: FieldChange = {
|
|
1182
|
+
...baseFieldChange,
|
|
1183
|
+
change: brand(handler.createEmpty()),
|
|
1184
|
+
};
|
|
1017
1185
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
};
|
|
1186
|
+
const rebasedNodeId =
|
|
1187
|
+
baseFieldId.nodeId !== undefined
|
|
1188
|
+
? rebasedNodeIdFromBaseNodeId(crossFieldTable, baseFieldId.nodeId)
|
|
1189
|
+
: undefined;
|
|
1023
1190
|
|
|
1024
|
-
|
|
1025
|
-
baseNodeId !== undefined
|
|
1026
|
-
? rebasedNodeIdFromBaseNodeId(crossFieldTable, baseNodeId)
|
|
1027
|
-
: undefined;
|
|
1191
|
+
const fieldId: FieldId = { nodeId: rebasedNodeId, field: baseFieldId.field };
|
|
1028
1192
|
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1193
|
+
const rebasedField: unknown = handler.rebaser.rebase(
|
|
1194
|
+
fieldChange.change,
|
|
1195
|
+
baseFieldChange.change,
|
|
1196
|
+
rebaseChild,
|
|
1197
|
+
genId,
|
|
1198
|
+
new RebaseNodeManagerI(crossFieldTable, fieldId),
|
|
1199
|
+
metadata,
|
|
1200
|
+
crossFieldTable.rebaseVersion,
|
|
1201
|
+
);
|
|
1038
1202
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1203
|
+
const rebasedFieldChange: FieldChange = {
|
|
1204
|
+
...baseFieldChange,
|
|
1205
|
+
change: brand(rebasedField),
|
|
1206
|
+
};
|
|
1043
1207
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
});
|
|
1052
|
-
crossFieldTable.rebasedFields.add(rebasedFieldChange);
|
|
1208
|
+
const context: RebaseFieldContext = {
|
|
1209
|
+
newChange: fieldChange,
|
|
1210
|
+
baseChange: baseFieldChange,
|
|
1211
|
+
rebasedChange: rebasedFieldChange,
|
|
1212
|
+
fieldId,
|
|
1213
|
+
baseNodeIds: newTupleBTree(),
|
|
1214
|
+
};
|
|
1053
1215
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
rebasedNodes,
|
|
1057
|
-
crossFieldTable,
|
|
1058
|
-
rebasedFieldChange,
|
|
1059
|
-
fieldId,
|
|
1060
|
-
genId,
|
|
1061
|
-
metadata,
|
|
1062
|
-
);
|
|
1216
|
+
if (baseNodeId !== undefined) {
|
|
1217
|
+
setInChangeAtomIdMap(context.baseNodeIds, baseNodeId, true);
|
|
1063
1218
|
}
|
|
1064
|
-
}
|
|
1065
1219
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
idAllocator: IdAllocator,
|
|
1072
|
-
): void {
|
|
1073
|
-
this.rebaseFieldsWithoutNewChanges(
|
|
1220
|
+
crossFieldTable.baseFieldToContext.set(baseFieldChange, context);
|
|
1221
|
+
|
|
1222
|
+
crossFieldTable.rebasedFields.add(rebasedFieldChange);
|
|
1223
|
+
|
|
1224
|
+
this.attachRebasedField(
|
|
1074
1225
|
rebasedFields,
|
|
1075
1226
|
rebasedNodes,
|
|
1076
|
-
|
|
1077
|
-
|
|
1227
|
+
crossFieldTable,
|
|
1228
|
+
rebasedFieldChange,
|
|
1229
|
+
fieldId,
|
|
1230
|
+
genId,
|
|
1078
1231
|
metadata,
|
|
1079
1232
|
);
|
|
1080
|
-
|
|
1081
|
-
this.rebaseFieldsWithUnattachedChild(table, metadata, idAllocator);
|
|
1082
|
-
this.rebaseInvalidatedFields(table, metadata, idAllocator);
|
|
1083
1233
|
}
|
|
1084
1234
|
|
|
1085
1235
|
private rebaseInvalidatedFields(
|
|
1236
|
+
rebasedFields: FieldChangeMap,
|
|
1237
|
+
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1086
1238
|
crossFieldTable: RebaseTable,
|
|
1087
1239
|
rebaseMetadata: RebaseRevisionMetadata,
|
|
1088
1240
|
genId: IdAllocator,
|
|
1089
1241
|
): void {
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1242
|
+
while (crossFieldTable.affectedBaseFields.size > 0) {
|
|
1243
|
+
const baseFields = crossFieldTable.affectedBaseFields.clone();
|
|
1244
|
+
crossFieldTable.affectedBaseFields.clear();
|
|
1245
|
+
|
|
1246
|
+
for (const baseFieldIdKey of baseFields.keys()) {
|
|
1247
|
+
const baseFieldId = normalizeFieldId(
|
|
1248
|
+
fieldIdFromFieldIdKey(baseFieldIdKey),
|
|
1249
|
+
crossFieldTable.baseChange.nodeAliases,
|
|
1250
|
+
);
|
|
1096
1251
|
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1252
|
+
const baseField = fieldChangeFromId(crossFieldTable.baseChange, baseFieldId);
|
|
1253
|
+
|
|
1254
|
+
assert(
|
|
1255
|
+
baseField !== undefined,
|
|
1256
|
+
0x9c2 /* Cross field key registered for empty field */,
|
|
1257
|
+
);
|
|
1258
|
+
|
|
1259
|
+
const context = crossFieldTable.baseFieldToContext.get(baseField);
|
|
1260
|
+
if (context === undefined) {
|
|
1261
|
+
this.rebaseFieldWithoutNewChanges(
|
|
1262
|
+
baseField,
|
|
1263
|
+
baseFieldId,
|
|
1264
|
+
crossFieldTable,
|
|
1265
|
+
rebasedFields,
|
|
1266
|
+
rebasedNodes,
|
|
1267
|
+
genId,
|
|
1268
|
+
rebaseMetadata,
|
|
1269
|
+
);
|
|
1270
|
+
} else {
|
|
1271
|
+
this.rebaseInvalidatedField(
|
|
1272
|
+
baseField,
|
|
1273
|
+
crossFieldTable,
|
|
1274
|
+
context,
|
|
1275
|
+
rebaseMetadata,
|
|
1276
|
+
genId,
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1105
1280
|
}
|
|
1106
1281
|
}
|
|
1107
1282
|
|
|
1108
1283
|
private rebaseInvalidatedField(
|
|
1109
1284
|
baseField: FieldChange,
|
|
1110
1285
|
crossFieldTable: RebaseTable,
|
|
1286
|
+
context: RebaseFieldContext,
|
|
1111
1287
|
rebaseMetadata: RebaseRevisionMetadata,
|
|
1112
1288
|
genId: IdAllocator,
|
|
1113
|
-
allowInval = false,
|
|
1114
1289
|
): void {
|
|
1115
|
-
const context = crossFieldTable.baseFieldToContext.get(baseField);
|
|
1116
|
-
assert(context !== undefined, 0x852 /* Every field should have a context */);
|
|
1117
1290
|
const {
|
|
1118
1291
|
changeHandler,
|
|
1119
1292
|
change1: fieldChangeset,
|
|
@@ -1128,25 +1301,28 @@ export class ModularChangeFamily
|
|
|
1128
1301
|
return curr;
|
|
1129
1302
|
}
|
|
1130
1303
|
|
|
1131
|
-
if (base !== undefined) {
|
|
1132
|
-
|
|
1133
|
-
if (areEqualChangeAtomIds(base, id)) {
|
|
1134
|
-
return base;
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1304
|
+
if (base !== undefined && getFromChangeAtomIdMap(context.baseNodeIds, base) === true) {
|
|
1305
|
+
return base;
|
|
1137
1306
|
}
|
|
1138
1307
|
|
|
1139
1308
|
return undefined;
|
|
1140
1309
|
};
|
|
1141
1310
|
|
|
1311
|
+
let allowInval = false;
|
|
1312
|
+
if (crossFieldTable.fieldsWithUnattachedChild.has(baseField)) {
|
|
1313
|
+
crossFieldTable.fieldsWithUnattachedChild.delete(baseField);
|
|
1314
|
+
allowInval = true;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1142
1317
|
context.rebasedChange.change = brand(
|
|
1143
1318
|
changeHandler.rebaser.rebase(
|
|
1144
1319
|
fieldChangeset,
|
|
1145
1320
|
baseChangeset,
|
|
1146
1321
|
rebaseChild,
|
|
1147
1322
|
genId,
|
|
1148
|
-
new
|
|
1323
|
+
new RebaseNodeManagerI(crossFieldTable, context.fieldId, allowInval),
|
|
1149
1324
|
rebaseMetadata,
|
|
1325
|
+
crossFieldTable.rebaseVersion,
|
|
1150
1326
|
),
|
|
1151
1327
|
);
|
|
1152
1328
|
}
|
|
@@ -1166,13 +1342,19 @@ export class ModularChangeFamily
|
|
|
1166
1342
|
}
|
|
1167
1343
|
const rebasedNode = getFromChangeAtomIdMap(rebasedNodes, nodeId);
|
|
1168
1344
|
if (rebasedNode !== undefined) {
|
|
1169
|
-
|
|
1170
|
-
|
|
1345
|
+
const updatedRebasedNode: Mutable<NodeChangeset> = cloneNodeChangeset(rebasedNode);
|
|
1346
|
+
setInChangeAtomIdMap(rebasedNodes, nodeId, updatedRebasedNode);
|
|
1347
|
+
|
|
1348
|
+
if (updatedRebasedNode.fieldChanges === undefined) {
|
|
1349
|
+
updatedRebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
|
|
1171
1350
|
return;
|
|
1172
1351
|
}
|
|
1173
1352
|
|
|
1174
|
-
assert(
|
|
1175
|
-
|
|
1353
|
+
assert(
|
|
1354
|
+
!updatedRebasedNode.fieldChanges.has(fieldKey),
|
|
1355
|
+
0x9c4 /* Expected an empty field */,
|
|
1356
|
+
);
|
|
1357
|
+
updatedRebasedNode.fieldChanges.set(fieldKey, rebasedField);
|
|
1176
1358
|
return;
|
|
1177
1359
|
}
|
|
1178
1360
|
|
|
@@ -1183,14 +1365,14 @@ export class ModularChangeFamily
|
|
|
1183
1365
|
setInChangeAtomIdMap(rebasedNodes, nodeId, newNode);
|
|
1184
1366
|
setInChangeAtomIdMap(table.baseToRebasedNodeId, nodeId, nodeId);
|
|
1185
1367
|
|
|
1186
|
-
const
|
|
1368
|
+
const parentBase = getNodeParent(table.baseChange, nodeId);
|
|
1187
1369
|
|
|
1188
1370
|
this.attachRebasedNode(
|
|
1189
1371
|
rebasedFields,
|
|
1190
1372
|
rebasedNodes,
|
|
1191
1373
|
table,
|
|
1192
1374
|
nodeId,
|
|
1193
|
-
|
|
1375
|
+
parentBase,
|
|
1194
1376
|
idAllocator,
|
|
1195
1377
|
metadata,
|
|
1196
1378
|
);
|
|
@@ -1201,65 +1383,100 @@ export class ModularChangeFamily
|
|
|
1201
1383
|
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1202
1384
|
table: RebaseTable,
|
|
1203
1385
|
baseNodeId: NodeId,
|
|
1204
|
-
|
|
1386
|
+
parentBase: NodeLocation,
|
|
1205
1387
|
idAllocator: IdAllocator,
|
|
1206
1388
|
metadata: RebaseRevisionMetadata,
|
|
1207
1389
|
): void {
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1390
|
+
if (parentBase.root !== undefined) {
|
|
1391
|
+
const renamedRoot = firstAttachIdFromDetachId(
|
|
1392
|
+
table.baseChange.rootNodes,
|
|
1393
|
+
parentBase.root,
|
|
1394
|
+
1,
|
|
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
|
+
}
|
|
1216
1447
|
|
|
1217
|
-
const context = table.baseFieldToContext.get(baseFieldChange);
|
|
1218
|
-
if (context !== undefined) {
|
|
1219
|
-
// We've already processed this field.
|
|
1220
|
-
// The new child node will be attached in rebaseFieldsWithUnattachedChild.
|
|
1221
|
-
context.baseNodeIds.push(baseNodeId);
|
|
1222
|
-
table.fieldsWithUnattachedChild.add(baseFieldChange);
|
|
1223
1448
|
return;
|
|
1224
1449
|
}
|
|
1225
1450
|
|
|
1226
|
-
const
|
|
1227
|
-
|
|
1228
|
-
const fieldChange: FieldChange = {
|
|
1229
|
-
...baseFieldChange,
|
|
1230
|
-
change: brand(handler.createEmpty()),
|
|
1231
|
-
};
|
|
1451
|
+
const parentFieldIdBase = parentBase.field;
|
|
1452
|
+
const baseFieldChange = fieldChangeFromId(table.baseChange, parentFieldIdBase);
|
|
1232
1453
|
|
|
1233
|
-
const
|
|
1234
|
-
|
|
1235
|
-
baseFieldChange.change,
|
|
1236
|
-
(_idNew, idBase) =>
|
|
1237
|
-
idBase !== undefined && areEqualChangeAtomIds(idBase, baseNodeId)
|
|
1238
|
-
? baseNodeId
|
|
1239
|
-
: undefined,
|
|
1240
|
-
idAllocator,
|
|
1241
|
-
new RebaseManager(table, baseFieldChange, rebasedFieldId),
|
|
1242
|
-
metadata,
|
|
1243
|
-
);
|
|
1454
|
+
const rebasedFieldId = rebasedFieldIdFromBaseId(table, parentFieldIdBase);
|
|
1455
|
+
setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId, { field: rebasedFieldId });
|
|
1244
1456
|
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
baseNodeIds
|
|
1253
|
-
|
|
1457
|
+
const context = table.baseFieldToContext.get(baseFieldChange);
|
|
1458
|
+
if (context !== undefined) {
|
|
1459
|
+
// We've already processed this field.
|
|
1460
|
+
// The new child node will be attached in the next pass.
|
|
1461
|
+
// Note that adding to `fieldsWithUnattachedChild` allows that field to generate new invalidations,
|
|
1462
|
+
// so to avoid invalidation cycles we make sure we only add to it once per new unattached child.
|
|
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
|
+
}
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1254
1470
|
|
|
1255
|
-
this.
|
|
1471
|
+
this.rebaseFieldWithoutNewChanges(
|
|
1472
|
+
baseFieldChange,
|
|
1473
|
+
parentFieldIdBase,
|
|
1474
|
+
table,
|
|
1256
1475
|
rebasedFields,
|
|
1257
1476
|
rebasedNodes,
|
|
1258
|
-
table,
|
|
1259
|
-
rebasedField,
|
|
1260
|
-
rebasedFieldId,
|
|
1261
1477
|
idAllocator,
|
|
1262
1478
|
metadata,
|
|
1479
|
+
baseNodeId,
|
|
1263
1480
|
);
|
|
1264
1481
|
}
|
|
1265
1482
|
|
|
@@ -1298,7 +1515,7 @@ export class ModularChangeFamily
|
|
|
1298
1515
|
change2: baseChangeset,
|
|
1299
1516
|
} = this.normalizeFieldChanges(fieldChange, baseChange);
|
|
1300
1517
|
|
|
1301
|
-
const manager = new
|
|
1518
|
+
const manager = new RebaseNodeManagerI(crossFieldTable, fieldId);
|
|
1302
1519
|
|
|
1303
1520
|
const rebasedField = changeHandler.rebaser.rebase(
|
|
1304
1521
|
fieldChangeset,
|
|
@@ -1307,6 +1524,7 @@ export class ModularChangeFamily
|
|
|
1307
1524
|
genId,
|
|
1308
1525
|
manager,
|
|
1309
1526
|
revisionMetadata,
|
|
1527
|
+
crossFieldTable.rebaseVersion,
|
|
1310
1528
|
);
|
|
1311
1529
|
|
|
1312
1530
|
const rebasedFieldChange: FieldChange = {
|
|
@@ -1321,7 +1539,7 @@ export class ModularChangeFamily
|
|
|
1321
1539
|
newChange: fieldChange,
|
|
1322
1540
|
rebasedChange: rebasedFieldChange,
|
|
1323
1541
|
fieldId,
|
|
1324
|
-
baseNodeIds:
|
|
1542
|
+
baseNodeIds: newTupleBTree(),
|
|
1325
1543
|
});
|
|
1326
1544
|
|
|
1327
1545
|
crossFieldTable.rebasedFields.add(rebasedFieldChange);
|
|
@@ -1337,8 +1555,16 @@ export class ModularChangeFamily
|
|
|
1337
1555
|
crossFieldTable: RebaseTable,
|
|
1338
1556
|
revisionMetadata: RebaseRevisionMetadata,
|
|
1339
1557
|
): NodeChangeset {
|
|
1340
|
-
const change = nodeChangeFromId(
|
|
1341
|
-
|
|
1558
|
+
const change = nodeChangeFromId(
|
|
1559
|
+
crossFieldTable.newChange.nodeChanges,
|
|
1560
|
+
crossFieldTable.newChange.nodeAliases,
|
|
1561
|
+
newId,
|
|
1562
|
+
);
|
|
1563
|
+
const over = nodeChangeFromId(
|
|
1564
|
+
crossFieldTable.baseChange.nodeChanges,
|
|
1565
|
+
crossFieldTable.baseChange.nodeAliases,
|
|
1566
|
+
baseId,
|
|
1567
|
+
);
|
|
1342
1568
|
|
|
1343
1569
|
const baseMap: FieldChangeMap = over?.fieldChanges ?? new Map();
|
|
1344
1570
|
|
|
@@ -1354,7 +1580,7 @@ export class ModularChangeFamily
|
|
|
1354
1580
|
)
|
|
1355
1581
|
: change.fieldChanges;
|
|
1356
1582
|
|
|
1357
|
-
const rebasedChange: NodeChangeset = {};
|
|
1583
|
+
const rebasedChange: Mutable<NodeChangeset> = {};
|
|
1358
1584
|
|
|
1359
1585
|
if (fieldChanges !== undefined && fieldChanges.size > 0) {
|
|
1360
1586
|
rebasedChange.fieldChanges = fieldChanges;
|
|
@@ -1372,6 +1598,37 @@ export class ModularChangeFamily
|
|
|
1372
1598
|
return rebasedChange;
|
|
1373
1599
|
}
|
|
1374
1600
|
|
|
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
|
+
|
|
1375
1632
|
private updateConstraintsForFields(
|
|
1376
1633
|
fields: FieldChangeMap,
|
|
1377
1634
|
parentInputAttachState: NodeAttachState,
|
|
@@ -1382,20 +1639,18 @@ export class ModularChangeFamily
|
|
|
1382
1639
|
): void {
|
|
1383
1640
|
for (const field of fields.values()) {
|
|
1384
1641
|
const handler = getChangeHandler(this.fieldKinds, field.fieldKind);
|
|
1385
|
-
for (const [nodeId
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
? NodeAttachState.Detached
|
|
1390
|
-
: NodeAttachState.Attached;
|
|
1391
|
-
const isOutputDetached = outputIndex === undefined;
|
|
1642
|
+
for (const [nodeId] of handler.getNestedChanges(field.change)) {
|
|
1643
|
+
// XXX: This is incorrect if the rebased changeset detaches this node.
|
|
1644
|
+
// Efficiently computing whether the changeset detaches the node would require maintaining a mapping from node ID to detach ID.
|
|
1645
|
+
const isOutputDetached = false;
|
|
1392
1646
|
const outputAttachState =
|
|
1393
1647
|
parentOutputAttachState === NodeAttachState.Detached || isOutputDetached
|
|
1394
1648
|
? NodeAttachState.Detached
|
|
1395
1649
|
: NodeAttachState.Attached;
|
|
1650
|
+
|
|
1396
1651
|
this.updateConstraintsForNode(
|
|
1397
1652
|
nodeId,
|
|
1398
|
-
|
|
1653
|
+
parentInputAttachState,
|
|
1399
1654
|
outputAttachState,
|
|
1400
1655
|
nodes,
|
|
1401
1656
|
constraintState,
|
|
@@ -1413,12 +1668,15 @@ export class ModularChangeFamily
|
|
|
1413
1668
|
constraintState: ConstraintState,
|
|
1414
1669
|
revertConstraintState: ConstraintState,
|
|
1415
1670
|
): void {
|
|
1416
|
-
const node =
|
|
1417
|
-
|
|
1671
|
+
const node = getFromChangeAtomIdMap(nodes, nodeId) ?? fail(0xb24 /* Unknown node ID */);
|
|
1672
|
+
|
|
1673
|
+
const updatedNode: Mutable<NodeChangeset> = { ...node };
|
|
1674
|
+
setInChangeAtomIdMap(nodes, nodeId, updatedNode);
|
|
1675
|
+
|
|
1418
1676
|
if (node.nodeExistsConstraint !== undefined) {
|
|
1419
1677
|
const isNowViolated = inputAttachState === NodeAttachState.Detached;
|
|
1420
1678
|
if (node.nodeExistsConstraint.violated !== isNowViolated) {
|
|
1421
|
-
|
|
1679
|
+
updatedNode.nodeExistsConstraint = {
|
|
1422
1680
|
...node.nodeExistsConstraint,
|
|
1423
1681
|
violated: isNowViolated,
|
|
1424
1682
|
};
|
|
@@ -1428,7 +1686,7 @@ export class ModularChangeFamily
|
|
|
1428
1686
|
if (node.nodeExistsConstraintOnRevert !== undefined) {
|
|
1429
1687
|
const isNowViolated = outputAttachState === NodeAttachState.Detached;
|
|
1430
1688
|
if (node.nodeExistsConstraintOnRevert.violated !== isNowViolated) {
|
|
1431
|
-
|
|
1689
|
+
updatedNode.nodeExistsConstraintOnRevert = {
|
|
1432
1690
|
...node.nodeExistsConstraintOnRevert,
|
|
1433
1691
|
violated: isNowViolated,
|
|
1434
1692
|
};
|
|
@@ -1450,7 +1708,13 @@ export class ModularChangeFamily
|
|
|
1450
1708
|
|
|
1451
1709
|
private pruneFieldMap(
|
|
1452
1710
|
changeset: FieldChangeMap | undefined,
|
|
1711
|
+
parentId: NodeId | undefined,
|
|
1453
1712
|
nodeMap: ChangeAtomIdBTree<NodeChangeset>,
|
|
1713
|
+
nodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
1714
|
+
aliases: ChangeAtomIdBTree<NodeId>,
|
|
1715
|
+
roots: RootNodeTable,
|
|
1716
|
+
fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
|
|
1717
|
+
fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
|
|
1454
1718
|
): FieldChangeMap | undefined {
|
|
1455
1719
|
if (changeset === undefined) {
|
|
1456
1720
|
return undefined;
|
|
@@ -1461,10 +1725,48 @@ export class ModularChangeFamily
|
|
|
1461
1725
|
const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
|
|
1462
1726
|
|
|
1463
1727
|
const prunedFieldChangeset = handler.rebaser.prune(fieldChange.change, (nodeId) =>
|
|
1464
|
-
this.pruneNodeChange(
|
|
1728
|
+
this.pruneNodeChange(
|
|
1729
|
+
nodeId,
|
|
1730
|
+
nodeMap,
|
|
1731
|
+
nodeToParent,
|
|
1732
|
+
aliases,
|
|
1733
|
+
roots,
|
|
1734
|
+
fieldsWithRootMoves,
|
|
1735
|
+
fieldsToRootChanges,
|
|
1736
|
+
),
|
|
1465
1737
|
);
|
|
1466
1738
|
|
|
1467
|
-
|
|
1739
|
+
const fieldId: FieldId = { nodeId: parentId, field };
|
|
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) {
|
|
1468
1770
|
prunedChangeset.set(field, { ...fieldChange, change: brand(prunedFieldChangeset) });
|
|
1469
1771
|
}
|
|
1470
1772
|
}
|
|
@@ -1472,14 +1774,64 @@ export class ModularChangeFamily
|
|
|
1472
1774
|
return prunedChangeset.size > 0 ? prunedChangeset : undefined;
|
|
1473
1775
|
}
|
|
1474
1776
|
|
|
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
|
+
|
|
1475
1813
|
private pruneNodeChange(
|
|
1476
1814
|
nodeId: NodeId,
|
|
1477
|
-
|
|
1815
|
+
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1816
|
+
nodeToParent: ChangeAtomIdBTree<NodeLocation>,
|
|
1817
|
+
aliases: ChangeAtomIdBTree<NodeId>,
|
|
1818
|
+
roots: RootNodeTable,
|
|
1819
|
+
fieldsWithRootMoves: TupleBTree<FieldIdKey, boolean>,
|
|
1820
|
+
fieldsToRootChanges: TupleBTree<FieldIdKey, ChangeAtomId[]>,
|
|
1478
1821
|
): NodeId | undefined {
|
|
1479
|
-
const changeset = nodeChangeFromId(
|
|
1822
|
+
const changeset = nodeChangeFromId(nodes, aliases, nodeId);
|
|
1480
1823
|
const prunedFields =
|
|
1481
1824
|
changeset.fieldChanges !== undefined
|
|
1482
|
-
? this.pruneFieldMap(
|
|
1825
|
+
? this.pruneFieldMap(
|
|
1826
|
+
changeset.fieldChanges,
|
|
1827
|
+
nodeId,
|
|
1828
|
+
nodes,
|
|
1829
|
+
nodeToParent,
|
|
1830
|
+
aliases,
|
|
1831
|
+
roots,
|
|
1832
|
+
fieldsWithRootMoves,
|
|
1833
|
+
fieldsToRootChanges,
|
|
1834
|
+
)
|
|
1483
1835
|
: undefined;
|
|
1484
1836
|
|
|
1485
1837
|
const prunedChange = { ...changeset, fieldChanges: prunedFields };
|
|
@@ -1488,10 +1840,14 @@ export class ModularChangeFamily
|
|
|
1488
1840
|
}
|
|
1489
1841
|
|
|
1490
1842
|
if (isEmptyNodeChangeset(prunedChange)) {
|
|
1491
|
-
|
|
1843
|
+
const nodeIdKey: ChangeAtomIdKey = [nodeId.revision, nodeId.localId];
|
|
1844
|
+
|
|
1845
|
+
// TODO: Shouldn't we also delete all aliases associated with this node?
|
|
1846
|
+
nodes.delete(nodeIdKey);
|
|
1847
|
+
nodeToParent.delete(nodeIdKey);
|
|
1492
1848
|
return undefined;
|
|
1493
1849
|
} else {
|
|
1494
|
-
setInChangeAtomIdMap(
|
|
1850
|
+
setInChangeAtomIdMap(nodes, nodeId, prunedChange);
|
|
1495
1851
|
return nodeId;
|
|
1496
1852
|
}
|
|
1497
1853
|
}
|
|
@@ -1520,12 +1876,12 @@ export class ModularChangeFamily
|
|
|
1520
1876
|
);
|
|
1521
1877
|
}
|
|
1522
1878
|
|
|
1523
|
-
const updatedNodeToParent: ChangeAtomIdBTree<
|
|
1524
|
-
for (const [[revision, id],
|
|
1879
|
+
const updatedNodeToParent: ChangeAtomIdBTree<NodeLocation> = newTupleBTree();
|
|
1880
|
+
for (const [[revision, id], location] of change.nodeToParent.entries()) {
|
|
1525
1881
|
updatedNodeToParent.set(
|
|
1526
1882
|
[replaceRevision(revision, oldRevisions, newRevision), id],
|
|
1527
|
-
|
|
1528
|
-
|
|
1883
|
+
replaceNodeLocationRevision(
|
|
1884
|
+
normalizeNodeLocation(location, change.nodeAliases),
|
|
1529
1885
|
oldRevisions,
|
|
1530
1886
|
newRevision,
|
|
1531
1887
|
),
|
|
@@ -1537,15 +1893,24 @@ export class ModularChangeFamily
|
|
|
1537
1893
|
fieldChanges: updatedFields,
|
|
1538
1894
|
nodeChanges: updatedNodes,
|
|
1539
1895
|
nodeToParent: updatedNodeToParent,
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
nodeAliases: newTupleBTree(),
|
|
1543
|
-
crossFieldKeys: replaceCrossFieldKeyTableRevisions(
|
|
1544
|
-
change.crossFieldKeys,
|
|
1896
|
+
rootNodes: replaceRootTableRevision(
|
|
1897
|
+
change.rootNodes,
|
|
1545
1898
|
oldRevisions,
|
|
1546
1899
|
newRevision,
|
|
1547
1900
|
change.nodeAliases,
|
|
1548
1901
|
),
|
|
1902
|
+
|
|
1903
|
+
// We've updated all references to old node IDs, so we no longer need an alias table.
|
|
1904
|
+
nodeAliases: newTupleBTree(),
|
|
1905
|
+
crossFieldKeys: change.crossFieldKeys.mapEntries(
|
|
1906
|
+
(key) => replaceCrossFieldKeyRevision(key, oldRevisions, newRevision),
|
|
1907
|
+
(id) =>
|
|
1908
|
+
replaceFieldIdRevision(
|
|
1909
|
+
normalizeFieldId(id, change.nodeAliases),
|
|
1910
|
+
oldRevisions,
|
|
1911
|
+
newRevision,
|
|
1912
|
+
),
|
|
1913
|
+
),
|
|
1549
1914
|
};
|
|
1550
1915
|
|
|
1551
1916
|
if (change.builds !== undefined) {
|
|
@@ -1613,7 +1978,7 @@ export class ModularChangeFamily
|
|
|
1613
1978
|
fields: FieldChangeMap,
|
|
1614
1979
|
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1615
1980
|
): CrossFieldKeyTable {
|
|
1616
|
-
const keys: CrossFieldKeyTable =
|
|
1981
|
+
const keys: CrossFieldKeyTable = newCrossFieldRangeTable();
|
|
1617
1982
|
this.populateCrossFieldKeyTableForFieldMap(keys, fields, undefined);
|
|
1618
1983
|
nodes.forEachPair(([revision, localId], node) => {
|
|
1619
1984
|
if (node.fieldChanges !== undefined) {
|
|
@@ -1654,60 +2019,102 @@ export class ModularChangeFamily
|
|
|
1654
2019
|
}
|
|
1655
2020
|
|
|
1656
2021
|
public validateChangeset(change: ModularChangeset): void {
|
|
1657
|
-
|
|
2022
|
+
const unreachableNodes: ChangeAtomIdBTree<NodeLocation> = brand(
|
|
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
|
+
);
|
|
1658
2035
|
|
|
1659
2036
|
for (const [[revision, localId], node] of change.nodeChanges.entries()) {
|
|
1660
2037
|
if (node.fieldChanges === undefined) {
|
|
1661
2038
|
continue;
|
|
1662
2039
|
}
|
|
1663
2040
|
|
|
1664
|
-
const nodeId
|
|
1665
|
-
|
|
2041
|
+
const nodeId = normalizeNodeId({ revision, localId }, change.nodeAliases);
|
|
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");
|
|
1666
2055
|
|
|
1667
|
-
|
|
2056
|
+
const normalizedNodeId = normalizeNodeId(nodeId, change.nodeAliases);
|
|
2057
|
+
unreachableNodes.delete([normalizedNodeId.revision, normalizedNodeId.localId]);
|
|
2058
|
+
|
|
2059
|
+
const fieldChanges = nodeChangeFromId(
|
|
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
|
+
}
|
|
1668
2074
|
}
|
|
1669
2075
|
|
|
1670
|
-
assert(
|
|
1671
|
-
|
|
1672
|
-
0xa4d /* Node table contains unparented nodes */,
|
|
1673
|
-
);
|
|
2076
|
+
assert(unreachableNodes.size === 0, "Unreachable nodes found");
|
|
2077
|
+
assert(unreachableCFKs.entries().length === 0, "Unreachable cross-field keys found");
|
|
1674
2078
|
}
|
|
1675
2079
|
|
|
1676
2080
|
/**
|
|
1677
|
-
* Asserts that each
|
|
1678
|
-
*
|
|
2081
|
+
* Asserts that each node has a correct entry in `change.nodeToParent`,
|
|
2082
|
+
* and each cross field key has a correct entry in `change.crossFieldKeys`.
|
|
1679
2083
|
* @returns the number of children found.
|
|
1680
2084
|
*/
|
|
1681
2085
|
private validateFieldChanges(
|
|
1682
2086
|
change: ModularChangeset,
|
|
1683
2087
|
fieldChanges: FieldChangeMap,
|
|
1684
2088
|
nodeParent: NodeId | undefined,
|
|
1685
|
-
|
|
1686
|
-
|
|
2089
|
+
unreachableNodes: ChangeAtomIdBTree<NodeLocation>,
|
|
2090
|
+
unreachableCFKs: CrossFieldRangeTable<FieldId>,
|
|
2091
|
+
): void {
|
|
1687
2092
|
for (const [field, fieldChange] of fieldChanges.entries()) {
|
|
1688
2093
|
const fieldId = { nodeId: nodeParent, field };
|
|
1689
2094
|
const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
|
|
1690
2095
|
for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
|
|
1691
|
-
const parentFieldId =
|
|
2096
|
+
const parentFieldId = getNodeParent(change, child);
|
|
1692
2097
|
assert(
|
|
1693
|
-
areEqualFieldIds(parentFieldId, fieldId),
|
|
2098
|
+
parentFieldId.field !== undefined && areEqualFieldIds(parentFieldId.field, fieldId),
|
|
1694
2099
|
0xa4e /* Inconsistent node parentage */,
|
|
1695
2100
|
);
|
|
1696
|
-
|
|
2101
|
+
|
|
2102
|
+
unreachableNodes.delete([child.revision, child.localId]);
|
|
1697
2103
|
}
|
|
1698
2104
|
|
|
1699
2105
|
for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
|
|
1700
2106
|
const fields = getFieldsForCrossFieldKey(change, keyRange.key, keyRange.count);
|
|
1701
|
-
assert(
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
areEqualFieldIds(
|
|
1705
|
-
|
|
1706
|
-
|
|
2107
|
+
assert(fields.length > 0, "Unregistered cross-field key");
|
|
2108
|
+
for (const fieldFromLookup of fields) {
|
|
2109
|
+
assert(
|
|
2110
|
+
areEqualFieldIds(fieldFromLookup, fieldId),
|
|
2111
|
+
0xa4f /* Inconsistent cross field keys */,
|
|
2112
|
+
);
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
unreachableCFKs.delete(keyRange.key, keyRange.count);
|
|
1707
2116
|
}
|
|
1708
2117
|
}
|
|
1709
|
-
|
|
1710
|
-
return numChildren;
|
|
1711
2118
|
}
|
|
1712
2119
|
|
|
1713
2120
|
private getEffectiveChange(change: ModularChangeset): ModularChangeset {
|
|
@@ -1723,7 +2130,8 @@ export class ModularChangeFamily
|
|
|
1723
2130
|
private muteChange(change: ModularChangeset): ModularChangeset {
|
|
1724
2131
|
const muted: Mutable<ModularChangeset> = {
|
|
1725
2132
|
...change,
|
|
1726
|
-
|
|
2133
|
+
rootNodes: muteRootChanges(change.rootNodes),
|
|
2134
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
1727
2135
|
fieldChanges: this.muteFieldChanges(change.fieldChanges),
|
|
1728
2136
|
nodeChanges: brand(change.nodeChanges.mapValues((v) => this.muteNodeChange(v))),
|
|
1729
2137
|
};
|
|
@@ -1755,37 +2163,16 @@ export class ModularChangeFamily
|
|
|
1755
2163
|
}
|
|
1756
2164
|
}
|
|
1757
2165
|
|
|
1758
|
-
function
|
|
1759
|
-
|
|
2166
|
+
function replaceCrossFieldKeyRevision(
|
|
2167
|
+
key: CrossFieldKey,
|
|
1760
2168
|
oldRevisions: Set<RevisionTag | undefined>,
|
|
1761
2169
|
newRevision: RevisionTag | undefined,
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
target: key.target,
|
|
1769
|
-
revision: replaceRevision(key.revision, oldRevisions, newRevision),
|
|
1770
|
-
localId: key.localId,
|
|
1771
|
-
};
|
|
1772
|
-
|
|
1773
|
-
const field = entry.value;
|
|
1774
|
-
const normalizedFieldId = normalizeFieldId(field, nodeAliases);
|
|
1775
|
-
const updatedNodeId =
|
|
1776
|
-
normalizedFieldId.nodeId !== undefined
|
|
1777
|
-
? replaceAtomRevisions(normalizedFieldId.nodeId, oldRevisions, newRevision)
|
|
1778
|
-
: undefined;
|
|
1779
|
-
|
|
1780
|
-
const updatedValue: FieldId = {
|
|
1781
|
-
...normalizedFieldId,
|
|
1782
|
-
nodeId: updatedNodeId,
|
|
1783
|
-
};
|
|
1784
|
-
|
|
1785
|
-
updated.set(updatedKey, entry.length, updatedValue);
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
|
-
return updated;
|
|
2170
|
+
): CrossFieldKey {
|
|
2171
|
+
return {
|
|
2172
|
+
target: key.target,
|
|
2173
|
+
revision: replaceRevision(key.revision, oldRevisions, newRevision),
|
|
2174
|
+
localId: key.localId,
|
|
2175
|
+
};
|
|
1789
2176
|
}
|
|
1790
2177
|
|
|
1791
2178
|
function replaceRevision(
|
|
@@ -1879,6 +2266,20 @@ function composeBuildsDestroysAndRefreshers(
|
|
|
1879
2266
|
}
|
|
1880
2267
|
}
|
|
1881
2268
|
|
|
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
|
+
|
|
1882
2283
|
return { allBuilds, allDestroys, allRefreshers };
|
|
1883
2284
|
}
|
|
1884
2285
|
|
|
@@ -1910,27 +2311,77 @@ export function* relevantRemovedRoots(
|
|
|
1910
2311
|
change: ModularChangeset,
|
|
1911
2312
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
1912
2313
|
): Iterable<DeltaDetachedNodeId> {
|
|
1913
|
-
|
|
2314
|
+
const rootIds: ChangeAtomIdRangeMap<boolean> = newChangeAtomIdRangeMap();
|
|
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
|
+
}
|
|
1914
2328
|
}
|
|
1915
2329
|
|
|
1916
|
-
function*
|
|
1917
|
-
change
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
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
|
+
}
|
|
1931
2365
|
}
|
|
1932
|
-
}
|
|
1933
|
-
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
function addRenamesToSet(
|
|
2371
|
+
change: ModularChangeset,
|
|
2372
|
+
rootIds: ChangeAtomIdRangeMap<boolean>,
|
|
2373
|
+
): void {
|
|
2374
|
+
for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
|
|
2375
|
+
for (const detachEntry of change.crossFieldKeys.getAll2(
|
|
2376
|
+
{ ...renameEntry.start, target: CrossFieldTarget.Source },
|
|
2377
|
+
renameEntry.length,
|
|
2378
|
+
)) {
|
|
2379
|
+
// We only want to include renames of nodes which are detached in the input context of the changeset.
|
|
2380
|
+
// So if there is a detach for the node, the rename is not relevant.
|
|
2381
|
+
if (detachEntry.value === undefined) {
|
|
2382
|
+
rootIds.set(renameEntry.start, renameEntry.length, true);
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
1934
2385
|
}
|
|
1935
2386
|
}
|
|
1936
2387
|
|
|
@@ -2003,6 +2454,7 @@ export function updateRefreshers(
|
|
|
2003
2454
|
nodeChanges,
|
|
2004
2455
|
nodeToParent: change.nodeToParent,
|
|
2005
2456
|
nodeAliases: change.nodeAliases,
|
|
2457
|
+
rootNodes: change.rootNodes,
|
|
2006
2458
|
crossFieldKeys: change.crossFieldKeys,
|
|
2007
2459
|
maxId: maxId as number,
|
|
2008
2460
|
revisions,
|
|
@@ -2026,18 +2478,42 @@ export function intoDelta(
|
|
|
2026
2478
|
): DeltaRoot {
|
|
2027
2479
|
const change = taggedChange.change;
|
|
2028
2480
|
const rootDelta: Mutable<DeltaRoot> = {};
|
|
2029
|
-
const global: DeltaDetachedNodeChanges[] = [];
|
|
2030
|
-
const rename: DeltaDetachedNodeRename[] = [];
|
|
2031
2481
|
|
|
2032
2482
|
if (!hasConflicts(change)) {
|
|
2033
2483
|
// If there are no constraint violations, then tree changes apply.
|
|
2034
2484
|
const fieldDeltas = intoDeltaImpl(
|
|
2035
2485
|
change.fieldChanges,
|
|
2036
2486
|
change.nodeChanges,
|
|
2487
|
+
change.nodeAliases,
|
|
2037
2488
|
fieldKinds,
|
|
2038
|
-
global,
|
|
2039
|
-
rename,
|
|
2040
2489
|
);
|
|
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
|
+
|
|
2041
2517
|
if (fieldDeltas.size > 0) {
|
|
2042
2518
|
rootDelta.fields = fieldDeltas;
|
|
2043
2519
|
}
|
|
@@ -2066,6 +2542,7 @@ export function intoDelta(
|
|
|
2066
2542
|
if (change.refreshers && change.refreshers.size > 0) {
|
|
2067
2543
|
rootDelta.refreshers = copyDetachedNodes(change.refreshers);
|
|
2068
2544
|
}
|
|
2545
|
+
|
|
2069
2546
|
return rootDelta;
|
|
2070
2547
|
}
|
|
2071
2548
|
|
|
@@ -2091,29 +2568,22 @@ function copyDetachedNodes(
|
|
|
2091
2568
|
function intoDeltaImpl(
|
|
2092
2569
|
change: FieldChangeMap,
|
|
2093
2570
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
|
|
2571
|
+
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
2094
2572
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
2095
|
-
global: DeltaDetachedNodeChanges[],
|
|
2096
|
-
rename: DeltaDetachedNodeRename[],
|
|
2097
2573
|
): Map<FieldKey, DeltaFieldChanges> {
|
|
2098
2574
|
const delta: Map<FieldKey, DeltaFieldChanges> = new Map();
|
|
2099
2575
|
|
|
2100
2576
|
for (const [field, fieldChange] of change) {
|
|
2101
|
-
const
|
|
2102
|
-
local: fieldChanges,
|
|
2103
|
-
global: fieldGlobal,
|
|
2104
|
-
rename: fieldRename,
|
|
2105
|
-
} = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(
|
|
2577
|
+
const fieldDelta = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(
|
|
2106
2578
|
fieldChange.change,
|
|
2107
2579
|
(childChange): DeltaFieldMap => {
|
|
2108
|
-
const nodeChange = nodeChangeFromId(nodeChanges, childChange);
|
|
2109
|
-
return deltaFromNodeChange(nodeChange, nodeChanges,
|
|
2580
|
+
const nodeChange = nodeChangeFromId(nodeChanges, nodeAliases, childChange);
|
|
2581
|
+
return deltaFromNodeChange(nodeChange, nodeChanges, nodeAliases, fieldKinds);
|
|
2110
2582
|
},
|
|
2111
2583
|
);
|
|
2112
|
-
if (
|
|
2113
|
-
delta.set(field,
|
|
2584
|
+
if (fieldDelta !== undefined && fieldDelta.length > 0) {
|
|
2585
|
+
delta.set(field, fieldDelta);
|
|
2114
2586
|
}
|
|
2115
|
-
fieldGlobal?.forEach((c) => global.push(c));
|
|
2116
|
-
fieldRename?.forEach((r) => rename.push(r));
|
|
2117
2587
|
}
|
|
2118
2588
|
return delta;
|
|
2119
2589
|
}
|
|
@@ -2121,12 +2591,11 @@ function intoDeltaImpl(
|
|
|
2121
2591
|
function deltaFromNodeChange(
|
|
2122
2592
|
change: NodeChangeset,
|
|
2123
2593
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
|
|
2594
|
+
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
2124
2595
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
2125
|
-
global: DeltaDetachedNodeChanges[],
|
|
2126
|
-
rename: DeltaDetachedNodeRename[],
|
|
2127
2596
|
): DeltaFieldMap {
|
|
2128
2597
|
if (change.fieldChanges !== undefined) {
|
|
2129
|
-
return intoDeltaImpl(change.fieldChanges, nodeChanges,
|
|
2598
|
+
return intoDeltaImpl(change.fieldChanges, nodeChanges, nodeAliases, fieldKinds);
|
|
2130
2599
|
}
|
|
2131
2600
|
// TODO: update the API to allow undefined to be returned here
|
|
2132
2601
|
return new Map();
|
|
@@ -2191,19 +2660,21 @@ export function getChangeHandler(
|
|
|
2191
2660
|
return getFieldKind(fieldKinds, kind).changeHandler;
|
|
2192
2661
|
}
|
|
2193
2662
|
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
interface CrossFieldTable<TFieldData> {
|
|
2197
|
-
srcTable: CrossFieldMap<unknown>;
|
|
2198
|
-
dstTable: CrossFieldMap<unknown>;
|
|
2199
|
-
srcDependents: CrossFieldMap<TFieldData>;
|
|
2200
|
-
dstDependents: CrossFieldMap<TFieldData>;
|
|
2201
|
-
invalidatedFields: Set<TFieldData>;
|
|
2202
|
-
}
|
|
2663
|
+
interface InvertTable {
|
|
2664
|
+
change: ModularChangeset;
|
|
2203
2665
|
|
|
2204
|
-
|
|
2666
|
+
// Entries are keyed on attach ID
|
|
2667
|
+
entries: CrossFieldMap<NodeId>;
|
|
2205
2668
|
originalFieldToContext: Map<FieldChange, InvertContext>;
|
|
2206
|
-
invertedNodeToParent: ChangeAtomIdBTree<
|
|
2669
|
+
invertedNodeToParent: ChangeAtomIdBTree<NodeLocation>;
|
|
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>;
|
|
2207
2678
|
}
|
|
2208
2679
|
|
|
2209
2680
|
interface InvertContext {
|
|
@@ -2211,7 +2682,11 @@ interface InvertContext {
|
|
|
2211
2682
|
invertedField: FieldChange;
|
|
2212
2683
|
}
|
|
2213
2684
|
|
|
2214
|
-
interface RebaseTable
|
|
2685
|
+
interface RebaseTable {
|
|
2686
|
+
readonly rebaseVersion: RebaseVersion;
|
|
2687
|
+
|
|
2688
|
+
// Entries are keyed on attach ID
|
|
2689
|
+
readonly entries: CrossFieldMap<RebaseDetachedNodeEntry>;
|
|
2215
2690
|
readonly baseChange: ModularChangeset;
|
|
2216
2691
|
readonly newChange: ModularChangeset;
|
|
2217
2692
|
|
|
@@ -2220,10 +2695,13 @@ interface RebaseTable extends CrossFieldTable<FieldChange> {
|
|
|
2220
2695
|
* to the context for the field.
|
|
2221
2696
|
*/
|
|
2222
2697
|
readonly baseFieldToContext: Map<FieldChange, RebaseFieldContext>;
|
|
2698
|
+
readonly baseRoots: RootNodeTable;
|
|
2223
2699
|
readonly baseToRebasedNodeId: ChangeAtomIdBTree<NodeId>;
|
|
2224
2700
|
readonly rebasedFields: Set<FieldChange>;
|
|
2225
|
-
readonly rebasedNodeToParent: ChangeAtomIdBTree<
|
|
2226
|
-
readonly
|
|
2701
|
+
readonly rebasedNodeToParent: ChangeAtomIdBTree<NodeLocation>;
|
|
2702
|
+
readonly rebasedDetachLocations: ChangeAtomIdRangeMap<FieldId>;
|
|
2703
|
+
readonly movedDetaches: ChangeAtomIdRangeMap<boolean>;
|
|
2704
|
+
readonly rebasedRootNodes: RootNodeTable;
|
|
2227
2705
|
|
|
2228
2706
|
/**
|
|
2229
2707
|
* List of unprocessed (newId, baseId) pairs encountered so far.
|
|
@@ -2237,7 +2715,7 @@ interface RebaseTable extends CrossFieldTable<FieldChange> {
|
|
|
2237
2715
|
readonly fieldsWithUnattachedChild: Set<FieldChange>;
|
|
2238
2716
|
}
|
|
2239
2717
|
|
|
2240
|
-
type FieldIdKey = [RevisionTag | undefined, ChangesetLocalId | undefined, FieldKey];
|
|
2718
|
+
export type FieldIdKey = [RevisionTag | undefined, ChangesetLocalId | undefined, FieldKey];
|
|
2241
2719
|
|
|
2242
2720
|
interface RebaseFieldContext {
|
|
2243
2721
|
baseChange: FieldChange;
|
|
@@ -2249,32 +2727,43 @@ interface RebaseFieldContext {
|
|
|
2249
2727
|
* The set of node IDs in the base changeset which should be included in the rebased field,
|
|
2250
2728
|
* even if there is no corresponding node changeset in the new change.
|
|
2251
2729
|
*/
|
|
2252
|
-
baseNodeIds:
|
|
2730
|
+
baseNodeIds: ChangeAtomIdBTree<boolean>;
|
|
2253
2731
|
}
|
|
2254
2732
|
|
|
2255
2733
|
function newComposeTable(
|
|
2256
2734
|
baseChange: ModularChangeset,
|
|
2257
2735
|
newChange: ModularChangeset,
|
|
2258
|
-
|
|
2736
|
+
composedRootNodes: RootNodeTable,
|
|
2737
|
+
movedCrossFieldKeys: CrossFieldKeyTable,
|
|
2738
|
+
removedCrossFieldKeys: CrossFieldRangeTable<boolean>,
|
|
2739
|
+
pendingCompositions: PendingCompositions,
|
|
2259
2740
|
): ComposeTable {
|
|
2260
2741
|
return {
|
|
2261
|
-
|
|
2742
|
+
rebaseVersion: Math.max(
|
|
2743
|
+
baseChange.rebaseVersion,
|
|
2744
|
+
newChange.rebaseVersion,
|
|
2745
|
+
) as RebaseVersion,
|
|
2746
|
+
entries: newDetachedEntryMap(),
|
|
2262
2747
|
baseChange,
|
|
2263
2748
|
newChange,
|
|
2264
2749
|
fieldToContext: new Map(),
|
|
2265
2750
|
newFieldToBaseField: new Map(),
|
|
2266
2751
|
newToBaseNodeId: newTupleBTree(),
|
|
2267
2752
|
composedNodes: new Set(),
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2753
|
+
movedNodeToParent: newTupleBTree(),
|
|
2754
|
+
composedRootNodes,
|
|
2755
|
+
movedCrossFieldKeys,
|
|
2756
|
+
removedCrossFieldKeys,
|
|
2757
|
+
renamesToDelete: newChangeAtomIdRangeMap(),
|
|
2758
|
+
pendingCompositions,
|
|
2274
2759
|
};
|
|
2275
2760
|
}
|
|
2276
2761
|
|
|
2277
|
-
interface ComposeTable
|
|
2762
|
+
interface ComposeTable {
|
|
2763
|
+
readonly rebaseVersion: RebaseVersion;
|
|
2764
|
+
|
|
2765
|
+
// Entries are keyed on detach ID
|
|
2766
|
+
readonly entries: ChangeAtomIdRangeMap<DetachedNodeEntry>;
|
|
2278
2767
|
readonly baseChange: ModularChangeset;
|
|
2279
2768
|
readonly newChange: ModularChangeset;
|
|
2280
2769
|
|
|
@@ -2285,7 +2774,11 @@ interface ComposeTable extends CrossFieldTable<FieldChange> {
|
|
|
2285
2774
|
readonly newFieldToBaseField: Map<FieldChange, FieldChange>;
|
|
2286
2775
|
readonly newToBaseNodeId: ChangeAtomIdBTree<NodeId>;
|
|
2287
2776
|
readonly composedNodes: Set<NodeChangeset>;
|
|
2288
|
-
readonly
|
|
2777
|
+
readonly movedNodeToParent: ChangeAtomIdBTree<NodeLocation>;
|
|
2778
|
+
readonly composedRootNodes: RootNodeTable;
|
|
2779
|
+
readonly movedCrossFieldKeys: CrossFieldKeyTable;
|
|
2780
|
+
readonly removedCrossFieldKeys: CrossFieldRangeTable<boolean>;
|
|
2781
|
+
readonly renamesToDelete: ChangeAtomIdRangeMap<boolean>;
|
|
2289
2782
|
readonly pendingCompositions: PendingCompositions;
|
|
2290
2783
|
}
|
|
2291
2784
|
|
|
@@ -2300,11 +2793,6 @@ interface PendingCompositions {
|
|
|
2300
2793
|
* The set of fields in the base changeset which have been affected by a cross field effect.
|
|
2301
2794
|
*/
|
|
2302
2795
|
readonly affectedBaseFields: BTree<FieldIdKey, true>;
|
|
2303
|
-
|
|
2304
|
-
/**
|
|
2305
|
-
* The set of fields in the new changeset which have been affected by a cross field effect.
|
|
2306
|
-
*/
|
|
2307
|
-
readonly affectedNewFields: BTree<FieldIdKey, true>;
|
|
2308
2796
|
}
|
|
2309
2797
|
|
|
2310
2798
|
interface ComposeFieldContext {
|
|
@@ -2317,16 +2805,6 @@ interface ComposeFieldContext {
|
|
|
2317
2805
|
composedChange: FieldChange;
|
|
2318
2806
|
}
|
|
2319
2807
|
|
|
2320
|
-
function newCrossFieldTable<T>(): CrossFieldTable<T> {
|
|
2321
|
-
return {
|
|
2322
|
-
srcTable: newChangeAtomIdRangeMap(),
|
|
2323
|
-
dstTable: newChangeAtomIdRangeMap(),
|
|
2324
|
-
srcDependents: newChangeAtomIdRangeMap(),
|
|
2325
|
-
dstDependents: newChangeAtomIdRangeMap(),
|
|
2326
|
-
invalidatedFields: new Set(),
|
|
2327
|
-
};
|
|
2328
|
-
}
|
|
2329
|
-
|
|
2330
2808
|
interface ConstraintState {
|
|
2331
2809
|
violationCount: number;
|
|
2332
2810
|
}
|
|
@@ -2337,283 +2815,697 @@ function newConstraintState(violationCount: number): ConstraintState {
|
|
|
2337
2815
|
};
|
|
2338
2816
|
}
|
|
2339
2817
|
|
|
2340
|
-
|
|
2818
|
+
class InvertNodeManagerI implements InvertNodeManager {
|
|
2341
2819
|
public constructor(
|
|
2342
|
-
|
|
2343
|
-
private readonly
|
|
2344
|
-
protected readonly allowInval = true,
|
|
2820
|
+
private readonly table: InvertTable,
|
|
2821
|
+
private readonly fieldId: FieldId,
|
|
2345
2822
|
) {}
|
|
2346
2823
|
|
|
2347
|
-
public
|
|
2348
|
-
|
|
2349
|
-
revision: RevisionTag | undefined,
|
|
2350
|
-
id: ChangesetLocalId,
|
|
2824
|
+
public invertDetach(
|
|
2825
|
+
detachId: ChangeAtomId,
|
|
2351
2826
|
count: number,
|
|
2352
|
-
|
|
2353
|
-
|
|
2827
|
+
nodeChange: NodeId | undefined,
|
|
2828
|
+
newAttachId: ChangeAtomId,
|
|
2354
2829
|
): void {
|
|
2355
|
-
if (
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
lastChangedId - firstId + 1,
|
|
2364
|
-
);
|
|
2365
|
-
if (dependentEntry.value !== undefined) {
|
|
2366
|
-
this.crossFieldTable.invalidatedFields.add(dependentEntry.value);
|
|
2367
|
-
}
|
|
2830
|
+
if (nodeChange !== undefined) {
|
|
2831
|
+
assert(count === 1, "A node change should only affect one node");
|
|
2832
|
+
|
|
2833
|
+
const attachEntry = firstAttachIdFromDetachId(
|
|
2834
|
+
this.table.change.rootNodes,
|
|
2835
|
+
detachId,
|
|
2836
|
+
count,
|
|
2837
|
+
);
|
|
2368
2838
|
|
|
2369
|
-
|
|
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,
|
|
2857
|
+
);
|
|
2370
2858
|
}
|
|
2371
2859
|
}
|
|
2372
|
-
setInCrossFieldMap(this.getMap(target), revision, id, count, newValue);
|
|
2373
|
-
}
|
|
2374
2860
|
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
count: number,
|
|
2380
|
-
addDependency: boolean,
|
|
2381
|
-
): RangeQueryResult<ChangeAtomId, unknown> {
|
|
2382
|
-
if (addDependency) {
|
|
2383
|
-
// We assume that if there is already an entry for this ID it is because
|
|
2384
|
-
// a field handler has called compose on the same node multiple times.
|
|
2385
|
-
// In this case we only want to update the latest version, so we overwrite the dependency.
|
|
2386
|
-
setInCrossFieldMap(
|
|
2387
|
-
this.getDependents(target),
|
|
2388
|
-
revision,
|
|
2389
|
-
id,
|
|
2861
|
+
if (!areEqualChangeAtomIds(detachId, newAttachId)) {
|
|
2862
|
+
for (const entry of doesChangeAttachNodes(
|
|
2863
|
+
this.table.change.crossFieldKeys,
|
|
2864
|
+
detachId,
|
|
2390
2865
|
count,
|
|
2391
|
-
|
|
2392
|
-
|
|
2866
|
+
)) {
|
|
2867
|
+
if (!entry.value) {
|
|
2868
|
+
this.table.attachToDetachId.set(newAttachId, count, detachId);
|
|
2869
|
+
this.table.invertedRoots.detachLocations.set(detachId, count, this.fieldId);
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2393
2872
|
}
|
|
2394
|
-
return getFirstFromCrossFieldMap(this.getMap(target), revision, id, count);
|
|
2395
2873
|
}
|
|
2396
2874
|
|
|
2397
|
-
public
|
|
2398
|
-
|
|
2399
|
-
public abstract moveKey(
|
|
2400
|
-
target: CrossFieldTarget,
|
|
2401
|
-
revision: RevisionTag | undefined,
|
|
2402
|
-
id: ChangesetLocalId,
|
|
2875
|
+
public invertAttach(
|
|
2876
|
+
attachId: ChangeAtomId,
|
|
2403
2877
|
count: number,
|
|
2404
|
-
):
|
|
2878
|
+
): RangeQueryResult<DetachedNodeEntry> {
|
|
2879
|
+
let countToProcess = count;
|
|
2405
2880
|
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2881
|
+
const detachIdEntry = firstDetachIdFromAttachId(
|
|
2882
|
+
this.table.change.rootNodes,
|
|
2883
|
+
attachId,
|
|
2884
|
+
countToProcess,
|
|
2885
|
+
);
|
|
2411
2886
|
|
|
2412
|
-
|
|
2413
|
-
return target === CrossFieldTarget.Source
|
|
2414
|
-
? this.crossFieldTable.srcDependents
|
|
2415
|
-
: this.crossFieldTable.dstDependents;
|
|
2416
|
-
}
|
|
2417
|
-
}
|
|
2887
|
+
countToProcess = detachIdEntry.length;
|
|
2418
2888
|
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
) {
|
|
2426
|
-
super(table, field, allowInval);
|
|
2427
|
-
}
|
|
2889
|
+
const detachEntry = getFirstFieldForCrossFieldKey(
|
|
2890
|
+
this.table.change,
|
|
2891
|
+
{ target: CrossFieldTarget.Source, ...detachIdEntry.value },
|
|
2892
|
+
countToProcess,
|
|
2893
|
+
);
|
|
2894
|
+
countToProcess = detachEntry.length;
|
|
2428
2895
|
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2896
|
+
let result: RangeQueryResult<DetachedNodeEntry>;
|
|
2897
|
+
if (detachEntry.value !== undefined) {
|
|
2898
|
+
const moveEntry = this.table.entries.getFirst(attachId, countToProcess);
|
|
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
|
+
);
|
|
2432
2907
|
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
assert(false, 0x9c5 /* Keys should not be moved manually during invert */);
|
|
2440
|
-
}
|
|
2908
|
+
countToProcess = nodeIdEntry.length;
|
|
2909
|
+
result = {
|
|
2910
|
+
value: { nodeChange: nodeIdEntry.value, detachId: detachIdEntry.value },
|
|
2911
|
+
length: countToProcess,
|
|
2912
|
+
};
|
|
2913
|
+
}
|
|
2441
2914
|
|
|
2442
|
-
|
|
2443
|
-
|
|
2915
|
+
if (result.value?.nodeChange !== undefined) {
|
|
2916
|
+
setInChangeAtomIdMap(this.table.invertedNodeToParent, result.value.nodeChange, {
|
|
2917
|
+
field: this.fieldId,
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
return result;
|
|
2444
2921
|
}
|
|
2445
2922
|
}
|
|
2446
2923
|
|
|
2447
|
-
class
|
|
2924
|
+
class RebaseNodeManagerI implements RebaseNodeManager {
|
|
2448
2925
|
public constructor(
|
|
2449
|
-
table: RebaseTable,
|
|
2450
|
-
currentField: FieldChange,
|
|
2926
|
+
private readonly table: RebaseTable,
|
|
2451
2927
|
private readonly fieldId: FieldId,
|
|
2452
|
-
allowInval = true,
|
|
2453
|
-
) {
|
|
2454
|
-
super(table, currentField, allowInval);
|
|
2455
|
-
}
|
|
2928
|
+
private readonly allowInval: boolean = true,
|
|
2929
|
+
) {}
|
|
2456
2930
|
|
|
2457
|
-
public
|
|
2458
|
-
|
|
2459
|
-
revision: RevisionTag | undefined,
|
|
2460
|
-
id: ChangesetLocalId,
|
|
2931
|
+
public getNewChangesForBaseAttach(
|
|
2932
|
+
baseAttachId: ChangeAtomId,
|
|
2461
2933
|
count: number,
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
): void {
|
|
2465
|
-
if (invalidateDependents && this.allowInval) {
|
|
2466
|
-
const newFieldIds = getFieldsForCrossFieldKey(
|
|
2467
|
-
this.table.newChange,
|
|
2468
|
-
{
|
|
2469
|
-
target,
|
|
2470
|
-
revision,
|
|
2471
|
-
localId: id,
|
|
2472
|
-
},
|
|
2473
|
-
count,
|
|
2474
|
-
);
|
|
2934
|
+
): RangeQueryResult<RebaseDetachedNodeEntry | undefined> {
|
|
2935
|
+
let countToProcess = count;
|
|
2475
2936
|
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2937
|
+
const detachEntry = firstDetachIdFromAttachId(
|
|
2938
|
+
this.table.baseChange.rootNodes,
|
|
2939
|
+
baseAttachId,
|
|
2940
|
+
countToProcess,
|
|
2941
|
+
);
|
|
2480
2942
|
|
|
2481
|
-
|
|
2482
|
-
this.table.baseChange,
|
|
2483
|
-
{
|
|
2484
|
-
target,
|
|
2485
|
-
revision,
|
|
2486
|
-
localId: id,
|
|
2487
|
-
},
|
|
2488
|
-
count,
|
|
2489
|
-
);
|
|
2943
|
+
countToProcess = detachEntry.length;
|
|
2490
2944
|
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2945
|
+
const nodeEntry = rangeQueryChangeAtomIdMap(
|
|
2946
|
+
this.table.newChange.rootNodes.nodeChanges,
|
|
2947
|
+
detachEntry.value,
|
|
2948
|
+
countToProcess,
|
|
2949
|
+
);
|
|
2495
2950
|
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
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;
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
public rebaseOverDetach(
|
|
2993
|
+
baseDetachId: ChangeAtomId,
|
|
2994
|
+
count: number,
|
|
2995
|
+
newDetachId: ChangeAtomId | undefined,
|
|
2996
|
+
nodeChange: NodeId | undefined,
|
|
2997
|
+
cellRename?: ChangeAtomId,
|
|
2998
|
+
): void {
|
|
2999
|
+
let countToProcess = count;
|
|
3000
|
+
const attachIdEntry = firstAttachIdFromDetachId(
|
|
3001
|
+
this.table.baseRoots,
|
|
3002
|
+
baseDetachId,
|
|
3003
|
+
countToProcess,
|
|
3004
|
+
);
|
|
3005
|
+
const baseAttachId = attachIdEntry.value;
|
|
3006
|
+
countToProcess = attachIdEntry.length;
|
|
3007
|
+
|
|
3008
|
+
const attachFieldEntry = getFirstFieldForCrossFieldKey(
|
|
3009
|
+
this.table.baseChange,
|
|
3010
|
+
{ ...baseAttachId, target: CrossFieldTarget.Destination },
|
|
3011
|
+
countToProcess,
|
|
3012
|
+
);
|
|
3013
|
+
countToProcess = attachFieldEntry.length;
|
|
3014
|
+
|
|
3015
|
+
const detachedMoveEntry = this.table.baseChange.rootNodes.outputDetachLocations.getFirst(
|
|
3016
|
+
baseDetachId,
|
|
3017
|
+
countToProcess,
|
|
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
|
+
});
|
|
3029
|
+
|
|
3030
|
+
if (nodeChange !== undefined || newDetachId !== undefined) {
|
|
3031
|
+
this.invalidateBaseFields([destinationField]);
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
if (attachFieldEntry.value === undefined) {
|
|
3036
|
+
// These nodes are detached in the output context of the base changeset.
|
|
3037
|
+
if (nodeChange !== undefined) {
|
|
3038
|
+
assignRootChange(
|
|
3039
|
+
this.table.rebasedRootNodes,
|
|
3040
|
+
this.table.rebasedNodeToParent,
|
|
3041
|
+
baseAttachId,
|
|
3042
|
+
nodeChange,
|
|
3043
|
+
this.fieldId,
|
|
3044
|
+
this.table.rebaseVersion,
|
|
3045
|
+
);
|
|
3046
|
+
}
|
|
3047
|
+
|
|
3048
|
+
if (newDetachId !== undefined) {
|
|
3049
|
+
addNodeRename(
|
|
3050
|
+
this.table.rebasedRootNodes,
|
|
3051
|
+
baseAttachId,
|
|
3052
|
+
newDetachId,
|
|
3053
|
+
countToProcess,
|
|
3054
|
+
this.fieldId,
|
|
2500
3055
|
);
|
|
2501
3056
|
}
|
|
2502
3057
|
}
|
|
2503
3058
|
|
|
2504
|
-
|
|
3059
|
+
if (newDetachId !== undefined) {
|
|
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);
|
|
2505
3082
|
}
|
|
2506
3083
|
|
|
2507
|
-
public
|
|
2508
|
-
|
|
3084
|
+
public removeDetach(id: ChangeAtomId, count: number): void {
|
|
3085
|
+
this.table.movedDetaches.set(id, count, true);
|
|
2509
3086
|
}
|
|
2510
3087
|
|
|
2511
|
-
public
|
|
2512
|
-
|
|
2513
|
-
revision: RevisionTag | undefined,
|
|
2514
|
-
id: ChangesetLocalId,
|
|
3088
|
+
public doesBaseAttachNodes(
|
|
3089
|
+
id: ChangeAtomId,
|
|
2515
3090
|
count: number,
|
|
2516
|
-
):
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
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 };
|
|
3101
|
+
}
|
|
3102
|
+
|
|
3103
|
+
public getBaseRename(
|
|
3104
|
+
id: ChangeAtomId,
|
|
3105
|
+
count: number,
|
|
3106
|
+
): RangeQueryResult<ChangeAtomId | undefined> {
|
|
3107
|
+
return this.table.baseChange.rootNodes.oldToNewId.getFirst(id, count);
|
|
3108
|
+
}
|
|
3109
|
+
|
|
3110
|
+
public getNewRenameForBaseRename(
|
|
3111
|
+
baseRenameTo: ChangeAtomId,
|
|
3112
|
+
count: number,
|
|
3113
|
+
): RangeQueryResult<ChangeAtomId | undefined> {
|
|
3114
|
+
let countToProcess = count;
|
|
3115
|
+
const inputEntry = firstDetachIdFromAttachId(
|
|
3116
|
+
this.table.baseChange.rootNodes,
|
|
3117
|
+
baseRenameTo,
|
|
3118
|
+
countToProcess,
|
|
3119
|
+
);
|
|
3120
|
+
|
|
3121
|
+
const attachEntry = getFirstAttachField(
|
|
3122
|
+
this.table.baseChange.crossFieldKeys,
|
|
3123
|
+
baseRenameTo,
|
|
3124
|
+
countToProcess,
|
|
2521
3125
|
);
|
|
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
|
+
}
|
|
2522
3152
|
}
|
|
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);
|
|
2523
3169
|
|
|
2524
|
-
|
|
2525
|
-
|
|
3170
|
+
if (nodeToParent !== undefined) {
|
|
3171
|
+
setInChangeAtomIdMap(nodeToParent, nodeId, { root: detachId });
|
|
2526
3172
|
}
|
|
3173
|
+
|
|
3174
|
+
table.detachLocations.set(detachId, 1, detachLocation);
|
|
2527
3175
|
}
|
|
2528
3176
|
|
|
2529
|
-
|
|
2530
|
-
class ComposeManager extends CrossFieldManagerI<FieldChange> {
|
|
3177
|
+
class ComposeNodeManagerI implements ComposeNodeManager {
|
|
2531
3178
|
public constructor(
|
|
2532
|
-
table: ComposeTable,
|
|
2533
|
-
currentField: FieldChange,
|
|
3179
|
+
private readonly table: ComposeTable,
|
|
2534
3180
|
private readonly fieldId: FieldId,
|
|
2535
|
-
allowInval = true,
|
|
2536
|
-
) {
|
|
2537
|
-
|
|
3181
|
+
private readonly allowInval: boolean = true,
|
|
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;
|
|
2538
3235
|
}
|
|
2539
3236
|
|
|
2540
|
-
public
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
id: ChangesetLocalId,
|
|
3237
|
+
public composeAttachDetach(
|
|
3238
|
+
baseAttachId: ChangeAtomId,
|
|
3239
|
+
newDetachId: ChangeAtomId,
|
|
2544
3240
|
count: number,
|
|
2545
|
-
newValue: unknown,
|
|
2546
|
-
invalidateDependents: boolean,
|
|
2547
3241
|
): void {
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
3242
|
+
let countToProcess = count;
|
|
3243
|
+
|
|
3244
|
+
const newAttachEntry = getFirstAttachField(
|
|
3245
|
+
this.table.newChange.crossFieldKeys,
|
|
3246
|
+
newDetachId,
|
|
3247
|
+
countToProcess,
|
|
3248
|
+
);
|
|
3249
|
+
|
|
3250
|
+
countToProcess = newAttachEntry.length;
|
|
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,
|
|
2557
3266
|
);
|
|
3267
|
+
}
|
|
2558
3268
|
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
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
|
+
|
|
3291
|
+
this.table.entries.set(baseAttachId, baseDetachEntry.length, {
|
|
3292
|
+
...prevEntry,
|
|
3293
|
+
detachId: newDetachId,
|
|
3294
|
+
});
|
|
3295
|
+
|
|
3296
|
+
// The new detach will replace the base detach, so we remove the key for the base detach, unless they have the same ID.
|
|
3297
|
+
if (!areEqualChangeAtomIds(baseAttachId, newDetachId)) {
|
|
3298
|
+
this.table.removedCrossFieldKeys.set(
|
|
3299
|
+
{ ...baseAttachId, target: CrossFieldTarget.Source },
|
|
3300
|
+
countToProcess,
|
|
3301
|
+
true,
|
|
2575
3302
|
);
|
|
3303
|
+
}
|
|
2576
3304
|
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
3305
|
+
this.table.movedCrossFieldKeys.set(
|
|
3306
|
+
{ ...newDetachId, target: CrossFieldTarget.Source },
|
|
3307
|
+
countToProcess,
|
|
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,
|
|
2580
3342
|
);
|
|
2581
3343
|
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
3344
|
+
countToProcess = newOutputDetachLocationEntry.length;
|
|
3345
|
+
|
|
3346
|
+
this.table.composedRootNodes.outputDetachLocations.set(
|
|
3347
|
+
newDetachId,
|
|
3348
|
+
countToProcess,
|
|
3349
|
+
newOutputDetachLocationEntry.value ?? this.fieldId,
|
|
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
|
+
);
|
|
2589
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 });
|
|
2590
3386
|
|
|
2591
|
-
|
|
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
|
+
);
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
2592
3409
|
}
|
|
2593
3410
|
|
|
2594
|
-
|
|
2595
|
-
|
|
3411
|
+
private areSameNodes(
|
|
3412
|
+
baseDetachId: ChangeAtomId,
|
|
3413
|
+
newAttachId: ChangeAtomId,
|
|
3414
|
+
count: number,
|
|
3415
|
+
): RangeQueryResult<boolean> {
|
|
3416
|
+
const renamedDetachEntry = firstAttachIdFromDetachId(
|
|
3417
|
+
this.table.composedRootNodes,
|
|
3418
|
+
baseDetachId,
|
|
3419
|
+
count,
|
|
3420
|
+
);
|
|
3421
|
+
|
|
3422
|
+
const isReattachOfSameNodes = areEqualChangeAtomIds(renamedDetachEntry.value, newAttachId);
|
|
3423
|
+
return { ...renamedDetachEntry, value: isReattachOfSameNodes };
|
|
2596
3424
|
}
|
|
2597
3425
|
|
|
2598
|
-
public
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
id: ChangesetLocalId,
|
|
3426
|
+
public composeDetachAttach(
|
|
3427
|
+
baseDetachId: ChangeAtomId,
|
|
3428
|
+
newAttachId: ChangeAtomId,
|
|
2602
3429
|
count: number,
|
|
3430
|
+
composeToPin: boolean,
|
|
2603
3431
|
): void {
|
|
2604
|
-
|
|
3432
|
+
const areSameEntry = this.areSameNodes(baseDetachId, newAttachId, count);
|
|
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
|
+
}
|
|
2605
3488
|
}
|
|
2606
3489
|
|
|
2607
|
-
private
|
|
2608
|
-
|
|
3490
|
+
private invalidateBaseFields(fields: FieldId[]): void {
|
|
3491
|
+
if (this.allowInval) {
|
|
3492
|
+
for (const fieldId of fields) {
|
|
3493
|
+
this.table.pendingCompositions.affectedBaseFields.set(
|
|
3494
|
+
fieldIdKeyFromFieldId(fieldId),
|
|
3495
|
+
true,
|
|
3496
|
+
);
|
|
3497
|
+
}
|
|
3498
|
+
}
|
|
2609
3499
|
}
|
|
2610
3500
|
}
|
|
2611
3501
|
|
|
2612
3502
|
function makeModularChangeset(
|
|
2613
3503
|
props: {
|
|
3504
|
+
rebaseVersion?: RebaseVersion;
|
|
2614
3505
|
fieldChanges?: FieldChangeMap;
|
|
2615
3506
|
nodeChanges?: ChangeAtomIdBTree<NodeChangeset>;
|
|
2616
|
-
|
|
3507
|
+
rootNodes?: RootNodeTable;
|
|
3508
|
+
nodeToParent?: ChangeAtomIdBTree<NodeLocation>;
|
|
2617
3509
|
nodeAliases?: ChangeAtomIdBTree<NodeId>;
|
|
2618
3510
|
crossFieldKeys?: CrossFieldKeyTable;
|
|
2619
3511
|
maxId: number;
|
|
@@ -2628,11 +3520,13 @@ function makeModularChangeset(
|
|
|
2628
3520
|
},
|
|
2629
3521
|
): ModularChangeset {
|
|
2630
3522
|
const changeset: Mutable<ModularChangeset> = {
|
|
3523
|
+
rebaseVersion: props.rebaseVersion ?? 1,
|
|
2631
3524
|
fieldChanges: props.fieldChanges ?? new Map(),
|
|
2632
3525
|
nodeChanges: props.nodeChanges ?? newTupleBTree(),
|
|
3526
|
+
rootNodes: props.rootNodes ?? newRootTable(),
|
|
2633
3527
|
nodeToParent: props.nodeToParent ?? newTupleBTree(),
|
|
2634
3528
|
nodeAliases: props.nodeAliases ?? newTupleBTree(),
|
|
2635
|
-
crossFieldKeys: props.crossFieldKeys ??
|
|
3529
|
+
crossFieldKeys: props.crossFieldKeys ?? newCrossFieldRangeTable(),
|
|
2636
3530
|
};
|
|
2637
3531
|
|
|
2638
3532
|
if (props.revisions !== undefined && props.revisions.length > 0) {
|
|
@@ -2659,6 +3553,7 @@ function makeModularChangeset(
|
|
|
2659
3553
|
if (props.refreshers !== undefined && props.refreshers.size > 0) {
|
|
2660
3554
|
changeset.refreshers = props.refreshers;
|
|
2661
3555
|
}
|
|
3556
|
+
|
|
2662
3557
|
return changeset;
|
|
2663
3558
|
}
|
|
2664
3559
|
|
|
@@ -2675,6 +3570,10 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2675
3570
|
this.idAllocator = idAllocatorFromMaxId();
|
|
2676
3571
|
}
|
|
2677
3572
|
|
|
3573
|
+
public isInTransaction(): boolean {
|
|
3574
|
+
return this.transactionDepth > 0;
|
|
3575
|
+
}
|
|
3576
|
+
|
|
2678
3577
|
public override enterTransaction(): void {
|
|
2679
3578
|
this.transactionDepth += 1;
|
|
2680
3579
|
if (this.transactionDepth === 1) {
|
|
@@ -2729,7 +3628,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2729
3628
|
* @param revision - the revision of the change
|
|
2730
3629
|
*/
|
|
2731
3630
|
public submitChange(
|
|
2732
|
-
field:
|
|
3631
|
+
field: NormalizedFieldUpPath,
|
|
2733
3632
|
fieldKind: FieldKindIdentifier,
|
|
2734
3633
|
change: FieldChangeset,
|
|
2735
3634
|
revision: RevisionTag,
|
|
@@ -2743,7 +3642,8 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2743
3642
|
fieldChange: { fieldKind, change },
|
|
2744
3643
|
nodeChanges: newTupleBTree(),
|
|
2745
3644
|
nodeToParent: newTupleBTree(),
|
|
2746
|
-
crossFieldKeys:
|
|
3645
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
3646
|
+
rootNodes: newRootTable(),
|
|
2747
3647
|
idAllocator: this.idAllocator,
|
|
2748
3648
|
localCrossFieldKeys,
|
|
2749
3649
|
revision,
|
|
@@ -2765,6 +3665,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2765
3665
|
? makeModularChangeset({
|
|
2766
3666
|
maxId: this.idAllocator.getMaxId(),
|
|
2767
3667
|
builds: change.builds,
|
|
3668
|
+
rootNodes: renameTableFromRenameDescriptions(change.renames ?? []),
|
|
2768
3669
|
revisions: [{ revision: change.revision }],
|
|
2769
3670
|
})
|
|
2770
3671
|
: buildModularChangesetFromField({
|
|
@@ -2775,7 +3676,8 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2775
3676
|
},
|
|
2776
3677
|
nodeChanges: newTupleBTree(),
|
|
2777
3678
|
nodeToParent: newTupleBTree(),
|
|
2778
|
-
crossFieldKeys:
|
|
3679
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
3680
|
+
rootNodes: newRootTable(),
|
|
2779
3681
|
idAllocator: this.idAllocator,
|
|
2780
3682
|
localCrossFieldKeys: getChangeHandler(
|
|
2781
3683
|
this.fieldKinds,
|
|
@@ -2802,7 +3704,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2802
3704
|
return brand(this.idAllocator.allocate(count));
|
|
2803
3705
|
}
|
|
2804
3706
|
|
|
2805
|
-
public addNodeExistsConstraint(path:
|
|
3707
|
+
public addNodeExistsConstraint(path: NormalizedUpPath, revision: RevisionTag): void {
|
|
2806
3708
|
const nodeChange: NodeChangeset = {
|
|
2807
3709
|
nodeExistsConstraint: { violated: false },
|
|
2808
3710
|
};
|
|
@@ -2814,7 +3716,8 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2814
3716
|
nodeChange,
|
|
2815
3717
|
nodeChanges: newTupleBTree(),
|
|
2816
3718
|
nodeToParent: newTupleBTree(),
|
|
2817
|
-
crossFieldKeys:
|
|
3719
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
3720
|
+
rootNodes: newRootTable(),
|
|
2818
3721
|
idAllocator: this.idAllocator,
|
|
2819
3722
|
revision,
|
|
2820
3723
|
}),
|
|
@@ -2823,7 +3726,7 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2823
3726
|
);
|
|
2824
3727
|
}
|
|
2825
3728
|
|
|
2826
|
-
public addNodeExistsConstraintOnRevert(path:
|
|
3729
|
+
public addNodeExistsConstraintOnRevert(path: NormalizedUpPath, revision: RevisionTag): void {
|
|
2827
3730
|
const nodeChange: NodeChangeset = {
|
|
2828
3731
|
nodeExistsConstraintOnRevert: { violated: false },
|
|
2829
3732
|
};
|
|
@@ -2835,7 +3738,8 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2835
3738
|
nodeChange,
|
|
2836
3739
|
nodeChanges: newTupleBTree(),
|
|
2837
3740
|
nodeToParent: newTupleBTree(),
|
|
2838
|
-
crossFieldKeys:
|
|
3741
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
3742
|
+
rootNodes: newRootTable(),
|
|
2839
3743
|
idAllocator: this.idAllocator,
|
|
2840
3744
|
revision,
|
|
2841
3745
|
}),
|
|
@@ -2845,12 +3749,13 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2845
3749
|
}
|
|
2846
3750
|
}
|
|
2847
3751
|
|
|
2848
|
-
function buildModularChangesetFromField(props: {
|
|
2849
|
-
path:
|
|
3752
|
+
export function buildModularChangesetFromField(props: {
|
|
3753
|
+
path: NormalizedFieldUpPath;
|
|
2850
3754
|
fieldChange: FieldChange;
|
|
2851
3755
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
|
|
2852
|
-
nodeToParent: ChangeAtomIdBTree<
|
|
3756
|
+
nodeToParent: ChangeAtomIdBTree<NodeLocation>;
|
|
2853
3757
|
crossFieldKeys: CrossFieldKeyTable;
|
|
3758
|
+
rootNodes: RootNodeTable;
|
|
2854
3759
|
localCrossFieldKeys?: CrossFieldKeyRange[];
|
|
2855
3760
|
revision: RevisionTag;
|
|
2856
3761
|
idAllocator?: IdAllocator;
|
|
@@ -2862,6 +3767,7 @@ function buildModularChangesetFromField(props: {
|
|
|
2862
3767
|
nodeChanges,
|
|
2863
3768
|
nodeToParent,
|
|
2864
3769
|
crossFieldKeys,
|
|
3770
|
+
rootNodes,
|
|
2865
3771
|
idAllocator = idAllocatorFromMaxId(),
|
|
2866
3772
|
localCrossFieldKeys = [],
|
|
2867
3773
|
childId,
|
|
@@ -2870,14 +3776,17 @@ function buildModularChangesetFromField(props: {
|
|
|
2870
3776
|
const fieldChanges: FieldChangeMap = new Map([[path.field, fieldChange]]);
|
|
2871
3777
|
|
|
2872
3778
|
if (path.parent === undefined) {
|
|
3779
|
+
const field = { nodeId: undefined, field: path.field };
|
|
2873
3780
|
for (const { key, count } of localCrossFieldKeys) {
|
|
2874
|
-
crossFieldKeys.set(key, count,
|
|
3781
|
+
crossFieldKeys.set(key, count, field);
|
|
2875
3782
|
}
|
|
2876
3783
|
|
|
2877
3784
|
if (childId !== undefined) {
|
|
2878
3785
|
setInChangeAtomIdMap(nodeToParent, childId, {
|
|
2879
|
-
|
|
2880
|
-
|
|
3786
|
+
field: {
|
|
3787
|
+
nodeId: undefined,
|
|
3788
|
+
field: path.field,
|
|
3789
|
+
},
|
|
2881
3790
|
});
|
|
2882
3791
|
}
|
|
2883
3792
|
|
|
@@ -2886,6 +3795,7 @@ function buildModularChangesetFromField(props: {
|
|
|
2886
3795
|
nodeChanges,
|
|
2887
3796
|
nodeToParent,
|
|
2888
3797
|
crossFieldKeys,
|
|
3798
|
+
rootNodes,
|
|
2889
3799
|
maxId: idAllocator.getMaxId(),
|
|
2890
3800
|
revisions: [{ revision }],
|
|
2891
3801
|
});
|
|
@@ -2896,6 +3806,7 @@ function buildModularChangesetFromField(props: {
|
|
|
2896
3806
|
};
|
|
2897
3807
|
|
|
2898
3808
|
const parentId: NodeId = { localId: brand(idAllocator.allocate()), revision };
|
|
3809
|
+
const fieldId = { nodeId: parentId, field: path.field };
|
|
2899
3810
|
|
|
2900
3811
|
for (const { key, count } of localCrossFieldKeys) {
|
|
2901
3812
|
crossFieldKeys.set(key, count, { nodeId: parentId, field: path.field });
|
|
@@ -2903,8 +3814,7 @@ function buildModularChangesetFromField(props: {
|
|
|
2903
3814
|
|
|
2904
3815
|
if (childId !== undefined) {
|
|
2905
3816
|
setInChangeAtomIdMap(nodeToParent, childId, {
|
|
2906
|
-
|
|
2907
|
-
field: path.field,
|
|
3817
|
+
field: fieldId,
|
|
2908
3818
|
});
|
|
2909
3819
|
}
|
|
2910
3820
|
|
|
@@ -2914,6 +3824,7 @@ function buildModularChangesetFromField(props: {
|
|
|
2914
3824
|
nodeChanges,
|
|
2915
3825
|
nodeToParent,
|
|
2916
3826
|
crossFieldKeys,
|
|
3827
|
+
rootNodes,
|
|
2917
3828
|
idAllocator,
|
|
2918
3829
|
revision,
|
|
2919
3830
|
nodeId: parentId,
|
|
@@ -2921,11 +3832,12 @@ function buildModularChangesetFromField(props: {
|
|
|
2921
3832
|
}
|
|
2922
3833
|
|
|
2923
3834
|
function buildModularChangesetFromNode(props: {
|
|
2924
|
-
path:
|
|
3835
|
+
path: NormalizedUpPath;
|
|
2925
3836
|
nodeChange: NodeChangeset;
|
|
2926
3837
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
|
|
2927
|
-
nodeToParent: ChangeAtomIdBTree<
|
|
3838
|
+
nodeToParent: ChangeAtomIdBTree<NodeLocation>;
|
|
2928
3839
|
crossFieldKeys: CrossFieldKeyTable;
|
|
3840
|
+
rootNodes: RootNodeTable;
|
|
2929
3841
|
idAllocator: IdAllocator;
|
|
2930
3842
|
revision: RevisionTag;
|
|
2931
3843
|
nodeId?: NodeId;
|
|
@@ -2935,27 +3847,43 @@ function buildModularChangesetFromNode(props: {
|
|
|
2935
3847
|
nodeId = { localId: brand(props.idAllocator.allocate()), revision: props.revision },
|
|
2936
3848
|
} = props;
|
|
2937
3849
|
setInChangeAtomIdMap(props.nodeChanges, nodeId, props.nodeChange);
|
|
2938
|
-
const fieldChangeset = genericFieldKind.changeHandler.editor.buildChildChanges([
|
|
2939
|
-
[path.parentIndex, nodeId],
|
|
2940
|
-
]);
|
|
2941
3850
|
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
3851
|
+
if (isDetachedUpPathRoot(path)) {
|
|
3852
|
+
props.rootNodes.nodeChanges.set(
|
|
3853
|
+
[path.detachedNodeId.major, brand(path.detachedNodeId.minor)],
|
|
3854
|
+
nodeId,
|
|
3855
|
+
);
|
|
3856
|
+
return makeModularChangeset({
|
|
3857
|
+
rootNodes: props.rootNodes,
|
|
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
|
+
]);
|
|
2946
3868
|
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
3869
|
+
const fieldChange: FieldChange = {
|
|
3870
|
+
fieldKind: genericFieldKind.identifier,
|
|
3871
|
+
change: fieldChangeset,
|
|
3872
|
+
};
|
|
3873
|
+
|
|
3874
|
+
return buildModularChangesetFromField({
|
|
3875
|
+
...props,
|
|
3876
|
+
path: { parent: path.parent, field: path.parentField },
|
|
3877
|
+
fieldChange,
|
|
3878
|
+
localCrossFieldKeys: [],
|
|
3879
|
+
childId: nodeId,
|
|
3880
|
+
});
|
|
3881
|
+
}
|
|
2954
3882
|
}
|
|
2955
3883
|
|
|
2956
3884
|
export interface FieldEditDescription {
|
|
2957
3885
|
type: "field";
|
|
2958
|
-
field:
|
|
3886
|
+
field: NormalizedFieldUpPath;
|
|
2959
3887
|
fieldKind: FieldKindIdentifier;
|
|
2960
3888
|
change: FieldChangeset;
|
|
2961
3889
|
revision: RevisionTag;
|
|
@@ -2965,6 +3893,23 @@ export interface GlobalEditDescription {
|
|
|
2965
3893
|
type: "global";
|
|
2966
3894
|
revision: RevisionTag;
|
|
2967
3895
|
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;
|
|
2968
3913
|
}
|
|
2969
3914
|
|
|
2970
3915
|
export type EditDescription = FieldEditDescription | GlobalEditDescription;
|
|
@@ -2981,22 +3926,6 @@ function getRevInfoFromTaggedChanges(changes: TaggedChange<ModularChangeset>[]):
|
|
|
2981
3926
|
revInfos.push(...revisionInfoFromTaggedChange(taggedChange));
|
|
2982
3927
|
}
|
|
2983
3928
|
|
|
2984
|
-
const revisions = new Set<RevisionTag>();
|
|
2985
|
-
const rolledBackRevisions: RevisionTag[] = [];
|
|
2986
|
-
for (const info of revInfos) {
|
|
2987
|
-
revisions.add(info.revision);
|
|
2988
|
-
if (info.rollbackOf !== undefined) {
|
|
2989
|
-
rolledBackRevisions.push(info.rollbackOf);
|
|
2990
|
-
}
|
|
2991
|
-
}
|
|
2992
|
-
|
|
2993
|
-
rolledBackRevisions.reverse();
|
|
2994
|
-
for (const revision of rolledBackRevisions) {
|
|
2995
|
-
if (!revisions.has(revision)) {
|
|
2996
|
-
revInfos.push({ revision });
|
|
2997
|
-
}
|
|
2998
|
-
}
|
|
2999
|
-
|
|
3000
3929
|
return { maxId: brand(maxId), revInfos };
|
|
3001
3930
|
}
|
|
3002
3931
|
|
|
@@ -3016,25 +3945,28 @@ function revisionInfoFromTaggedChange(
|
|
|
3016
3945
|
return revInfos;
|
|
3017
3946
|
}
|
|
3018
3947
|
|
|
3019
|
-
function fieldChangeFromId(
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3948
|
+
function fieldChangeFromId(change: ModularChangeset, id: FieldId): FieldChange {
|
|
3949
|
+
const fieldId = normalizeFieldId(id, change.nodeAliases);
|
|
3950
|
+
const fieldMap = fieldMapFromNodeId(
|
|
3951
|
+
change.fieldChanges,
|
|
3952
|
+
change.nodeChanges,
|
|
3953
|
+
change.nodeAliases,
|
|
3954
|
+
fieldId.nodeId,
|
|
3955
|
+
);
|
|
3025
3956
|
return fieldMap.get(id.field) ?? fail(0xb25 /* No field exists for the given ID */);
|
|
3026
3957
|
}
|
|
3027
3958
|
|
|
3028
3959
|
function fieldMapFromNodeId(
|
|
3029
3960
|
rootFieldMap: FieldChangeMap,
|
|
3030
3961
|
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
3962
|
+
aliases: ChangeAtomIdBTree<NodeId>,
|
|
3031
3963
|
nodeId: NodeId | undefined,
|
|
3032
3964
|
): FieldChangeMap {
|
|
3033
3965
|
if (nodeId === undefined) {
|
|
3034
3966
|
return rootFieldMap;
|
|
3035
3967
|
}
|
|
3036
3968
|
|
|
3037
|
-
const node = nodeChangeFromId(nodes, nodeId);
|
|
3969
|
+
const node = nodeChangeFromId(nodes, aliases, nodeId);
|
|
3038
3970
|
assert(node.fieldChanges !== undefined, 0x9c9 /* Expected node to have field changes */);
|
|
3039
3971
|
return node.fieldChanges;
|
|
3040
3972
|
}
|
|
@@ -3051,8 +3983,13 @@ function rebasedNodeIdFromBaseNodeId(table: RebaseTable, baseId: NodeId): NodeId
|
|
|
3051
3983
|
return getFromChangeAtomIdMap(table.baseToRebasedNodeId, baseId) ?? baseId;
|
|
3052
3984
|
}
|
|
3053
3985
|
|
|
3054
|
-
function nodeChangeFromId(
|
|
3055
|
-
|
|
3986
|
+
function nodeChangeFromId(
|
|
3987
|
+
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
3988
|
+
aliases: ChangeAtomIdBTree<NodeId>,
|
|
3989
|
+
id: NodeId,
|
|
3990
|
+
): NodeChangeset {
|
|
3991
|
+
const normalizedId = normalizeNodeId(id, aliases);
|
|
3992
|
+
const node = getFromChangeAtomIdMap(nodes, normalizedId);
|
|
3056
3993
|
assert(node !== undefined, 0x9ca /* Unknown node ID */);
|
|
3057
3994
|
return node;
|
|
3058
3995
|
}
|
|
@@ -3062,6 +3999,10 @@ function fieldIdFromFieldIdKey([revision, localId, field]: FieldIdKey): FieldId
|
|
|
3062
3999
|
return { nodeId, field };
|
|
3063
4000
|
}
|
|
3064
4001
|
|
|
4002
|
+
function fieldIdKeyFromFieldId(fieldId: FieldId): FieldIdKey {
|
|
4003
|
+
return [fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field];
|
|
4004
|
+
}
|
|
4005
|
+
|
|
3065
4006
|
function cloneNodeChangeset(nodeChangeset: NodeChangeset): NodeChangeset {
|
|
3066
4007
|
if (nodeChangeset.fieldChanges !== undefined) {
|
|
3067
4008
|
return { ...nodeChangeset, fieldChanges: new Map(nodeChangeset.fieldChanges) };
|
|
@@ -3070,6 +4011,16 @@ function cloneNodeChangeset(nodeChangeset: NodeChangeset): NodeChangeset {
|
|
|
3070
4011
|
return { ...nodeChangeset };
|
|
3071
4012
|
}
|
|
3072
4013
|
|
|
4014
|
+
function replaceNodeLocationRevision(
|
|
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
|
+
|
|
3073
4024
|
function replaceFieldIdRevision(
|
|
3074
4025
|
fieldId: FieldId,
|
|
3075
4026
|
oldRevisions: Set<RevisionTag | undefined>,
|
|
@@ -3085,10 +4036,16 @@ function replaceFieldIdRevision(
|
|
|
3085
4036
|
};
|
|
3086
4037
|
}
|
|
3087
4038
|
|
|
3088
|
-
export function
|
|
3089
|
-
const
|
|
3090
|
-
|
|
3091
|
-
|
|
4039
|
+
export function getNodeParent(changeset: ModularChangeset, nodeId: NodeId): NodeLocation {
|
|
4040
|
+
const normalizedNodeId = normalizeNodeId(nodeId, changeset.nodeAliases);
|
|
4041
|
+
const location = getFromChangeAtomIdMap(changeset.nodeToParent, normalizedNodeId);
|
|
4042
|
+
assert(location !== undefined, 0x9cb /* Parent field should be defined */);
|
|
4043
|
+
|
|
4044
|
+
if (location.field !== undefined) {
|
|
4045
|
+
return { field: normalizeFieldId(location.field, changeset.nodeAliases) };
|
|
4046
|
+
}
|
|
4047
|
+
|
|
4048
|
+
return location;
|
|
3092
4049
|
}
|
|
3093
4050
|
|
|
3094
4051
|
function getFieldsForCrossFieldKey(
|
|
@@ -3101,6 +4058,30 @@ function getFieldsForCrossFieldKey(
|
|
|
3101
4058
|
.map(({ value: fieldId }) => normalizeFieldId(fieldId, changeset.nodeAliases));
|
|
3102
4059
|
}
|
|
3103
4060
|
|
|
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
|
+
|
|
3104
4085
|
// This is only exported for use in test utilities.
|
|
3105
4086
|
export function normalizeFieldId(
|
|
3106
4087
|
fieldId: FieldId,
|
|
@@ -3114,8 +4095,12 @@ export function normalizeFieldId(
|
|
|
3114
4095
|
/**
|
|
3115
4096
|
* @returns The canonical form of nodeId, according to nodeAliases
|
|
3116
4097
|
*/
|
|
3117
|
-
function normalizeNodeId(
|
|
4098
|
+
export function normalizeNodeId(
|
|
4099
|
+
nodeId: NodeId,
|
|
4100
|
+
nodeAliases: ChangeAtomIdBTree<NodeId>,
|
|
4101
|
+
): NodeId {
|
|
3118
4102
|
let currentId = nodeId;
|
|
4103
|
+
let cycleProbeId: NodeId | undefined = nodeId;
|
|
3119
4104
|
|
|
3120
4105
|
// eslint-disable-next-line no-constant-condition
|
|
3121
4106
|
while (true) {
|
|
@@ -3125,6 +4110,16 @@ function normalizeNodeId(nodeId: NodeId, nodeAliases: ChangeAtomIdBTree<NodeId>)
|
|
|
3125
4110
|
}
|
|
3126
4111
|
|
|
3127
4112
|
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");
|
|
3128
4123
|
}
|
|
3129
4124
|
}
|
|
3130
4125
|
|
|
@@ -3135,22 +4130,835 @@ function hasConflicts(change: ModularChangeset): boolean {
|
|
|
3135
4130
|
interface ModularChangesetContent {
|
|
3136
4131
|
fieldChanges: FieldChangeMap;
|
|
3137
4132
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>;
|
|
3138
|
-
nodeToParent: ChangeAtomIdBTree<
|
|
4133
|
+
nodeToParent: ChangeAtomIdBTree<NodeLocation>;
|
|
4134
|
+
rootNodes: RootNodeTable;
|
|
3139
4135
|
nodeAliases: ChangeAtomIdBTree<NodeId>;
|
|
3140
4136
|
crossFieldKeys: CrossFieldKeyTable;
|
|
3141
4137
|
}
|
|
3142
4138
|
|
|
3143
|
-
function
|
|
3144
|
-
|
|
3145
|
-
id: ChangeAtomId,
|
|
3146
|
-
): T | undefined {
|
|
3147
|
-
return map.get([id.revision, id.localId]);
|
|
4139
|
+
function areEqualFieldIds(a: FieldId, b: FieldId): boolean {
|
|
4140
|
+
return areEqualChangeAtomIdOpts(a.nodeId, b.nodeId) && a.field === b.field;
|
|
3148
4141
|
}
|
|
3149
4142
|
|
|
3150
|
-
function
|
|
3151
|
-
|
|
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 };
|
|
3152
4150
|
}
|
|
3153
4151
|
|
|
3154
|
-
function
|
|
3155
|
-
|
|
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
|
+
};
|
|
3156
4964
|
}
|