@fluidframework/tree 2.73.0 → 2.74.0-368706
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +2 -2
- package/api-report/tree.alpha.api.md +133 -85
- package/api-report/tree.beta.api.md +0 -1
- package/api-report/tree.legacy.beta.api.md +0 -1
- package/api-report/tree.legacy.public.api.md +0 -1
- package/api-report/tree.public.api.md +0 -1
- package/dist/alpha.d.ts +7 -2
- package/dist/codec/codec.d.ts +14 -1
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +11 -0
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/versioned/codec.d.ts +1 -1
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/codec/versioned/format.d.ts +4 -1
- package/dist/codec/versioned/format.d.ts.map +1 -1
- package/dist/codec/versioned/format.js +4 -1
- package/dist/codec/versioned/format.js.map +1 -1
- package/dist/core/change-family/changeFamily.d.ts +4 -1
- package/dist/core/change-family/changeFamily.d.ts.map +1 -1
- package/dist/core/change-family/changeFamily.js.map +1 -1
- package/dist/core/change-family/index.d.ts +1 -1
- package/dist/core/change-family/index.d.ts.map +1 -1
- package/dist/core/change-family/index.js.map +1 -1
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +7 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/rebase/changeRebaser.d.ts +6 -1
- package/dist/core/rebase/changeRebaser.d.ts.map +1 -1
- package/dist/core/rebase/changeRebaser.js.map +1 -1
- package/dist/core/rebase/index.d.ts +1 -1
- package/dist/core/rebase/index.d.ts.map +1 -1
- package/dist/core/rebase/index.js +2 -1
- package/dist/core/rebase/index.js.map +1 -1
- package/dist/core/rebase/types.d.ts +2 -1
- package/dist/core/rebase/types.d.ts.map +1 -1
- package/dist/core/rebase/types.js +5 -1
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/rebase/utils.d.ts.map +1 -1
- package/dist/core/rebase/utils.js +25 -7
- package/dist/core/rebase/utils.js.map +1 -1
- package/dist/core/tree/detachedFieldIndex.d.ts +40 -13
- package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndex.js +21 -12
- package/dist/core/tree/detachedFieldIndex.js.map +1 -1
- package/dist/core/tree/index.d.ts +4 -3
- package/dist/core/tree/index.d.ts.map +1 -1
- package/dist/core/tree/index.js +6 -2
- package/dist/core/tree/index.js.map +1 -1
- package/dist/core/tree/pathTree.d.ts +11 -3
- package/dist/core/tree/pathTree.d.ts.map +1 -1
- package/dist/core/tree/pathTree.js +14 -2
- package/dist/core/tree/pathTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +7 -0
- package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +4 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -2
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts +15 -7
- package/dist/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +7 -2
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +90 -42
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js +234 -69
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +4 -4
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +33 -28
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/default-schema/index.d.ts +2 -1
- package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/index.js +4 -2
- package/dist/feature-libraries/default-schema/index.js.map +1 -1
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +36 -0
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +1 -0
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js +126 -0
- package/dist/feature-libraries/default-schema/locationBasedEditBuilder.js.map +1 -0
- package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts +7 -6
- package/dist/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/mappedEditBuilder.js +15 -0
- package/dist/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
- package/dist/feature-libraries/deltaUtils.d.ts +1 -0
- package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
- package/dist/feature-libraries/deltaUtils.js +6 -1
- package/dist/feature-libraries/deltaUtils.js.map +1 -1
- package/dist/feature-libraries/detachedFieldIndexSummarizer.d.ts +30 -8
- package/dist/feature-libraries/detachedFieldIndexSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/detachedFieldIndexSummarizer.js +41 -11
- package/dist/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/dist/feature-libraries/flex-tree/context.d.ts +9 -0
- package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js +6 -0
- package/dist/feature-libraries/flex-tree/context.js.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.d.ts +8 -7
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +37 -8
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.d.ts +2 -2
- package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.js +4 -4
- package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +9 -13
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +22 -27
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/forest-summary/format.d.ts +41 -5
- package/dist/feature-libraries/forest-summary/format.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/format.js +7 -7
- package/dist/feature-libraries/forest-summary/format.js.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +11 -9
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +16 -29
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/dist/feature-libraries/forest-summary/index.d.ts +2 -1
- package/dist/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/index.js +3 -2
- package/dist/feature-libraries/forest-summary/index.js.map +1 -1
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts +47 -0
- package/dist/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/summaryTypes.js +57 -0
- package/dist/feature-libraries/forest-summary/summaryTypes.js.map +1 -0
- package/dist/feature-libraries/index.d.ts +5 -5
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +7 -4
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.js +1 -0
- package/dist/feature-libraries/mapTreeCursor.js.map +1 -1
- package/dist/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/mitigatedChangeFamily.js +2 -2
- package/dist/feature-libraries/mitigatedChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.d.ts +18 -2
- package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.js +54 -3
- package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +97 -21
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js +4 -7
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +20 -52
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldKind.d.ts +25 -13
- package/dist/feature-libraries/modular-schema/fieldKind.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldKind.js +0 -21
- package/dist/feature-libraries/modular-schema/fieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +7 -10
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindCodecs.js +2 -2
- package/dist/feature-libraries/modular-schema/genericFieldKindCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +5 -5
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +12 -8
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +17 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +388 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +17 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js +413 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +4 -4
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +8 -284
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +48 -15
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1298 -465
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/{modularChangeFormat.d.ts → modularChangeFormatV1.d.ts} +2 -2
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/{modularChangeFormat.js → modularChangeFormatV1.js} +5 -5
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +146 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +32 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +50 -10
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js +24 -3
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/dist/feature-libraries/optional-field/index.d.ts +2 -2
- package/dist/feature-libraries/optional-field/index.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/index.js +1 -2
- package/dist/feature-libraries/optional-field/index.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.d.ts +5 -26
- package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +217 -451
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +24 -33
- package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js +57 -28
- package/dist/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts +27 -8
- package/dist/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js +42 -16
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.d.ts +6 -7
- package/dist/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +80 -256
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV2.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV2.js +1 -0
- package/dist/feature-libraries/sequence-field/formatV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/helperTypes.d.ts +14 -10
- package/dist/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/helperTypes.js.map +1 -1
- package/dist/feature-libraries/sequence-field/index.d.ts +2 -3
- package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/index.js +1 -3
- package/dist/feature-libraries/sequence-field/index.js.map +1 -1
- package/dist/feature-libraries/sequence-field/invert.d.ts +3 -3
- package/dist/feature-libraries/sequence-field/invert.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/invert.js +65 -167
- package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
- package/dist/feature-libraries/sequence-field/markQueue.d.ts +2 -2
- package/dist/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +4 -56
- package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/moveEffectTable.js +7 -86
- package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.d.ts +3 -3
- package/dist/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.js +106 -112
- package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/dist/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/replaceRevisions.js +16 -33
- package/dist/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +0 -2
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +22 -4
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +358 -179
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js +20 -60
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
- package/dist/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +3 -2
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +14 -109
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/dist/feature-libraries/sequence-field/types.d.ts +30 -59
- package/dist/feature-libraries/sequence-field/types.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/types.js.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.d.ts +15 -24
- package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +111 -299
- package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
- package/dist/feature-libraries/treeCompressionUtils.d.ts +2 -12
- package/dist/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
- package/dist/feature-libraries/treeCompressionUtils.js +4 -14
- package/dist/feature-libraries/treeCompressionUtils.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- 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 +1 -1
- package/dist/shared-tree/independentView.d.ts.map +1 -1
- package/dist/shared-tree/independentView.js.map +1 -1
- package/dist/shared-tree/index.d.ts +1 -1
- package/dist/shared-tree/index.d.ts.map +1 -1
- package/dist/shared-tree/index.js.map +1 -1
- package/dist/shared-tree/schematizeTree.d.ts +4 -4
- package/dist/shared-tree/schematizeTree.d.ts.map +1 -1
- package/dist/shared-tree/schematizeTree.js +2 -1
- package/dist/shared-tree/schematizeTree.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +1 -5
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +32 -33
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +18 -15
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +15 -4
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js +1 -0
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.d.ts +20 -8
- package/dist/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.js +25 -11
- package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.d.ts +6 -6
- 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 +16 -6
- package/dist/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeEditBuilder.js +13 -6
- package/dist/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +1 -1
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +14 -12
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +66 -17
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branch.d.ts +3 -2
- package/dist/shared-tree-core/branch.d.ts.map +1 -1
- package/dist/shared-tree-core/branch.js +4 -3
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/editManager.d.ts +2 -2
- package/dist/shared-tree-core/editManager.d.ts.map +1 -1
- package/dist/shared-tree-core/editManager.js +9 -9
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.d.ts +4 -0
- package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.js +16 -6
- package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/{lib/shared-tree-core/editManagerCodecsV5.d.ts → dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts} +3 -3
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{editManagerCodecsV5.js → editManagerCodecsVSharedBranches.js} +7 -7
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts +20 -6
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.js +22 -7
- package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
- package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.js +1 -0
- package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/dist/shared-tree-core/{editManagerFormatV5.d.ts → editManagerFormatVSharedBranches.d.ts} +3 -3
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{editManagerFormatV5.js → editManagerFormatVSharedBranches.js} +2 -2
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/editManagerSummarizer.d.ts +29 -9
- package/dist/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js +41 -13
- package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/dist/shared-tree-core/index.d.ts +5 -3
- package/dist/shared-tree-core/index.d.ts.map +1 -1
- package/dist/shared-tree-core/index.js +8 -1
- package/dist/shared-tree-core/index.js.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.d.ts +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- package/{lib/shared-tree-core/messageCodecV5.d.ts → dist/shared-tree-core/messageCodecVSharedBranches.d.ts} +2 -2
- package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{messageCodecV5.js → messageCodecVSharedBranches.js} +6 -6
- package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/messageCodecs.d.ts +4 -0
- package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecs.js +16 -6
- package/dist/shared-tree-core/messageCodecs.js.map +1 -1
- package/dist/shared-tree-core/messageFormat.d.ts +20 -6
- package/dist/shared-tree-core/messageFormat.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormat.js +22 -7
- package/dist/shared-tree-core/messageFormat.js.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts +3 -2
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js +8 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/{messageFormatV5.d.ts → messageFormatVSharedBranches.d.ts} +5 -7
- package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -0
- package/dist/shared-tree-core/{messageFormatV5.js → messageFormatVSharedBranches.js} +3 -2
- package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -0
- package/dist/shared-tree-core/sharedTreeCore.d.ts +14 -47
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +30 -18
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/shared-tree-core/summaryTypes.d.ts +94 -0
- package/dist/shared-tree-core/summaryTypes.d.ts.map +1 -0
- package/dist/shared-tree-core/summaryTypes.js +47 -0
- package/dist/shared-tree-core/summaryTypes.js.map +1 -0
- package/dist/shared-tree-core/versionedSummarizer.d.ts +67 -0
- package/dist/shared-tree-core/versionedSummarizer.d.ts.map +1 -0
- package/dist/shared-tree-core/versionedSummarizer.js +63 -0
- package/dist/shared-tree-core/versionedSummarizer.js.map +1 -0
- package/dist/simple-tree/api/configuration.d.ts +3 -26
- package/dist/simple-tree/api/configuration.d.ts.map +1 -1
- package/dist/simple-tree/api/configuration.js +10 -21
- package/dist/simple-tree/api/configuration.js.map +1 -1
- package/dist/simple-tree/api/dirtyIndex.d.ts +11 -0
- package/dist/simple-tree/api/dirtyIndex.d.ts.map +1 -1
- package/dist/simple-tree/api/dirtyIndex.js +7 -0
- package/dist/simple-tree/api/dirtyIndex.js.map +1 -1
- package/dist/simple-tree/api/discrepancies.d.ts +1 -1
- package/dist/simple-tree/api/discrepancies.d.ts.map +1 -1
- package/dist/simple-tree/api/discrepancies.js.map +1 -1
- package/dist/simple-tree/api/getSimpleSchema.d.ts +3 -3
- package/dist/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/getSimpleSchema.js +9 -3
- package/dist/simple-tree/api/getSimpleSchema.js.map +1 -1
- package/dist/simple-tree/api/incrementalAllowedTypes.d.ts +16 -13
- package/dist/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -1
- package/dist/simple-tree/api/incrementalAllowedTypes.js +24 -14
- package/dist/simple-tree/api/incrementalAllowedTypes.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +4 -5
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +5 -6
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.d.ts +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +5 -5
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.js +0 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/dist/simple-tree/api/schemaFromSimple.d.ts +6 -1
- package/dist/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFromSimple.js +5 -0
- package/dist/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/dist/simple-tree/api/schemaStatics.d.ts +12 -12
- package/dist/simple-tree/api/simpleSchemaCodec.d.ts +15 -3
- package/dist/simple-tree/api/simpleSchemaCodec.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaCodec.js +18 -6
- package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts +8 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js +13 -8
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.d.ts +3 -3
- package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
- package/dist/simple-tree/core/allowedTypes.d.ts +2 -2
- package/dist/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/dist/simple-tree/core/allowedTypes.js.map +1 -1
- package/dist/simple-tree/core/index.d.ts +1 -1
- package/dist/simple-tree/core/index.d.ts.map +1 -1
- package/dist/simple-tree/core/index.js +2 -3
- package/dist/simple-tree/core/index.js.map +1 -1
- package/dist/simple-tree/core/toStored.d.ts +17 -15
- package/dist/simple-tree/core/toStored.d.ts.map +1 -1
- package/dist/simple-tree/core/toStored.js +5 -40
- package/dist/simple-tree/core/toStored.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +1 -0
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts +15 -15
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +59 -8
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/core/walkSchema.d.ts.map +1 -1
- package/dist/simple-tree/core/walkSchema.js +4 -0
- package/dist/simple-tree/core/walkSchema.js.map +1 -1
- package/dist/simple-tree/createContext.d.ts.map +1 -1
- package/dist/simple-tree/createContext.js +20 -5
- package/dist/simple-tree/createContext.js.map +1 -1
- package/dist/simple-tree/fieldSchema.d.ts +7 -7
- package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
- package/dist/simple-tree/fieldSchema.js.map +1 -1
- package/dist/simple-tree/index.d.ts +8 -7
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +16 -13
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.d.ts +5 -5
- package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +6 -3
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNodeTypes.d.ts +3 -3
- package/dist/simple-tree/node-kinds/array/arrayNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNodeTypes.js.map +1 -1
- package/dist/simple-tree/node-kinds/common.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/common.js +1 -1
- package/dist/simple-tree/node-kinds/common.js.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNode.js +2 -2
- package/dist/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNodeTypes.d.ts +3 -3
- package/dist/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/map/mapNodeTypes.js.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.js +19 -18
- package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts +2 -2
- package/dist/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNodeTypes.js.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNode.js +4 -2
- package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNodeTypes.d.ts +3 -3
- package/dist/simple-tree/node-kinds/record/recordNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
- package/dist/simple-tree/prepareForInsertion.d.ts +54 -47
- package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/dist/simple-tree/prepareForInsertion.js +183 -125
- package/dist/simple-tree/prepareForInsertion.js.map +1 -1
- package/dist/simple-tree/simpleSchema.d.ts +55 -23
- package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/simpleSchema.js +17 -0
- package/dist/simple-tree/simpleSchema.js.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.d.ts +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.d.ts.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.js +8 -1
- package/dist/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts +58 -11
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +205 -30
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/dist/simple-tree/treeSchema.d.ts +23 -0
- package/dist/simple-tree/treeSchema.d.ts.map +1 -0
- package/dist/simple-tree/treeSchema.js +25 -0
- package/dist/simple-tree/treeSchema.js.map +1 -0
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +13 -4
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +29 -11
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/dist/tableSchema.d.ts +117 -63
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +159 -58
- package/dist/tableSchema.js.map +1 -1
- package/dist/treeFactory.d.ts +5 -0
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +29 -8
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/breakable.js +3 -3
- package/dist/util/breakable.js.map +1 -1
- package/dist/util/index.d.ts +2 -1
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +4 -1
- package/dist/util/index.js.map +1 -1
- package/dist/util/rangeMap.d.ts +24 -12
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +46 -6
- package/dist/util/rangeMap.js.map +1 -1
- package/dist/util/readSnapshotBlob.d.ts +13 -0
- package/dist/util/readSnapshotBlob.d.ts.map +1 -0
- package/dist/util/readSnapshotBlob.js +18 -0
- package/dist/util/readSnapshotBlob.js.map +1 -0
- package/dist/util/typeCheckTests.d.ts.map +1 -1
- package/dist/util/typeCheckTests.js.map +1 -1
- package/lib/alpha.d.ts +7 -2
- package/lib/codec/codec.d.ts +14 -1
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +11 -0
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/versioned/codec.d.ts +1 -1
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/codec/versioned/format.d.ts +4 -1
- package/lib/codec/versioned/format.d.ts.map +1 -1
- package/lib/codec/versioned/format.js +4 -1
- package/lib/codec/versioned/format.js.map +1 -1
- package/lib/core/change-family/changeFamily.d.ts +4 -1
- package/lib/core/change-family/changeFamily.d.ts.map +1 -1
- package/lib/core/change-family/changeFamily.js.map +1 -1
- package/lib/core/change-family/index.d.ts +1 -1
- package/lib/core/change-family/index.d.ts.map +1 -1
- package/lib/core/change-family/index.js.map +1 -1
- package/lib/core/index.d.ts +3 -3
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +2 -2
- package/lib/core/index.js.map +1 -1
- package/lib/core/rebase/changeRebaser.d.ts +6 -1
- package/lib/core/rebase/changeRebaser.d.ts.map +1 -1
- package/lib/core/rebase/changeRebaser.js.map +1 -1
- package/lib/core/rebase/index.d.ts +1 -1
- package/lib/core/rebase/index.d.ts.map +1 -1
- package/lib/core/rebase/index.js +1 -1
- package/lib/core/rebase/index.js.map +1 -1
- package/lib/core/rebase/types.d.ts +2 -1
- package/lib/core/rebase/types.d.ts.map +1 -1
- package/lib/core/rebase/types.js +3 -0
- package/lib/core/rebase/types.js.map +1 -1
- package/lib/core/rebase/utils.d.ts.map +1 -1
- package/lib/core/rebase/utils.js +25 -7
- package/lib/core/rebase/utils.js.map +1 -1
- package/lib/core/tree/detachedFieldIndex.d.ts +40 -13
- package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndex.js +22 -13
- package/lib/core/tree/detachedFieldIndex.js.map +1 -1
- package/lib/core/tree/index.d.ts +4 -3
- package/lib/core/tree/index.d.ts.map +1 -1
- package/lib/core/tree/index.js +3 -2
- package/lib/core/tree/index.js.map +1 -1
- package/lib/core/tree/pathTree.d.ts +11 -3
- package/lib/core/tree/pathTree.d.ts.map +1 -1
- package/lib/core/tree/pathTree.js +12 -1
- package/lib/core/tree/pathTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +8 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +4 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +2 -2
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +2 -2
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts +15 -7
- package/lib/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +7 -2
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +90 -42
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js +232 -69
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +4 -4
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +34 -29
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/default-schema/index.d.ts +2 -1
- package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/index.js +2 -1
- package/lib/feature-libraries/default-schema/index.js.map +1 -1
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts +36 -0
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.d.ts.map +1 -0
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js +122 -0
- package/lib/feature-libraries/default-schema/locationBasedEditBuilder.js.map +1 -0
- package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts +7 -6
- package/lib/feature-libraries/default-schema/mappedEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/mappedEditBuilder.js +15 -0
- package/lib/feature-libraries/default-schema/mappedEditBuilder.js.map +1 -1
- package/lib/feature-libraries/deltaUtils.d.ts +1 -0
- package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
- package/lib/feature-libraries/deltaUtils.js +5 -1
- package/lib/feature-libraries/deltaUtils.js.map +1 -1
- package/lib/feature-libraries/detachedFieldIndexSummarizer.d.ts +30 -8
- package/lib/feature-libraries/detachedFieldIndexSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/detachedFieldIndexSummarizer.js +38 -8
- package/lib/feature-libraries/detachedFieldIndexSummarizer.js.map +1 -1
- package/lib/feature-libraries/flex-tree/context.d.ts +9 -0
- package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js +6 -0
- package/lib/feature-libraries/flex-tree/context.js.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +6 -6
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.d.ts +8 -7
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +38 -9
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.d.ts +2 -2
- package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.js +5 -5
- package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +9 -13
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +19 -24
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/forest-summary/format.d.ts +41 -5
- package/lib/feature-libraries/forest-summary/format.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/format.js +3 -3
- package/lib/feature-libraries/forest-summary/format.js.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +11 -9
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +13 -26
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/lib/feature-libraries/forest-summary/index.d.ts +2 -1
- package/lib/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/index.js +2 -1
- package/lib/feature-libraries/forest-summary/index.js.map +1 -1
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts +47 -0
- package/lib/feature-libraries/forest-summary/summaryTypes.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/summaryTypes.js +53 -0
- package/lib/feature-libraries/forest-summary/summaryTypes.js.map +1 -0
- package/lib/feature-libraries/index.d.ts +5 -5
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +4 -4
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.js +2 -1
- package/lib/feature-libraries/mapTreeCursor.js.map +1 -1
- package/lib/feature-libraries/mitigatedChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/mitigatedChangeFamily.js +2 -2
- package/lib/feature-libraries/mitigatedChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.d.ts +18 -2
- package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.js +55 -5
- package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +97 -21
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js +3 -5
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +20 -52
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldKind.d.ts +25 -13
- package/lib/feature-libraries/modular-schema/fieldKind.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldKind.js +0 -21
- package/lib/feature-libraries/modular-schema/fieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +7 -10
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindCodecs.js +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +5 -5
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js +4 -3
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +17 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +384 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts +17 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js +409 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecV2.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +4 -4
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +10 -286
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +48 -15
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1284 -458
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/{modularChangeFormat.d.ts → modularChangeFormatV1.d.ts} +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/{modularChangeFormat.js → modularChangeFormatV1.js} +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +146 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js +29 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +50 -10
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js +20 -2
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/lib/feature-libraries/optional-field/index.d.ts +2 -2
- package/lib/feature-libraries/optional-field/index.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/index.js +1 -1
- package/lib/feature-libraries/optional-field/index.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.d.ts +5 -26
- package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +217 -449
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts +24 -33
- package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeTypes.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js +55 -26
- package/lib/feature-libraries/optional-field/optionalFieldCodecV2.js.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts +27 -8
- package/lib/feature-libraries/schema-index/schemaSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js +38 -12
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.d.ts +6 -7
- package/lib/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +82 -258
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV2.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV2.js +1 -0
- package/lib/feature-libraries/sequence-field/formatV2.js.map +1 -1
- package/lib/feature-libraries/sequence-field/helperTypes.d.ts +14 -10
- package/lib/feature-libraries/sequence-field/helperTypes.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/helperTypes.js.map +1 -1
- package/lib/feature-libraries/sequence-field/index.d.ts +2 -3
- package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/index.js +0 -1
- package/lib/feature-libraries/sequence-field/index.js.map +1 -1
- package/lib/feature-libraries/sequence-field/invert.d.ts +3 -3
- package/lib/feature-libraries/sequence-field/invert.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/invert.js +67 -169
- package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
- package/lib/feature-libraries/sequence-field/markQueue.d.ts +2 -2
- package/lib/feature-libraries/sequence-field/markQueue.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/markQueue.js.map +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +4 -56
- package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/moveEffectTable.js +6 -80
- package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.d.ts +3 -3
- package/lib/feature-libraries/sequence-field/rebase.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.js +108 -114
- package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/lib/feature-libraries/sequence-field/replaceRevisions.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/replaceRevisions.js +16 -33
- package/lib/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +0 -2
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts +22 -4
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +350 -175
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js +21 -61
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV3.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts +2 -2
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js +10 -10
- package/lib/feature-libraries/sequence-field/sequenceFieldEditor.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +3 -2
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +14 -109
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/lib/feature-libraries/sequence-field/types.d.ts +30 -59
- package/lib/feature-libraries/sequence-field/types.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/types.js.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.d.ts +15 -24
- package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +107 -292
- package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
- package/lib/feature-libraries/treeCompressionUtils.d.ts +2 -12
- package/lib/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
- package/lib/feature-libraries/treeCompressionUtils.js +3 -13
- package/lib/feature-libraries/treeCompressionUtils.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- 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 +1 -1
- package/lib/shared-tree/independentView.d.ts.map +1 -1
- package/lib/shared-tree/independentView.js.map +1 -1
- package/lib/shared-tree/index.d.ts +1 -1
- package/lib/shared-tree/index.d.ts.map +1 -1
- package/lib/shared-tree/index.js.map +1 -1
- package/lib/shared-tree/schematizeTree.d.ts +4 -4
- package/lib/shared-tree/schematizeTree.d.ts.map +1 -1
- package/lib/shared-tree/schematizeTree.js +3 -2
- package/lib/shared-tree/schematizeTree.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +1 -5
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +35 -36
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +18 -15
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +15 -4
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js +1 -0
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.d.ts +20 -8
- package/lib/shared-tree/sharedTreeChangeEnricher.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.js +25 -11
- package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.d.ts +6 -6
- 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 +16 -6
- package/lib/shared-tree/sharedTreeEditBuilder.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeEditBuilder.js +11 -5
- package/lib/shared-tree/sharedTreeEditBuilder.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +2 -2
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +14 -12
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +69 -20
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branch.d.ts +3 -2
- package/lib/shared-tree-core/branch.d.ts.map +1 -1
- package/lib/shared-tree-core/branch.js +4 -3
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/editManager.d.ts +2 -2
- package/lib/shared-tree-core/editManager.d.ts.map +1 -1
- package/lib/shared-tree-core/editManager.js +9 -9
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.d.ts +4 -0
- package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.js +14 -5
- package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/{dist/shared-tree-core/editManagerCodecsV5.d.ts → lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts} +3 -3
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{editManagerCodecsV5.js → editManagerCodecsVSharedBranches.js} +4 -4
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts +20 -6
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatCommons.js +22 -7
- package/lib/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts +2 -2
- package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.js +1 -0
- package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/lib/shared-tree-core/{editManagerFormatV5.d.ts → editManagerFormatVSharedBranches.d.ts} +3 -3
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{editManagerFormatV5.js → editManagerFormatVSharedBranches.js} +2 -2
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/editManagerSummarizer.d.ts +29 -9
- package/lib/shared-tree-core/editManagerSummarizer.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js +39 -11
- package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/lib/shared-tree-core/index.d.ts +5 -3
- package/lib/shared-tree-core/index.d.ts.map +1 -1
- package/lib/shared-tree-core/index.js +4 -2
- package/lib/shared-tree-core/index.js.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.d.ts +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- package/{dist/shared-tree-core/messageCodecV5.d.ts → lib/shared-tree-core/messageCodecVSharedBranches.d.ts} +2 -2
- package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{messageCodecV5.js → messageCodecVSharedBranches.js} +3 -3
- package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/messageCodecs.d.ts +4 -0
- package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecs.js +14 -5
- package/lib/shared-tree-core/messageCodecs.js.map +1 -1
- package/lib/shared-tree-core/messageFormat.d.ts +20 -6
- package/lib/shared-tree-core/messageFormat.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormat.js +22 -7
- package/lib/shared-tree-core/messageFormat.js.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts +3 -2
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js +8 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/lib/shared-tree-core/{messageFormatV5.d.ts → messageFormatVSharedBranches.d.ts} +5 -7
- package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -0
- package/lib/shared-tree-core/{messageFormatV5.js → messageFormatVSharedBranches.js} +3 -2
- package/lib/shared-tree-core/messageFormatVSharedBranches.js.map +1 -0
- package/lib/shared-tree-core/sharedTreeCore.d.ts +14 -47
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +28 -16
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/shared-tree-core/summaryTypes.d.ts +94 -0
- package/lib/shared-tree-core/summaryTypes.d.ts.map +1 -0
- package/lib/shared-tree-core/summaryTypes.js +43 -0
- package/lib/shared-tree-core/summaryTypes.js.map +1 -0
- package/lib/shared-tree-core/versionedSummarizer.d.ts +67 -0
- package/lib/shared-tree-core/versionedSummarizer.d.ts.map +1 -0
- package/lib/shared-tree-core/versionedSummarizer.js +59 -0
- package/lib/shared-tree-core/versionedSummarizer.js.map +1 -0
- package/lib/simple-tree/api/configuration.d.ts +3 -26
- package/lib/simple-tree/api/configuration.d.ts.map +1 -1
- package/lib/simple-tree/api/configuration.js +14 -25
- package/lib/simple-tree/api/configuration.js.map +1 -1
- package/lib/simple-tree/api/dirtyIndex.d.ts +11 -0
- package/lib/simple-tree/api/dirtyIndex.d.ts.map +1 -1
- package/lib/simple-tree/api/dirtyIndex.js +7 -0
- package/lib/simple-tree/api/dirtyIndex.js.map +1 -1
- package/lib/simple-tree/api/discrepancies.d.ts +1 -1
- package/lib/simple-tree/api/discrepancies.d.ts.map +1 -1
- package/lib/simple-tree/api/discrepancies.js.map +1 -1
- package/lib/simple-tree/api/getSimpleSchema.d.ts +3 -3
- package/lib/simple-tree/api/getSimpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/getSimpleSchema.js +9 -3
- package/lib/simple-tree/api/getSimpleSchema.js.map +1 -1
- package/lib/simple-tree/api/incrementalAllowedTypes.d.ts +16 -13
- package/lib/simple-tree/api/incrementalAllowedTypes.d.ts.map +1 -1
- package/lib/simple-tree/api/incrementalAllowedTypes.js +23 -13
- package/lib/simple-tree/api/incrementalAllowedTypes.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +4 -5
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +3 -4
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.d.ts +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaCompatibilityTester.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +5 -5
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.js +0 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/lib/simple-tree/api/schemaFromSimple.d.ts +6 -1
- package/lib/simple-tree/api/schemaFromSimple.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFromSimple.js +5 -0
- package/lib/simple-tree/api/schemaFromSimple.js.map +1 -1
- package/lib/simple-tree/api/schemaStatics.d.ts +12 -12
- package/lib/simple-tree/api/simpleSchemaCodec.d.ts +15 -3
- package/lib/simple-tree/api/simpleSchemaCodec.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaCodec.js +15 -3
- package/lib/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts +8 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.js +15 -10
- package/lib/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.d.ts +3 -3
- package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
- package/lib/simple-tree/core/allowedTypes.d.ts +2 -2
- package/lib/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/lib/simple-tree/core/allowedTypes.js.map +1 -1
- package/lib/simple-tree/core/index.d.ts +1 -1
- package/lib/simple-tree/core/index.d.ts.map +1 -1
- package/lib/simple-tree/core/index.js +1 -1
- package/lib/simple-tree/core/index.js.map +1 -1
- package/lib/simple-tree/core/toStored.d.ts +17 -15
- package/lib/simple-tree/core/toStored.d.ts.map +1 -1
- package/lib/simple-tree/core/toStored.js +4 -37
- package/lib/simple-tree/core/toStored.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +1 -0
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts +15 -15
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +58 -8
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/core/walkSchema.d.ts.map +1 -1
- package/lib/simple-tree/core/walkSchema.js +5 -1
- package/lib/simple-tree/core/walkSchema.js.map +1 -1
- package/lib/simple-tree/createContext.d.ts.map +1 -1
- package/lib/simple-tree/createContext.js +20 -5
- package/lib/simple-tree/createContext.js.map +1 -1
- package/lib/simple-tree/fieldSchema.d.ts +7 -7
- package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
- package/lib/simple-tree/fieldSchema.js.map +1 -1
- package/lib/simple-tree/index.d.ts +8 -7
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +6 -5
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.d.ts +5 -5
- package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +7 -4
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNodeTypes.d.ts +3 -3
- package/lib/simple-tree/node-kinds/array/arrayNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNodeTypes.js.map +1 -1
- package/lib/simple-tree/node-kinds/common.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/common.js +2 -2
- package/lib/simple-tree/node-kinds/common.js.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNode.js +2 -2
- package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNodeTypes.d.ts +3 -3
- package/lib/simple-tree/node-kinds/map/mapNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/map/mapNodeTypes.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.js +20 -19
- package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts +2 -2
- package/lib/simple-tree/node-kinds/object/objectNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNodeTypes.js.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNode.js +4 -2
- package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNodeTypes.d.ts +3 -3
- package/lib/simple-tree/node-kinds/record/recordNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNodeTypes.js.map +1 -1
- package/lib/simple-tree/prepareForInsertion.d.ts +54 -47
- package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/lib/simple-tree/prepareForInsertion.js +183 -124
- package/lib/simple-tree/prepareForInsertion.js.map +1 -1
- package/lib/simple-tree/simpleSchema.d.ts +55 -23
- package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/simpleSchema.js +16 -1
- package/lib/simple-tree/simpleSchema.js.map +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.d.ts +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.d.ts.map +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.js +8 -1
- package/lib/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts +58 -11
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +204 -31
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/lib/simple-tree/treeSchema.d.ts +23 -0
- package/lib/simple-tree/treeSchema.d.ts.map +1 -0
- package/lib/simple-tree/treeSchema.js +21 -0
- package/lib/simple-tree/treeSchema.js.map +1 -0
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts +13 -4
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +26 -9
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/lib/tableSchema.d.ts +117 -63
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +160 -59
- package/lib/tableSchema.js.map +1 -1
- package/lib/treeFactory.d.ts +5 -0
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +28 -8
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/breakable.js +3 -3
- package/lib/util/breakable.js.map +1 -1
- package/lib/util/index.d.ts +2 -1
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +2 -1
- package/lib/util/index.js.map +1 -1
- package/lib/util/rangeMap.d.ts +24 -12
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +44 -5
- package/lib/util/rangeMap.js.map +1 -1
- package/lib/util/readSnapshotBlob.d.ts +13 -0
- package/lib/util/readSnapshotBlob.d.ts.map +1 -0
- package/lib/util/readSnapshotBlob.js +14 -0
- package/lib/util/readSnapshotBlob.js.map +1 -0
- package/lib/util/typeCheckTests.d.ts.map +1 -1
- package/lib/util/typeCheckTests.js.map +1 -1
- package/package.json +22 -22
- package/src/codec/codec.ts +15 -1
- package/src/codec/versioned/codec.ts +1 -1
- package/src/codec/versioned/format.ts +4 -1
- package/src/core/change-family/changeFamily.ts +5 -0
- package/src/core/change-family/index.ts +1 -0
- package/src/core/index.ts +7 -2
- package/src/core/rebase/changeRebaser.ts +6 -1
- package/src/core/rebase/index.ts +1 -0
- package/src/core/rebase/types.ts +8 -1
- package/src/core/rebase/utils.ts +31 -7
- package/src/core/tree/detachedFieldIndex.ts +71 -14
- package/src/core/tree/index.ts +9 -3
- package/src/core/tree/pathTree.ts +16 -4
- package/src/feature-libraries/chunked-forest/basicChunk.ts +7 -1
- package/src/feature-libraries/chunked-forest/chunkTree.ts +6 -1
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +3 -7
- package/src/feature-libraries/chunked-forest/codec/incrementalEncodingPolicy.ts +18 -11
- package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +9 -9
- package/src/feature-libraries/default-schema/defaultEditBuilder.ts +393 -127
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +35 -38
- package/src/feature-libraries/default-schema/index.ts +16 -5
- package/src/feature-libraries/default-schema/locationBasedEditBuilder.ts +180 -0
- package/src/feature-libraries/default-schema/mappedEditBuilder.ts +35 -9
- package/src/feature-libraries/deltaUtils.ts +6 -1
- package/src/feature-libraries/detachedFieldIndexSummarizer.ts +62 -15
- package/src/feature-libraries/flex-tree/context.ts +17 -0
- package/src/feature-libraries/flex-tree/flexTreeTypes.ts +7 -8
- package/src/feature-libraries/flex-tree/lazyField.ts +66 -24
- package/src/feature-libraries/forest-summary/codec.ts +8 -8
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +47 -39
- package/src/feature-libraries/forest-summary/format.ts +4 -4
- package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +23 -39
- package/src/feature-libraries/forest-summary/index.ts +2 -1
- package/src/feature-libraries/forest-summary/summaryTypes.ts +61 -0
- package/src/feature-libraries/index.ts +23 -14
- package/src/feature-libraries/mapTreeCursor.ts +2 -1
- package/src/feature-libraries/mitigatedChangeFamily.ts +3 -1
- package/src/feature-libraries/modular-schema/comparison.ts +63 -5
- package/src/feature-libraries/modular-schema/crossFieldQueries.ts +142 -44
- package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +36 -57
- package/src/feature-libraries/modular-schema/fieldKind.ts +24 -40
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +10 -19
- package/src/feature-libraries/modular-schema/genericFieldKindCodecs.ts +1 -1
- package/src/feature-libraries/modular-schema/index.ts +21 -15
- package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +732 -0
- package/src/feature-libraries/modular-schema/modularChangeCodecV2.ts +790 -0
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +32 -505
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +2542 -742
- package/src/feature-libraries/modular-schema/{modularChangeFormat.ts → modularChangeFormatV1.ts} +2 -1
- package/src/feature-libraries/modular-schema/modularChangeFormatV2.ts +62 -0
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +98 -10
- package/src/feature-libraries/optional-field/index.ts +1 -3
- package/src/feature-libraries/optional-field/optionalField.ts +317 -574
- package/src/feature-libraries/optional-field/optionalFieldChangeTypes.ts +24 -38
- package/src/feature-libraries/optional-field/optionalFieldCodecV2.ts +89 -35
- package/src/feature-libraries/schema-index/schemaSummarizer.ts +59 -18
- package/src/feature-libraries/sequence-field/compose.ts +134 -519
- package/src/feature-libraries/sequence-field/formatV2.ts +1 -0
- package/src/feature-libraries/sequence-field/helperTypes.ts +34 -19
- package/src/feature-libraries/sequence-field/index.ts +0 -9
- package/src/feature-libraries/sequence-field/invert.ts +103 -228
- package/src/feature-libraries/sequence-field/markQueue.ts +2 -2
- package/src/feature-libraries/sequence-field/moveEffectTable.ts +8 -191
- package/src/feature-libraries/sequence-field/rebase.ts +168 -203
- package/src/feature-libraries/sequence-field/replaceRevisions.ts +31 -52
- package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +0 -2
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +643 -220
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV3.ts +56 -68
- package/src/feature-libraries/sequence-field/sequenceFieldEditor.ts +25 -27
- package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +19 -129
- package/src/feature-libraries/sequence-field/types.ts +34 -64
- package/src/feature-libraries/sequence-field/utils.ts +133 -346
- package/src/feature-libraries/treeCompressionUtils.ts +1 -15
- package/src/index.ts +7 -2
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/independentView.ts +1 -1
- package/src/shared-tree/index.ts +3 -2
- package/src/shared-tree/schematizeTree.ts +21 -8
- package/src/shared-tree/schematizingTreeView.ts +50 -68
- package/src/shared-tree/sharedTree.ts +51 -30
- package/src/shared-tree/sharedTreeChangeCodecs.ts +5 -1
- package/src/shared-tree/sharedTreeChangeEnricher.ts +31 -11
- package/src/shared-tree/sharedTreeChangeFamily.ts +9 -6
- package/src/shared-tree/sharedTreeEditBuilder.ts +46 -12
- package/src/shared-tree/treeAlpha.ts +2 -3
- package/src/shared-tree/treeCheckout.ts +106 -33
- package/src/shared-tree-core/branch.ts +8 -2
- package/src/shared-tree-core/editManager.ts +16 -2
- package/src/shared-tree-core/editManagerCodecs.ts +17 -5
- package/src/shared-tree-core/{editManagerCodecsV5.ts → editManagerCodecsVSharedBranches.ts} +3 -3
- package/src/shared-tree-core/editManagerFormatCommons.ts +22 -7
- package/src/shared-tree-core/editManagerFormatV1toV4.ts +3 -1
- package/src/shared-tree-core/{editManagerFormatV5.ts → editManagerFormatVSharedBranches.ts} +2 -2
- package/src/shared-tree-core/editManagerSummarizer.ts +58 -16
- package/src/shared-tree-core/index.ts +11 -3
- package/src/shared-tree-core/messageCodecV1ToV4.ts +2 -1
- package/src/shared-tree-core/{messageCodecV5.ts → messageCodecVSharedBranches.ts} +3 -3
- package/src/shared-tree-core/messageCodecs.ts +17 -5
- package/src/shared-tree-core/messageFormat.ts +22 -7
- package/src/shared-tree-core/messageFormatV1ToV4.ts +16 -2
- package/src/shared-tree-core/{messageFormatV5.ts → messageFormatVSharedBranches.ts} +4 -6
- package/src/shared-tree-core/sharedTreeCore.ts +67 -76
- package/src/shared-tree-core/summaryTypes.ts +122 -0
- package/src/shared-tree-core/versionedSummarizer.ts +107 -0
- package/src/simple-tree/api/configuration.ts +21 -68
- package/src/simple-tree/api/dirtyIndex.ts +11 -0
- package/src/simple-tree/api/discrepancies.ts +1 -1
- package/src/simple-tree/api/getSimpleSchema.ts +13 -6
- package/src/simple-tree/api/incrementalAllowedTypes.ts +34 -20
- package/src/simple-tree/api/index.ts +4 -5
- package/src/simple-tree/api/schemaCompatibilityTester.ts +1 -1
- package/src/simple-tree/api/schemaFactoryAlpha.ts +2 -2
- package/src/simple-tree/api/schemaFactoryRecursive.ts +0 -2
- package/src/simple-tree/api/schemaFromSimple.ts +11 -5
- package/src/simple-tree/api/simpleSchemaCodec.ts +17 -3
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +1 -1
- package/src/simple-tree/api/snapshotCompatibilityChecker.ts +18 -10
- package/src/simple-tree/api/tree.ts +1 -1
- package/src/simple-tree/api/typesUnsafe.ts +7 -3
- package/src/simple-tree/core/allowedTypes.ts +3 -3
- package/src/simple-tree/core/index.ts +2 -2
- package/src/simple-tree/core/toStored.ts +22 -55
- package/src/simple-tree/core/treeNodeKernel.ts +1 -0
- package/src/simple-tree/core/unhydratedFlexTree.ts +87 -36
- package/src/simple-tree/core/walkSchema.ts +6 -0
- package/src/simple-tree/createContext.ts +26 -11
- package/src/simple-tree/fieldSchema.ts +16 -7
- package/src/simple-tree/index.ts +13 -12
- package/src/simple-tree/node-kinds/array/arrayNode.ts +14 -7
- package/src/simple-tree/node-kinds/array/arrayNodeTypes.ts +3 -3
- package/src/simple-tree/node-kinds/common.ts +2 -5
- package/src/simple-tree/node-kinds/map/mapNode.ts +9 -6
- package/src/simple-tree/node-kinds/map/mapNodeTypes.ts +3 -3
- package/src/simple-tree/node-kinds/object/objectNode.ts +28 -27
- package/src/simple-tree/node-kinds/object/objectNodeTypes.ts +6 -2
- package/src/simple-tree/node-kinds/record/recordNode.ts +15 -11
- package/src/simple-tree/node-kinds/record/recordNodeTypes.ts +3 -3
- package/src/simple-tree/prepareForInsertion.ts +343 -200
- package/src/simple-tree/simpleSchema.ts +79 -32
- package/src/simple-tree/simpleSchemaFormatV1.ts +9 -1
- package/src/simple-tree/toStoredSchema.ts +319 -61
- package/src/simple-tree/treeSchema.ts +54 -0
- package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +42 -14
- package/src/tableSchema.ts +485 -166
- package/src/treeFactory.ts +32 -9
- package/src/util/breakable.ts +4 -4
- package/src/util/index.ts +5 -0
- package/src/util/rangeMap.ts +72 -18
- package/src/util/readSnapshotBlob.ts +23 -0
- package/src/util/typeCheckTests.ts +0 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +0 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormat.js.map +0 -1
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +0 -9
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +0 -1
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js +0 -50
- package/dist/feature-libraries/sequence-field/relevantRemovedRoots.js.map +0 -1
- package/dist/shared-tree-core/editManagerCodecsV5.d.ts.map +0 -1
- package/dist/shared-tree-core/editManagerCodecsV5.js.map +0 -1
- package/dist/shared-tree-core/editManagerFormatV5.d.ts.map +0 -1
- package/dist/shared-tree-core/editManagerFormatV5.js.map +0 -1
- package/dist/shared-tree-core/messageCodecV5.d.ts.map +0 -1
- package/dist/shared-tree-core/messageCodecV5.js.map +0 -1
- package/dist/shared-tree-core/messageFormatV5.d.ts.map +0 -1
- package/dist/shared-tree-core/messageFormatV5.js.map +0 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts +0 -40
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +0 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js +0 -177
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js.map +0 -1
- package/docs/main/sequence-field/move-composition.md +0 -46
- package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +0 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormat.js.map +0 -1
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts +0 -9
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.d.ts.map +0 -1
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js +0 -46
- package/lib/feature-libraries/sequence-field/relevantRemovedRoots.js.map +0 -1
- package/lib/shared-tree-core/editManagerCodecsV5.d.ts.map +0 -1
- package/lib/shared-tree-core/editManagerCodecsV5.js.map +0 -1
- package/lib/shared-tree-core/editManagerFormatV5.d.ts.map +0 -1
- package/lib/shared-tree-core/editManagerFormatV5.js.map +0 -1
- package/lib/shared-tree-core/messageCodecV5.d.ts.map +0 -1
- package/lib/shared-tree-core/messageCodecV5.js.map +0 -1
- package/lib/shared-tree-core/messageFormatV5.d.ts.map +0 -1
- package/lib/shared-tree-core/messageFormatV5.js.map +0 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts +0 -40
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +0 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js +0 -171
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js.map +0 -1
- package/src/feature-libraries/sequence-field/relevantRemovedRoots.ts +0 -57
- package/src/simple-tree/api/viewSchemaToSimpleSchema.ts +0 -209
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { assert, fail } from "@fluidframework/core-utils/internal";
|
|
6
6
|
import { BTree } from "@tylerbu/sorted-btree-es6";
|
|
7
|
-
import { EditBuilder, makeDetachedNodeId, replaceAtomRevisions, revisionMetadataSourceFromInfo, areEqualChangeAtomIds, areEqualChangeAtomIdOpts, tagChange, makeAnonChange, newChangeAtomIdRangeMap,
|
|
7
|
+
import { EditBuilder, makeDetachedNodeId, replaceAtomRevisions, revisionMetadataSourceFromInfo, areEqualChangeAtomIds, areEqualChangeAtomIdOpts, tagChange, makeAnonChange, mapTaggedChange, newChangeAtomIdRangeMap, newChangeAtomIdTransform, offsetChangeAtomId, isDetachedUpPathRoot, subtractChangeAtomIds, makeChangeAtomId, } from "../../core/index.js";
|
|
8
8
|
import { brand, idAllocatorFromMaxId, idAllocatorFromState, getOrCreate, newTupleBTree, mergeTupleBTrees, RangeMap, balancedReduce, } from "../../util/index.js";
|
|
9
|
-
import { CrossFieldTarget,
|
|
9
|
+
import { CrossFieldTarget, setInCrossFieldMap, } from "./crossFieldQueries.js";
|
|
10
10
|
import { NodeAttachState, } from "./fieldChangeHandler.js";
|
|
11
11
|
import { convertGenericChange, genericFieldKind } from "./genericFieldKind.js";
|
|
12
|
-
import {
|
|
12
|
+
import { getFromChangeAtomIdMap, newCrossFieldRangeTable, rangeQueryChangeAtomIdMap, setInChangeAtomIdMap, } from "./modularChangeTypes.js";
|
|
13
13
|
/**
|
|
14
14
|
* Implementation of ChangeFamily which delegates work in a given field to the appropriate FieldKind
|
|
15
15
|
* as determined by the schema.
|
|
@@ -64,18 +64,19 @@ export class ModularChangeFamily {
|
|
|
64
64
|
return convertedChange;
|
|
65
65
|
}
|
|
66
66
|
compose(changes) {
|
|
67
|
-
const {
|
|
67
|
+
const { maxId } = getRevInfoFromTaggedChanges(changes);
|
|
68
68
|
const idState = { maxId };
|
|
69
69
|
const pairwiseDelegate = (left, right) => {
|
|
70
|
-
return this.composePair(left, right,
|
|
70
|
+
return this.composePair(left, right, idState);
|
|
71
71
|
};
|
|
72
72
|
const innerChanges = changes.map((change) => change.change);
|
|
73
73
|
return balancedReduce(innerChanges, pairwiseDelegate, makeModularChangeset);
|
|
74
74
|
}
|
|
75
|
-
composePair(change1, change2,
|
|
76
|
-
const
|
|
75
|
+
composePair(change1, change2, idState) {
|
|
76
|
+
const revInfos = composeRevInfos(change1.revisions, change2.revisions);
|
|
77
|
+
const { fieldChanges, nodeChanges, nodeToParent, nodeAliases, crossFieldKeys, rootNodes } = this.composeAllFields(change1, change2, revInfos, idState);
|
|
77
78
|
const { allBuilds, allDestroys, allRefreshers } = composeBuildsDestroysAndRefreshers(change1, change2);
|
|
78
|
-
|
|
79
|
+
const composed = makeModularChangeset({
|
|
79
80
|
fieldChanges,
|
|
80
81
|
nodeChanges,
|
|
81
82
|
nodeToParent,
|
|
@@ -83,10 +84,14 @@ export class ModularChangeFamily {
|
|
|
83
84
|
crossFieldKeys,
|
|
84
85
|
maxId: idState.maxId,
|
|
85
86
|
revisions: revInfos,
|
|
87
|
+
rootNodes,
|
|
86
88
|
builds: allBuilds,
|
|
87
89
|
destroys: allDestroys,
|
|
88
90
|
refreshers: allRefreshers,
|
|
89
91
|
});
|
|
92
|
+
// XXX: This is an expensive assert which should be disabled before merging.
|
|
93
|
+
this.validateChangeset(composed);
|
|
94
|
+
return composed;
|
|
90
95
|
}
|
|
91
96
|
composeAllFields(potentiallyConflictedChange1, potentiallyConflictedChange2, revInfos, idState) {
|
|
92
97
|
// Our current cell ordering scheme in sequences depends on being able to rebase over a change with conflicts.
|
|
@@ -107,34 +112,50 @@ export class ModularChangeFamily {
|
|
|
107
112
|
const composedNodeChanges = brand(mergeTupleBTrees(change1.nodeChanges, change2.nodeChanges));
|
|
108
113
|
const composedNodeToParent = brand(mergeTupleBTrees(change1.nodeToParent, change2.nodeToParent));
|
|
109
114
|
const composedNodeAliases = brand(mergeTupleBTrees(change1.nodeAliases, change2.nodeAliases));
|
|
110
|
-
const
|
|
115
|
+
const pendingCompositions = {
|
|
116
|
+
nodeIdsToCompose: [],
|
|
117
|
+
affectedBaseFields: newTupleBTree(),
|
|
118
|
+
};
|
|
119
|
+
const movedCrossFieldKeys = newCrossFieldRangeTable();
|
|
120
|
+
const removedCrossFieldKeys = newCrossFieldRangeTable();
|
|
121
|
+
const composedRoots = composeRootTables(change1, change2, composedNodeToParent, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
|
|
122
|
+
const crossFieldTable = newComposeTable(change1, change2, composedRoots, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
|
|
111
123
|
const composedFields = this.composeFieldMaps(change1.fieldChanges, change2.fieldChanges, undefined, genId, crossFieldTable, revisionMetadata);
|
|
112
124
|
this.composeInvalidatedElements(crossFieldTable, composedFields, composedNodeChanges, composedNodeToParent, composedNodeAliases, genId, revisionMetadata);
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
for (const entry of crossFieldTable.renamesToDelete.entries()) {
|
|
126
|
+
deleteNodeRenameFrom(crossFieldTable.composedRootNodes, entry.start, entry.length);
|
|
127
|
+
}
|
|
128
|
+
for (const [nodeId, location] of crossFieldTable.movedNodeToParent.entries()) {
|
|
129
|
+
// Moved nodes are from change2.
|
|
130
|
+
// If there is a corresponding node in change1, then composedNodeToParent will already have the correct entry,
|
|
131
|
+
// because the location of the node is the same in change1 and the composed change
|
|
132
|
+
// (since they have the same input context).
|
|
133
|
+
if (crossFieldTable.newToBaseNodeId.get(nodeId) === undefined) {
|
|
134
|
+
composedNodeToParent.set(nodeId, location);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
115
137
|
return {
|
|
116
138
|
fieldChanges: composedFields,
|
|
117
139
|
nodeChanges: composedNodeChanges,
|
|
118
140
|
nodeToParent: composedNodeToParent,
|
|
119
141
|
nodeAliases: composedNodeAliases,
|
|
120
|
-
crossFieldKeys:
|
|
142
|
+
crossFieldKeys: composeCrossFieldKeyTables(change1.crossFieldKeys, change2.crossFieldKeys, crossFieldTable.movedCrossFieldKeys, crossFieldTable.removedCrossFieldKeys),
|
|
143
|
+
rootNodes: composedRoots,
|
|
121
144
|
};
|
|
122
145
|
}
|
|
123
146
|
composeInvalidatedField(fieldChange, crossFieldTable, genId, revisionMetadata) {
|
|
124
147
|
const context = crossFieldTable.fieldToContext.get(fieldChange);
|
|
125
148
|
assert(context !== undefined, 0x8cc /* Should have context for every invalidated field */);
|
|
126
|
-
const {
|
|
149
|
+
const { change1: fieldChange1, change2: fieldChange2, composedChange } = context;
|
|
150
|
+
crossFieldTable.pendingCompositions.affectedBaseFields.delete(fieldIdKeyFromFieldId(context.fieldId));
|
|
127
151
|
const rebaser = getChangeHandler(this.fieldKinds, composedChange.fieldKind).rebaser;
|
|
128
152
|
const composeNodes = (child1, child2) => {
|
|
129
|
-
if (child1 !== undefined &&
|
|
130
|
-
|
|
131
|
-
getFromChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2) === undefined) {
|
|
132
|
-
setInChangeAtomIdMap(crossFieldTable.newToBaseNodeId, child2, child1);
|
|
133
|
-
crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
|
|
153
|
+
if (child1 !== undefined && child2 !== undefined) {
|
|
154
|
+
addNodesToCompose(crossFieldTable, child1, child2);
|
|
134
155
|
}
|
|
135
156
|
return child1 ?? child2 ?? fail(0xb22 /* Should not compose two undefined nodes */);
|
|
136
157
|
};
|
|
137
|
-
const amendedChange = rebaser.compose(fieldChange1, fieldChange2, composeNodes, genId, new
|
|
158
|
+
const amendedChange = rebaser.compose(fieldChange1, fieldChange2, composeNodes, genId, new ComposeNodeManagerI(crossFieldTable, context.fieldId, false), revisionMetadata);
|
|
138
159
|
composedChange.change = brand(amendedChange);
|
|
139
160
|
}
|
|
140
161
|
/**
|
|
@@ -143,32 +164,23 @@ export class ModularChangeFamily {
|
|
|
143
164
|
* - discovering that two node changesets refer to the same node (`nodeIdsToCompose`)
|
|
144
165
|
* - a previously composed field being invalidated by a cross field effect (`invalidatedFields`)
|
|
145
166
|
* - a field which was copied directly from an input changeset being invalidated by a cross field effect
|
|
146
|
-
* (`affectedBaseFields`
|
|
167
|
+
* (`affectedBaseFields`)
|
|
147
168
|
*
|
|
148
169
|
* Updating an element may invalidate further elements. This function runs until there is no more invalidation.
|
|
149
170
|
*/
|
|
150
171
|
composeInvalidatedElements(table, composedFields, composedNodes, composedNodeToParent, nodeAliases, genId, metadata) {
|
|
151
172
|
const pending = table.pendingCompositions;
|
|
152
|
-
while (
|
|
153
|
-
|
|
154
|
-
pending.affectedBaseFields
|
|
155
|
-
pending.affectedNewFields.length > 0) {
|
|
156
|
-
// Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
157
|
-
for (const [id1, id2] of pending.nodeIdsToCompose) {
|
|
158
|
-
this.composeNodesById(table.baseChange.nodeChanges, table.newChange.nodeChanges, composedNodes, composedNodeToParent, nodeAliases, id1, id2, genId, table, metadata);
|
|
159
|
-
}
|
|
160
|
-
pending.nodeIdsToCompose.length = 0;
|
|
161
|
-
this.composeAffectedFields(table, table.baseChange, true, pending.affectedBaseFields, composedFields, composedNodes, genId, metadata);
|
|
162
|
-
this.composeAffectedFields(table, table.newChange, false, pending.affectedNewFields, composedFields, composedNodes, genId, metadata);
|
|
163
|
-
this.processInvalidatedCompositions(table, genId, metadata);
|
|
173
|
+
while (pending.nodeIdsToCompose.length > 0 || pending.affectedBaseFields.length > 0) {
|
|
174
|
+
this.processPendingNodeCompositions(table, composedNodes, composedNodeToParent, nodeAliases, genId, metadata);
|
|
175
|
+
this.composeAffectedFields(table, table.baseChange, pending.affectedBaseFields, composedFields, composedNodes, genId, metadata);
|
|
164
176
|
}
|
|
165
177
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this.composeInvalidatedField(fieldChange, table, genId, metadata);
|
|
178
|
+
processPendingNodeCompositions(table, composedNodes, composedNodeToParent, nodeAliases, genId, metadata) {
|
|
179
|
+
// Note that the call to `composeNodesById` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
180
|
+
for (const [id1, id2] of table.pendingCompositions.nodeIdsToCompose) {
|
|
181
|
+
this.composeNodesById(table.baseChange, table.newChange, composedNodes, composedNodeToParent, nodeAliases, id1, id2, genId, table, metadata);
|
|
171
182
|
}
|
|
183
|
+
table.pendingCompositions.nodeIdsToCompose.length = 0;
|
|
172
184
|
}
|
|
173
185
|
/**
|
|
174
186
|
* Ensures that each field in `affectedFields` has been updated in the composition output.
|
|
@@ -181,38 +193,36 @@ export class ModularChangeFamily {
|
|
|
181
193
|
* If not, they are assumed to be part of the new changeset.
|
|
182
194
|
* @param affectedFields - The set of fields to process.
|
|
183
195
|
*/
|
|
184
|
-
composeAffectedFields(table, change,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
196
|
+
composeAffectedFields(table, change, affectedFields, composedFields, composedNodes, genId, metadata) {
|
|
197
|
+
const fieldsToProcess = affectedFields.clone();
|
|
198
|
+
affectedFields.clear();
|
|
199
|
+
for (const fieldIdKey of fieldsToProcess.keys()) {
|
|
200
|
+
const fieldId = fieldIdFromFieldIdKey(fieldIdKey);
|
|
201
|
+
const fieldChange = fieldChangeFromId(change, fieldId);
|
|
188
202
|
if (table.fieldToContext.has(fieldChange) ||
|
|
189
203
|
table.newFieldToBaseField.has(fieldChange)) {
|
|
190
|
-
|
|
191
|
-
// If we've already processed this field then either it is up to date
|
|
192
|
-
// or there is pending inval which will be handled in processInvalidatedCompositions.
|
|
193
|
-
continue;
|
|
204
|
+
this.composeInvalidatedField(fieldChange, table, genId, metadata);
|
|
194
205
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
? [fieldChange, emptyChange]
|
|
198
|
-
: [emptyChange, fieldChange];
|
|
199
|
-
const composedField = this.composeFieldChanges(fieldId, change1, change2, genId, table, metadata);
|
|
200
|
-
if (fieldId.nodeId === undefined) {
|
|
201
|
-
composedFields.set(fieldId.field, composedField);
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
const nodeId = getFromChangeAtomIdMap(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId;
|
|
205
|
-
let nodeChangeset = nodeChangeFromId(composedNodes, nodeId);
|
|
206
|
-
if (!table.composedNodes.has(nodeChangeset)) {
|
|
207
|
-
nodeChangeset = cloneNodeChangeset(nodeChangeset);
|
|
208
|
-
setInChangeAtomIdMap(composedNodes, nodeId, nodeChangeset);
|
|
209
|
-
}
|
|
210
|
-
if (nodeChangeset.fieldChanges === undefined) {
|
|
211
|
-
nodeChangeset.fieldChanges = new Map();
|
|
206
|
+
else {
|
|
207
|
+
this.composeFieldWithNoNewChange(table, fieldChange, fieldId, composedFields, composedNodes, genId, metadata);
|
|
212
208
|
}
|
|
213
|
-
nodeChangeset.fieldChanges.set(fieldId.field, composedField);
|
|
214
209
|
}
|
|
215
|
-
|
|
210
|
+
}
|
|
211
|
+
composeFieldWithNoNewChange(table, baseFieldChange, fieldId, composedFields, composedNodes, genId, metadata) {
|
|
212
|
+
const emptyChange = this.createEmptyFieldChange(baseFieldChange.fieldKind);
|
|
213
|
+
const composedField = this.composeFieldChanges(fieldId, baseFieldChange, emptyChange, genId, table, metadata);
|
|
214
|
+
if (fieldId.nodeId === undefined) {
|
|
215
|
+
composedFields.set(fieldId.field, composedField);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const nodeId = normalizeNodeId(getFromChangeAtomIdMap(table.newToBaseNodeId, fieldId.nodeId) ?? fieldId.nodeId, table.baseChange.nodeAliases);
|
|
219
|
+
// We clone the node changeset before mutating it, as it may be from one of the input changesets.
|
|
220
|
+
const nodeChangeset = cloneNodeChangeset(nodeChangeFromId(composedNodes, table.baseChange.nodeAliases, nodeId));
|
|
221
|
+
setInChangeAtomIdMap(composedNodes, nodeId, nodeChangeset);
|
|
222
|
+
if (nodeChangeset.fieldChanges === undefined) {
|
|
223
|
+
nodeChangeset.fieldChanges = new Map();
|
|
224
|
+
}
|
|
225
|
+
nodeChangeset.fieldChanges.set(fieldId.field, composedField);
|
|
216
226
|
}
|
|
217
227
|
composeFieldMaps(change1, change2, parentId, genId, crossFieldTable, revisionMetadata) {
|
|
218
228
|
const composedFields = new Map();
|
|
@@ -222,6 +232,14 @@ export class ModularChangeFamily {
|
|
|
222
232
|
for (const [field, fieldChange1] of change1) {
|
|
223
233
|
const fieldId = { nodeId: parentId, field };
|
|
224
234
|
const fieldChange2 = change2.get(field);
|
|
235
|
+
const cachedComposedFieldChange = crossFieldTable.fieldToContext.get(fieldChange1)?.composedChange;
|
|
236
|
+
if (fieldChange2 === undefined && cachedComposedFieldChange !== undefined) {
|
|
237
|
+
// This can happen if the field was previous processed in `composeFieldWithNoNewChange`.
|
|
238
|
+
// If `change2` does not have a change for this field, then without this check we would
|
|
239
|
+
// lose the composed field change and instead simply have `change1`'s change.
|
|
240
|
+
composedFields.set(field, cachedComposedFieldChange);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
225
243
|
const composedField = fieldChange2 !== undefined
|
|
226
244
|
? this.composeFieldChanges(fieldId, fieldChange1, fieldChange2, genId, crossFieldTable, revisionMetadata)
|
|
227
245
|
: fieldChange1;
|
|
@@ -241,17 +259,16 @@ export class ModularChangeFamily {
|
|
|
241
259
|
* will be added to `crossFieldTable.pendingCompositions.nodeIdsToCompose`.
|
|
242
260
|
*
|
|
243
261
|
* Any fields which had cross-field information sent to them as part of this field composition
|
|
244
|
-
* will be added to
|
|
262
|
+
* will be added to `affectedBaseFields` in `crossFieldTable.pendingCompositions`.
|
|
245
263
|
*
|
|
246
264
|
* Any composed `FieldChange` which is invalidated by new cross-field information will be added to `crossFieldTable.invalidatedFields`.
|
|
247
265
|
*/
|
|
248
266
|
composeFieldChanges(fieldId, change1, change2, idAllocator, crossFieldTable, revisionMetadata) {
|
|
249
267
|
const { fieldKind, changeHandler, change1: change1Normalized, change2: change2Normalized, } = this.normalizeFieldChanges(change1, change2);
|
|
250
|
-
const manager = new
|
|
268
|
+
const manager = new ComposeNodeManagerI(crossFieldTable, fieldId);
|
|
251
269
|
const composedChange = changeHandler.rebaser.compose(change1Normalized, change2Normalized, (child1, child2) => {
|
|
252
270
|
if (child1 !== undefined && child2 !== undefined) {
|
|
253
|
-
|
|
254
|
-
crossFieldTable.pendingCompositions.nodeIdsToCompose.push([child1, child2]);
|
|
271
|
+
addNodesToCompose(crossFieldTable, child1, child2);
|
|
255
272
|
}
|
|
256
273
|
return child1 ?? child2 ?? fail(0xb23 /* Should not compose two undefined nodes */);
|
|
257
274
|
}, idAllocator, manager, revisionMetadata);
|
|
@@ -268,19 +285,18 @@ export class ModularChangeFamily {
|
|
|
268
285
|
crossFieldTable.newFieldToBaseField.set(change2, change1);
|
|
269
286
|
return composedField;
|
|
270
287
|
}
|
|
271
|
-
composeNodesById(
|
|
272
|
-
const nodeChangeset1 = nodeChangeFromId(
|
|
273
|
-
const nodeChangeset2 = nodeChangeFromId(
|
|
288
|
+
composeNodesById(change1, change2, composedNodes, composedNodeToParent, composedAliases, id1, id2, idAllocator, crossFieldTable, revisionMetadata) {
|
|
289
|
+
const nodeChangeset1 = nodeChangeFromId(change1.nodeChanges, change1.nodeAliases, id1);
|
|
290
|
+
const nodeChangeset2 = nodeChangeFromId(change2.nodeChanges, change2.nodeAliases, id2);
|
|
274
291
|
const composedNodeChangeset = this.composeNodeChanges(id1, nodeChangeset1, nodeChangeset2, idAllocator, crossFieldTable, revisionMetadata);
|
|
275
292
|
setInChangeAtomIdMap(composedNodes, id1, composedNodeChangeset);
|
|
276
293
|
if (!areEqualChangeAtomIds(id1, id2)) {
|
|
277
294
|
composedNodes.delete([id2.revision, id2.localId]);
|
|
278
295
|
composedNodeToParent.delete([id2.revision, id2.localId]);
|
|
279
|
-
setInChangeAtomIdMap(
|
|
296
|
+
setInChangeAtomIdMap(composedAliases, id2, id1);
|
|
280
297
|
// We need to delete id1 to avoid forming a cycle in case id1 already had an alias.
|
|
281
|
-
|
|
298
|
+
composedAliases.delete([id1.revision, id1.localId]);
|
|
282
299
|
}
|
|
283
|
-
crossFieldTable.composedNodes.add(composedNodeChangeset);
|
|
284
300
|
}
|
|
285
301
|
composeNodeChanges(nodeId, change1, change2, genId, crossFieldTable, revisionMetadata) {
|
|
286
302
|
// WARNING: this composition logic assumes that we never make compositions of the following form:
|
|
@@ -331,9 +347,14 @@ export class ModularChangeFamily {
|
|
|
331
347
|
}
|
|
332
348
|
const genId = idAllocatorFromMaxId(change.change.maxId ?? -1);
|
|
333
349
|
const crossFieldTable = {
|
|
334
|
-
|
|
350
|
+
change: change.change,
|
|
351
|
+
entries: newChangeAtomIdRangeMap(),
|
|
335
352
|
originalFieldToContext: new Map(),
|
|
353
|
+
invertRevision: revisionForInvert,
|
|
336
354
|
invertedNodeToParent: brand(change.change.nodeToParent.clone()),
|
|
355
|
+
invalidatedFields: new Set(),
|
|
356
|
+
invertedRoots: invertRootTable(change.change, isRollback),
|
|
357
|
+
attachToDetachId: newChangeAtomIdTransform(),
|
|
337
358
|
};
|
|
338
359
|
const { revInfos: oldRevInfos } = getRevInfoFromTaggedChanges([change]);
|
|
339
360
|
const revisionMetadata = revisionMetadataSourceFromInfo(oldRevInfos);
|
|
@@ -349,16 +370,18 @@ export class ModularChangeFamily {
|
|
|
349
370
|
const originalFieldChange = fieldChange.change;
|
|
350
371
|
const context = crossFieldTable.originalFieldToContext.get(fieldChange);
|
|
351
372
|
assert(context !== undefined, 0x851 /* Should have context for every invalidated field */);
|
|
352
|
-
const { invertedField
|
|
353
|
-
const amendedChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.invert(originalFieldChange, isRollback, genId, revisionForInvert, new
|
|
373
|
+
const { invertedField } = context;
|
|
374
|
+
const amendedChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.invert(originalFieldChange, isRollback, genId, revisionForInvert, new InvertNodeManagerI(crossFieldTable, context.fieldId), revisionMetadata);
|
|
354
375
|
invertedField.change = brand(amendedChange);
|
|
355
376
|
}
|
|
356
377
|
}
|
|
357
378
|
const crossFieldKeys = this.makeCrossFieldKeyTable(invertedFields, invertedNodes);
|
|
379
|
+
this.processInvertRenames(crossFieldTable);
|
|
358
380
|
return makeModularChangeset({
|
|
359
381
|
fieldChanges: invertedFields,
|
|
360
382
|
nodeChanges: invertedNodes,
|
|
361
383
|
nodeToParent: crossFieldTable.invertedNodeToParent,
|
|
384
|
+
rootNodes: crossFieldTable.invertedRoots,
|
|
362
385
|
nodeAliases: change.change.nodeAliases,
|
|
363
386
|
crossFieldKeys,
|
|
364
387
|
maxId: genId.getMaxId(),
|
|
@@ -372,7 +395,7 @@ export class ModularChangeFamily {
|
|
|
372
395
|
const invertedFields = new Map();
|
|
373
396
|
for (const [field, fieldChange] of changes) {
|
|
374
397
|
const fieldId = { nodeId: parentId, field };
|
|
375
|
-
const manager = new
|
|
398
|
+
const manager = new InvertNodeManagerI(crossFieldTable, fieldId);
|
|
376
399
|
const invertedChange = getChangeHandler(this.fieldKinds, fieldChange.fieldKind).rebaser.invert(fieldChange.change, isRollback, genId, revisionForInvert, manager, revisionMetadata);
|
|
377
400
|
const invertedFieldChange = {
|
|
378
401
|
...fieldChange,
|
|
@@ -404,6 +427,12 @@ export class ModularChangeFamily {
|
|
|
404
427
|
}
|
|
405
428
|
return inverse;
|
|
406
429
|
}
|
|
430
|
+
processInvertRenames(table) {
|
|
431
|
+
for (const { start: newAttachId, value: originalDetachId, length, } of table.attachToDetachId.entries()) {
|
|
432
|
+
// Note that the detach location is already set in `invertDetach`.
|
|
433
|
+
addNodeRename(table.invertedRoots, originalDetachId, newAttachId, length, undefined);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
407
436
|
rebase(taggedChange, potentiallyConflictedOver, revisionMetadata) {
|
|
408
437
|
// Our current cell ordering scheme in sequences depends on being able to rebase over a change with conflicts.
|
|
409
438
|
// This means that we must rebase over a muted version of the conflicted changeset.
|
|
@@ -414,17 +443,26 @@ export class ModularChangeFamily {
|
|
|
414
443
|
const maxId = Math.max(change.maxId ?? -1, over.change.maxId ?? -1);
|
|
415
444
|
const idState = { maxId };
|
|
416
445
|
const genId = idAllocatorFromState(idState);
|
|
446
|
+
const affectedBaseFields = newTupleBTree();
|
|
447
|
+
const nodesToRebase = [];
|
|
448
|
+
const rebasedNodeToParent = brand(change.nodeToParent.clone());
|
|
449
|
+
const rebaseVersion = Math.max(change.rebaseVersion, over.change.rebaseVersion);
|
|
450
|
+
const rebasedRootNodes = rebaseRoots(change, over.change, affectedBaseFields, nodesToRebase, rebasedNodeToParent, rebaseVersion);
|
|
417
451
|
const crossFieldTable = {
|
|
418
|
-
|
|
452
|
+
rebaseVersion,
|
|
453
|
+
entries: newDetachedEntryMap(),
|
|
419
454
|
newChange: change,
|
|
420
455
|
baseChange: over.change,
|
|
421
456
|
baseFieldToContext: new Map(),
|
|
457
|
+
baseRoots: over.change.rootNodes,
|
|
458
|
+
rebasedRootNodes,
|
|
422
459
|
baseToRebasedNodeId: newTupleBTree(),
|
|
423
460
|
rebasedFields: new Set(),
|
|
424
|
-
rebasedNodeToParent
|
|
425
|
-
|
|
461
|
+
rebasedNodeToParent,
|
|
462
|
+
rebasedDetachLocations: newChangeAtomIdRangeMap(),
|
|
463
|
+
movedDetaches: newChangeAtomIdRangeMap(),
|
|
426
464
|
nodeIdPairs: [],
|
|
427
|
-
affectedBaseFields
|
|
465
|
+
affectedBaseFields,
|
|
428
466
|
fieldsWithUnattachedChild: new Set(),
|
|
429
467
|
};
|
|
430
468
|
const getBaseRevisions = () => revisionInfoFromTaggedChange(over).map((info) => info.revision);
|
|
@@ -434,17 +472,22 @@ export class ModularChangeFamily {
|
|
|
434
472
|
getBaseRevisions,
|
|
435
473
|
};
|
|
436
474
|
const rebasedNodes = brand(change.nodeChanges.clone());
|
|
437
|
-
const rebasedFields = this.rebaseIntersectingFields(crossFieldTable, rebasedNodes, genId, rebaseMetadata);
|
|
438
|
-
this.
|
|
475
|
+
const rebasedFields = this.rebaseIntersectingFields(nodesToRebase, crossFieldTable, rebasedNodes, genId, rebaseMetadata);
|
|
476
|
+
this.rebaseInvalidatedFields(rebasedFields, rebasedNodes, crossFieldTable, rebaseMetadata, genId);
|
|
477
|
+
fixupRebasedDetachLocations(crossFieldTable);
|
|
439
478
|
const constraintState = newConstraintState(change.constraintViolationCount ?? 0);
|
|
440
479
|
const revertConstraintState = newConstraintState(change.constraintViolationCountOnRevert ?? 0);
|
|
441
|
-
this.
|
|
480
|
+
this.updateConstraints(rebasedFields, rebasedNodes, rebasedRootNodes, constraintState, revertConstraintState);
|
|
481
|
+
const fieldsWithRootMoves = getFieldsWithRootMoves(crossFieldTable.rebasedRootNodes, change.nodeAliases);
|
|
482
|
+
const fieldToRootChanges = getFieldToRootChanges(crossFieldTable.rebasedRootNodes, change.nodeAliases);
|
|
442
483
|
const rebased = makeModularChangeset({
|
|
443
|
-
fieldChanges: this.pruneFieldMap(rebasedFields, rebasedNodes),
|
|
484
|
+
fieldChanges: this.pruneFieldMap(rebasedFields, undefined, rebasedNodes, crossFieldTable.rebasedNodeToParent, change.nodeAliases, crossFieldTable.rebasedRootNodes, fieldsWithRootMoves, fieldToRootChanges),
|
|
444
485
|
nodeChanges: rebasedNodes,
|
|
445
486
|
nodeToParent: crossFieldTable.rebasedNodeToParent,
|
|
487
|
+
rootNodes: this.pruneRoots(crossFieldTable.rebasedRootNodes, rebasedNodes, crossFieldTable.rebasedNodeToParent, change.nodeAliases, fieldsWithRootMoves, fieldToRootChanges),
|
|
488
|
+
// TODO: Do we need to include aliases for node changesets added during rebasing?
|
|
446
489
|
nodeAliases: change.nodeAliases,
|
|
447
|
-
crossFieldKeys: crossFieldTable.
|
|
490
|
+
crossFieldKeys: rebaseCrossFieldKeys(change.crossFieldKeys, crossFieldTable.movedDetaches, crossFieldTable.rebasedDetachLocations),
|
|
448
491
|
maxId: idState.maxId,
|
|
449
492
|
revisions: change.revisions,
|
|
450
493
|
constraintViolationCount: constraintState.violationCount,
|
|
@@ -452,15 +495,22 @@ export class ModularChangeFamily {
|
|
|
452
495
|
builds: change.builds,
|
|
453
496
|
destroys: change.destroys,
|
|
454
497
|
refreshers: change.refreshers,
|
|
498
|
+
rebaseVersion,
|
|
455
499
|
});
|
|
500
|
+
// XXX: This is an expensive assert which should be disabled before merging.
|
|
501
|
+
this.validateChangeset(rebased);
|
|
456
502
|
return rebased;
|
|
457
503
|
}
|
|
458
504
|
// This performs a first pass on all fields which have both new and base changes.
|
|
459
505
|
// TODO: Can we also handle additional passes in this method?
|
|
460
|
-
rebaseIntersectingFields(crossFieldTable, rebasedNodes, genId, metadata) {
|
|
506
|
+
rebaseIntersectingFields(rootChanges, crossFieldTable, rebasedNodes, genId, metadata) {
|
|
461
507
|
const change = crossFieldTable.newChange;
|
|
462
508
|
const baseChange = crossFieldTable.baseChange;
|
|
463
509
|
const rebasedFields = this.rebaseFieldMap(change.fieldChanges, baseChange.fieldChanges, undefined, genId, crossFieldTable, metadata);
|
|
510
|
+
for (const [newChildChange, baseChildChange] of rootChanges) {
|
|
511
|
+
const rebasedNode = this.rebaseNodeChange(newChildChange, baseChildChange, genId, crossFieldTable, metadata);
|
|
512
|
+
setInChangeAtomIdMap(rebasedNodes, newChildChange, rebasedNode);
|
|
513
|
+
}
|
|
464
514
|
// This loop processes all fields which have both base and new changes.
|
|
465
515
|
// Note that the call to `rebaseNodeChange` can add entries to `crossFieldTable.nodeIdPairs`.
|
|
466
516
|
for (const [newId, baseId, _attachState] of crossFieldTable.nodeIdPairs) {
|
|
@@ -469,87 +519,85 @@ export class ModularChangeFamily {
|
|
|
469
519
|
}
|
|
470
520
|
return rebasedFields;
|
|
471
521
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
assert(
|
|
481
|
-
if (
|
|
482
|
-
// This field has already been processed because there were changes to rebase.
|
|
483
|
-
continue;
|
|
484
|
-
}
|
|
485
|
-
// This field has no changes in the new changeset, otherwise it would have been added to
|
|
486
|
-
// `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
|
|
487
|
-
const rebaseChild = (child, baseChild, stateChange) => {
|
|
488
|
-
assert(child === undefined, 0x9c3 /* There should be no new changes in this field */);
|
|
522
|
+
rebaseFieldWithoutNewChanges(baseFieldChange, baseFieldId, crossFieldTable, rebasedFields, rebasedNodes, genId, metadata,
|
|
523
|
+
/**
|
|
524
|
+
* The ID of a node in `baseFieldChange` which should be included in the rebased field change.
|
|
525
|
+
*/
|
|
526
|
+
baseNodeId) {
|
|
527
|
+
// This field has no changes in the new changeset, otherwise it would have been added to
|
|
528
|
+
// `crossFieldTable.baseFieldToContext` when processing fields with both base and new changes.
|
|
529
|
+
const rebaseChild = (child, baseChild, stateChange) => {
|
|
530
|
+
assert(child === undefined, 0x9c3 /* There should be no new changes in this field */);
|
|
531
|
+
if (baseChild === undefined || baseNodeId === undefined) {
|
|
489
532
|
return undefined;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
...baseFieldChange,
|
|
494
|
-
change: brand(handler.createEmpty()),
|
|
495
|
-
};
|
|
496
|
-
const rebasedNodeId = baseNodeId !== undefined
|
|
497
|
-
? rebasedNodeIdFromBaseNodeId(crossFieldTable, baseNodeId)
|
|
533
|
+
}
|
|
534
|
+
return areEqualChangeAtomIds(normalizeNodeId(baseChild, crossFieldTable.baseChange.nodeAliases), baseNodeId)
|
|
535
|
+
? baseNodeId
|
|
498
536
|
: undefined;
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
crossFieldTable
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
crossFieldTable.
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
537
|
+
};
|
|
538
|
+
const handler = getChangeHandler(this.fieldKinds, baseFieldChange.fieldKind);
|
|
539
|
+
const fieldChange = {
|
|
540
|
+
...baseFieldChange,
|
|
541
|
+
change: brand(handler.createEmpty()),
|
|
542
|
+
};
|
|
543
|
+
const rebasedNodeId = baseFieldId.nodeId !== undefined
|
|
544
|
+
? rebasedNodeIdFromBaseNodeId(crossFieldTable, baseFieldId.nodeId)
|
|
545
|
+
: undefined;
|
|
546
|
+
const fieldId = { nodeId: rebasedNodeId, field: baseFieldId.field };
|
|
547
|
+
const rebasedField = handler.rebaser.rebase(fieldChange.change, baseFieldChange.change, rebaseChild, genId, new RebaseNodeManagerI(crossFieldTable, fieldId), metadata, crossFieldTable.rebaseVersion);
|
|
548
|
+
const rebasedFieldChange = {
|
|
549
|
+
...baseFieldChange,
|
|
550
|
+
change: brand(rebasedField),
|
|
551
|
+
};
|
|
552
|
+
const context = {
|
|
553
|
+
newChange: fieldChange,
|
|
554
|
+
baseChange: baseFieldChange,
|
|
555
|
+
rebasedChange: rebasedFieldChange,
|
|
556
|
+
fieldId,
|
|
557
|
+
baseNodeIds: newTupleBTree(),
|
|
558
|
+
};
|
|
559
|
+
if (baseNodeId !== undefined) {
|
|
560
|
+
setInChangeAtomIdMap(context.baseNodeIds, baseNodeId, true);
|
|
561
|
+
}
|
|
562
|
+
crossFieldTable.baseFieldToContext.set(baseFieldChange, context);
|
|
563
|
+
crossFieldTable.rebasedFields.add(rebasedFieldChange);
|
|
564
|
+
this.attachRebasedField(rebasedFields, rebasedNodes, crossFieldTable, rebasedFieldChange, fieldId, genId, metadata);
|
|
565
|
+
}
|
|
566
|
+
rebaseInvalidatedFields(rebasedFields, rebasedNodes, crossFieldTable, rebaseMetadata, genId) {
|
|
567
|
+
while (crossFieldTable.affectedBaseFields.size > 0) {
|
|
568
|
+
const baseFields = crossFieldTable.affectedBaseFields.clone();
|
|
569
|
+
crossFieldTable.affectedBaseFields.clear();
|
|
570
|
+
for (const baseFieldIdKey of baseFields.keys()) {
|
|
571
|
+
const baseFieldId = normalizeFieldId(fieldIdFromFieldIdKey(baseFieldIdKey), crossFieldTable.baseChange.nodeAliases);
|
|
572
|
+
const baseField = fieldChangeFromId(crossFieldTable.baseChange, baseFieldId);
|
|
573
|
+
assert(baseField !== undefined, 0x9c2 /* Cross field key registered for empty field */);
|
|
574
|
+
const context = crossFieldTable.baseFieldToContext.get(baseField);
|
|
575
|
+
if (context === undefined) {
|
|
576
|
+
this.rebaseFieldWithoutNewChanges(baseField, baseFieldId, crossFieldTable, rebasedFields, rebasedNodes, genId, rebaseMetadata);
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
this.rebaseInvalidatedField(baseField, crossFieldTable, context, rebaseMetadata, genId);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
533
582
|
}
|
|
534
583
|
}
|
|
535
|
-
rebaseInvalidatedField(baseField, crossFieldTable, rebaseMetadata, genId
|
|
536
|
-
const context = crossFieldTable.baseFieldToContext.get(baseField);
|
|
537
|
-
assert(context !== undefined, 0x852 /* Every field should have a context */);
|
|
584
|
+
rebaseInvalidatedField(baseField, crossFieldTable, context, rebaseMetadata, genId) {
|
|
538
585
|
const { changeHandler, change1: fieldChangeset, change2: baseChangeset, } = this.normalizeFieldChanges(context.newChange, context.baseChange);
|
|
539
586
|
const rebaseChild = (curr, base) => {
|
|
540
587
|
if (curr !== undefined) {
|
|
541
588
|
return curr;
|
|
542
589
|
}
|
|
543
|
-
if (base !== undefined) {
|
|
544
|
-
|
|
545
|
-
if (areEqualChangeAtomIds(base, id)) {
|
|
546
|
-
return base;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
590
|
+
if (base !== undefined && getFromChangeAtomIdMap(context.baseNodeIds, base) === true) {
|
|
591
|
+
return base;
|
|
549
592
|
}
|
|
550
593
|
return undefined;
|
|
551
594
|
};
|
|
552
|
-
|
|
595
|
+
let allowInval = false;
|
|
596
|
+
if (crossFieldTable.fieldsWithUnattachedChild.has(baseField)) {
|
|
597
|
+
crossFieldTable.fieldsWithUnattachedChild.delete(baseField);
|
|
598
|
+
allowInval = true;
|
|
599
|
+
}
|
|
600
|
+
context.rebasedChange.change = brand(changeHandler.rebaser.rebase(fieldChangeset, baseChangeset, rebaseChild, genId, new RebaseNodeManagerI(crossFieldTable, context.fieldId, allowInval), rebaseMetadata, crossFieldTable.rebaseVersion));
|
|
553
601
|
}
|
|
554
602
|
attachRebasedField(rebasedFields, rebasedNodes, table, rebasedField, { nodeId, field: fieldKey }, idAllocator, metadata) {
|
|
555
603
|
if (nodeId === undefined) {
|
|
@@ -558,12 +606,14 @@ export class ModularChangeFamily {
|
|
|
558
606
|
}
|
|
559
607
|
const rebasedNode = getFromChangeAtomIdMap(rebasedNodes, nodeId);
|
|
560
608
|
if (rebasedNode !== undefined) {
|
|
561
|
-
|
|
562
|
-
|
|
609
|
+
const updatedRebasedNode = cloneNodeChangeset(rebasedNode);
|
|
610
|
+
setInChangeAtomIdMap(rebasedNodes, nodeId, updatedRebasedNode);
|
|
611
|
+
if (updatedRebasedNode.fieldChanges === undefined) {
|
|
612
|
+
updatedRebasedNode.fieldChanges = new Map([[fieldKey, rebasedField]]);
|
|
563
613
|
return;
|
|
564
614
|
}
|
|
565
|
-
assert(!
|
|
566
|
-
|
|
615
|
+
assert(!updatedRebasedNode.fieldChanges.has(fieldKey), 0x9c4 /* Expected an empty field */);
|
|
616
|
+
updatedRebasedNode.fieldChanges.set(fieldKey, rebasedField);
|
|
567
617
|
return;
|
|
568
618
|
}
|
|
569
619
|
const newNode = {
|
|
@@ -571,39 +621,51 @@ export class ModularChangeFamily {
|
|
|
571
621
|
};
|
|
572
622
|
setInChangeAtomIdMap(rebasedNodes, nodeId, newNode);
|
|
573
623
|
setInChangeAtomIdMap(table.baseToRebasedNodeId, nodeId, nodeId);
|
|
574
|
-
const
|
|
575
|
-
this.attachRebasedNode(rebasedFields, rebasedNodes, table, nodeId,
|
|
576
|
-
}
|
|
577
|
-
attachRebasedNode(rebasedFields, rebasedNodes, table, baseNodeId,
|
|
578
|
-
|
|
624
|
+
const parentBase = getNodeParent(table.baseChange, nodeId);
|
|
625
|
+
this.attachRebasedNode(rebasedFields, rebasedNodes, table, nodeId, parentBase, idAllocator, metadata);
|
|
626
|
+
}
|
|
627
|
+
attachRebasedNode(rebasedFields, rebasedNodes, table, baseNodeId, parentBase, idAllocator, metadata) {
|
|
628
|
+
if (parentBase.root !== undefined) {
|
|
629
|
+
const renamedRoot = firstAttachIdFromDetachId(table.baseChange.rootNodes, parentBase.root, 1).value;
|
|
630
|
+
const attachField = table.baseChange.crossFieldKeys.getFirst({ ...renamedRoot, target: CrossFieldTarget.Destination }, 1).value;
|
|
631
|
+
if (attachField !== undefined) {
|
|
632
|
+
// The base change inserts this node into `attachField`, so the rebased change should represent this node there.
|
|
633
|
+
const normalizedAttachField = normalizeFieldId(attachField, table.baseChange.nodeAliases);
|
|
634
|
+
const entry = table.entries.getFirst(renamedRoot, 1).value ?? {};
|
|
635
|
+
table.entries.set(renamedRoot, 1, { ...entry, nodeChange: baseNodeId });
|
|
636
|
+
table.affectedBaseFields.set(fieldIdKeyFromFieldId(normalizedAttachField), true);
|
|
637
|
+
this.attachRebasedNode(rebasedFields, rebasedNodes, table, baseNodeId, { field: normalizedAttachField }, idAllocator, metadata);
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
const baseDetachLocation = table.baseChange.rootNodes.detachLocations.getFirst(parentBase.root, 1).value;
|
|
641
|
+
assignRootChange(table.rebasedRootNodes, table.rebasedNodeToParent, renamedRoot, baseNodeId, baseDetachLocation, table.rebaseVersion);
|
|
642
|
+
// We need to make sure the rebased changeset includes the detach location,
|
|
643
|
+
// so we add that field to `affectedBaseFields` unless it's already been processed.
|
|
644
|
+
if (baseDetachLocation !== undefined &&
|
|
645
|
+
!table.baseFieldToContext.has(fieldChangeFromId(table.baseChange, baseDetachLocation))) {
|
|
646
|
+
table.affectedBaseFields.set(fieldIdKeyFromFieldId(baseDetachLocation), true);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
const parentFieldIdBase = parentBase.field;
|
|
652
|
+
const baseFieldChange = fieldChangeFromId(table.baseChange, parentFieldIdBase);
|
|
579
653
|
const rebasedFieldId = rebasedFieldIdFromBaseId(table, parentFieldIdBase);
|
|
580
|
-
setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId, rebasedFieldId);
|
|
654
|
+
setInChangeAtomIdMap(table.rebasedNodeToParent, baseNodeId, { field: rebasedFieldId });
|
|
581
655
|
const context = table.baseFieldToContext.get(baseFieldChange);
|
|
582
656
|
if (context !== undefined) {
|
|
583
657
|
// We've already processed this field.
|
|
584
|
-
// The new child node will be attached in
|
|
585
|
-
|
|
586
|
-
|
|
658
|
+
// The new child node will be attached in the next pass.
|
|
659
|
+
// Note that adding to `fieldsWithUnattachedChild` allows that field to generate new invalidations,
|
|
660
|
+
// so to avoid invalidation cycles we make sure we only add to it once per new unattached child.
|
|
661
|
+
// This is done by checking whether `context.baseNodeIds` already contained `baseNodeId`.
|
|
662
|
+
if (setInChangeAtomIdMap(context.baseNodeIds, baseNodeId, true)) {
|
|
663
|
+
table.fieldsWithUnattachedChild.add(baseFieldChange);
|
|
664
|
+
table.affectedBaseFields.set(fieldIdKeyFromFieldId(parentFieldIdBase), true);
|
|
665
|
+
}
|
|
587
666
|
return;
|
|
588
667
|
}
|
|
589
|
-
|
|
590
|
-
const fieldChange = {
|
|
591
|
-
...baseFieldChange,
|
|
592
|
-
change: brand(handler.createEmpty()),
|
|
593
|
-
};
|
|
594
|
-
const rebasedChangeset = handler.rebaser.rebase(handler.createEmpty(), baseFieldChange.change, (_idNew, idBase) => idBase !== undefined && areEqualChangeAtomIds(idBase, baseNodeId)
|
|
595
|
-
? baseNodeId
|
|
596
|
-
: undefined, idAllocator, new RebaseManager(table, baseFieldChange, rebasedFieldId), metadata);
|
|
597
|
-
const rebasedField = { ...baseFieldChange, change: brand(rebasedChangeset) };
|
|
598
|
-
table.rebasedFields.add(rebasedField);
|
|
599
|
-
table.baseFieldToContext.set(baseFieldChange, {
|
|
600
|
-
newChange: fieldChange,
|
|
601
|
-
baseChange: baseFieldChange,
|
|
602
|
-
rebasedChange: rebasedField,
|
|
603
|
-
fieldId: rebasedFieldId,
|
|
604
|
-
baseNodeIds: [],
|
|
605
|
-
});
|
|
606
|
-
this.attachRebasedField(rebasedFields, rebasedNodes, table, rebasedField, rebasedFieldId, idAllocator, metadata);
|
|
668
|
+
this.rebaseFieldWithoutNewChanges(baseFieldChange, parentFieldIdBase, table, rebasedFields, rebasedNodes, idAllocator, metadata, baseNodeId);
|
|
607
669
|
}
|
|
608
670
|
rebaseFieldMap(change, over, parentId, genId, crossFieldTable, revisionMetadata) {
|
|
609
671
|
const rebasedFields = new Map();
|
|
@@ -621,8 +683,8 @@ export class ModularChangeFamily {
|
|
|
621
683
|
continue;
|
|
622
684
|
}
|
|
623
685
|
const { fieldKind, changeHandler, change1: fieldChangeset, change2: baseChangeset, } = this.normalizeFieldChanges(fieldChange, baseChange);
|
|
624
|
-
const manager = new
|
|
625
|
-
const rebasedField = changeHandler.rebaser.rebase(fieldChangeset, baseChangeset, rebaseChild, genId, manager, revisionMetadata);
|
|
686
|
+
const manager = new RebaseNodeManagerI(crossFieldTable, fieldId);
|
|
687
|
+
const rebasedField = changeHandler.rebaser.rebase(fieldChangeset, baseChangeset, rebaseChild, genId, manager, revisionMetadata, crossFieldTable.rebaseVersion);
|
|
626
688
|
const rebasedFieldChange = {
|
|
627
689
|
fieldKind,
|
|
628
690
|
change: brand(rebasedField),
|
|
@@ -633,15 +695,15 @@ export class ModularChangeFamily {
|
|
|
633
695
|
newChange: fieldChange,
|
|
634
696
|
rebasedChange: rebasedFieldChange,
|
|
635
697
|
fieldId,
|
|
636
|
-
baseNodeIds:
|
|
698
|
+
baseNodeIds: newTupleBTree(),
|
|
637
699
|
});
|
|
638
700
|
crossFieldTable.rebasedFields.add(rebasedFieldChange);
|
|
639
701
|
}
|
|
640
702
|
return rebasedFields;
|
|
641
703
|
}
|
|
642
704
|
rebaseNodeChange(newId, baseId, genId, crossFieldTable, revisionMetadata) {
|
|
643
|
-
const change = nodeChangeFromId(crossFieldTable.newChange.nodeChanges, newId);
|
|
644
|
-
const over = nodeChangeFromId(crossFieldTable.baseChange.nodeChanges, baseId);
|
|
705
|
+
const change = nodeChangeFromId(crossFieldTable.newChange.nodeChanges, crossFieldTable.newChange.nodeAliases, newId);
|
|
706
|
+
const over = nodeChangeFromId(crossFieldTable.baseChange.nodeChanges, crossFieldTable.baseChange.nodeAliases, baseId);
|
|
645
707
|
const baseMap = over?.fieldChanges ?? new Map();
|
|
646
708
|
const fieldChanges = change.fieldChanges !== undefined && over.fieldChanges !== undefined
|
|
647
709
|
? this.rebaseFieldMap(change?.fieldChanges ?? new Map(), baseMap, newId, genId, crossFieldTable, revisionMetadata)
|
|
@@ -659,28 +721,37 @@ export class ModularChangeFamily {
|
|
|
659
721
|
setInChangeAtomIdMap(crossFieldTable.baseToRebasedNodeId, baseId, newId);
|
|
660
722
|
return rebasedChange;
|
|
661
723
|
}
|
|
724
|
+
updateConstraints(rebasedFields, rebasedNodes, rebasedRoots, constraintState, revertConstraintState) {
|
|
725
|
+
this.updateConstraintsForFields(rebasedFields, NodeAttachState.Attached, NodeAttachState.Attached, constraintState, revertConstraintState, rebasedNodes);
|
|
726
|
+
for (const [_detachId, nodeId] of rebasedRoots.nodeChanges.entries()) {
|
|
727
|
+
// XXX: This is incorrect if the rebased changeset attaches the node.
|
|
728
|
+
// Efficiently computing whether the changeset attaches the node would require maintaining a mapping from node ID to attach ID.
|
|
729
|
+
const detachedInOutput = true;
|
|
730
|
+
this.updateConstraintsForNode(nodeId, NodeAttachState.Detached, detachedInOutput ? NodeAttachState.Detached : NodeAttachState.Attached, rebasedNodes, constraintState, revertConstraintState);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
662
733
|
updateConstraintsForFields(fields, parentInputAttachState, parentOutputAttachState, constraintState, revertConstraintState, nodes) {
|
|
663
734
|
for (const field of fields.values()) {
|
|
664
735
|
const handler = getChangeHandler(this.fieldKinds, field.fieldKind);
|
|
665
|
-
for (const [nodeId
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
: NodeAttachState.Attached;
|
|
670
|
-
const isOutputDetached = outputIndex === undefined;
|
|
736
|
+
for (const [nodeId] of handler.getNestedChanges(field.change)) {
|
|
737
|
+
// XXX: This is incorrect if the rebased changeset detaches this node.
|
|
738
|
+
// Efficiently computing whether the changeset detaches the node would require maintaining a mapping from node ID to detach ID.
|
|
739
|
+
const isOutputDetached = false;
|
|
671
740
|
const outputAttachState = parentOutputAttachState === NodeAttachState.Detached || isOutputDetached
|
|
672
741
|
? NodeAttachState.Detached
|
|
673
742
|
: NodeAttachState.Attached;
|
|
674
|
-
this.updateConstraintsForNode(nodeId,
|
|
743
|
+
this.updateConstraintsForNode(nodeId, parentInputAttachState, outputAttachState, nodes, constraintState, revertConstraintState);
|
|
675
744
|
}
|
|
676
745
|
}
|
|
677
746
|
}
|
|
678
747
|
updateConstraintsForNode(nodeId, inputAttachState, outputAttachState, nodes, constraintState, revertConstraintState) {
|
|
679
|
-
const node = nodes
|
|
748
|
+
const node = getFromChangeAtomIdMap(nodes, nodeId) ?? fail(0xb24 /* Unknown node ID */);
|
|
749
|
+
const updatedNode = { ...node };
|
|
750
|
+
setInChangeAtomIdMap(nodes, nodeId, updatedNode);
|
|
680
751
|
if (node.nodeExistsConstraint !== undefined) {
|
|
681
752
|
const isNowViolated = inputAttachState === NodeAttachState.Detached;
|
|
682
753
|
if (node.nodeExistsConstraint.violated !== isNowViolated) {
|
|
683
|
-
|
|
754
|
+
updatedNode.nodeExistsConstraint = {
|
|
684
755
|
...node.nodeExistsConstraint,
|
|
685
756
|
violated: isNowViolated,
|
|
686
757
|
};
|
|
@@ -690,7 +761,7 @@ export class ModularChangeFamily {
|
|
|
690
761
|
if (node.nodeExistsConstraintOnRevert !== undefined) {
|
|
691
762
|
const isNowViolated = outputAttachState === NodeAttachState.Detached;
|
|
692
763
|
if (node.nodeExistsConstraintOnRevert.violated !== isNowViolated) {
|
|
693
|
-
|
|
764
|
+
updatedNode.nodeExistsConstraintOnRevert = {
|
|
694
765
|
...node.nodeExistsConstraintOnRevert,
|
|
695
766
|
violated: isNowViolated,
|
|
696
767
|
};
|
|
@@ -701,35 +772,70 @@ export class ModularChangeFamily {
|
|
|
701
772
|
this.updateConstraintsForFields(node.fieldChanges, inputAttachState, outputAttachState, constraintState, revertConstraintState, nodes);
|
|
702
773
|
}
|
|
703
774
|
}
|
|
704
|
-
pruneFieldMap(changeset, nodeMap) {
|
|
775
|
+
pruneFieldMap(changeset, parentId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges) {
|
|
705
776
|
if (changeset === undefined) {
|
|
706
777
|
return undefined;
|
|
707
778
|
}
|
|
708
779
|
const prunedChangeset = new Map();
|
|
709
780
|
for (const [field, fieldChange] of changeset) {
|
|
710
781
|
const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
|
|
711
|
-
const prunedFieldChangeset = handler.rebaser.prune(fieldChange.change, (nodeId) => this.pruneNodeChange(nodeId, nodeMap));
|
|
712
|
-
|
|
782
|
+
const prunedFieldChangeset = handler.rebaser.prune(fieldChange.change, (nodeId) => this.pruneNodeChange(nodeId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges));
|
|
783
|
+
const fieldId = { nodeId: parentId, field };
|
|
784
|
+
const fieldIdKey = fieldIdKeyFromFieldId(fieldId);
|
|
785
|
+
const rootsWithChanges = fieldsToRootChanges.get(fieldIdKey) ?? [];
|
|
786
|
+
let hasRootWithNodeChange = false;
|
|
787
|
+
for (const rootId of rootsWithChanges) {
|
|
788
|
+
const nodeId = getFromChangeAtomIdMap(roots.nodeChanges, rootId) ?? fail("No root change found");
|
|
789
|
+
const isRootChangeEmpty = this.pruneNodeChange(nodeId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges) === undefined;
|
|
790
|
+
if (isRootChangeEmpty) {
|
|
791
|
+
roots.nodeChanges.delete([rootId.revision, rootId.localId]);
|
|
792
|
+
tryRemoveDetachLocation(roots, rootId, 1);
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
hasRootWithNodeChange = true;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
const hasRootChanges = hasRootWithNodeChange || fieldsWithRootMoves.get(fieldIdKey) === true;
|
|
799
|
+
if (!handler.isEmpty(prunedFieldChangeset) || hasRootChanges) {
|
|
713
800
|
prunedChangeset.set(field, { ...fieldChange, change: brand(prunedFieldChangeset) });
|
|
714
801
|
}
|
|
715
802
|
}
|
|
716
803
|
return prunedChangeset.size > 0 ? prunedChangeset : undefined;
|
|
717
804
|
}
|
|
718
|
-
|
|
719
|
-
const
|
|
805
|
+
pruneRoots(roots, nodeMap, nodeToParent, aliases, fieldsWithRootMoves, fieldsToRootChanges) {
|
|
806
|
+
const pruned = { ...roots, nodeChanges: newTupleBTree() };
|
|
807
|
+
for (const [rootIdKey, nodeId] of roots.nodeChanges.entries()) {
|
|
808
|
+
const rootId = { revision: rootIdKey[0], localId: rootIdKey[1] };
|
|
809
|
+
const hasDetachLocation = roots.detachLocations.getFirst(rootId, 1).value !== undefined;
|
|
810
|
+
// If the root has a detach location it should be pruned by recursion when pruning the field it was detached from.
|
|
811
|
+
const prunedId = hasDetachLocation
|
|
812
|
+
? nodeId
|
|
813
|
+
: this.pruneNodeChange(nodeId, nodeMap, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges);
|
|
814
|
+
if (prunedId !== undefined) {
|
|
815
|
+
pruned.nodeChanges.set(rootIdKey, prunedId);
|
|
816
|
+
}
|
|
817
|
+
tryRemoveDetachLocation(pruned, rootId, 1);
|
|
818
|
+
}
|
|
819
|
+
return pruned;
|
|
820
|
+
}
|
|
821
|
+
pruneNodeChange(nodeId, nodes, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges) {
|
|
822
|
+
const changeset = nodeChangeFromId(nodes, aliases, nodeId);
|
|
720
823
|
const prunedFields = changeset.fieldChanges !== undefined
|
|
721
|
-
? this.pruneFieldMap(changeset.fieldChanges,
|
|
824
|
+
? this.pruneFieldMap(changeset.fieldChanges, nodeId, nodes, nodeToParent, aliases, roots, fieldsWithRootMoves, fieldsToRootChanges)
|
|
722
825
|
: undefined;
|
|
723
826
|
const prunedChange = { ...changeset, fieldChanges: prunedFields };
|
|
724
827
|
if (prunedChange.fieldChanges === undefined) {
|
|
725
828
|
delete prunedChange.fieldChanges;
|
|
726
829
|
}
|
|
727
830
|
if (isEmptyNodeChangeset(prunedChange)) {
|
|
728
|
-
|
|
831
|
+
const nodeIdKey = [nodeId.revision, nodeId.localId];
|
|
832
|
+
// TODO: Shouldn't we also delete all aliases associated with this node?
|
|
833
|
+
nodes.delete(nodeIdKey);
|
|
834
|
+
nodeToParent.delete(nodeIdKey);
|
|
729
835
|
return undefined;
|
|
730
836
|
}
|
|
731
837
|
else {
|
|
732
|
-
setInChangeAtomIdMap(
|
|
838
|
+
setInChangeAtomIdMap(nodes, nodeId, prunedChange);
|
|
733
839
|
return nodeId;
|
|
734
840
|
}
|
|
735
841
|
}
|
|
@@ -743,17 +849,18 @@ export class ModularChangeFamily {
|
|
|
743
849
|
updatedNodes.set([replaceRevision(revision, oldRevisions, newRevision), id], this.replaceNodeChangesetRevisions(nodeChangeset, oldRevisions, newRevision));
|
|
744
850
|
}
|
|
745
851
|
const updatedNodeToParent = newTupleBTree();
|
|
746
|
-
for (const [[revision, id],
|
|
747
|
-
updatedNodeToParent.set([replaceRevision(revision, oldRevisions, newRevision), id],
|
|
852
|
+
for (const [[revision, id], location] of change.nodeToParent.entries()) {
|
|
853
|
+
updatedNodeToParent.set([replaceRevision(revision, oldRevisions, newRevision), id], replaceNodeLocationRevision(normalizeNodeLocation(location, change.nodeAliases), oldRevisions, newRevision));
|
|
748
854
|
}
|
|
749
855
|
const updated = {
|
|
750
856
|
...change,
|
|
751
857
|
fieldChanges: updatedFields,
|
|
752
858
|
nodeChanges: updatedNodes,
|
|
753
859
|
nodeToParent: updatedNodeToParent,
|
|
860
|
+
rootNodes: replaceRootTableRevision(change.rootNodes, oldRevisions, newRevision, change.nodeAliases),
|
|
754
861
|
// We've updated all references to old node IDs, so we no longer need an alias table.
|
|
755
862
|
nodeAliases: newTupleBTree(),
|
|
756
|
-
crossFieldKeys:
|
|
863
|
+
crossFieldKeys: change.crossFieldKeys.mapEntries((key) => replaceCrossFieldKeyRevision(key, oldRevisions, newRevision), (id) => replaceFieldIdRevision(normalizeFieldId(id, change.nodeAliases), oldRevisions, newRevision)),
|
|
757
864
|
};
|
|
758
865
|
if (change.builds !== undefined) {
|
|
759
866
|
updated.builds = replaceIdMapRevisions(change.builds, oldRevisions, newRevision);
|
|
@@ -792,7 +899,7 @@ export class ModularChangeFamily {
|
|
|
792
899
|
return updatedFields;
|
|
793
900
|
}
|
|
794
901
|
makeCrossFieldKeyTable(fields, nodes) {
|
|
795
|
-
const keys =
|
|
902
|
+
const keys = newCrossFieldRangeTable();
|
|
796
903
|
this.populateCrossFieldKeyTableForFieldMap(keys, fields, undefined);
|
|
797
904
|
nodes.forEachPair(([revision, localId], node) => {
|
|
798
905
|
if (node.fieldChanges !== undefined) {
|
|
@@ -820,40 +927,53 @@ export class ModularChangeFamily {
|
|
|
820
927
|
return { fieldKind, change: brand(emptyChange) };
|
|
821
928
|
}
|
|
822
929
|
validateChangeset(change) {
|
|
823
|
-
|
|
930
|
+
const unreachableNodes = brand(change.nodeToParent.clone());
|
|
931
|
+
const unreachableCFKs = change.crossFieldKeys.clone();
|
|
932
|
+
this.validateFieldChanges(change, change.fieldChanges, undefined, unreachableNodes, unreachableCFKs);
|
|
824
933
|
for (const [[revision, localId], node] of change.nodeChanges.entries()) {
|
|
825
934
|
if (node.fieldChanges === undefined) {
|
|
826
935
|
continue;
|
|
827
936
|
}
|
|
828
|
-
const nodeId = { revision, localId };
|
|
829
|
-
|
|
830
|
-
|
|
937
|
+
const nodeId = normalizeNodeId({ revision, localId }, change.nodeAliases);
|
|
938
|
+
this.validateFieldChanges(change, node.fieldChanges, nodeId, unreachableNodes, unreachableCFKs);
|
|
939
|
+
}
|
|
940
|
+
for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
941
|
+
const detachId = { revision: detachIdKey[0], localId: detachIdKey[1] };
|
|
942
|
+
const location = getNodeParent(change, nodeId);
|
|
943
|
+
assert(areEqualChangeAtomIdOpts(location.root, detachId), "Inconsistent node location");
|
|
944
|
+
const normalizedNodeId = normalizeNodeId(nodeId, change.nodeAliases);
|
|
945
|
+
unreachableNodes.delete([normalizedNodeId.revision, normalizedNodeId.localId]);
|
|
946
|
+
const fieldChanges = nodeChangeFromId(change.nodeChanges, change.nodeAliases, nodeId).fieldChanges;
|
|
947
|
+
if (fieldChanges !== undefined) {
|
|
948
|
+
this.validateFieldChanges(change, fieldChanges, normalizedNodeId, unreachableNodes, unreachableCFKs);
|
|
949
|
+
}
|
|
831
950
|
}
|
|
832
|
-
assert(
|
|
951
|
+
assert(unreachableNodes.size === 0, "Unreachable nodes found");
|
|
952
|
+
assert(unreachableCFKs.entries().length === 0, "Unreachable cross-field keys found");
|
|
833
953
|
}
|
|
834
954
|
/**
|
|
835
|
-
* Asserts that each
|
|
836
|
-
*
|
|
955
|
+
* Asserts that each node has a correct entry in `change.nodeToParent`,
|
|
956
|
+
* and each cross field key has a correct entry in `change.crossFieldKeys`.
|
|
837
957
|
* @returns the number of children found.
|
|
838
958
|
*/
|
|
839
|
-
validateFieldChanges(change, fieldChanges, nodeParent) {
|
|
840
|
-
let numChildren = 0;
|
|
959
|
+
validateFieldChanges(change, fieldChanges, nodeParent, unreachableNodes, unreachableCFKs) {
|
|
841
960
|
for (const [field, fieldChange] of fieldChanges.entries()) {
|
|
842
961
|
const fieldId = { nodeId: nodeParent, field };
|
|
843
962
|
const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
|
|
844
963
|
for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
|
|
845
|
-
const parentFieldId =
|
|
846
|
-
assert(areEqualFieldIds(parentFieldId, fieldId), 0xa4e /* Inconsistent node parentage */);
|
|
847
|
-
|
|
964
|
+
const parentFieldId = getNodeParent(change, child);
|
|
965
|
+
assert(parentFieldId.field !== undefined && areEqualFieldIds(parentFieldId.field, fieldId), 0xa4e /* Inconsistent node parentage */);
|
|
966
|
+
unreachableNodes.delete([child.revision, child.localId]);
|
|
848
967
|
}
|
|
849
968
|
for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
|
|
850
969
|
const fields = getFieldsForCrossFieldKey(change, keyRange.key, keyRange.count);
|
|
851
|
-
assert(fields.length
|
|
852
|
-
|
|
853
|
-
areEqualFieldIds(
|
|
970
|
+
assert(fields.length > 0, "Unregistered cross-field key");
|
|
971
|
+
for (const fieldFromLookup of fields) {
|
|
972
|
+
assert(areEqualFieldIds(fieldFromLookup, fieldId), 0xa4f /* Inconsistent cross field keys */);
|
|
973
|
+
}
|
|
974
|
+
unreachableCFKs.delete(keyRange.key, keyRange.count);
|
|
854
975
|
}
|
|
855
976
|
}
|
|
856
|
-
return numChildren;
|
|
857
977
|
}
|
|
858
978
|
getEffectiveChange(change) {
|
|
859
979
|
if (hasConflicts(change)) {
|
|
@@ -867,7 +987,8 @@ export class ModularChangeFamily {
|
|
|
867
987
|
muteChange(change) {
|
|
868
988
|
const muted = {
|
|
869
989
|
...change,
|
|
870
|
-
|
|
990
|
+
rootNodes: muteRootChanges(change.rootNodes),
|
|
991
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
871
992
|
fieldChanges: this.muteFieldChanges(change.fieldChanges),
|
|
872
993
|
nodeChanges: brand(change.nodeChanges.mapValues((v) => this.muteNodeChange(v))),
|
|
873
994
|
};
|
|
@@ -894,27 +1015,12 @@ export class ModularChangeFamily {
|
|
|
894
1015
|
}
|
|
895
1016
|
}
|
|
896
1017
|
ModularChangeFamily.emptyChange = makeModularChangeset();
|
|
897
|
-
function
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
revision: replaceRevision(key.revision, oldRevisions, newRevision),
|
|
904
|
-
localId: key.localId,
|
|
905
|
-
};
|
|
906
|
-
const field = entry.value;
|
|
907
|
-
const normalizedFieldId = normalizeFieldId(field, nodeAliases);
|
|
908
|
-
const updatedNodeId = normalizedFieldId.nodeId !== undefined
|
|
909
|
-
? replaceAtomRevisions(normalizedFieldId.nodeId, oldRevisions, newRevision)
|
|
910
|
-
: undefined;
|
|
911
|
-
const updatedValue = {
|
|
912
|
-
...normalizedFieldId,
|
|
913
|
-
nodeId: updatedNodeId,
|
|
914
|
-
};
|
|
915
|
-
updated.set(updatedKey, entry.length, updatedValue);
|
|
916
|
-
}
|
|
917
|
-
return updated;
|
|
1018
|
+
function replaceCrossFieldKeyRevision(key, oldRevisions, newRevision) {
|
|
1019
|
+
return {
|
|
1020
|
+
target: key.target,
|
|
1021
|
+
revision: replaceRevision(key.revision, oldRevisions, newRevision),
|
|
1022
|
+
localId: key.localId,
|
|
1023
|
+
};
|
|
918
1024
|
}
|
|
919
1025
|
function replaceRevision(revision, oldRevisions, newRevision) {
|
|
920
1026
|
return oldRevisions.has(revision) ? newRevision : revision;
|
|
@@ -960,6 +1066,19 @@ function composeBuildsDestroysAndRefreshers(change1, change2) {
|
|
|
960
1066
|
}
|
|
961
1067
|
}
|
|
962
1068
|
}
|
|
1069
|
+
// 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.
|
|
1070
|
+
if (change1.builds !== undefined && change2.refreshers !== undefined) {
|
|
1071
|
+
for (const [key, chunk] of change2.refreshers.entries()) {
|
|
1072
|
+
assert(chunk.topLevelLength === 1, "Expected refresher chunk to have length 1");
|
|
1073
|
+
const match = change1.builds.getPairOrNextLower(key);
|
|
1074
|
+
if (match !== undefined) {
|
|
1075
|
+
const [buildKey, buildChunk] = match;
|
|
1076
|
+
if (buildKey[0] === key[0] && buildKey[1] + buildChunk.topLevelLength > key[1]) {
|
|
1077
|
+
allRefreshers.delete(key);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
963
1082
|
return { allBuilds, allDestroys, allRefreshers };
|
|
964
1083
|
}
|
|
965
1084
|
function invertBuilds(builds) {
|
|
@@ -984,18 +1103,44 @@ function invertBuilds(builds) {
|
|
|
984
1103
|
* @param fieldKinds - The field kinds to delegate to.
|
|
985
1104
|
*/
|
|
986
1105
|
export function* relevantRemovedRoots(change, fieldKinds) {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
for (const [
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1106
|
+
const rootIds = newChangeAtomIdRangeMap();
|
|
1107
|
+
addAttachesToSet(change, rootIds);
|
|
1108
|
+
addRenamesToSet(change, rootIds);
|
|
1109
|
+
for (const [[revision, localId]] of change.rootNodes.nodeChanges.entries()) {
|
|
1110
|
+
rootIds.set({ revision, localId }, 1, true);
|
|
1111
|
+
}
|
|
1112
|
+
for (const entry of rootIds.entries()) {
|
|
1113
|
+
for (let offset = 0; offset < entry.length; offset++) {
|
|
1114
|
+
const detachId = offsetChangeAtomId(entry.start, offset);
|
|
1115
|
+
yield makeDetachedNodeId(detachId.revision, detachId.localId);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
function addAttachesToSet(change, rootIds) {
|
|
1120
|
+
// This includes each attach which does not have a corresponding detach.
|
|
1121
|
+
for (const entry of change.crossFieldKeys.entries()) {
|
|
1122
|
+
if (entry.start.target !== CrossFieldTarget.Destination) {
|
|
1123
|
+
continue;
|
|
1124
|
+
}
|
|
1125
|
+
for (const detachIdEntry of change.rootNodes.newToOldId.getAll2(entry.start, entry.length)) {
|
|
1126
|
+
const detachId = detachIdEntry.value ?? offsetChangeAtomId(entry.start, detachIdEntry.offset);
|
|
1127
|
+
for (const detachEntry of change.crossFieldKeys.getAll2({ ...detachId, target: CrossFieldTarget.Source }, detachIdEntry.length)) {
|
|
1128
|
+
if (detachEntry.value === undefined) {
|
|
1129
|
+
rootIds.set(offsetChangeAtomId(detachId, detachEntry.offset), detachEntry.length, true);
|
|
1130
|
+
}
|
|
996
1131
|
}
|
|
997
|
-
}
|
|
998
|
-
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
function addRenamesToSet(change, rootIds) {
|
|
1136
|
+
for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
|
|
1137
|
+
for (const detachEntry of change.crossFieldKeys.getAll2({ ...renameEntry.start, target: CrossFieldTarget.Source }, renameEntry.length)) {
|
|
1138
|
+
// We only want to include renames of nodes which are detached in the input context of the changeset.
|
|
1139
|
+
// So if there is a detach for the node, the rename is not relevant.
|
|
1140
|
+
if (detachEntry.value === undefined) {
|
|
1141
|
+
rootIds.set(renameEntry.start, renameEntry.length, true);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
999
1144
|
}
|
|
1000
1145
|
}
|
|
1001
1146
|
/**
|
|
@@ -1047,6 +1192,7 @@ export function updateRefreshers(change, getDetachedNode, removedRoots, requireR
|
|
|
1047
1192
|
nodeChanges,
|
|
1048
1193
|
nodeToParent: change.nodeToParent,
|
|
1049
1194
|
nodeAliases: change.nodeAliases,
|
|
1195
|
+
rootNodes: change.rootNodes,
|
|
1050
1196
|
crossFieldKeys: change.crossFieldKeys,
|
|
1051
1197
|
maxId: maxId,
|
|
1052
1198
|
revisions,
|
|
@@ -1066,11 +1212,24 @@ export function updateRefreshers(change, getDetachedNode, removedRoots, requireR
|
|
|
1066
1212
|
export function intoDelta(taggedChange, fieldKinds) {
|
|
1067
1213
|
const change = taggedChange.change;
|
|
1068
1214
|
const rootDelta = {};
|
|
1069
|
-
const global = [];
|
|
1070
|
-
const rename = [];
|
|
1071
1215
|
if (!hasConflicts(change)) {
|
|
1072
1216
|
// If there are no constraint violations, then tree changes apply.
|
|
1073
|
-
const fieldDeltas = intoDeltaImpl(change.fieldChanges, change.nodeChanges,
|
|
1217
|
+
const fieldDeltas = intoDeltaImpl(change.fieldChanges, change.nodeChanges, change.nodeAliases, fieldKinds);
|
|
1218
|
+
const global = [];
|
|
1219
|
+
for (const [[major, minor], nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
1220
|
+
global.push({
|
|
1221
|
+
id: { major, minor },
|
|
1222
|
+
fields: deltaFromNodeChange(nodeChangeFromId(change.nodeChanges, change.nodeAliases, nodeId), change.nodeChanges, change.nodeAliases, fieldKinds),
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
const rename = [];
|
|
1226
|
+
for (const { start: oldId, value: newId, length, } of change.rootNodes.oldToNewId.entries()) {
|
|
1227
|
+
rename.push({
|
|
1228
|
+
count: length,
|
|
1229
|
+
oldId: makeDetachedNodeId(oldId.revision, oldId.localId),
|
|
1230
|
+
newId: makeDetachedNodeId(newId.revision, newId.localId),
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1074
1233
|
if (fieldDeltas.size > 0) {
|
|
1075
1234
|
rootDelta.fields = fieldDeltas;
|
|
1076
1235
|
}
|
|
@@ -1116,24 +1275,22 @@ function copyDetachedNodes(detachedNodes) {
|
|
|
1116
1275
|
/**
|
|
1117
1276
|
* @param change - The change to convert into a delta.
|
|
1118
1277
|
*/
|
|
1119
|
-
function intoDeltaImpl(change, nodeChanges,
|
|
1278
|
+
function intoDeltaImpl(change, nodeChanges, nodeAliases, fieldKinds) {
|
|
1120
1279
|
const delta = new Map();
|
|
1121
1280
|
for (const [field, fieldChange] of change) {
|
|
1122
|
-
const
|
|
1123
|
-
const nodeChange = nodeChangeFromId(nodeChanges, childChange);
|
|
1124
|
-
return deltaFromNodeChange(nodeChange, nodeChanges,
|
|
1281
|
+
const fieldDelta = getChangeHandler(fieldKinds, fieldChange.fieldKind).intoDelta(fieldChange.change, (childChange) => {
|
|
1282
|
+
const nodeChange = nodeChangeFromId(nodeChanges, nodeAliases, childChange);
|
|
1283
|
+
return deltaFromNodeChange(nodeChange, nodeChanges, nodeAliases, fieldKinds);
|
|
1125
1284
|
});
|
|
1126
|
-
if (
|
|
1127
|
-
delta.set(field,
|
|
1285
|
+
if (fieldDelta !== undefined && fieldDelta.length > 0) {
|
|
1286
|
+
delta.set(field, fieldDelta);
|
|
1128
1287
|
}
|
|
1129
|
-
fieldGlobal?.forEach((c) => global.push(c));
|
|
1130
|
-
fieldRename?.forEach((r) => rename.push(r));
|
|
1131
1288
|
}
|
|
1132
1289
|
return delta;
|
|
1133
1290
|
}
|
|
1134
|
-
function deltaFromNodeChange(change, nodeChanges,
|
|
1291
|
+
function deltaFromNodeChange(change, nodeChanges, nodeAliases, fieldKinds) {
|
|
1135
1292
|
if (change.fieldChanges !== undefined) {
|
|
1136
|
-
return intoDeltaImpl(change.fieldChanges, nodeChanges,
|
|
1293
|
+
return intoDeltaImpl(change.fieldChanges, nodeChanges, nodeAliases, fieldKinds);
|
|
1137
1294
|
}
|
|
1138
1295
|
// TODO: update the API to allow undefined to be returned here
|
|
1139
1296
|
return new Map();
|
|
@@ -1180,30 +1337,22 @@ export function getFieldKind(fieldKinds, kind) {
|
|
|
1180
1337
|
export function getChangeHandler(fieldKinds, kind) {
|
|
1181
1338
|
return getFieldKind(fieldKinds, kind).changeHandler;
|
|
1182
1339
|
}
|
|
1183
|
-
function newComposeTable(baseChange, newChange,
|
|
1340
|
+
function newComposeTable(baseChange, newChange, composedRootNodes, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions) {
|
|
1184
1341
|
return {
|
|
1185
|
-
|
|
1342
|
+
rebaseVersion: Math.max(baseChange.rebaseVersion, newChange.rebaseVersion),
|
|
1343
|
+
entries: newDetachedEntryMap(),
|
|
1186
1344
|
baseChange,
|
|
1187
1345
|
newChange,
|
|
1188
1346
|
fieldToContext: new Map(),
|
|
1189
1347
|
newFieldToBaseField: new Map(),
|
|
1190
1348
|
newToBaseNodeId: newTupleBTree(),
|
|
1191
1349
|
composedNodes: new Set(),
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
};
|
|
1199
|
-
}
|
|
1200
|
-
function newCrossFieldTable() {
|
|
1201
|
-
return {
|
|
1202
|
-
srcTable: newChangeAtomIdRangeMap(),
|
|
1203
|
-
dstTable: newChangeAtomIdRangeMap(),
|
|
1204
|
-
srcDependents: newChangeAtomIdRangeMap(),
|
|
1205
|
-
dstDependents: newChangeAtomIdRangeMap(),
|
|
1206
|
-
invalidatedFields: new Set(),
|
|
1350
|
+
movedNodeToParent: newTupleBTree(),
|
|
1351
|
+
composedRootNodes,
|
|
1352
|
+
movedCrossFieldKeys,
|
|
1353
|
+
removedCrossFieldKeys,
|
|
1354
|
+
renamesToDelete: newChangeAtomIdRangeMap(),
|
|
1355
|
+
pendingCompositions,
|
|
1207
1356
|
};
|
|
1208
1357
|
}
|
|
1209
1358
|
function newConstraintState(violationCount) {
|
|
@@ -1211,147 +1360,354 @@ function newConstraintState(violationCount) {
|
|
|
1211
1360
|
violationCount,
|
|
1212
1361
|
};
|
|
1213
1362
|
}
|
|
1214
|
-
class
|
|
1215
|
-
constructor(
|
|
1216
|
-
this.
|
|
1217
|
-
this.
|
|
1218
|
-
this.allowInval = allowInval;
|
|
1363
|
+
class InvertNodeManagerI {
|
|
1364
|
+
constructor(table, fieldId) {
|
|
1365
|
+
this.table = table;
|
|
1366
|
+
this.fieldId = fieldId;
|
|
1219
1367
|
}
|
|
1220
|
-
|
|
1221
|
-
if (
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1368
|
+
invertDetach(detachId, count, nodeChange, newAttachId) {
|
|
1369
|
+
if (nodeChange !== undefined) {
|
|
1370
|
+
assert(count === 1, "A node change should only affect one node");
|
|
1371
|
+
const attachEntry = firstAttachIdFromDetachId(this.table.change.rootNodes, detachId, count);
|
|
1372
|
+
const attachFieldEntry = this.table.change.crossFieldKeys.getFirst({ target: CrossFieldTarget.Destination, ...attachEntry.value }, count);
|
|
1373
|
+
if (attachFieldEntry.value !== undefined) {
|
|
1374
|
+
setInCrossFieldMap(this.table.entries, attachEntry.value, count, nodeChange);
|
|
1375
|
+
this.table.invalidatedFields.add(fieldChangeFromId(this.table.change, attachFieldEntry.value));
|
|
1376
|
+
}
|
|
1377
|
+
else {
|
|
1378
|
+
assignRootChange(this.table.invertedRoots, this.table.invertedNodeToParent, attachEntry.value, nodeChange, this.fieldId, this.table.change.rebaseVersion);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
if (!areEqualChangeAtomIds(detachId, newAttachId)) {
|
|
1382
|
+
for (const entry of doesChangeAttachNodes(this.table.change.crossFieldKeys, detachId, count)) {
|
|
1383
|
+
if (!entry.value) {
|
|
1384
|
+
this.table.attachToDetachId.set(newAttachId, count, detachId);
|
|
1385
|
+
this.table.invertedRoots.detachLocations.set(detachId, count, this.fieldId);
|
|
1228
1386
|
}
|
|
1229
|
-
firstId = brand(firstId + dependentEntry.length);
|
|
1230
1387
|
}
|
|
1231
1388
|
}
|
|
1232
|
-
setInCrossFieldMap(this.getMap(target), revision, id, count, newValue);
|
|
1233
1389
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1390
|
+
invertAttach(attachId, count) {
|
|
1391
|
+
let countToProcess = count;
|
|
1392
|
+
const detachIdEntry = firstDetachIdFromAttachId(this.table.change.rootNodes, attachId, countToProcess);
|
|
1393
|
+
countToProcess = detachIdEntry.length;
|
|
1394
|
+
const detachEntry = getFirstFieldForCrossFieldKey(this.table.change, { target: CrossFieldTarget.Source, ...detachIdEntry.value }, countToProcess);
|
|
1395
|
+
countToProcess = detachEntry.length;
|
|
1396
|
+
let result;
|
|
1397
|
+
if (detachEntry.value !== undefined) {
|
|
1398
|
+
const moveEntry = this.table.entries.getFirst(attachId, countToProcess);
|
|
1399
|
+
result = { ...moveEntry, value: { nodeChange: moveEntry.value } };
|
|
1240
1400
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
super(table, field, allowInval);
|
|
1257
|
-
this.fieldId = fieldId;
|
|
1258
|
-
}
|
|
1259
|
-
onMoveIn(id) {
|
|
1260
|
-
setInChangeAtomIdMap(this.table.invertedNodeToParent, id, this.fieldId);
|
|
1261
|
-
}
|
|
1262
|
-
moveKey(target, revision, id, count) {
|
|
1263
|
-
assert(false, 0x9c5 /* Keys should not be moved manually during invert */);
|
|
1264
|
-
}
|
|
1265
|
-
get table() {
|
|
1266
|
-
return this.crossFieldTable;
|
|
1401
|
+
else {
|
|
1402
|
+
// This node is detached in the input context of the original change.
|
|
1403
|
+
const nodeIdEntry = rangeQueryChangeAtomIdMap(this.table.change.rootNodes.nodeChanges, detachIdEntry.value, countToProcess);
|
|
1404
|
+
countToProcess = nodeIdEntry.length;
|
|
1405
|
+
result = {
|
|
1406
|
+
value: { nodeChange: nodeIdEntry.value, detachId: detachIdEntry.value },
|
|
1407
|
+
length: countToProcess,
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
if (result.value?.nodeChange !== undefined) {
|
|
1411
|
+
setInChangeAtomIdMap(this.table.invertedNodeToParent, result.value.nodeChange, {
|
|
1412
|
+
field: this.fieldId,
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
return result;
|
|
1267
1416
|
}
|
|
1268
1417
|
}
|
|
1269
|
-
class
|
|
1270
|
-
constructor(table,
|
|
1271
|
-
|
|
1418
|
+
class RebaseNodeManagerI {
|
|
1419
|
+
constructor(table, fieldId, allowInval = true) {
|
|
1420
|
+
this.table = table;
|
|
1272
1421
|
this.fieldId = fieldId;
|
|
1422
|
+
this.allowInval = allowInval;
|
|
1273
1423
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1424
|
+
getNewChangesForBaseAttach(baseAttachId, count) {
|
|
1425
|
+
let countToProcess = count;
|
|
1426
|
+
const detachEntry = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseAttachId, countToProcess);
|
|
1427
|
+
countToProcess = detachEntry.length;
|
|
1428
|
+
const nodeEntry = rangeQueryChangeAtomIdMap(this.table.newChange.rootNodes.nodeChanges, detachEntry.value, countToProcess);
|
|
1429
|
+
countToProcess = nodeEntry.length;
|
|
1430
|
+
const newNodeId = nodeEntry.value;
|
|
1431
|
+
const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(detachEntry.value, countToProcess);
|
|
1432
|
+
countToProcess = newRenameEntry.length;
|
|
1433
|
+
let result;
|
|
1434
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
1435
|
+
if (newNodeId !== undefined || newRenameEntry.value !== undefined) {
|
|
1436
|
+
result = {
|
|
1437
|
+
...newRenameEntry,
|
|
1438
|
+
value: { detachId: newRenameEntry.value, nodeChange: newNodeId },
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
else {
|
|
1442
|
+
// This handles the case where the base changeset has moved these nodes,
|
|
1443
|
+
// meaning they were attached in the input context of the base changeset.
|
|
1444
|
+
result = this.table.entries.getFirst(baseAttachId, countToProcess);
|
|
1445
|
+
}
|
|
1446
|
+
// TODO: Consider moving these two checks into a separate method so that this function has no side effects.
|
|
1447
|
+
if (result.value?.detachId !== undefined) {
|
|
1448
|
+
this.table.rebasedDetachLocations.set(result.value.detachId, result.length, this.fieldId);
|
|
1449
|
+
}
|
|
1450
|
+
if (result.value?.nodeChange !== undefined) {
|
|
1451
|
+
setInChangeAtomIdMap(this.table.rebasedNodeToParent, result.value.nodeChange, {
|
|
1452
|
+
field: this.fieldId,
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
return result;
|
|
1456
|
+
}
|
|
1457
|
+
rebaseOverDetach(baseDetachId, count, newDetachId, nodeChange, cellRename) {
|
|
1458
|
+
let countToProcess = count;
|
|
1459
|
+
const attachIdEntry = firstAttachIdFromDetachId(this.table.baseRoots, baseDetachId, countToProcess);
|
|
1460
|
+
const baseAttachId = attachIdEntry.value;
|
|
1461
|
+
countToProcess = attachIdEntry.length;
|
|
1462
|
+
const attachFieldEntry = getFirstFieldForCrossFieldKey(this.table.baseChange, { ...baseAttachId, target: CrossFieldTarget.Destination }, countToProcess);
|
|
1463
|
+
countToProcess = attachFieldEntry.length;
|
|
1464
|
+
const detachedMoveEntry = this.table.baseChange.rootNodes.outputDetachLocations.getFirst(baseDetachId, countToProcess);
|
|
1465
|
+
countToProcess = detachedMoveEntry.length;
|
|
1466
|
+
const destinationField = attachFieldEntry.value ?? detachedMoveEntry.value;
|
|
1467
|
+
if (destinationField !== undefined) {
|
|
1468
|
+
// The base detach is part of a move (or move of detach location) in the base changeset.
|
|
1469
|
+
setInCrossFieldMap(this.table.entries, baseAttachId, countToProcess, {
|
|
1470
|
+
nodeChange,
|
|
1471
|
+
detachId: newDetachId,
|
|
1472
|
+
cellRename,
|
|
1473
|
+
});
|
|
1474
|
+
if (nodeChange !== undefined || newDetachId !== undefined) {
|
|
1475
|
+
this.invalidateBaseFields([destinationField]);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
if (attachFieldEntry.value === undefined) {
|
|
1479
|
+
// These nodes are detached in the output context of the base changeset.
|
|
1480
|
+
if (nodeChange !== undefined) {
|
|
1481
|
+
assignRootChange(this.table.rebasedRootNodes, this.table.rebasedNodeToParent, baseAttachId, nodeChange, this.fieldId, this.table.rebaseVersion);
|
|
1482
|
+
}
|
|
1483
|
+
if (newDetachId !== undefined) {
|
|
1484
|
+
addNodeRename(this.table.rebasedRootNodes, baseAttachId, newDetachId, countToProcess, this.fieldId);
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
if (newDetachId !== undefined) {
|
|
1488
|
+
this.table.movedDetaches.set(newDetachId, countToProcess, true);
|
|
1489
|
+
}
|
|
1490
|
+
if (countToProcess < count) {
|
|
1491
|
+
const remainingCount = count - countToProcess;
|
|
1492
|
+
const nextDetachId = newDetachId !== undefined
|
|
1493
|
+
? offsetChangeAtomId(newDetachId, countToProcess)
|
|
1494
|
+
: undefined;
|
|
1495
|
+
this.rebaseOverDetach(offsetChangeAtomId(baseDetachId, countToProcess), remainingCount, nextDetachId, nodeChange);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
addDetach(id, count) {
|
|
1499
|
+
this.table.rebasedDetachLocations.set(id, count, this.fieldId);
|
|
1500
|
+
}
|
|
1501
|
+
removeDetach(id, count) {
|
|
1502
|
+
this.table.movedDetaches.set(id, count, true);
|
|
1503
|
+
}
|
|
1504
|
+
doesBaseAttachNodes(id, count) {
|
|
1505
|
+
let countToProcess = count;
|
|
1506
|
+
const attachEntry = getFirstAttachField(this.table.baseChange.crossFieldKeys, id, countToProcess);
|
|
1507
|
+
countToProcess = attachEntry.length;
|
|
1508
|
+
return { start: id, value: attachEntry.value !== undefined, length: countToProcess };
|
|
1509
|
+
}
|
|
1510
|
+
getBaseRename(id, count) {
|
|
1511
|
+
return this.table.baseChange.rootNodes.oldToNewId.getFirst(id, count);
|
|
1512
|
+
}
|
|
1513
|
+
getNewRenameForBaseRename(baseRenameTo, count) {
|
|
1514
|
+
let countToProcess = count;
|
|
1515
|
+
const inputEntry = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseRenameTo, countToProcess);
|
|
1516
|
+
const attachEntry = getFirstAttachField(this.table.baseChange.crossFieldKeys, baseRenameTo, countToProcess);
|
|
1517
|
+
countToProcess = attachEntry.length;
|
|
1518
|
+
if (attachEntry.value !== undefined) {
|
|
1519
|
+
// These nodes are attached in the output context of the base changeset.
|
|
1520
|
+
return { value: undefined, length: countToProcess };
|
|
1521
|
+
}
|
|
1522
|
+
countToProcess = inputEntry.length;
|
|
1523
|
+
const inputId = inputEntry.value;
|
|
1524
|
+
const moveEntry = this.table.entries.getFirst(inputId, countToProcess);
|
|
1525
|
+
countToProcess = moveEntry.length;
|
|
1526
|
+
if (moveEntry.value !== undefined) {
|
|
1527
|
+
return { ...moveEntry, value: moveEntry.value.cellRename ?? moveEntry.value.detachId };
|
|
1528
|
+
}
|
|
1529
|
+
return this.table.newChange.rootNodes.oldToNewId.getFirst(inputId, countToProcess);
|
|
1530
|
+
}
|
|
1531
|
+
invalidateBaseFields(fields) {
|
|
1532
|
+
if (this.allowInval) {
|
|
1533
|
+
for (const fieldId of fields) {
|
|
1534
|
+
this.table.affectedBaseFields.set(fieldIdKeyFromFieldId(fieldId), true);
|
|
1290
1535
|
}
|
|
1291
1536
|
}
|
|
1292
|
-
super.set(target, revision, id, count, newValue, invalidateDependents);
|
|
1293
|
-
}
|
|
1294
|
-
onMoveIn(id) {
|
|
1295
|
-
setInChangeAtomIdMap(this.table.rebasedNodeToParent, id, this.fieldId);
|
|
1296
|
-
}
|
|
1297
|
-
moveKey(target, revision, id, count) {
|
|
1298
|
-
this.table.rebasedCrossFieldKeys.set({ target, revision, localId: id }, count, this.fieldId);
|
|
1299
1537
|
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1538
|
+
}
|
|
1539
|
+
function assignRootChange(table, nodeToParent, detachId, nodeId, detachLocation, rebaseVersion) {
|
|
1540
|
+
assert(rebaseVersion >= 2 || detachLocation !== undefined, "All root changes need a detach location to support compatibility with older client versions");
|
|
1541
|
+
setInChangeAtomIdMap(table.nodeChanges, detachId, nodeId);
|
|
1542
|
+
if (nodeToParent !== undefined) {
|
|
1543
|
+
setInChangeAtomIdMap(nodeToParent, nodeId, { root: detachId });
|
|
1302
1544
|
}
|
|
1545
|
+
table.detachLocations.set(detachId, 1, detachLocation);
|
|
1303
1546
|
}
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
super(table, currentField, allowInval);
|
|
1547
|
+
class ComposeNodeManagerI {
|
|
1548
|
+
constructor(table, fieldId, allowInval = true) {
|
|
1549
|
+
this.table = table;
|
|
1308
1550
|
this.fieldId = fieldId;
|
|
1551
|
+
this.allowInval = allowInval;
|
|
1309
1552
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
if
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1553
|
+
getNewChangesForBaseDetach(baseDetachId, count) {
|
|
1554
|
+
let countToProcess = count;
|
|
1555
|
+
const baseAttachEntry = getFirstFieldForCrossFieldKey(this.table.baseChange, { target: CrossFieldTarget.Destination, ...baseDetachId }, countToProcess);
|
|
1556
|
+
countToProcess = baseAttachEntry.length;
|
|
1557
|
+
let result;
|
|
1558
|
+
if (baseAttachEntry.value !== undefined) {
|
|
1559
|
+
// The base detach was part of a move.
|
|
1560
|
+
// We check if we've previously seen a node change at the move destination.
|
|
1561
|
+
const entry = this.table.entries.getFirst(baseDetachId, countToProcess);
|
|
1562
|
+
result = { value: entry.value, length: entry.length };
|
|
1563
|
+
}
|
|
1564
|
+
else {
|
|
1565
|
+
// The detached nodes are still detached in the new change's input context.
|
|
1566
|
+
const rootEntry = rangeQueryChangeAtomIdMap(this.table.newChange.rootNodes.nodeChanges, baseDetachId, countToProcess);
|
|
1567
|
+
countToProcess = rootEntry.length;
|
|
1568
|
+
const newRenameEntry = this.table.newChange.rootNodes.oldToNewId.getFirst(baseDetachId, countToProcess);
|
|
1569
|
+
countToProcess = newRenameEntry.length;
|
|
1570
|
+
result = {
|
|
1571
|
+
value: { nodeChange: rootEntry.value, detachId: newRenameEntry.value },
|
|
1572
|
+
length: countToProcess,
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
// TODO: Consider moving this to a separate method so that this method can be side-effect free.
|
|
1576
|
+
if (result.value?.nodeChange !== undefined) {
|
|
1577
|
+
setInChangeAtomIdMap(this.table.movedNodeToParent, result.value.nodeChange, {
|
|
1578
|
+
field: this.fieldId,
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1581
|
+
return result;
|
|
1582
|
+
}
|
|
1583
|
+
composeAttachDetach(baseAttachId, newDetachId, count) {
|
|
1584
|
+
let countToProcess = count;
|
|
1585
|
+
const newAttachEntry = getFirstAttachField(this.table.newChange.crossFieldKeys, newDetachId, countToProcess);
|
|
1586
|
+
countToProcess = newAttachEntry.length;
|
|
1587
|
+
// Both changes can have the same ID if they came from inverse changesets.
|
|
1588
|
+
// If the new detach is part of a move,
|
|
1589
|
+
// then both input changesets contain the attach cross-field key for this ID.
|
|
1590
|
+
// The new attach may still exist in the composed changeset so we do not remove it here.
|
|
1591
|
+
// The new attach will typically cancel with a base detach,
|
|
1592
|
+
// in which case the cross-field key will be removed in `composeDetachAttach`.
|
|
1593
|
+
const hasNewAttachWithBaseAttachId = areEqualChangeAtomIds(baseAttachId, newDetachId) && newAttachEntry.value !== undefined;
|
|
1594
|
+
if (!hasNewAttachWithBaseAttachId) {
|
|
1595
|
+
this.table.removedCrossFieldKeys.set({ ...baseAttachId, target: CrossFieldTarget.Destination }, countToProcess, true);
|
|
1596
|
+
}
|
|
1597
|
+
const baseDetachEntry = getFirstDetachField(this.table.baseChange.crossFieldKeys, baseAttachId, countToProcess);
|
|
1598
|
+
countToProcess = baseDetachEntry.length;
|
|
1599
|
+
const baseRootIdEntry = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseAttachId, countToProcess);
|
|
1600
|
+
countToProcess = baseRootIdEntry.length;
|
|
1601
|
+
const baseDetachId = baseRootIdEntry.value;
|
|
1602
|
+
if (baseDetachEntry.value !== undefined) {
|
|
1603
|
+
// The base change moves these nodes.
|
|
1604
|
+
const prevEntry = this.table.entries.getFirst(baseAttachId, baseDetachEntry.length).value ?? {};
|
|
1605
|
+
this.table.entries.set(baseAttachId, baseDetachEntry.length, {
|
|
1606
|
+
...prevEntry,
|
|
1607
|
+
detachId: newDetachId,
|
|
1608
|
+
});
|
|
1609
|
+
// The new detach will replace the base detach, so we remove the key for the base detach, unless they have the same ID.
|
|
1610
|
+
if (!areEqualChangeAtomIds(baseAttachId, newDetachId)) {
|
|
1611
|
+
this.table.removedCrossFieldKeys.set({ ...baseAttachId, target: CrossFieldTarget.Source }, countToProcess, true);
|
|
1612
|
+
}
|
|
1613
|
+
this.table.movedCrossFieldKeys.set({ ...newDetachId, target: CrossFieldTarget.Source }, countToProcess, baseDetachEntry.value);
|
|
1614
|
+
this.invalidateBaseFields([baseDetachEntry.value]);
|
|
1615
|
+
}
|
|
1616
|
+
else {
|
|
1617
|
+
const baseDetachLocationEntry = this.table.baseChange.rootNodes.detachLocations.getFirst(baseDetachId, countToProcess);
|
|
1618
|
+
countToProcess = baseDetachLocationEntry.length;
|
|
1619
|
+
// These nodes were detached in the base change's input context,
|
|
1620
|
+
// so the net effect of the two changes is a rename.
|
|
1621
|
+
appendNodeRename(this.table.composedRootNodes, baseAttachId, newDetachId, baseDetachEntry.length, this.table.baseChange.rootNodes, baseDetachLocationEntry.value ?? this.fieldId);
|
|
1622
|
+
this.table.removedCrossFieldKeys.set({ ...newDetachId, target: CrossFieldTarget.Source }, countToProcess, true);
|
|
1623
|
+
}
|
|
1624
|
+
if (newAttachEntry.value === undefined) {
|
|
1625
|
+
const newOutputDetachLocationEntry = this.table.newChange.rootNodes.outputDetachLocations.getFirst(newDetachId, countToProcess);
|
|
1626
|
+
countToProcess = newOutputDetachLocationEntry.length;
|
|
1627
|
+
this.table.composedRootNodes.outputDetachLocations.set(newDetachId, countToProcess, newOutputDetachLocationEntry.value ?? this.fieldId);
|
|
1628
|
+
}
|
|
1629
|
+
if (countToProcess < count) {
|
|
1630
|
+
const remainingCount = count - countToProcess;
|
|
1631
|
+
this.composeAttachDetach(offsetChangeAtomId(baseAttachId, countToProcess), offsetChangeAtomId(newDetachId, countToProcess), remainingCount);
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
sendNewChangesToBaseSourceLocation(baseAttachId, newChanges) {
|
|
1635
|
+
const { value: baseDetachId } = firstDetachIdFromAttachId(this.table.baseChange.rootNodes, baseAttachId, 1);
|
|
1636
|
+
const detachFields = getFieldsForCrossFieldKey(this.table.baseChange, {
|
|
1637
|
+
...baseDetachId,
|
|
1638
|
+
target: CrossFieldTarget.Source,
|
|
1639
|
+
}, 1);
|
|
1640
|
+
if (detachFields.length > 0) {
|
|
1641
|
+
// The base attach is part of a move in the base changeset.
|
|
1642
|
+
const prevEntry = this.table.entries.getFirst(baseDetachId, 1).value ?? {};
|
|
1643
|
+
this.table.entries.set(baseDetachId, 1, { ...prevEntry, nodeChange: newChanges });
|
|
1644
|
+
if (newChanges !== undefined) {
|
|
1645
|
+
this.invalidateBaseFields(detachFields);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
else {
|
|
1649
|
+
const baseNodeId = getFromChangeAtomIdMap(this.table.baseChange.rootNodes.nodeChanges, baseDetachId);
|
|
1650
|
+
if (baseNodeId !== undefined) {
|
|
1651
|
+
addNodesToCompose(this.table, baseNodeId, newChanges);
|
|
1321
1652
|
}
|
|
1322
1653
|
else {
|
|
1323
|
-
|
|
1324
|
-
target,
|
|
1325
|
-
revision,
|
|
1326
|
-
localId: id,
|
|
1327
|
-
}, count);
|
|
1328
|
-
assert(baseFieldIds.length > 0, 0x9c8 /* Cross field key not registered in base or new change */);
|
|
1329
|
-
for (const baseFieldId of baseFieldIds) {
|
|
1330
|
-
this.table.pendingCompositions.affectedBaseFields.set([baseFieldId.nodeId?.revision, baseFieldId.nodeId?.localId, baseFieldId.field], true);
|
|
1331
|
-
}
|
|
1654
|
+
assignRootChange(this.table.composedRootNodes, this.table.movedNodeToParent, baseDetachId, newChanges, this.fieldId, this.table.rebaseVersion);
|
|
1332
1655
|
}
|
|
1333
1656
|
}
|
|
1334
|
-
super.set(target, revision, id, count, newValue, invalidateDependents);
|
|
1335
|
-
}
|
|
1336
|
-
onMoveIn(id) {
|
|
1337
|
-
setInChangeAtomIdMap(this.table.composedNodeToParent, id, this.fieldId);
|
|
1338
1657
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1658
|
+
areSameNodes(baseDetachId, newAttachId, count) {
|
|
1659
|
+
const renamedDetachEntry = firstAttachIdFromDetachId(this.table.composedRootNodes, baseDetachId, count);
|
|
1660
|
+
const isReattachOfSameNodes = areEqualChangeAtomIds(renamedDetachEntry.value, newAttachId);
|
|
1661
|
+
return { ...renamedDetachEntry, value: isReattachOfSameNodes };
|
|
1662
|
+
}
|
|
1663
|
+
composeDetachAttach(baseDetachId, newAttachId, count, composeToPin) {
|
|
1664
|
+
const areSameEntry = this.areSameNodes(baseDetachId, newAttachId, count);
|
|
1665
|
+
const countToProcess = areSameEntry.length;
|
|
1666
|
+
if (areSameEntry.value) {
|
|
1667
|
+
// These nodes have been moved back to their original location, so the composed changeset should not have any renames for them.
|
|
1668
|
+
// Note that deleting the rename from `this.table.composedRootNodes` would change the result of this method
|
|
1669
|
+
// if it were rerun due to the field being invalidated, so we instead record that the rename should be deleted later.
|
|
1670
|
+
this.table.renamesToDelete.set(baseDetachId, countToProcess, true);
|
|
1671
|
+
}
|
|
1672
|
+
if (composeToPin) {
|
|
1673
|
+
this.table.movedCrossFieldKeys.set({ target: CrossFieldTarget.Source, ...newAttachId }, countToProcess, this.fieldId);
|
|
1674
|
+
if (!areEqualChangeAtomIds(baseDetachId, newAttachId)) {
|
|
1675
|
+
// The pin will have `newAttachId` as both its detach and attach ID.
|
|
1676
|
+
// So we remove `baseDetachId` unless that is equal to the pin's detach ID.
|
|
1677
|
+
this.table.removedCrossFieldKeys.set({ target: CrossFieldTarget.Source, ...baseDetachId }, countToProcess, true);
|
|
1678
|
+
}
|
|
1679
|
+
// Note that while change2 should already have this key, change1 may have a rollback for the same ID in a different location.
|
|
1680
|
+
// In that case, change1's attach should be canceled out by a detach from change2.
|
|
1681
|
+
// Here we make sure that the composed change has the correct location (this field) for the attach ID.
|
|
1682
|
+
this.table.movedCrossFieldKeys.set({ target: CrossFieldTarget.Destination, ...newAttachId }, countToProcess, this.fieldId);
|
|
1683
|
+
}
|
|
1684
|
+
else {
|
|
1685
|
+
this.table.removedCrossFieldKeys.set({ target: CrossFieldTarget.Source, ...baseDetachId }, countToProcess, true);
|
|
1686
|
+
this.table.removedCrossFieldKeys.set({ target: CrossFieldTarget.Destination, ...newAttachId }, countToProcess, true);
|
|
1687
|
+
}
|
|
1688
|
+
if (countToProcess < count) {
|
|
1689
|
+
this.composeAttachDetach(offsetChangeAtomId(baseDetachId, countToProcess), offsetChangeAtomId(newAttachId, countToProcess), count - countToProcess);
|
|
1690
|
+
}
|
|
1341
1691
|
}
|
|
1342
|
-
|
|
1343
|
-
|
|
1692
|
+
invalidateBaseFields(fields) {
|
|
1693
|
+
if (this.allowInval) {
|
|
1694
|
+
for (const fieldId of fields) {
|
|
1695
|
+
this.table.pendingCompositions.affectedBaseFields.set(fieldIdKeyFromFieldId(fieldId), true);
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1344
1698
|
}
|
|
1345
1699
|
}
|
|
1346
1700
|
function makeModularChangeset(props = {
|
|
1347
1701
|
maxId: -1,
|
|
1348
1702
|
}) {
|
|
1349
1703
|
const changeset = {
|
|
1704
|
+
rebaseVersion: props.rebaseVersion ?? 1,
|
|
1350
1705
|
fieldChanges: props.fieldChanges ?? new Map(),
|
|
1351
1706
|
nodeChanges: props.nodeChanges ?? newTupleBTree(),
|
|
1707
|
+
rootNodes: props.rootNodes ?? newRootTable(),
|
|
1352
1708
|
nodeToParent: props.nodeToParent ?? newTupleBTree(),
|
|
1353
1709
|
nodeAliases: props.nodeAliases ?? newTupleBTree(),
|
|
1354
|
-
crossFieldKeys: props.crossFieldKeys ??
|
|
1710
|
+
crossFieldKeys: props.crossFieldKeys ?? newCrossFieldRangeTable(),
|
|
1355
1711
|
};
|
|
1356
1712
|
if (props.revisions !== undefined && props.revisions.length > 0) {
|
|
1357
1713
|
changeset.revisions = props.revisions;
|
|
@@ -1384,6 +1740,9 @@ export class ModularEditBuilder extends EditBuilder {
|
|
|
1384
1740
|
this.transactionDepth = 0;
|
|
1385
1741
|
this.idAllocator = idAllocatorFromMaxId();
|
|
1386
1742
|
}
|
|
1743
|
+
isInTransaction() {
|
|
1744
|
+
return this.transactionDepth > 0;
|
|
1745
|
+
}
|
|
1387
1746
|
enterTransaction() {
|
|
1388
1747
|
this.transactionDepth += 1;
|
|
1389
1748
|
if (this.transactionDepth === 1) {
|
|
@@ -1434,7 +1793,8 @@ export class ModularEditBuilder extends EditBuilder {
|
|
|
1434
1793
|
fieldChange: { fieldKind, change },
|
|
1435
1794
|
nodeChanges: newTupleBTree(),
|
|
1436
1795
|
nodeToParent: newTupleBTree(),
|
|
1437
|
-
crossFieldKeys:
|
|
1796
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
1797
|
+
rootNodes: newRootTable(),
|
|
1438
1798
|
idAllocator: this.idAllocator,
|
|
1439
1799
|
localCrossFieldKeys,
|
|
1440
1800
|
revision,
|
|
@@ -1453,6 +1813,7 @@ export class ModularEditBuilder extends EditBuilder {
|
|
|
1453
1813
|
? makeModularChangeset({
|
|
1454
1814
|
maxId: this.idAllocator.getMaxId(),
|
|
1455
1815
|
builds: change.builds,
|
|
1816
|
+
rootNodes: renameTableFromRenameDescriptions(change.renames ?? []),
|
|
1456
1817
|
revisions: [{ revision: change.revision }],
|
|
1457
1818
|
})
|
|
1458
1819
|
: buildModularChangesetFromField({
|
|
@@ -1463,7 +1824,8 @@ export class ModularEditBuilder extends EditBuilder {
|
|
|
1463
1824
|
},
|
|
1464
1825
|
nodeChanges: newTupleBTree(),
|
|
1465
1826
|
nodeToParent: newTupleBTree(),
|
|
1466
|
-
crossFieldKeys:
|
|
1827
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
1828
|
+
rootNodes: newRootTable(),
|
|
1467
1829
|
idAllocator: this.idAllocator,
|
|
1468
1830
|
localCrossFieldKeys: getChangeHandler(this.fieldKinds, change.fieldKind).getCrossFieldKeys(change.change),
|
|
1469
1831
|
revision: change.revision,
|
|
@@ -1492,7 +1854,8 @@ export class ModularEditBuilder extends EditBuilder {
|
|
|
1492
1854
|
nodeChange,
|
|
1493
1855
|
nodeChanges: newTupleBTree(),
|
|
1494
1856
|
nodeToParent: newTupleBTree(),
|
|
1495
|
-
crossFieldKeys:
|
|
1857
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
1858
|
+
rootNodes: newRootTable(),
|
|
1496
1859
|
idAllocator: this.idAllocator,
|
|
1497
1860
|
revision,
|
|
1498
1861
|
}), revision));
|
|
@@ -1506,23 +1869,27 @@ export class ModularEditBuilder extends EditBuilder {
|
|
|
1506
1869
|
nodeChange,
|
|
1507
1870
|
nodeChanges: newTupleBTree(),
|
|
1508
1871
|
nodeToParent: newTupleBTree(),
|
|
1509
|
-
crossFieldKeys:
|
|
1872
|
+
crossFieldKeys: newCrossFieldRangeTable(),
|
|
1873
|
+
rootNodes: newRootTable(),
|
|
1510
1874
|
idAllocator: this.idAllocator,
|
|
1511
1875
|
revision,
|
|
1512
1876
|
}), revision));
|
|
1513
1877
|
}
|
|
1514
1878
|
}
|
|
1515
|
-
function buildModularChangesetFromField(props) {
|
|
1516
|
-
const { path, fieldChange, nodeChanges, nodeToParent, crossFieldKeys, idAllocator = idAllocatorFromMaxId(), localCrossFieldKeys = [], childId, revision, } = props;
|
|
1879
|
+
export function buildModularChangesetFromField(props) {
|
|
1880
|
+
const { path, fieldChange, nodeChanges, nodeToParent, crossFieldKeys, rootNodes, idAllocator = idAllocatorFromMaxId(), localCrossFieldKeys = [], childId, revision, } = props;
|
|
1517
1881
|
const fieldChanges = new Map([[path.field, fieldChange]]);
|
|
1518
1882
|
if (path.parent === undefined) {
|
|
1883
|
+
const field = { nodeId: undefined, field: path.field };
|
|
1519
1884
|
for (const { key, count } of localCrossFieldKeys) {
|
|
1520
|
-
crossFieldKeys.set(key, count,
|
|
1885
|
+
crossFieldKeys.set(key, count, field);
|
|
1521
1886
|
}
|
|
1522
1887
|
if (childId !== undefined) {
|
|
1523
1888
|
setInChangeAtomIdMap(nodeToParent, childId, {
|
|
1524
|
-
|
|
1525
|
-
|
|
1889
|
+
field: {
|
|
1890
|
+
nodeId: undefined,
|
|
1891
|
+
field: path.field,
|
|
1892
|
+
},
|
|
1526
1893
|
});
|
|
1527
1894
|
}
|
|
1528
1895
|
return makeModularChangeset({
|
|
@@ -1530,6 +1897,7 @@ function buildModularChangesetFromField(props) {
|
|
|
1530
1897
|
nodeChanges,
|
|
1531
1898
|
nodeToParent,
|
|
1532
1899
|
crossFieldKeys,
|
|
1900
|
+
rootNodes,
|
|
1533
1901
|
maxId: idAllocator.getMaxId(),
|
|
1534
1902
|
revisions: [{ revision }],
|
|
1535
1903
|
});
|
|
@@ -1538,13 +1906,13 @@ function buildModularChangesetFromField(props) {
|
|
|
1538
1906
|
fieldChanges,
|
|
1539
1907
|
};
|
|
1540
1908
|
const parentId = { localId: brand(idAllocator.allocate()), revision };
|
|
1909
|
+
const fieldId = { nodeId: parentId, field: path.field };
|
|
1541
1910
|
for (const { key, count } of localCrossFieldKeys) {
|
|
1542
1911
|
crossFieldKeys.set(key, count, { nodeId: parentId, field: path.field });
|
|
1543
1912
|
}
|
|
1544
1913
|
if (childId !== undefined) {
|
|
1545
1914
|
setInChangeAtomIdMap(nodeToParent, childId, {
|
|
1546
|
-
|
|
1547
|
-
field: path.field,
|
|
1915
|
+
field: fieldId,
|
|
1548
1916
|
});
|
|
1549
1917
|
}
|
|
1550
1918
|
return buildModularChangesetFromNode({
|
|
@@ -1553,6 +1921,7 @@ function buildModularChangesetFromField(props) {
|
|
|
1553
1921
|
nodeChanges,
|
|
1554
1922
|
nodeToParent,
|
|
1555
1923
|
crossFieldKeys,
|
|
1924
|
+
rootNodes,
|
|
1556
1925
|
idAllocator,
|
|
1557
1926
|
revision,
|
|
1558
1927
|
nodeId: parentId,
|
|
@@ -1561,20 +1930,40 @@ function buildModularChangesetFromField(props) {
|
|
|
1561
1930
|
function buildModularChangesetFromNode(props) {
|
|
1562
1931
|
const { path, nodeId = { localId: brand(props.idAllocator.allocate()), revision: props.revision }, } = props;
|
|
1563
1932
|
setInChangeAtomIdMap(props.nodeChanges, nodeId, props.nodeChange);
|
|
1564
|
-
|
|
1565
|
-
[path.
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1933
|
+
if (isDetachedUpPathRoot(path)) {
|
|
1934
|
+
props.rootNodes.nodeChanges.set([path.detachedNodeId.major, brand(path.detachedNodeId.minor)], nodeId);
|
|
1935
|
+
return makeModularChangeset({
|
|
1936
|
+
rootNodes: props.rootNodes,
|
|
1937
|
+
nodeChanges: props.nodeChanges,
|
|
1938
|
+
nodeToParent: props.nodeToParent,
|
|
1939
|
+
crossFieldKeys: props.crossFieldKeys,
|
|
1940
|
+
maxId: props.idAllocator.getMaxId(),
|
|
1941
|
+
revisions: [{ revision: props.revision }],
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
else {
|
|
1945
|
+
const fieldChangeset = genericFieldKind.changeHandler.editor.buildChildChanges([
|
|
1946
|
+
[path.parentIndex, nodeId],
|
|
1947
|
+
]);
|
|
1948
|
+
const fieldChange = {
|
|
1949
|
+
fieldKind: genericFieldKind.identifier,
|
|
1950
|
+
change: fieldChangeset,
|
|
1951
|
+
};
|
|
1952
|
+
return buildModularChangesetFromField({
|
|
1953
|
+
...props,
|
|
1954
|
+
path: { parent: path.parent, field: path.parentField },
|
|
1955
|
+
fieldChange,
|
|
1956
|
+
localCrossFieldKeys: [],
|
|
1957
|
+
childId: nodeId,
|
|
1958
|
+
});
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
function renameTableFromRenameDescriptions(renames) {
|
|
1962
|
+
const table = newRootTable();
|
|
1963
|
+
for (const rename of renames) {
|
|
1964
|
+
addNodeRename(table, rename.oldId, rename.newId, rename.count, rename.detachLocation);
|
|
1965
|
+
}
|
|
1966
|
+
return table;
|
|
1578
1967
|
}
|
|
1579
1968
|
function getRevInfoFromTaggedChanges(changes) {
|
|
1580
1969
|
let maxId = -1;
|
|
@@ -1584,20 +1973,6 @@ function getRevInfoFromTaggedChanges(changes) {
|
|
|
1584
1973
|
maxId = Math.max(change.maxId ?? -1, maxId);
|
|
1585
1974
|
revInfos.push(...revisionInfoFromTaggedChange(taggedChange));
|
|
1586
1975
|
}
|
|
1587
|
-
const revisions = new Set();
|
|
1588
|
-
const rolledBackRevisions = [];
|
|
1589
|
-
for (const info of revInfos) {
|
|
1590
|
-
revisions.add(info.revision);
|
|
1591
|
-
if (info.rollbackOf !== undefined) {
|
|
1592
|
-
rolledBackRevisions.push(info.rollbackOf);
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
rolledBackRevisions.reverse();
|
|
1596
|
-
for (const revision of rolledBackRevisions) {
|
|
1597
|
-
if (!revisions.has(revision)) {
|
|
1598
|
-
revInfos.push({ revision });
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
1976
|
return { maxId: brand(maxId), revInfos };
|
|
1602
1977
|
}
|
|
1603
1978
|
function revisionInfoFromTaggedChange(taggedChange) {
|
|
@@ -1614,15 +1989,16 @@ function revisionInfoFromTaggedChange(taggedChange) {
|
|
|
1614
1989
|
}
|
|
1615
1990
|
return revInfos;
|
|
1616
1991
|
}
|
|
1617
|
-
function fieldChangeFromId(
|
|
1618
|
-
const
|
|
1992
|
+
function fieldChangeFromId(change, id) {
|
|
1993
|
+
const fieldId = normalizeFieldId(id, change.nodeAliases);
|
|
1994
|
+
const fieldMap = fieldMapFromNodeId(change.fieldChanges, change.nodeChanges, change.nodeAliases, fieldId.nodeId);
|
|
1619
1995
|
return fieldMap.get(id.field) ?? fail(0xb25 /* No field exists for the given ID */);
|
|
1620
1996
|
}
|
|
1621
|
-
function fieldMapFromNodeId(rootFieldMap, nodes, nodeId) {
|
|
1997
|
+
function fieldMapFromNodeId(rootFieldMap, nodes, aliases, nodeId) {
|
|
1622
1998
|
if (nodeId === undefined) {
|
|
1623
1999
|
return rootFieldMap;
|
|
1624
2000
|
}
|
|
1625
|
-
const node = nodeChangeFromId(nodes, nodeId);
|
|
2001
|
+
const node = nodeChangeFromId(nodes, aliases, nodeId);
|
|
1626
2002
|
assert(node.fieldChanges !== undefined, 0x9c9 /* Expected node to have field changes */);
|
|
1627
2003
|
return node.fieldChanges;
|
|
1628
2004
|
}
|
|
@@ -1635,8 +2011,9 @@ function rebasedFieldIdFromBaseId(table, baseId) {
|
|
|
1635
2011
|
function rebasedNodeIdFromBaseNodeId(table, baseId) {
|
|
1636
2012
|
return getFromChangeAtomIdMap(table.baseToRebasedNodeId, baseId) ?? baseId;
|
|
1637
2013
|
}
|
|
1638
|
-
function nodeChangeFromId(nodes, id) {
|
|
1639
|
-
const
|
|
2014
|
+
function nodeChangeFromId(nodes, aliases, id) {
|
|
2015
|
+
const normalizedId = normalizeNodeId(id, aliases);
|
|
2016
|
+
const node = getFromChangeAtomIdMap(nodes, normalizedId);
|
|
1640
2017
|
assert(node !== undefined, 0x9ca /* Unknown node ID */);
|
|
1641
2018
|
return node;
|
|
1642
2019
|
}
|
|
@@ -1644,12 +2021,20 @@ function fieldIdFromFieldIdKey([revision, localId, field]) {
|
|
|
1644
2021
|
const nodeId = localId !== undefined ? { revision, localId } : undefined;
|
|
1645
2022
|
return { nodeId, field };
|
|
1646
2023
|
}
|
|
2024
|
+
function fieldIdKeyFromFieldId(fieldId) {
|
|
2025
|
+
return [fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field];
|
|
2026
|
+
}
|
|
1647
2027
|
function cloneNodeChangeset(nodeChangeset) {
|
|
1648
2028
|
if (nodeChangeset.fieldChanges !== undefined) {
|
|
1649
2029
|
return { ...nodeChangeset, fieldChanges: new Map(nodeChangeset.fieldChanges) };
|
|
1650
2030
|
}
|
|
1651
2031
|
return { ...nodeChangeset };
|
|
1652
2032
|
}
|
|
2033
|
+
function replaceNodeLocationRevision(location, oldRevisions, newRevision) {
|
|
2034
|
+
return location.field !== undefined
|
|
2035
|
+
? { field: replaceFieldIdRevision(location.field, oldRevisions, newRevision) }
|
|
2036
|
+
: { root: replaceAtomRevisions(location.root, oldRevisions, newRevision) };
|
|
2037
|
+
}
|
|
1653
2038
|
function replaceFieldIdRevision(fieldId, oldRevisions, newRevision) {
|
|
1654
2039
|
if (fieldId.nodeId === undefined) {
|
|
1655
2040
|
return fieldId;
|
|
@@ -1659,16 +2044,33 @@ function replaceFieldIdRevision(fieldId, oldRevisions, newRevision) {
|
|
|
1659
2044
|
nodeId: replaceAtomRevisions(fieldId.nodeId, oldRevisions, newRevision),
|
|
1660
2045
|
};
|
|
1661
2046
|
}
|
|
1662
|
-
export function
|
|
1663
|
-
const
|
|
1664
|
-
|
|
1665
|
-
|
|
2047
|
+
export function getNodeParent(changeset, nodeId) {
|
|
2048
|
+
const normalizedNodeId = normalizeNodeId(nodeId, changeset.nodeAliases);
|
|
2049
|
+
const location = getFromChangeAtomIdMap(changeset.nodeToParent, normalizedNodeId);
|
|
2050
|
+
assert(location !== undefined, 0x9cb /* Parent field should be defined */);
|
|
2051
|
+
if (location.field !== undefined) {
|
|
2052
|
+
return { field: normalizeFieldId(location.field, changeset.nodeAliases) };
|
|
2053
|
+
}
|
|
2054
|
+
return location;
|
|
1666
2055
|
}
|
|
1667
2056
|
function getFieldsForCrossFieldKey(changeset, key, count) {
|
|
1668
2057
|
return changeset.crossFieldKeys
|
|
1669
2058
|
.getAll(key, count)
|
|
1670
2059
|
.map(({ value: fieldId }) => normalizeFieldId(fieldId, changeset.nodeAliases));
|
|
1671
2060
|
}
|
|
2061
|
+
function getFirstFieldForCrossFieldKey(changeset, key, count) {
|
|
2062
|
+
const result = changeset.crossFieldKeys.getFirst(key, count);
|
|
2063
|
+
if (result.value === undefined) {
|
|
2064
|
+
return result;
|
|
2065
|
+
}
|
|
2066
|
+
return { ...result, value: normalizeFieldId(result.value, changeset.nodeAliases) };
|
|
2067
|
+
}
|
|
2068
|
+
function normalizeNodeLocation(location, nodeAliases) {
|
|
2069
|
+
if (location.field !== undefined) {
|
|
2070
|
+
return { field: normalizeFieldId(location.field, nodeAliases) };
|
|
2071
|
+
}
|
|
2072
|
+
return location;
|
|
2073
|
+
}
|
|
1672
2074
|
// This is only exported for use in test utilities.
|
|
1673
2075
|
export function normalizeFieldId(fieldId, nodeAliases) {
|
|
1674
2076
|
return fieldId.nodeId !== undefined
|
|
@@ -1678,8 +2080,9 @@ export function normalizeFieldId(fieldId, nodeAliases) {
|
|
|
1678
2080
|
/**
|
|
1679
2081
|
* @returns The canonical form of nodeId, according to nodeAliases
|
|
1680
2082
|
*/
|
|
1681
|
-
function normalizeNodeId(nodeId, nodeAliases) {
|
|
2083
|
+
export function normalizeNodeId(nodeId, nodeAliases) {
|
|
1682
2084
|
let currentId = nodeId;
|
|
2085
|
+
let cycleProbeId = nodeId;
|
|
1683
2086
|
// eslint-disable-next-line no-constant-condition
|
|
1684
2087
|
while (true) {
|
|
1685
2088
|
const dealiased = getFromChangeAtomIdMap(nodeAliases, currentId);
|
|
@@ -1687,18 +2090,441 @@ function normalizeNodeId(nodeId, nodeAliases) {
|
|
|
1687
2090
|
return currentId;
|
|
1688
2091
|
}
|
|
1689
2092
|
currentId = dealiased;
|
|
2093
|
+
if (cycleProbeId !== undefined) {
|
|
2094
|
+
cycleProbeId = getFromChangeAtomIdMap(nodeAliases, cycleProbeId);
|
|
2095
|
+
}
|
|
2096
|
+
if (cycleProbeId !== undefined) {
|
|
2097
|
+
cycleProbeId = getFromChangeAtomIdMap(nodeAliases, cycleProbeId);
|
|
2098
|
+
}
|
|
2099
|
+
assert(!areEqualChangeAtomIdOpts(cycleProbeId, currentId), "Alias cycle detected");
|
|
1690
2100
|
}
|
|
1691
2101
|
}
|
|
1692
2102
|
function hasConflicts(change) {
|
|
1693
2103
|
return (change.constraintViolationCount ?? 0) > 0;
|
|
1694
2104
|
}
|
|
1695
|
-
function getFromChangeAtomIdMap(map, id) {
|
|
1696
|
-
return map.get([id.revision, id.localId]);
|
|
1697
|
-
}
|
|
1698
|
-
function setInChangeAtomIdMap(map, id, value) {
|
|
1699
|
-
map.set([id.revision, id.localId], value);
|
|
1700
|
-
}
|
|
1701
2105
|
function areEqualFieldIds(a, b) {
|
|
1702
2106
|
return areEqualChangeAtomIdOpts(a.nodeId, b.nodeId) && a.field === b.field;
|
|
1703
2107
|
}
|
|
2108
|
+
function firstAttachIdFromDetachId(roots, detachId, count) {
|
|
2109
|
+
const result = roots.oldToNewId.getFirst(detachId, count);
|
|
2110
|
+
return { ...result, value: result.value ?? detachId };
|
|
2111
|
+
}
|
|
2112
|
+
function firstDetachIdFromAttachId(roots, attachId, count) {
|
|
2113
|
+
const result = roots.newToOldId.getFirst(attachId, count);
|
|
2114
|
+
return { ...result, start: attachId, value: result.value ?? attachId };
|
|
2115
|
+
}
|
|
2116
|
+
function rebaseCrossFieldKeys(sourceTable, movedDetaches, newDetachLocations) {
|
|
2117
|
+
const rebasedTable = sourceTable.clone();
|
|
2118
|
+
for (const entry of movedDetaches.entries()) {
|
|
2119
|
+
rebasedTable.delete({ ...entry.start, target: CrossFieldTarget.Source }, entry.length);
|
|
2120
|
+
}
|
|
2121
|
+
for (const entry of newDetachLocations.entries()) {
|
|
2122
|
+
rebasedTable.set({ ...entry.start, target: CrossFieldTarget.Source }, entry.length, entry.value);
|
|
2123
|
+
}
|
|
2124
|
+
return rebasedTable;
|
|
2125
|
+
}
|
|
2126
|
+
export function newRootTable() {
|
|
2127
|
+
return {
|
|
2128
|
+
newToOldId: newChangeAtomIdTransform(),
|
|
2129
|
+
oldToNewId: newChangeAtomIdTransform(),
|
|
2130
|
+
nodeChanges: newTupleBTree(),
|
|
2131
|
+
detachLocations: newChangeAtomIdRangeMap(),
|
|
2132
|
+
outputDetachLocations: newChangeAtomIdRangeMap(),
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
function rebaseRoots(change, base, affectedBaseFields, nodesToRebase, rebasedNodeToParent, rebaseVersion) {
|
|
2136
|
+
const rebasedRoots = newRootTable();
|
|
2137
|
+
for (const renameEntry of change.rootNodes.oldToNewId.entries()) {
|
|
2138
|
+
rebaseRename(change.rootNodes, rebasedRoots, renameEntry, base, affectedBaseFields);
|
|
2139
|
+
}
|
|
2140
|
+
for (const [detachIdKey, nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
2141
|
+
const changes = base.rootNodes.nodeChanges.get(detachIdKey);
|
|
2142
|
+
if (changes !== undefined) {
|
|
2143
|
+
nodesToRebase.push([nodeId, changes]);
|
|
2144
|
+
}
|
|
2145
|
+
const detachId = makeChangeAtomId(detachIdKey[1], detachIdKey[0]);
|
|
2146
|
+
const attachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
|
|
2147
|
+
const baseAttachEntry = base.crossFieldKeys.getFirst({ target: CrossFieldTarget.Destination, ...attachId }, 1);
|
|
2148
|
+
if (baseAttachEntry.value !== undefined) {
|
|
2149
|
+
affectedBaseFields.set(fieldIdKeyFromFieldId(baseAttachEntry.value), true);
|
|
2150
|
+
rebasedNodeToParent.delete(detachIdKey);
|
|
2151
|
+
}
|
|
2152
|
+
else {
|
|
2153
|
+
const renamedDetachId = firstAttachIdFromDetachId(base.rootNodes, detachId, 1).value;
|
|
2154
|
+
const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(renamedDetachId, 1).value;
|
|
2155
|
+
if (baseOutputDetachLocation !== undefined) {
|
|
2156
|
+
affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
|
|
2157
|
+
}
|
|
2158
|
+
const detachLocation = baseOutputDetachLocation ??
|
|
2159
|
+
change.rootNodes.detachLocations.getFirst(detachId, 1).value;
|
|
2160
|
+
// Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
|
|
2161
|
+
// We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
|
|
2162
|
+
assignRootChange(rebasedRoots, rebasedNodeToParent, renamedDetachId, nodeId, detachLocation, rebaseVersion);
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
for (const entry of change.rootNodes.outputDetachLocations.entries()) {
|
|
2166
|
+
rebasedRoots.outputDetachLocations.set(entry.start, entry.length, entry.value);
|
|
2167
|
+
}
|
|
2168
|
+
return rebasedRoots;
|
|
2169
|
+
}
|
|
2170
|
+
function rebaseRename(newRoots, rebasedRoots, renameEntry, base, affectedBaseFields) {
|
|
2171
|
+
let count = renameEntry.length;
|
|
2172
|
+
const baseRenameEntry = firstAttachIdFromDetachId(base.rootNodes, renameEntry.start, count);
|
|
2173
|
+
count = baseRenameEntry.length;
|
|
2174
|
+
const baseAttachEntry = base.crossFieldKeys.getFirst({
|
|
2175
|
+
...baseRenameEntry.value,
|
|
2176
|
+
target: CrossFieldTarget.Destination,
|
|
2177
|
+
}, count);
|
|
2178
|
+
count = baseAttachEntry.length;
|
|
2179
|
+
if (baseAttachEntry.value !== undefined) {
|
|
2180
|
+
// This rename represents an intention to detach these nodes.
|
|
2181
|
+
// The rebased change should have a detach in the field where the base change attaches the nodes,
|
|
2182
|
+
// so we need to ensure that field is processed.
|
|
2183
|
+
affectedBaseFields.set(fieldIdKeyFromFieldId(normalizeFieldId(baseAttachEntry.value, base.nodeAliases)), true);
|
|
2184
|
+
}
|
|
2185
|
+
else {
|
|
2186
|
+
const baseOutputDetachLocation = base.rootNodes.outputDetachLocations.getFirst(baseRenameEntry.value, 1).value;
|
|
2187
|
+
if (baseOutputDetachLocation !== undefined) {
|
|
2188
|
+
affectedBaseFields.set(fieldIdKeyFromFieldId(baseOutputDetachLocation), true);
|
|
2189
|
+
}
|
|
2190
|
+
const detachEntry = newRoots.detachLocations.getFirst(renameEntry.start, count);
|
|
2191
|
+
count = detachEntry.length;
|
|
2192
|
+
const detachLocation = baseOutputDetachLocation ?? detachEntry.value;
|
|
2193
|
+
// Note that `baseOutputDetachLocation` may contain a node ID from the base changeset.
|
|
2194
|
+
// We will replace the detach location entry with the node ID from the rebased changeset in `fixupRebasedDetachLocations`
|
|
2195
|
+
addNodeRename(rebasedRoots, baseRenameEntry.value, renameEntry.value, count, detachLocation);
|
|
2196
|
+
}
|
|
2197
|
+
const countRemaining = renameEntry.length - count;
|
|
2198
|
+
if (countRemaining > 0) {
|
|
2199
|
+
rebaseRename(newRoots, rebasedRoots, {
|
|
2200
|
+
start: offsetChangeAtomId(renameEntry.start, count),
|
|
2201
|
+
value: offsetChangeAtomId(renameEntry.value, count),
|
|
2202
|
+
length: countRemaining,
|
|
2203
|
+
}, base, affectedBaseFields);
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
/**
|
|
2207
|
+
* For each root detach location, replaces any node ID from the base changeset
|
|
2208
|
+
* with the corresponding ID in the new changeset.
|
|
2209
|
+
*/
|
|
2210
|
+
function fixupRebasedDetachLocations(table) {
|
|
2211
|
+
for (const { start, length, value: detachLocation, } of table.rebasedRootNodes.detachLocations.entries()) {
|
|
2212
|
+
const normalizedDetachLocation = normalizeFieldId(detachLocation, table.baseChange.nodeAliases);
|
|
2213
|
+
if (normalizedDetachLocation.nodeId !== undefined) {
|
|
2214
|
+
const rebasedNodeId = getFromChangeAtomIdMap(table.baseToRebasedNodeId, normalizedDetachLocation.nodeId);
|
|
2215
|
+
if (rebasedNodeId !== undefined) {
|
|
2216
|
+
table.rebasedRootNodes.detachLocations.set(start, length, {
|
|
2217
|
+
...normalizedDetachLocation,
|
|
2218
|
+
nodeId: rebasedNodeId,
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
function addNodesToCompose(table, id1, id2) {
|
|
2225
|
+
const normalizedId1 = normalizeNodeId(id1, table.baseChange.nodeAliases);
|
|
2226
|
+
const normalizedId2 = normalizeNodeId(id2, table.newChange.nodeAliases);
|
|
2227
|
+
if (getFromChangeAtomIdMap(table.newToBaseNodeId, normalizedId2) === undefined) {
|
|
2228
|
+
setInChangeAtomIdMap(table.newToBaseNodeId, normalizedId2, normalizedId1);
|
|
2229
|
+
table.pendingCompositions.nodeIdsToCompose.push([normalizedId1, normalizedId2]);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
function composeRevInfos(revisions1, revisions2) {
|
|
2233
|
+
const result = [...(revisions1 ?? []), ...(revisions2 ?? [])];
|
|
2234
|
+
return result;
|
|
2235
|
+
}
|
|
2236
|
+
function composeCrossFieldKeyTables(table1, table2, movedCrossFieldKeys, removedCrossFieldKeys) {
|
|
2237
|
+
const composedTable = RangeMap.union(table1, table2);
|
|
2238
|
+
for (const entry of movedCrossFieldKeys.entries()) {
|
|
2239
|
+
composedTable.set(entry.start, entry.length, entry.value);
|
|
2240
|
+
}
|
|
2241
|
+
for (const entry of removedCrossFieldKeys.entries()) {
|
|
2242
|
+
composedTable.delete(entry.start, entry.length);
|
|
2243
|
+
}
|
|
2244
|
+
return composedTable;
|
|
2245
|
+
}
|
|
2246
|
+
function composeRootTables(change1, change2, composedNodeToParent, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions) {
|
|
2247
|
+
const composedTable = cloneRootTable(change1.rootNodes);
|
|
2248
|
+
for (const renameEntry of change2.rootNodes.oldToNewId.entries()) {
|
|
2249
|
+
composeRename(change1, change2, composedTable, renameEntry.start, renameEntry.value, renameEntry.length, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
|
|
2250
|
+
}
|
|
2251
|
+
for (const [[revision2, id2], nodeId2] of change2.rootNodes.nodeChanges.entries()) {
|
|
2252
|
+
const detachId2 = { revision: revision2, localId: id2 };
|
|
2253
|
+
const detachId1 = firstDetachIdFromAttachId(change1.rootNodes, detachId2, 1).value;
|
|
2254
|
+
const nodeId1 = getFromChangeAtomIdMap(change1.rootNodes.nodeChanges, detachId1);
|
|
2255
|
+
if (nodeId1 !== undefined) {
|
|
2256
|
+
pendingCompositions.nodeIdsToCompose.push([nodeId1, nodeId2]);
|
|
2257
|
+
}
|
|
2258
|
+
else {
|
|
2259
|
+
const fieldId = getFieldsForCrossFieldKey(change1, { ...detachId1, target: CrossFieldTarget.Source }, 1)[0];
|
|
2260
|
+
if (fieldId !== undefined) {
|
|
2261
|
+
// In this case, this node is attached in the input context of change1,
|
|
2262
|
+
// and is represented in detachFieldId.
|
|
2263
|
+
pendingCompositions.affectedBaseFields.set([fieldId.nodeId?.revision, fieldId.nodeId?.localId, fieldId.field], true);
|
|
2264
|
+
}
|
|
2265
|
+
else {
|
|
2266
|
+
assignRootChange(composedTable, composedNodeToParent, detachId1, nodeId2, change1.rootNodes.detachLocations.getFirst(detachId1, 1).value ??
|
|
2267
|
+
change2.rootNodes.detachLocations.getFirst(detachId2, 1).value, Math.max(change1.rebaseVersion, change2.rebaseVersion));
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
for (const outputDetachEntry of change1.rootNodes.outputDetachLocations.entries()) {
|
|
2272
|
+
composeOutputDetachLocation(outputDetachEntry.start, outputDetachEntry.length, outputDetachEntry.value, change2, composedTable);
|
|
2273
|
+
}
|
|
2274
|
+
for (const entry of change2.rootNodes.outputDetachLocations.entries()) {
|
|
2275
|
+
composedTable.outputDetachLocations.set(entry.start, entry.length, entry.value);
|
|
2276
|
+
}
|
|
2277
|
+
return composedTable;
|
|
2278
|
+
}
|
|
2279
|
+
function composeOutputDetachLocation(outputDetachId1, count, detachLocation, change2, composedTable) {
|
|
2280
|
+
let countToProcess = count;
|
|
2281
|
+
const renameEntry = firstAttachIdFromDetachId(change2.rootNodes, outputDetachId1, countToProcess);
|
|
2282
|
+
countToProcess = renameEntry.length;
|
|
2283
|
+
const attachEntry = getFirstAttachField(change2.crossFieldKeys, renameEntry.value, countToProcess);
|
|
2284
|
+
countToProcess = attachEntry.length;
|
|
2285
|
+
composedTable.outputDetachLocations.delete(outputDetachId1, countToProcess);
|
|
2286
|
+
if (attachEntry.value === undefined) {
|
|
2287
|
+
// We update the key for the detach location to the renamed ID of the root in the composed output context.
|
|
2288
|
+
composedTable.outputDetachLocations.set(renameEntry.value, countToProcess, detachLocation);
|
|
2289
|
+
}
|
|
2290
|
+
else {
|
|
2291
|
+
// These nodes are attached by `change2` and thus attached in the composed output context,
|
|
2292
|
+
// so there should be no output detach location.
|
|
2293
|
+
}
|
|
2294
|
+
const countRemaining = count - countToProcess;
|
|
2295
|
+
if (countRemaining > 0) {
|
|
2296
|
+
composeOutputDetachLocation(offsetChangeAtomId(outputDetachId1, countToProcess), countRemaining, detachLocation, change2, composedTable);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
function composeRename(change1, change2, mergedTable, oldId, newId, count, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions) {
|
|
2300
|
+
let countToProcess = count;
|
|
2301
|
+
const detachEntry = getFirstDetachField(change1.crossFieldKeys, oldId, countToProcess);
|
|
2302
|
+
countToProcess = detachEntry.length;
|
|
2303
|
+
if (detachEntry.value !== undefined) {
|
|
2304
|
+
// `change1` detached these nodes,
|
|
2305
|
+
// so we invalidate the detach location so that the detach's ID can be replaced with the new ID.
|
|
2306
|
+
pendingCompositions.affectedBaseFields.set(fieldIdKeyFromFieldId(detachEntry.value), true);
|
|
2307
|
+
if (!areEqualChangeAtomIds(oldId, newId)) {
|
|
2308
|
+
// `change1`'s detach will be replaced by `change2`'s detach, so we update the cross-field keys.
|
|
2309
|
+
removedCrossFieldKeys.set({ ...oldId, target: CrossFieldTarget.Source }, countToProcess, true);
|
|
2310
|
+
}
|
|
2311
|
+
movedCrossFieldKeys.set({ ...newId, target: CrossFieldTarget.Source }, countToProcess, detachEntry.value);
|
|
2312
|
+
}
|
|
2313
|
+
else {
|
|
2314
|
+
// `change1` may also have a rename to `renameEntry.value`, in which case it must refer to a different node.
|
|
2315
|
+
// That node must have been attached by `change1` and detached by `change2`.
|
|
2316
|
+
// The final rename for that node will be created in `composeAttachDetach`.
|
|
2317
|
+
// We delete any such rename for now to avoid colliding with the rename currently being processed.
|
|
2318
|
+
deleteNodeRenameTo(mergedTable, newId, countToProcess);
|
|
2319
|
+
// The nodes were detached before `change`, so we append this rename.
|
|
2320
|
+
appendNodeRename(mergedTable, oldId, newId, countToProcess, change1.rootNodes, change2.rootNodes.detachLocations.getFirst(oldId, countToProcess).value);
|
|
2321
|
+
}
|
|
2322
|
+
if (countToProcess < count) {
|
|
2323
|
+
composeRename(change1, change2, mergedTable, offsetChangeAtomId(oldId, countToProcess), offsetChangeAtomId(newId, countToProcess), count - countToProcess, movedCrossFieldKeys, removedCrossFieldKeys, pendingCompositions);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
export function cloneRootTable(table) {
|
|
2327
|
+
return {
|
|
2328
|
+
oldToNewId: table.oldToNewId.clone(),
|
|
2329
|
+
newToOldId: table.newToOldId.clone(),
|
|
2330
|
+
nodeChanges: brand(table.nodeChanges.clone()),
|
|
2331
|
+
detachLocations: table.detachLocations.clone(),
|
|
2332
|
+
outputDetachLocations: table.outputDetachLocations.clone(),
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
function invertRootTable(change, isRollback) {
|
|
2336
|
+
const invertedRoots = newRootTable();
|
|
2337
|
+
for (const [[revision, localId], nodeId] of change.rootNodes.nodeChanges.entries()) {
|
|
2338
|
+
const detachId = { revision, localId };
|
|
2339
|
+
const renamedId = firstAttachIdFromDetachId(change.rootNodes, detachId, 1).value;
|
|
2340
|
+
// This checks whether `change` attaches this node.
|
|
2341
|
+
// 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.
|
|
2342
|
+
if (change.crossFieldKeys.getFirst({ ...renamedId, target: CrossFieldTarget.Destination }, 1)
|
|
2343
|
+
.value === undefined) {
|
|
2344
|
+
assignRootChange(invertedRoots, undefined, renamedId, nodeId, change.rootNodes.detachLocations.getFirst(detachId, 1).value, change.rebaseVersion);
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
if (isRollback) {
|
|
2348
|
+
// We only invert renames of nodes which are not attached or detached by this changeset.
|
|
2349
|
+
// When we invert an attach we will create a detach which incorporates the rename.
|
|
2350
|
+
for (const { start: oldId, value: newId, length, } of change.rootNodes.oldToNewId.entries()) {
|
|
2351
|
+
invertRename(change, invertedRoots, oldId, newId, length);
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
return invertedRoots;
|
|
2355
|
+
}
|
|
2356
|
+
function invertRename(change, invertedRoots, oldId, newId, length) {
|
|
2357
|
+
for (const detachEntry of doesChangeDetachNodes(change.crossFieldKeys, newId, length)) {
|
|
2358
|
+
assert(!detachEntry.value, "A changeset should not have a rename and detach for the same node.");
|
|
2359
|
+
}
|
|
2360
|
+
let countProcessed = length;
|
|
2361
|
+
const attachEntry = getFirstAttachField(change.crossFieldKeys, newId, countProcessed);
|
|
2362
|
+
countProcessed = attachEntry.length;
|
|
2363
|
+
if (attachEntry.value === undefined) {
|
|
2364
|
+
const outputDetachEntry = change.rootNodes.outputDetachLocations.getFirst(newId, countProcessed);
|
|
2365
|
+
countProcessed = outputDetachEntry.length;
|
|
2366
|
+
const inputDetachEntry = change.rootNodes.detachLocations.getFirst(oldId, countProcessed);
|
|
2367
|
+
countProcessed = inputDetachEntry.length;
|
|
2368
|
+
addNodeRename(invertedRoots, newId, oldId, countProcessed, outputDetachEntry.value ?? inputDetachEntry.value);
|
|
2369
|
+
}
|
|
2370
|
+
if (countProcessed < length) {
|
|
2371
|
+
invertRename(change, invertedRoots, offsetChangeAtomId(oldId, countProcessed), offsetChangeAtomId(newId, countProcessed), length - countProcessed);
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
function doesChangeAttachNodes(table, id, count) {
|
|
2375
|
+
return table
|
|
2376
|
+
.getAll2({ ...id, target: CrossFieldTarget.Destination }, count)
|
|
2377
|
+
.map((entry) => ({ ...entry, value: entry.value !== undefined }));
|
|
2378
|
+
}
|
|
2379
|
+
function doesChangeDetachNodes(table, id, count) {
|
|
2380
|
+
return table
|
|
2381
|
+
.getAll2({ ...id, target: CrossFieldTarget.Source }, count)
|
|
2382
|
+
.map((entry) => ({ ...entry, value: entry.value !== undefined }));
|
|
2383
|
+
}
|
|
2384
|
+
export function getFirstDetachField(table, id, count) {
|
|
2385
|
+
return table.getFirst({ target: CrossFieldTarget.Source, ...id }, count);
|
|
2386
|
+
}
|
|
2387
|
+
export function getFirstAttachField(table, id, count) {
|
|
2388
|
+
return table.getFirst({ target: CrossFieldTarget.Destination, ...id }, count);
|
|
2389
|
+
}
|
|
2390
|
+
export function addNodeRename(table, oldId, newId, count, detachLocation) {
|
|
2391
|
+
if (areEqualChangeAtomIds(oldId, newId)) {
|
|
2392
|
+
return;
|
|
2393
|
+
}
|
|
2394
|
+
for (const entry of table.oldToNewId.getAll2(oldId, count)) {
|
|
2395
|
+
assert(entry.value === undefined ||
|
|
2396
|
+
areEqualChangeAtomIds(entry.value, offsetChangeAtomId(newId, entry.offset)), "Rename collision detected");
|
|
2397
|
+
}
|
|
2398
|
+
for (const entry of table.newToOldId.getAll2(newId, count)) {
|
|
2399
|
+
assert(entry.value === undefined ||
|
|
2400
|
+
areEqualChangeAtomIds(entry.value, offsetChangeAtomId(oldId, entry.offset)), "Rename collision detected");
|
|
2401
|
+
}
|
|
2402
|
+
table.oldToNewId.set(oldId, count, newId);
|
|
2403
|
+
table.newToOldId.set(newId, count, oldId);
|
|
2404
|
+
if (detachLocation !== undefined) {
|
|
2405
|
+
table.detachLocations.set(oldId, count, detachLocation);
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Deletes any renames from `id`.
|
|
2410
|
+
*/
|
|
2411
|
+
function deleteNodeRenameFrom(roots, id, count) {
|
|
2412
|
+
for (const entry of roots.oldToNewId.getAll(id, count)) {
|
|
2413
|
+
deleteNodeRenameEntry(roots, entry.start, entry.value, entry.length);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
/**
|
|
2417
|
+
* Deletes any renames to `id`.
|
|
2418
|
+
*/
|
|
2419
|
+
function deleteNodeRenameTo(roots, id, count) {
|
|
2420
|
+
for (const entry of roots.newToOldId.getAll(id, count)) {
|
|
2421
|
+
deleteNodeRenameEntry(roots, entry.value, entry.start, entry.length);
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
function appendNodeRename(composedTable, oldId, newId, count, change1Table, detachLocation) {
|
|
2425
|
+
let countToProcess = count;
|
|
2426
|
+
const rename1Entry = change1Table.newToOldId.getFirst(oldId, countToProcess);
|
|
2427
|
+
countToProcess = rename1Entry.length;
|
|
2428
|
+
if (rename1Entry.value !== undefined) {
|
|
2429
|
+
deleteNodeRenameFrom(composedTable, rename1Entry.value, countToProcess);
|
|
2430
|
+
}
|
|
2431
|
+
addNodeRename(composedTable, rename1Entry.value ?? oldId, newId, countToProcess, detachLocation);
|
|
2432
|
+
tryRemoveDetachLocation(composedTable, newId, countToProcess);
|
|
2433
|
+
if (countToProcess < count) {
|
|
2434
|
+
const countRemaining = count - countToProcess;
|
|
2435
|
+
appendNodeRename(composedTable, offsetChangeAtomId(oldId, countToProcess), offsetChangeAtomId(newId, countToProcess), countRemaining, change1Table, detachLocation);
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
function tryRemoveDetachLocation(roots, rootId, count) {
|
|
2439
|
+
let countProcessed = count;
|
|
2440
|
+
const renameEntry = roots.oldToNewId.getFirst(rootId, countProcessed);
|
|
2441
|
+
countProcessed = renameEntry.length;
|
|
2442
|
+
const outputDetachEntry = roots.outputDetachLocations.getFirst(rootId, countProcessed);
|
|
2443
|
+
countProcessed = outputDetachEntry.length;
|
|
2444
|
+
const nodeChangeEntry = rangeQueryChangeAtomIdMap(roots.nodeChanges, rootId, countProcessed);
|
|
2445
|
+
countProcessed = nodeChangeEntry.length;
|
|
2446
|
+
if (nodeChangeEntry.value === undefined &&
|
|
2447
|
+
renameEntry.value === undefined &&
|
|
2448
|
+
outputDetachEntry.value === undefined) {
|
|
2449
|
+
roots.detachLocations.delete(rootId, countProcessed);
|
|
2450
|
+
}
|
|
2451
|
+
const countRemaining = count - countProcessed;
|
|
2452
|
+
if (countRemaining > 0) {
|
|
2453
|
+
tryRemoveDetachLocation(roots, offsetChangeAtomId(rootId, countProcessed), countRemaining);
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
/**
|
|
2457
|
+
* Deletes the entry renaming the ID range of length `count` from `oldId` to `newId`.
|
|
2458
|
+
* This function assumes that such an entry exists.
|
|
2459
|
+
*/
|
|
2460
|
+
function deleteNodeRenameEntry(roots, oldId, newId, count) {
|
|
2461
|
+
roots.oldToNewId.delete(oldId, count);
|
|
2462
|
+
roots.newToOldId.delete(newId, count);
|
|
2463
|
+
}
|
|
2464
|
+
function replaceRootTableRevision(table, oldRevisions, newRevision, nodeAliases) {
|
|
2465
|
+
const oldToNewId = table.oldToNewId.mapEntries((id) => replaceAtomRevisions(id, oldRevisions, newRevision), (id) => replaceAtomRevisions(id, oldRevisions, newRevision));
|
|
2466
|
+
const newToOldId = table.newToOldId.mapEntries((id) => replaceAtomRevisions(id, oldRevisions, newRevision), (id) => replaceAtomRevisions(id, oldRevisions, newRevision));
|
|
2467
|
+
const nodeChanges = newTupleBTree([...table.nodeChanges.entries()].map(([[revision, id], nodeId]) => [
|
|
2468
|
+
[oldRevisions.has(revision) ? newRevision : revision, id],
|
|
2469
|
+
replaceAtomRevisions(normalizeNodeId(nodeId, nodeAliases), oldRevisions, newRevision),
|
|
2470
|
+
]));
|
|
2471
|
+
const detachLocations = table.detachLocations.mapEntries((id) => replaceAtomRevisions(id, oldRevisions, newRevision), (fieldId) => replaceFieldIdRevision(normalizeFieldId(fieldId, nodeAliases), oldRevisions, newRevision));
|
|
2472
|
+
const outputDetachLocations = table.outputDetachLocations.mapEntries((id) => replaceAtomRevisions(id, oldRevisions, newRevision), (fieldId) => replaceFieldIdRevision(normalizeFieldId(fieldId, nodeAliases), oldRevisions, newRevision));
|
|
2473
|
+
return { oldToNewId, newToOldId, nodeChanges, detachLocations, outputDetachLocations };
|
|
2474
|
+
}
|
|
2475
|
+
function newDetachedEntryMap() {
|
|
2476
|
+
return new RangeMap(offsetChangeAtomId, subtractChangeAtomIds, offsetDetachedNodeEntry);
|
|
2477
|
+
}
|
|
2478
|
+
function offsetDetachedNodeEntry(entry, count) {
|
|
2479
|
+
assert(count <= 1 || entry.nodeChange === undefined, "Cannot split an entry with a node change");
|
|
2480
|
+
return entry.detachId !== undefined
|
|
2481
|
+
? { ...entry, detachId: offsetChangeAtomId(entry.detachId, count) }
|
|
2482
|
+
: entry;
|
|
2483
|
+
}
|
|
2484
|
+
function getFieldsWithRootMoves(roots, nodeAliases) {
|
|
2485
|
+
const fields = newTupleBTree();
|
|
2486
|
+
for (const { start: rootId, value: fieldId, length } of roots.detachLocations.entries()) {
|
|
2487
|
+
let isRootMoved = false;
|
|
2488
|
+
for (const renameEntry of roots.oldToNewId.getAll2(rootId, length)) {
|
|
2489
|
+
if (renameEntry.value !== undefined) {
|
|
2490
|
+
isRootMoved = true;
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
for (const outputDetachEntry of roots.outputDetachLocations.getAll2(rootId, length)) {
|
|
2494
|
+
if (outputDetachEntry.value !== undefined) {
|
|
2495
|
+
isRootMoved = true;
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
if (isRootMoved) {
|
|
2499
|
+
fields.set(fieldIdKeyFromFieldId(normalizeFieldId(fieldId, nodeAliases)), true);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
return fields;
|
|
2503
|
+
}
|
|
2504
|
+
function getFieldToRootChanges(roots, nodeAliases) {
|
|
2505
|
+
const fields = newTupleBTree();
|
|
2506
|
+
for (const rootIdKey of roots.nodeChanges.keys()) {
|
|
2507
|
+
const rootId = { revision: rootIdKey[0], localId: rootIdKey[1] };
|
|
2508
|
+
const detachLocation = roots.detachLocations.getFirst(rootId, 1).value;
|
|
2509
|
+
if (detachLocation !== undefined) {
|
|
2510
|
+
const fieldIdKey = fieldIdKeyFromFieldId(normalizeFieldId(detachLocation, nodeAliases));
|
|
2511
|
+
let rootsInField = fields.get(fieldIdKey);
|
|
2512
|
+
if (rootsInField === undefined) {
|
|
2513
|
+
rootsInField = [];
|
|
2514
|
+
fields.set(fieldIdKey, rootsInField);
|
|
2515
|
+
}
|
|
2516
|
+
rootsInField.push(rootId);
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
return fields;
|
|
2520
|
+
}
|
|
2521
|
+
function muteRootChanges(roots) {
|
|
2522
|
+
return {
|
|
2523
|
+
oldToNewId: newChangeAtomIdTransform(),
|
|
2524
|
+
newToOldId: newChangeAtomIdTransform(),
|
|
2525
|
+
nodeChanges: brand(roots.nodeChanges.clone()),
|
|
2526
|
+
detachLocations: roots.detachLocations.clone(),
|
|
2527
|
+
outputDetachLocations: newChangeAtomIdRangeMap(),
|
|
2528
|
+
};
|
|
2529
|
+
}
|
|
1704
2530
|
//# sourceMappingURL=modularChangeFamily.js.map
|