@fluidframework/tree 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +136 -0
- package/api-report/tree.alpha.api.md +86 -10
- package/api-report/tree.beta.api.md +22 -10
- package/api-report/tree.legacy.alpha.api.md +22 -10
- package/api-report/tree.legacy.public.api.md +22 -10
- package/api-report/tree.public.api.md +22 -10
- package/dist/alpha.d.ts +11 -0
- package/dist/beta.d.ts +2 -0
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +10 -0
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js +3 -0
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +0 -1
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +2 -4
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js +8 -2
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +12 -5
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +2 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +1 -0
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +89 -25
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +12 -0
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +24 -4
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.d.ts +2 -2
- package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +14 -5
- package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +2 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/public.d.ts +2 -0
- package/dist/shared-tree/index.d.ts +2 -1
- package/dist/shared-tree/index.d.ts.map +1 -1
- package/dist/shared-tree/index.js +2 -1
- package/dist/shared-tree/index.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +10 -1
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +43 -0
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +6 -3
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +3 -1
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/transactionTypes.d.ts +105 -0
- package/dist/shared-tree/transactionTypes.d.ts.map +1 -0
- package/dist/shared-tree/transactionTypes.js +13 -0
- package/dist/shared-tree/transactionTypes.js.map +1 -0
- package/dist/shared-tree/treeApi.d.ts +1 -25
- package/dist/shared-tree/treeApi.d.ts.map +1 -1
- package/dist/shared-tree/treeApi.js +4 -8
- package/dist/shared-tree/treeApi.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +4 -1
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +130 -15
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +1 -0
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +3 -1
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/jsonSchema.d.ts +6 -0
- package/dist/simple-tree/api/jsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/jsonSchema.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +21 -12
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +5 -2
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +83 -0
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -0
- package/dist/simple-tree/api/schemaFactoryAlpha.js +90 -0
- package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -0
- package/dist/simple-tree/api/simpleSchema.d.ts +5 -1
- package/dist/simple-tree/api/simpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchema.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +13 -10
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/testRecursiveDomain.d.ts +5 -5
- package/dist/simple-tree/api/tree.d.ts +60 -0
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js +11 -11
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
- package/dist/simple-tree/arrayNode.d.ts +2 -2
- package/dist/simple-tree/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/arrayNode.js +2 -1
- package/dist/simple-tree/arrayNode.js.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.d.ts +10 -6
- package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/dist/simple-tree/index.d.ts +2 -2
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +3 -2
- 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/mapNode.d.ts +2 -2
- package/dist/simple-tree/mapNode.d.ts.map +1 -1
- package/dist/simple-tree/mapNode.js +2 -1
- package/dist/simple-tree/mapNode.js.map +1 -1
- package/dist/simple-tree/objectNode.d.ts +2 -2
- package/dist/simple-tree/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/objectNode.js +2 -1
- package/dist/simple-tree/objectNode.js.map +1 -1
- package/dist/simple-tree/objectNodeTypes.d.ts +2 -2
- package/dist/simple-tree/objectNodeTypes.d.ts.map +1 -1
- package/dist/simple-tree/objectNodeTypes.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +47 -1
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/util/index.d.ts +2 -2
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +3 -5
- package/dist/util/index.js.map +1 -1
- package/dist/util/rangeMap.d.ts +72 -42
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +161 -151
- package/dist/util/rangeMap.js.map +1 -1
- package/dist/util/utils.d.ts +22 -1
- package/dist/util/utils.d.ts.map +1 -1
- package/dist/util/utils.js +10 -1
- package/dist/util/utils.js.map +1 -1
- package/lib/alpha.d.ts +11 -0
- package/lib/beta.d.ts +2 -0
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +10 -0
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js +3 -0
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +0 -1
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +0 -1
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js +9 -3
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +12 -5
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +2 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +1 -0
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +89 -25
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +12 -0
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +24 -4
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.d.ts +2 -2
- package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +14 -5
- package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +2 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +2 -0
- package/lib/shared-tree/index.d.ts +2 -1
- package/lib/shared-tree/index.d.ts.map +1 -1
- package/lib/shared-tree/index.js +2 -1
- package/lib/shared-tree/index.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +10 -1
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +46 -3
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +6 -3
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +3 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/transactionTypes.d.ts +105 -0
- package/lib/shared-tree/transactionTypes.d.ts.map +1 -0
- package/lib/shared-tree/transactionTypes.js +10 -0
- package/lib/shared-tree/transactionTypes.js.map +1 -0
- package/lib/shared-tree/treeApi.d.ts +1 -25
- package/lib/shared-tree/treeApi.d.ts.map +1 -1
- package/lib/shared-tree/treeApi.js +1 -5
- package/lib/shared-tree/treeApi.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +4 -1
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +130 -15
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +1 -0
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -0
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/jsonSchema.d.ts +6 -0
- package/lib/simple-tree/api/jsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/jsonSchema.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +21 -12
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +5 -2
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +83 -0
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -0
- package/lib/simple-tree/api/schemaFactoryAlpha.js +86 -0
- package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -0
- package/lib/simple-tree/api/simpleSchema.d.ts +5 -1
- package/lib/simple-tree/api/simpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchema.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +14 -11
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/testRecursiveDomain.d.ts +5 -5
- package/lib/simple-tree/api/tree.d.ts +60 -0
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js +12 -12
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
- package/lib/simple-tree/arrayNode.d.ts +2 -2
- package/lib/simple-tree/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/arrayNode.js +2 -1
- package/lib/simple-tree/arrayNode.js.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.d.ts +10 -6
- package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/lib/simple-tree/index.d.ts +2 -2
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +1 -1
- 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/mapNode.d.ts +2 -2
- package/lib/simple-tree/mapNode.d.ts.map +1 -1
- package/lib/simple-tree/mapNode.js +2 -1
- package/lib/simple-tree/mapNode.js.map +1 -1
- package/lib/simple-tree/objectNode.d.ts +2 -2
- package/lib/simple-tree/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/objectNode.js +2 -1
- package/lib/simple-tree/objectNode.js.map +1 -1
- package/lib/simple-tree/objectNodeTypes.d.ts +2 -2
- package/lib/simple-tree/objectNodeTypes.d.ts.map +1 -1
- package/lib/simple-tree/objectNodeTypes.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +47 -1
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/util/index.d.ts +2 -2
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +2 -2
- package/lib/util/index.js.map +1 -1
- package/lib/util/rangeMap.d.ts +72 -42
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +159 -146
- package/lib/util/rangeMap.js.map +1 -1
- package/lib/util/utils.d.ts +22 -1
- package/lib/util/utils.d.ts.map +1 -1
- package/lib/util/utils.js +8 -0
- package/lib/util/utils.js.map +1 -1
- package/package.json +22 -22
- package/src/feature-libraries/default-schema/defaultEditBuilder.ts +14 -1
- package/src/feature-libraries/index.ts +0 -1
- package/src/feature-libraries/modular-schema/crossFieldQueries.ts +9 -9
- package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +13 -9
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +4 -2
- package/src/feature-libraries/modular-schema/index.ts +1 -0
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +124 -31
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +12 -0
- package/src/feature-libraries/optional-field/optionalField.ts +34 -5
- package/src/feature-libraries/sequence-field/utils.ts +18 -7
- package/src/index.ts +11 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/index.ts +12 -2
- package/src/shared-tree/schematizingTreeView.ts +91 -2
- package/src/shared-tree/sharedTree.ts +9 -4
- package/src/shared-tree/transactionTypes.ts +125 -0
- package/src/shared-tree/treeApi.ts +1 -28
- package/src/shared-tree/treeCheckout.ts +147 -13
- package/src/shared-tree-core/sharedTreeCore.ts +1 -1
- package/src/simple-tree/api/index.ts +1 -0
- package/src/simple-tree/api/jsonSchema.ts +7 -0
- package/src/simple-tree/api/schemaFactory.ts +33 -6
- package/src/simple-tree/api/schemaFactoryAlpha.ts +253 -0
- package/src/simple-tree/api/simpleSchema.ts +6 -1
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +22 -12
- package/src/simple-tree/api/tree.ts +76 -4
- package/src/simple-tree/api/viewSchemaToSimpleSchema.ts +19 -13
- package/src/simple-tree/arrayNode.ts +7 -1
- package/src/simple-tree/core/treeNodeSchema.ts +51 -7
- package/src/simple-tree/index.ts +3 -0
- package/src/simple-tree/mapNode.ts +7 -1
- package/src/simple-tree/objectNode.ts +7 -1
- package/src/simple-tree/objectNodeTypes.ts +4 -1
- package/src/simple-tree/schemaTypes.ts +50 -1
- package/src/util/index.ts +2 -6
- package/src/util/rangeMap.ts +199 -189
- package/src/util/utils.ts +47 -1
- package/dist/feature-libraries/memoizedIdRangeAllocator.d.ts +0 -38
- package/dist/feature-libraries/memoizedIdRangeAllocator.d.ts.map +0 -1
- package/dist/feature-libraries/memoizedIdRangeAllocator.js +0 -74
- package/dist/feature-libraries/memoizedIdRangeAllocator.js.map +0 -1
- package/lib/feature-libraries/memoizedIdRangeAllocator.d.ts +0 -38
- package/lib/feature-libraries/memoizedIdRangeAllocator.d.ts.map +0 -1
- package/lib/feature-libraries/memoizedIdRangeAllocator.js +0 -71
- package/lib/feature-libraries/memoizedIdRangeAllocator.js.map +0 -1
- package/src/feature-libraries/memoizedIdRangeAllocator.ts +0 -112
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/tree",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Distributed tree",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -89,17 +89,17 @@
|
|
|
89
89
|
"temp-directory": "nyc/.nyc_output"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@fluid-internal/client-utils": "~2.
|
|
93
|
-
"@fluidframework/container-runtime": "~2.
|
|
94
|
-
"@fluidframework/core-interfaces": "~2.
|
|
95
|
-
"@fluidframework/core-utils": "~2.
|
|
96
|
-
"@fluidframework/datastore-definitions": "~2.
|
|
97
|
-
"@fluidframework/driver-definitions": "~2.
|
|
98
|
-
"@fluidframework/id-compressor": "~2.
|
|
99
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
100
|
-
"@fluidframework/runtime-utils": "~2.
|
|
101
|
-
"@fluidframework/shared-object-base": "~2.
|
|
102
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
92
|
+
"@fluid-internal/client-utils": "~2.13.0",
|
|
93
|
+
"@fluidframework/container-runtime": "~2.13.0",
|
|
94
|
+
"@fluidframework/core-interfaces": "~2.13.0",
|
|
95
|
+
"@fluidframework/core-utils": "~2.13.0",
|
|
96
|
+
"@fluidframework/datastore-definitions": "~2.13.0",
|
|
97
|
+
"@fluidframework/driver-definitions": "~2.13.0",
|
|
98
|
+
"@fluidframework/id-compressor": "~2.13.0",
|
|
99
|
+
"@fluidframework/runtime-definitions": "~2.13.0",
|
|
100
|
+
"@fluidframework/runtime-utils": "~2.13.0",
|
|
101
|
+
"@fluidframework/shared-object-base": "~2.13.0",
|
|
102
|
+
"@fluidframework/telemetry-utils": "~2.13.0",
|
|
103
103
|
"@sinclair/typebox": "^0.32.29",
|
|
104
104
|
"@tylerbu/sorted-btree-es6": "^1.8.0",
|
|
105
105
|
"@types/ungap__structured-clone": "^1.2.0",
|
|
@@ -109,24 +109,24 @@
|
|
|
109
109
|
"devDependencies": {
|
|
110
110
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
111
111
|
"@biomejs/biome": "~1.9.3",
|
|
112
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
113
|
-
"@fluid-private/stochastic-test-utils": "~2.
|
|
114
|
-
"@fluid-private/test-dds-utils": "~2.
|
|
115
|
-
"@fluid-private/test-drivers": "~2.
|
|
112
|
+
"@fluid-internal/mocha-test-setup": "~2.13.0",
|
|
113
|
+
"@fluid-private/stochastic-test-utils": "~2.13.0",
|
|
114
|
+
"@fluid-private/test-dds-utils": "~2.13.0",
|
|
115
|
+
"@fluid-private/test-drivers": "~2.13.0",
|
|
116
116
|
"@fluid-tools/benchmark": "^0.50.0",
|
|
117
117
|
"@fluid-tools/build-cli": "^0.51.0",
|
|
118
118
|
"@fluidframework/build-common": "^2.0.3",
|
|
119
119
|
"@fluidframework/build-tools": "^0.51.0",
|
|
120
|
-
"@fluidframework/container-definitions": "~2.
|
|
121
|
-
"@fluidframework/container-loader": "~2.
|
|
120
|
+
"@fluidframework/container-definitions": "~2.13.0",
|
|
121
|
+
"@fluidframework/container-loader": "~2.13.0",
|
|
122
122
|
"@fluidframework/eslint-config-fluid": "^5.6.0",
|
|
123
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
124
|
-
"@fluidframework/test-utils": "~2.
|
|
125
|
-
"@fluidframework/tree-previous": "npm:@fluidframework/tree@2.
|
|
123
|
+
"@fluidframework/test-runtime-utils": "~2.13.0",
|
|
124
|
+
"@fluidframework/test-utils": "~2.13.0",
|
|
125
|
+
"@fluidframework/tree-previous": "npm:@fluidframework/tree@2.12.0",
|
|
126
126
|
"@microsoft/api-extractor": "7.47.8",
|
|
127
127
|
"@types/diff": "^3.5.1",
|
|
128
128
|
"@types/easy-table": "^0.0.32",
|
|
129
|
-
"@types/mocha": "^
|
|
129
|
+
"@types/mocha": "^10.0.10",
|
|
130
130
|
"@types/node": "^18.19.0",
|
|
131
131
|
"@types/uuid": "^9.0.2",
|
|
132
132
|
"ajv": "^8.12.0",
|
|
@@ -160,8 +160,17 @@ export interface IDefaultEditBuilder {
|
|
|
160
160
|
destinationIndex: number,
|
|
161
161
|
): void;
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Add a constraint that the node at the given path must exist.
|
|
165
|
+
* @param path - The path to the node that must exist.
|
|
166
|
+
*/
|
|
164
167
|
addNodeExistsConstraint(path: UpPath): void;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Add a constraint that the node at the given path must exist when reverting a change.
|
|
171
|
+
* @param path - The path to the node that must exist when reverting a change.
|
|
172
|
+
*/
|
|
173
|
+
addNodeExistsConstraintOnRevert(path: UpPath): void;
|
|
165
174
|
}
|
|
166
175
|
|
|
167
176
|
/**
|
|
@@ -191,6 +200,10 @@ export class DefaultEditBuilder implements ChangeFamilyEditor, IDefaultEditBuild
|
|
|
191
200
|
this.modularBuilder.addNodeExistsConstraint(path, this.mintRevisionTag());
|
|
192
201
|
}
|
|
193
202
|
|
|
203
|
+
public addNodeExistsConstraintOnRevert(path: UpPath): void {
|
|
204
|
+
this.modularBuilder.addNodeExistsConstraintOnRevert(path, this.mintRevisionTag());
|
|
205
|
+
}
|
|
206
|
+
|
|
194
207
|
public valueField(field: FieldUpPath): ValueFieldEditBuilder<ITreeCursorSynchronous> {
|
|
195
208
|
return {
|
|
196
209
|
set: (newContent: ITreeCursorSynchronous): void => {
|
|
@@ -16,7 +16,6 @@ export {
|
|
|
16
16
|
mapTreeFromCursor,
|
|
17
17
|
mapTreeFieldFromCursor,
|
|
18
18
|
} from "./mapTreeCursor.js";
|
|
19
|
-
export { MemoizedIdRangeAllocator, type IdRange } from "./memoizedIdRangeAllocator.js";
|
|
20
19
|
export { buildForest } from "./object-forest/index.js";
|
|
21
20
|
export { SchemaSummarizer, encodeTreeSchema, makeSchemaCodec } from "./schema-index/index.js";
|
|
22
21
|
export {
|
|
@@ -4,13 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { ChangesetLocalId, RevisionTag } from "../../core/index.js";
|
|
7
|
-
import {
|
|
8
|
-
type RangeMap,
|
|
9
|
-
type RangeQueryResult,
|
|
10
|
-
getFromRangeMap,
|
|
11
|
-
getOrAddInMap,
|
|
12
|
-
setInRangeMap,
|
|
13
|
-
} from "../../util/index.js";
|
|
7
|
+
import { RangeMap, type RangeQueryResult } from "../../util/index.js";
|
|
14
8
|
import type { NodeId } from "./modularChangeTypes.js";
|
|
15
9
|
|
|
16
10
|
export type CrossFieldMap<T> = Map<RevisionTag | undefined, RangeMap<T>>;
|
|
@@ -32,7 +26,12 @@ export function setInCrossFieldMap<T>(
|
|
|
32
26
|
count: number,
|
|
33
27
|
value: T,
|
|
34
28
|
): void {
|
|
35
|
-
|
|
29
|
+
let rangeMap = map.get(revision);
|
|
30
|
+
if (rangeMap === undefined) {
|
|
31
|
+
rangeMap = new RangeMap();
|
|
32
|
+
map.set(revision, rangeMap);
|
|
33
|
+
}
|
|
34
|
+
rangeMap.set(id, count, value);
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
export function getFirstFromCrossFieldMap<T>(
|
|
@@ -41,7 +40,8 @@ export function getFirstFromCrossFieldMap<T>(
|
|
|
41
40
|
id: ChangesetLocalId,
|
|
42
41
|
count: number,
|
|
43
42
|
): RangeQueryResult<T> {
|
|
44
|
-
|
|
43
|
+
const rangeMap = map.has(revision) ? (map.get(revision) as RangeMap<T>) : new RangeMap<T>();
|
|
44
|
+
return rangeMap.get(id, count);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -14,12 +14,17 @@ import type {
|
|
|
14
14
|
RevisionTag,
|
|
15
15
|
} from "../../core/index.js";
|
|
16
16
|
import type { IdAllocator, Invariant } from "../../util/index.js";
|
|
17
|
-
import type { MemoizedIdRangeAllocator } from "../memoizedIdRangeAllocator.js";
|
|
18
17
|
|
|
19
18
|
import type { CrossFieldManager } from "./crossFieldQueries.js";
|
|
20
19
|
import type { CrossFieldKeyRange, NodeId } from "./modularChangeTypes.js";
|
|
21
20
|
import type { EncodedNodeChangeset } from "./modularChangeFormat.js";
|
|
22
21
|
|
|
22
|
+
export type NestedChangesIndices = [
|
|
23
|
+
NodeId,
|
|
24
|
+
number | undefined /* inputIndex */,
|
|
25
|
+
number | undefined /* outputIndex */,
|
|
26
|
+
][];
|
|
27
|
+
|
|
23
28
|
/**
|
|
24
29
|
* Functionality provided by a field kind which will be composed with other `FieldChangeHandler`s to
|
|
25
30
|
* implement a unified ChangeFamily supporting documents with multiple field kinds.
|
|
@@ -39,11 +44,7 @@ export interface FieldChangeHandler<
|
|
|
39
44
|
>,
|
|
40
45
|
) => ICodecFamily<TChangeset, FieldChangeEncodingContext>;
|
|
41
46
|
readonly editor: TEditor;
|
|
42
|
-
intoDelta(
|
|
43
|
-
change: TChangeset,
|
|
44
|
-
deltaFromChild: ToDelta,
|
|
45
|
-
idAllocator: MemoizedIdRangeAllocator,
|
|
46
|
-
): DeltaFieldChanges;
|
|
47
|
+
intoDelta(change: TChangeset, deltaFromChild: ToDelta): DeltaFieldChanges;
|
|
47
48
|
/**
|
|
48
49
|
* Returns the set of removed roots that should be in memory for the given change to be applied.
|
|
49
50
|
* A removed root is relevant if any of the following is true:
|
|
@@ -75,13 +76,16 @@ export interface FieldChangeHandler<
|
|
|
75
76
|
* @param change - The field change to get the child changes from.
|
|
76
77
|
*
|
|
77
78
|
* @returns The set of `NodeId`s that correspond to nested changes in the given `change`.
|
|
78
|
-
* Each `NodeId` is associated with the
|
|
79
|
-
*
|
|
79
|
+
* Each `NodeId` is associated with the following:
|
|
80
|
+
* - index of the node in the field in the input context of the changeset (or `undefined` if the node is not
|
|
81
|
+
* attached in the input context).
|
|
82
|
+
* - index of the node in the field in the output context of the changeset (or `undefined` if the node is not
|
|
83
|
+
* attached in the output context).
|
|
80
84
|
* For all returned entries where the index is defined,
|
|
81
85
|
* the indices are are ordered from smallest to largest (with no duplicates).
|
|
82
86
|
* The returned array is owned by the caller.
|
|
83
87
|
*/
|
|
84
|
-
getNestedChanges(change: TChangeset):
|
|
88
|
+
getNestedChanges(change: TChangeset): NestedChangesIndices;
|
|
85
89
|
|
|
86
90
|
/**
|
|
87
91
|
* @returns A list of all cross-field keys contained in the change.
|
|
@@ -17,6 +17,7 @@ import { assert } from "@fluidframework/core-utils/internal";
|
|
|
17
17
|
import type { CrossFieldManager } from "./crossFieldQueries.js";
|
|
18
18
|
import type {
|
|
19
19
|
FieldChangeHandler,
|
|
20
|
+
NestedChangesIndices,
|
|
20
21
|
NodeChangeComposer,
|
|
21
22
|
NodeChangePruner,
|
|
22
23
|
NodeChangeRebaser,
|
|
@@ -82,8 +83,9 @@ function compose(
|
|
|
82
83
|
return composed;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
function getNestedChanges(change: GenericChangeset):
|
|
86
|
-
|
|
86
|
+
function getNestedChanges(change: GenericChangeset): NestedChangesIndices {
|
|
87
|
+
// For generic changeset, the indices in the input and output contexts are the same.
|
|
88
|
+
return change.toArray().map(([index, nodeChange]) => [nodeChange, index, index]);
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
function rebaseGenericChange(
|
|
@@ -59,7 +59,6 @@ import {
|
|
|
59
59
|
defaultChunkPolicy,
|
|
60
60
|
} from "../chunked-forest/index.js";
|
|
61
61
|
import { cursorForMapTreeNode, mapTreeFromCursor } from "../mapTreeCursor.js";
|
|
62
|
-
import { MemoizedIdRangeAllocator } from "../memoizedIdRangeAllocator.js";
|
|
63
62
|
|
|
64
63
|
import {
|
|
65
64
|
type CrossFieldManager,
|
|
@@ -649,8 +648,21 @@ export class ModularChangeFamily
|
|
|
649
648
|
crossFieldTable: ComposeTable,
|
|
650
649
|
revisionMetadata: RevisionMetadataSource,
|
|
651
650
|
): NodeChangeset {
|
|
651
|
+
// WARNING: this composition logic assumes that we never make compositions of the following form:
|
|
652
|
+
// change1: a changeset that impact the existence of a node
|
|
653
|
+
// change2: a node-exists constraint on that node.
|
|
654
|
+
// This is currently enforced by the fact that constraints which apply to the input context are included first in the composition.
|
|
655
|
+
// If that weren't the case, we would need to rebase the status of the constraint backward over the changes from change1.
|
|
652
656
|
const nodeExistsConstraint = change1.nodeExistsConstraint ?? change2.nodeExistsConstraint;
|
|
653
657
|
|
|
658
|
+
// WARNING: this composition logic assumes that we never make compositions of the following form:
|
|
659
|
+
// change1: a node-exists-on-revert constraint on a node
|
|
660
|
+
// change2: a changeset that impacts the existence of that node
|
|
661
|
+
// This is currently enforced by the fact that constraints which apply to the revert are included last in the composition.
|
|
662
|
+
// If that weren't the case, we would need to rebase the status of the constraint forward over the changes from change2.
|
|
663
|
+
const nodeExistsConstraintOnRevert =
|
|
664
|
+
change1.nodeExistsConstraintOnRevert ?? change2.nodeExistsConstraintOnRevert;
|
|
665
|
+
|
|
654
666
|
const composedFieldChanges = this.composeFieldMaps(
|
|
655
667
|
change1.fieldChanges,
|
|
656
668
|
change2.fieldChanges,
|
|
@@ -670,6 +682,10 @@ export class ModularChangeFamily
|
|
|
670
682
|
composedNodeChange.nodeExistsConstraint = nodeExistsConstraint;
|
|
671
683
|
}
|
|
672
684
|
|
|
685
|
+
if (nodeExistsConstraintOnRevert !== undefined) {
|
|
686
|
+
composedNodeChange.nodeExistsConstraintOnRevert = nodeExistsConstraintOnRevert;
|
|
687
|
+
}
|
|
688
|
+
|
|
673
689
|
return composedNodeChange;
|
|
674
690
|
}
|
|
675
691
|
|
|
@@ -778,7 +794,8 @@ export class ModularChangeFamily
|
|
|
778
794
|
crossFieldKeys,
|
|
779
795
|
maxId: genId.getMaxId(),
|
|
780
796
|
revisions: revInfos,
|
|
781
|
-
constraintViolationCount: change.change.
|
|
797
|
+
constraintViolationCount: change.change.constraintViolationCountOnRevert,
|
|
798
|
+
constraintViolationCountOnRevert: change.change.constraintViolationCount,
|
|
782
799
|
destroys,
|
|
783
800
|
});
|
|
784
801
|
}
|
|
@@ -835,6 +852,19 @@ export class ModularChangeFamily
|
|
|
835
852
|
): NodeChangeset {
|
|
836
853
|
const inverse: NodeChangeset = {};
|
|
837
854
|
|
|
855
|
+
// If the node has a constraint, it should be inverted to a node-exist-on-revert constraint. This ensure that if
|
|
856
|
+
// the inverse is inverted again, the original input constraint will be restored.
|
|
857
|
+
if (change.nodeExistsConstraint !== undefined) {
|
|
858
|
+
inverse.nodeExistsConstraintOnRevert = change.nodeExistsConstraint;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// The node-exist-on-revert constraint of a node is the constraint that should apply when the a change is reverted.
|
|
862
|
+
// So, it should become the constraint in the inverse. If this constraint is violated when applying the inverse,
|
|
863
|
+
// it will be discarded.
|
|
864
|
+
if (change.nodeExistsConstraintOnRevert !== undefined) {
|
|
865
|
+
inverse.nodeExistsConstraint = change.nodeExistsConstraintOnRevert;
|
|
866
|
+
}
|
|
867
|
+
|
|
838
868
|
if (change.fieldChanges !== undefined) {
|
|
839
869
|
inverse.fieldChanges = this.invertFieldMap(
|
|
840
870
|
change.fieldChanges,
|
|
@@ -878,8 +908,6 @@ export class ModularChangeFamily
|
|
|
878
908
|
fieldsWithUnattachedChild: new Set(),
|
|
879
909
|
};
|
|
880
910
|
|
|
881
|
-
const constraintState = newConstraintState(change.constraintViolationCount ?? 0);
|
|
882
|
-
|
|
883
911
|
const getBaseRevisions = (): RevisionTag[] =>
|
|
884
912
|
revisionInfoFromTaggedChange(over).map((info) => info.revision);
|
|
885
913
|
|
|
@@ -895,7 +923,6 @@ export class ModularChangeFamily
|
|
|
895
923
|
crossFieldTable,
|
|
896
924
|
rebasedNodes,
|
|
897
925
|
genId,
|
|
898
|
-
constraintState,
|
|
899
926
|
rebaseMetadata,
|
|
900
927
|
);
|
|
901
928
|
|
|
@@ -907,10 +934,16 @@ export class ModularChangeFamily
|
|
|
907
934
|
genId,
|
|
908
935
|
);
|
|
909
936
|
|
|
937
|
+
const constraintState = newConstraintState(change.constraintViolationCount ?? 0);
|
|
938
|
+
const revertConstraintState = newConstraintState(
|
|
939
|
+
change.constraintViolationCountOnRevert ?? 0,
|
|
940
|
+
);
|
|
910
941
|
this.updateConstraintsForFields(
|
|
911
942
|
rebasedFields,
|
|
912
943
|
NodeAttachState.Attached,
|
|
944
|
+
NodeAttachState.Attached,
|
|
913
945
|
constraintState,
|
|
946
|
+
revertConstraintState,
|
|
914
947
|
rebasedNodes,
|
|
915
948
|
);
|
|
916
949
|
|
|
@@ -923,6 +956,7 @@ export class ModularChangeFamily
|
|
|
923
956
|
maxId: idState.maxId,
|
|
924
957
|
revisions: change.revisions,
|
|
925
958
|
constraintViolationCount: constraintState.violationCount,
|
|
959
|
+
constraintViolationCountOnRevert: revertConstraintState.violationCount,
|
|
926
960
|
builds: change.builds,
|
|
927
961
|
destroys: change.destroys,
|
|
928
962
|
refreshers: change.refreshers,
|
|
@@ -937,7 +971,6 @@ export class ModularChangeFamily
|
|
|
937
971
|
crossFieldTable: RebaseTable,
|
|
938
972
|
rebasedNodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
939
973
|
genId: IdAllocator,
|
|
940
|
-
constraintState: ConstraintState,
|
|
941
974
|
metadata: RebaseRevisionMetadata,
|
|
942
975
|
): FieldChangeMap {
|
|
943
976
|
const change = crossFieldTable.newChange;
|
|
@@ -960,7 +993,6 @@ export class ModularChangeFamily
|
|
|
960
993
|
genId,
|
|
961
994
|
crossFieldTable,
|
|
962
995
|
metadata,
|
|
963
|
-
constraintState,
|
|
964
996
|
);
|
|
965
997
|
|
|
966
998
|
setInChangeAtomIdMap(rebasedNodes, newId, rebasedNode);
|
|
@@ -1336,7 +1368,6 @@ export class ModularChangeFamily
|
|
|
1336
1368
|
genId: IdAllocator,
|
|
1337
1369
|
crossFieldTable: RebaseTable,
|
|
1338
1370
|
revisionMetadata: RebaseRevisionMetadata,
|
|
1339
|
-
constraintState: ConstraintState,
|
|
1340
1371
|
): NodeChangeset {
|
|
1341
1372
|
const change = nodeChangeFromId(crossFieldTable.newChange.nodeChanges, newId);
|
|
1342
1373
|
const over = nodeChangeFromId(crossFieldTable.baseChange.nodeChanges, baseId);
|
|
@@ -1365,38 +1396,58 @@ export class ModularChangeFamily
|
|
|
1365
1396
|
rebasedChange.nodeExistsConstraint = change.nodeExistsConstraint;
|
|
1366
1397
|
}
|
|
1367
1398
|
|
|
1399
|
+
if (change?.nodeExistsConstraintOnRevert !== undefined) {
|
|
1400
|
+
rebasedChange.nodeExistsConstraintOnRevert = change.nodeExistsConstraintOnRevert;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1368
1403
|
setInChangeAtomIdMap(crossFieldTable.baseToRebasedNodeId, baseId, newId);
|
|
1369
1404
|
return rebasedChange;
|
|
1370
1405
|
}
|
|
1371
1406
|
|
|
1372
1407
|
private updateConstraintsForFields(
|
|
1373
1408
|
fields: FieldChangeMap,
|
|
1374
|
-
|
|
1409
|
+
parentInputAttachState: NodeAttachState,
|
|
1410
|
+
parentOutputAttachState: NodeAttachState,
|
|
1375
1411
|
constraintState: ConstraintState,
|
|
1412
|
+
revertConstraintState: ConstraintState,
|
|
1376
1413
|
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1377
1414
|
): void {
|
|
1378
1415
|
for (const field of fields.values()) {
|
|
1379
1416
|
const handler = getChangeHandler(this.fieldKinds, field.fieldKind);
|
|
1380
|
-
for (const [nodeId,
|
|
1381
|
-
const
|
|
1382
|
-
const
|
|
1383
|
-
|
|
1417
|
+
for (const [nodeId, inputIndex, outputIndex] of handler.getNestedChanges(field.change)) {
|
|
1418
|
+
const isInputDetached = inputIndex === undefined;
|
|
1419
|
+
const inputAttachState =
|
|
1420
|
+
parentInputAttachState === NodeAttachState.Detached || isInputDetached
|
|
1384
1421
|
? NodeAttachState.Detached
|
|
1385
1422
|
: NodeAttachState.Attached;
|
|
1386
|
-
|
|
1423
|
+
const isOutputDetached = outputIndex === undefined;
|
|
1424
|
+
const outputAttachState =
|
|
1425
|
+
parentOutputAttachState === NodeAttachState.Detached || isOutputDetached
|
|
1426
|
+
? NodeAttachState.Detached
|
|
1427
|
+
: NodeAttachState.Attached;
|
|
1428
|
+
this.updateConstraintsForNode(
|
|
1429
|
+
nodeId,
|
|
1430
|
+
inputAttachState,
|
|
1431
|
+
outputAttachState,
|
|
1432
|
+
nodes,
|
|
1433
|
+
constraintState,
|
|
1434
|
+
revertConstraintState,
|
|
1435
|
+
);
|
|
1387
1436
|
}
|
|
1388
1437
|
}
|
|
1389
1438
|
}
|
|
1390
1439
|
|
|
1391
1440
|
private updateConstraintsForNode(
|
|
1392
1441
|
nodeId: NodeId,
|
|
1393
|
-
|
|
1394
|
-
|
|
1442
|
+
inputAttachState: NodeAttachState,
|
|
1443
|
+
outputAttachState: NodeAttachState,
|
|
1395
1444
|
nodes: ChangeAtomIdBTree<NodeChangeset>,
|
|
1445
|
+
constraintState: ConstraintState,
|
|
1446
|
+
revertConstraintState: ConstraintState,
|
|
1396
1447
|
): void {
|
|
1397
1448
|
const node = nodes.get([nodeId.revision, nodeId.localId]) ?? fail("Unknown node ID");
|
|
1398
1449
|
if (node.nodeExistsConstraint !== undefined) {
|
|
1399
|
-
const isNowViolated =
|
|
1450
|
+
const isNowViolated = inputAttachState === NodeAttachState.Detached;
|
|
1400
1451
|
if (node.nodeExistsConstraint.violated !== isNowViolated) {
|
|
1401
1452
|
node.nodeExistsConstraint = {
|
|
1402
1453
|
...node.nodeExistsConstraint,
|
|
@@ -1405,9 +1456,26 @@ export class ModularChangeFamily
|
|
|
1405
1456
|
constraintState.violationCount += isNowViolated ? 1 : -1;
|
|
1406
1457
|
}
|
|
1407
1458
|
}
|
|
1459
|
+
if (node.nodeExistsConstraintOnRevert !== undefined) {
|
|
1460
|
+
const isNowViolated = outputAttachState === NodeAttachState.Detached;
|
|
1461
|
+
if (node.nodeExistsConstraintOnRevert.violated !== isNowViolated) {
|
|
1462
|
+
node.nodeExistsConstraintOnRevert = {
|
|
1463
|
+
...node.nodeExistsConstraintOnRevert,
|
|
1464
|
+
violated: isNowViolated,
|
|
1465
|
+
};
|
|
1466
|
+
revertConstraintState.violationCount += isNowViolated ? 1 : -1;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1408
1469
|
|
|
1409
1470
|
if (node.fieldChanges !== undefined) {
|
|
1410
|
-
this.updateConstraintsForFields(
|
|
1471
|
+
this.updateConstraintsForFields(
|
|
1472
|
+
node.fieldChanges,
|
|
1473
|
+
inputAttachState,
|
|
1474
|
+
outputAttachState,
|
|
1475
|
+
constraintState,
|
|
1476
|
+
revertConstraintState,
|
|
1477
|
+
nodes,
|
|
1478
|
+
);
|
|
1411
1479
|
}
|
|
1412
1480
|
}
|
|
1413
1481
|
|
|
@@ -1907,6 +1975,7 @@ export function updateRefreshers(
|
|
|
1907
1975
|
maxId,
|
|
1908
1976
|
revisions,
|
|
1909
1977
|
constraintViolationCount,
|
|
1978
|
+
constraintViolationCountOnRevert,
|
|
1910
1979
|
builds,
|
|
1911
1980
|
destroys,
|
|
1912
1981
|
} = change;
|
|
@@ -1920,6 +1989,7 @@ export function updateRefreshers(
|
|
|
1920
1989
|
maxId: maxId as number,
|
|
1921
1990
|
revisions,
|
|
1922
1991
|
constraintViolationCount,
|
|
1992
|
+
constraintViolationCountOnRevert,
|
|
1923
1993
|
builds,
|
|
1924
1994
|
destroys,
|
|
1925
1995
|
refreshers,
|
|
@@ -1935,17 +2005,11 @@ export function intoDelta(
|
|
|
1935
2005
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>,
|
|
1936
2006
|
): DeltaRoot {
|
|
1937
2007
|
const change = taggedChange.change;
|
|
1938
|
-
const idAllocator = MemoizedIdRangeAllocator.fromNextId();
|
|
1939
2008
|
const rootDelta: Mutable<DeltaRoot> = {};
|
|
1940
2009
|
|
|
1941
2010
|
if (!hasConflicts(change)) {
|
|
1942
2011
|
// If there are no constraint violations, then tree changes apply.
|
|
1943
|
-
const fieldDeltas = intoDeltaImpl(
|
|
1944
|
-
change.fieldChanges,
|
|
1945
|
-
change.nodeChanges,
|
|
1946
|
-
idAllocator,
|
|
1947
|
-
fieldKinds,
|
|
1948
|
-
);
|
|
2012
|
+
const fieldDeltas = intoDeltaImpl(change.fieldChanges, change.nodeChanges, fieldKinds);
|
|
1949
2013
|
if (fieldDeltas.size > 0) {
|
|
1950
2014
|
rootDelta.fields = fieldDeltas;
|
|
1951
2015
|
}
|
|
@@ -1995,7 +2059,6 @@ function copyDetachedNodes(
|
|
|
1995
2059
|
function intoDeltaImpl(
|
|
1996
2060
|
change: FieldChangeMap,
|
|
1997
2061
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
|
|
1998
|
-
idAllocator: MemoizedIdRangeAllocator,
|
|
1999
2062
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>,
|
|
2000
2063
|
): Map<FieldKey, DeltaFieldChanges> {
|
|
2001
2064
|
const delta: Map<FieldKey, DeltaFieldChanges> = new Map();
|
|
@@ -2004,9 +2067,8 @@ function intoDeltaImpl(
|
|
|
2004
2067
|
fieldChange.change,
|
|
2005
2068
|
(childChange): DeltaFieldMap => {
|
|
2006
2069
|
const nodeChange = nodeChangeFromId(nodeChanges, childChange);
|
|
2007
|
-
return deltaFromNodeChange(nodeChange, nodeChanges,
|
|
2070
|
+
return deltaFromNodeChange(nodeChange, nodeChanges, fieldKinds);
|
|
2008
2071
|
},
|
|
2009
|
-
idAllocator,
|
|
2010
2072
|
);
|
|
2011
2073
|
if (!isEmptyFieldChanges(deltaField)) {
|
|
2012
2074
|
delta.set(field, deltaField);
|
|
@@ -2018,11 +2080,10 @@ function intoDeltaImpl(
|
|
|
2018
2080
|
function deltaFromNodeChange(
|
|
2019
2081
|
change: NodeChangeset,
|
|
2020
2082
|
nodeChanges: ChangeAtomIdBTree<NodeChangeset>,
|
|
2021
|
-
idAllocator: MemoizedIdRangeAllocator,
|
|
2022
2083
|
fieldKinds: ReadonlyMap<FieldKindIdentifier, FieldKindWithEditor>,
|
|
2023
2084
|
): DeltaFieldMap {
|
|
2024
2085
|
if (change.fieldChanges !== undefined) {
|
|
2025
|
-
return intoDeltaImpl(change.fieldChanges, nodeChanges,
|
|
2086
|
+
return intoDeltaImpl(change.fieldChanges, nodeChanges, fieldKinds);
|
|
2026
2087
|
}
|
|
2027
2088
|
// TODO: update the API to allow undefined to be returned here
|
|
2028
2089
|
return new Map();
|
|
@@ -2061,7 +2122,11 @@ export function rebaseRevisionMetadataFromInfo(
|
|
|
2061
2122
|
}
|
|
2062
2123
|
|
|
2063
2124
|
function isEmptyNodeChangeset(change: NodeChangeset): boolean {
|
|
2064
|
-
return
|
|
2125
|
+
return (
|
|
2126
|
+
change.fieldChanges === undefined &&
|
|
2127
|
+
change.nodeExistsConstraint === undefined &&
|
|
2128
|
+
change.nodeExistsConstraintOnRevert === undefined
|
|
2129
|
+
);
|
|
2065
2130
|
}
|
|
2066
2131
|
|
|
2067
2132
|
export function getFieldKind(
|
|
@@ -2504,6 +2569,7 @@ function makeModularChangeset(
|
|
|
2504
2569
|
maxId: number;
|
|
2505
2570
|
revisions?: readonly RevisionInfo[];
|
|
2506
2571
|
constraintViolationCount?: number;
|
|
2572
|
+
constraintViolationCountOnRevert?: number;
|
|
2507
2573
|
builds?: ChangeAtomIdBTree<TreeChunk>;
|
|
2508
2574
|
destroys?: ChangeAtomIdBTree<number>;
|
|
2509
2575
|
refreshers?: ChangeAtomIdBTree<TreeChunk>;
|
|
@@ -2528,6 +2594,12 @@ function makeModularChangeset(
|
|
|
2528
2594
|
if (props.constraintViolationCount !== undefined && props.constraintViolationCount > 0) {
|
|
2529
2595
|
changeset.constraintViolationCount = props.constraintViolationCount;
|
|
2530
2596
|
}
|
|
2597
|
+
if (
|
|
2598
|
+
props.constraintViolationCountOnRevert !== undefined &&
|
|
2599
|
+
props.constraintViolationCountOnRevert > 0
|
|
2600
|
+
) {
|
|
2601
|
+
changeset.constraintViolationCountOnRevert = props.constraintViolationCountOnRevert;
|
|
2602
|
+
}
|
|
2531
2603
|
if (props.builds !== undefined && props.builds.size > 0) {
|
|
2532
2604
|
changeset.builds = props.builds;
|
|
2533
2605
|
}
|
|
@@ -2702,6 +2774,27 @@ export class ModularEditBuilder extends EditBuilder<ModularChangeset> {
|
|
|
2702
2774
|
),
|
|
2703
2775
|
);
|
|
2704
2776
|
}
|
|
2777
|
+
|
|
2778
|
+
public addNodeExistsConstraintOnRevert(path: UpPath, revision: RevisionTag): void {
|
|
2779
|
+
const nodeChange: NodeChangeset = {
|
|
2780
|
+
nodeExistsConstraintOnRevert: { violated: false },
|
|
2781
|
+
};
|
|
2782
|
+
|
|
2783
|
+
this.applyChange(
|
|
2784
|
+
tagChange(
|
|
2785
|
+
buildModularChangesetFromNode({
|
|
2786
|
+
path,
|
|
2787
|
+
nodeChange,
|
|
2788
|
+
nodeChanges: newTupleBTree(),
|
|
2789
|
+
nodeToParent: newTupleBTree(),
|
|
2790
|
+
crossFieldKeys: newCrossFieldKeyTable(),
|
|
2791
|
+
idAllocator: this.idAllocator,
|
|
2792
|
+
revision,
|
|
2793
|
+
}),
|
|
2794
|
+
revision,
|
|
2795
|
+
),
|
|
2796
|
+
);
|
|
2797
|
+
}
|
|
2705
2798
|
}
|
|
2706
2799
|
|
|
2707
2800
|
function buildModularChangesetFromField(props: {
|
|
@@ -56,7 +56,16 @@ export interface ModularChangeset extends HasFieldChanges {
|
|
|
56
56
|
*/
|
|
57
57
|
readonly nodeAliases: ChangeAtomIdBTree<NodeId>;
|
|
58
58
|
readonly crossFieldKeys: CrossFieldKeyTable;
|
|
59
|
+
/**
|
|
60
|
+
* The number of constraint violations that apply to the input context of the changeset, i.e., before this change is applied.
|
|
61
|
+
* If this count is greater than 0, it will prevent the changeset from being applied.
|
|
62
|
+
*/
|
|
59
63
|
readonly constraintViolationCount?: number;
|
|
64
|
+
/**
|
|
65
|
+
* The number of constraint violations that apply to the revert of the changeset. If this count is greater than 0, it will
|
|
66
|
+
* prevent the changeset from being reverted or undone.
|
|
67
|
+
*/
|
|
68
|
+
readonly constraintViolationCountOnRevert?: number;
|
|
60
69
|
readonly builds?: ChangeAtomIdBTree<TreeChunk>;
|
|
61
70
|
readonly destroys?: ChangeAtomIdBTree<number>;
|
|
62
71
|
readonly refreshers?: ChangeAtomIdBTree<TreeChunk>;
|
|
@@ -97,7 +106,10 @@ export interface NodeExistsConstraint {
|
|
|
97
106
|
* Changeset for a subtree rooted at a specific node.
|
|
98
107
|
*/
|
|
99
108
|
export interface NodeChangeset extends HasFieldChanges {
|
|
109
|
+
/** Keeps track of whether node exists constraint has been violated by this change */
|
|
100
110
|
nodeExistsConstraint?: NodeExistsConstraint;
|
|
111
|
+
/** Keeps track of whether node exists constraint will be violated when this change is reverted */
|
|
112
|
+
nodeExistsConstraintOnRevert?: NodeExistsConstraint;
|
|
101
113
|
}
|
|
102
114
|
|
|
103
115
|
export type NodeId = ChangeAtomId;
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
type NodeId,
|
|
40
40
|
type RelevantRemovedRootsFromChild,
|
|
41
41
|
type ToDelta,
|
|
42
|
+
type NestedChangesIndices,
|
|
42
43
|
} from "../modular-schema/index.js";
|
|
43
44
|
|
|
44
45
|
import type {
|
|
@@ -536,6 +537,16 @@ function areEqualRegisterIds(id1: RegisterId, id2: RegisterId): boolean {
|
|
|
536
537
|
return id1 === "self" || id2 === "self" ? id1 === id2 : areEqualChangeAtomIds(id1, id2);
|
|
537
538
|
}
|
|
538
539
|
|
|
540
|
+
function areEqualRegisterIdsOpt(
|
|
541
|
+
id1: RegisterId | undefined,
|
|
542
|
+
id2: RegisterId | undefined,
|
|
543
|
+
): boolean {
|
|
544
|
+
if (id1 === undefined || id2 === undefined) {
|
|
545
|
+
return id1 === id2;
|
|
546
|
+
}
|
|
547
|
+
return areEqualRegisterIds(id1, id2);
|
|
548
|
+
}
|
|
549
|
+
|
|
539
550
|
function getBidirectionalMaps(moves: OptionalChangeset["moves"]): {
|
|
540
551
|
srcToDst: ChangeAtomIdMap<ChangeAtomId>;
|
|
541
552
|
dstToSrc: ChangeAtomIdMap<ChangeAtomId>;
|
|
@@ -720,11 +731,29 @@ export const optionalChangeHandler: FieldChangeHandler<
|
|
|
720
731
|
getCrossFieldKeys: (_change) => [],
|
|
721
732
|
};
|
|
722
733
|
|
|
723
|
-
function getNestedChanges(change: OptionalChangeset):
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
734
|
+
function getNestedChanges(change: OptionalChangeset): NestedChangesIndices {
|
|
735
|
+
// True iff the content of the field changes in some way
|
|
736
|
+
const isFieldContentChanged =
|
|
737
|
+
change.valueReplace !== undefined && change.valueReplace.src !== "self";
|
|
738
|
+
|
|
739
|
+
// The node that is moved into the field (if any).
|
|
740
|
+
const nodeMovedIntoField = change.valueReplace?.src;
|
|
741
|
+
|
|
742
|
+
return change.childChanges.map(([register, nodeId]) => {
|
|
743
|
+
// The node is removed in the input context iif register is not self.
|
|
744
|
+
const inputIndex = register === "self" ? 0 : undefined;
|
|
745
|
+
const outputIndex =
|
|
746
|
+
register === "self"
|
|
747
|
+
? // If the node starts out as not-removed, it is removed in the output context iff the field content is changed
|
|
748
|
+
isFieldContentChanged
|
|
749
|
+
? undefined
|
|
750
|
+
: 0
|
|
751
|
+
: // If the node starts out as removed, then it remains removed in the output context iff it is not the node that is moved into the field
|
|
752
|
+
!areEqualRegisterIdsOpt(register, nodeMovedIntoField)
|
|
753
|
+
? undefined
|
|
754
|
+
: 0;
|
|
755
|
+
return [nodeId, inputIndex, outputIndex];
|
|
756
|
+
});
|
|
728
757
|
}
|
|
729
758
|
|
|
730
759
|
function* relevantRemovedRoots(
|