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