@fluidframework/tree 2.41.0 → 2.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -0
- package/CHANGELOG.md +33 -0
- package/api-report/tree.alpha.api.md +11 -7
- package/dist/alpha.d.ts +1 -0
- package/dist/codec/codec.d.ts +23 -3
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/index.d.ts +1 -1
- package/dist/codec/index.d.ts.map +1 -1
- package/dist/codec/index.js.map +1 -1
- package/dist/codec/versioned/codec.d.ts +35 -2
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js +38 -3
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/core/tree/detachedFieldIndex.d.ts +2 -2
- package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndex.js +5 -1
- package/dist/core/tree/detachedFieldIndex.js.map +1 -1
- package/dist/core/tree/mapTree.d.ts +2 -1
- package/dist/core/tree/mapTree.d.ts.map +1 -1
- package/dist/core/tree/mapTree.js +11 -5
- package/dist/core/tree/mapTree.js.map +1 -1
- package/dist/core/tree/visitorUtils.d.ts +2 -2
- package/dist/core/tree/visitorUtils.d.ts.map +1 -1
- package/dist/core/tree/visitorUtils.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts +3 -2
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/default-schema/schemaChecker.d.ts +4 -3
- package/dist/feature-libraries/default-schema/schemaChecker.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/schemaChecker.js +4 -3
- package/dist/feature-libraries/default-schema/schemaChecker.js.map +1 -1
- package/dist/feature-libraries/flex-tree/context.d.ts +14 -6
- package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +34 -14
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.js +4 -0
- package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/dist/feature-libraries/flex-tree/index.d.ts +2 -2
- package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/index.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.d.ts +6 -6
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.d.ts +3 -2
- package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +3 -0
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +2 -2
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +7 -7
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +2 -2
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +4 -2
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.d.ts +39 -3
- package/dist/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/dist/feature-libraries/mapTreeCursor.js +45 -7
- package/dist/feature-libraries/mapTreeCursor.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +5 -5
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/treeCursorUtils.d.ts +5 -1
- package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
- package/dist/feature-libraries/treeCursorUtils.js +8 -2
- package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +11 -1
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +36 -22
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +3 -3
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +1 -0
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/tree.d.ts.map +1 -1
- package/dist/shared-tree/tree.js +8 -24
- package/dist/shared-tree/tree.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts +2 -3
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +13 -15
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +5 -2
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/simple-tree/api/configuration.d.ts +2 -2
- package/dist/simple-tree/api/configuration.js +1 -1
- package/dist/simple-tree/api/configuration.js.map +1 -1
- package/dist/simple-tree/api/create.d.ts +9 -4
- package/dist/simple-tree/api/create.d.ts.map +1 -1
- package/dist/simple-tree/api/create.js +29 -16
- package/dist/simple-tree/api/create.js.map +1 -1
- package/dist/simple-tree/api/customTree.d.ts +4 -0
- package/dist/simple-tree/api/customTree.d.ts.map +1 -1
- package/dist/simple-tree/api/customTree.js +9 -1
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +1 -1
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +1 -2
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +10 -2
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +38 -9
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.d.ts +14 -3
- package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.js +32 -17
- package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/dist/simple-tree/api/verboseTree.js +12 -9
- package/dist/simple-tree/api/verboseTree.js.map +1 -1
- package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
- package/dist/simple-tree/core/getOrCreateNode.js +2 -1
- package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
- package/dist/simple-tree/core/index.d.ts +2 -2
- package/dist/simple-tree/core/index.d.ts.map +1 -1
- package/dist/simple-tree/core/index.js +3 -4
- package/dist/simple-tree/core/index.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts +15 -25
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +26 -33
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts +128 -59
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +169 -182
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/index.d.ts +3 -3
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +5 -5
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +5 -6
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/index.d.ts +1 -1
- package/dist/simple-tree/node-kinds/index.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/index.js +1 -2
- package/dist/simple-tree/node-kinds/index.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/object/index.d.ts +1 -1
- package/dist/simple-tree/node-kinds/object/index.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/index.js +1 -2
- package/dist/simple-tree/node-kinds/object/index.js.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.d.ts +3 -14
- package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.js +12 -43
- package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/dist/simple-tree/prepareForInsertion.d.ts +20 -6
- package/dist/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/dist/simple-tree/prepareForInsertion.js +26 -19
- package/dist/simple-tree/prepareForInsertion.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +8 -8
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts +6 -1
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +6 -3
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/dist/simple-tree/{toMapTree.d.ts → unhydratedFlexTreeFromInsertable.d.ts} +12 -23
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -0
- package/dist/simple-tree/{toMapTree.js → unhydratedFlexTreeFromInsertable.js} +103 -185
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -0
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +6 -1
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/index.d.ts +1 -1
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +2 -1
- package/dist/util/index.js.map +1 -1
- package/dist/util/utils.d.ts +4 -0
- package/dist/util/utils.d.ts.map +1 -1
- package/dist/util/utils.js +8 -1
- package/dist/util/utils.js.map +1 -1
- package/docs/user-facing/schema-evolution.md +1 -1
- package/lib/alpha.d.ts +1 -0
- package/lib/codec/codec.d.ts +23 -3
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/index.d.ts +1 -1
- package/lib/codec/index.d.ts.map +1 -1
- package/lib/codec/index.js.map +1 -1
- package/lib/codec/versioned/codec.d.ts +35 -2
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js +36 -2
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/core/tree/detachedFieldIndex.d.ts +2 -2
- package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndex.js +6 -2
- package/lib/core/tree/detachedFieldIndex.js.map +1 -1
- package/lib/core/tree/mapTree.d.ts +2 -1
- package/lib/core/tree/mapTree.d.ts.map +1 -1
- package/lib/core/tree/mapTree.js +11 -5
- package/lib/core/tree/mapTree.js.map +1 -1
- package/lib/core/tree/visitorUtils.d.ts +2 -2
- package/lib/core/tree/visitorUtils.d.ts.map +1 -1
- package/lib/core/tree/visitorUtils.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts +3 -2
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/default-schema/schemaChecker.d.ts +4 -3
- package/lib/feature-libraries/default-schema/schemaChecker.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/schemaChecker.js +4 -3
- package/lib/feature-libraries/default-schema/schemaChecker.js.map +1 -1
- package/lib/feature-libraries/flex-tree/context.d.ts +14 -6
- package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +34 -14
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.js +4 -0
- package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/lib/feature-libraries/flex-tree/index.d.ts +2 -2
- package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/index.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.d.ts +6 -6
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.d.ts +3 -2
- package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +3 -0
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +2 -2
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +2 -2
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +2 -2
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +1 -1
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.d.ts +39 -3
- package/lib/feature-libraries/mapTreeCursor.d.ts.map +1 -1
- package/lib/feature-libraries/mapTreeCursor.js +43 -7
- package/lib/feature-libraries/mapTreeCursor.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +5 -5
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/treeCursorUtils.d.ts +5 -1
- package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
- package/lib/feature-libraries/treeCursorUtils.js +8 -2
- package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +11 -1
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +34 -21
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +3 -3
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +2 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/tree.d.ts.map +1 -1
- package/lib/shared-tree/tree.js +2 -18
- package/lib/shared-tree/tree.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts +2 -3
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +4 -6
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +6 -3
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/simple-tree/api/configuration.d.ts +2 -2
- package/lib/simple-tree/api/configuration.js +1 -1
- package/lib/simple-tree/api/configuration.js.map +1 -1
- package/lib/simple-tree/api/create.d.ts +9 -4
- package/lib/simple-tree/api/create.d.ts.map +1 -1
- package/lib/simple-tree/api/create.js +22 -9
- package/lib/simple-tree/api/create.js.map +1 -1
- package/lib/simple-tree/api/customTree.d.ts +4 -0
- package/lib/simple-tree/api/customTree.d.ts.map +1 -1
- package/lib/simple-tree/api/customTree.js +7 -0
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +1 -1
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -1
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +10 -2
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +40 -11
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.d.ts +14 -3
- package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.js +35 -20
- package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/lib/simple-tree/api/verboseTree.js +13 -10
- package/lib/simple-tree/api/verboseTree.js.map +1 -1
- package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
- package/lib/simple-tree/core/getOrCreateNode.js +3 -2
- package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
- package/lib/simple-tree/core/index.d.ts +2 -2
- package/lib/simple-tree/core/index.d.ts.map +1 -1
- package/lib/simple-tree/core/index.js +2 -2
- package/lib/simple-tree/core/index.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts +15 -25
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +24 -32
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts +128 -59
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +166 -181
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/index.d.ts +3 -3
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +3 -3
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +4 -5
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/index.d.ts +1 -1
- package/lib/simple-tree/node-kinds/index.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/index.js +1 -1
- package/lib/simple-tree/node-kinds/index.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 +3 -3
- package/lib/simple-tree/node-kinds/map/mapNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/index.d.ts +1 -1
- package/lib/simple-tree/node-kinds/object/index.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/index.js +1 -1
- package/lib/simple-tree/node-kinds/object/index.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.d.ts +3 -14
- package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.js +3 -33
- package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/lib/simple-tree/prepareForInsertion.d.ts +20 -6
- package/lib/simple-tree/prepareForInsertion.d.ts.map +1 -1
- package/lib/simple-tree/prepareForInsertion.js +25 -19
- package/lib/simple-tree/prepareForInsertion.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +8 -8
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts +6 -1
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +4 -1
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/lib/simple-tree/{toMapTree.d.ts → unhydratedFlexTreeFromInsertable.d.ts} +12 -23
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -0
- package/lib/simple-tree/{toMapTree.js → unhydratedFlexTreeFromInsertable.js} +105 -186
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -0
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +6 -1
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/index.d.ts +1 -1
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +1 -1
- package/lib/util/index.js.map +1 -1
- package/lib/util/utils.d.ts +4 -0
- package/lib/util/utils.d.ts.map +1 -1
- package/lib/util/utils.js +6 -0
- package/lib/util/utils.js.map +1 -1
- package/package.json +21 -21
- package/src/codec/codec.ts +24 -3
- package/src/codec/index.ts +1 -0
- package/src/codec/versioned/codec.ts +42 -5
- package/src/core/tree/detachedFieldIndex.ts +13 -4
- package/src/core/tree/mapTree.ts +22 -7
- package/src/core/tree/visitorUtils.ts +2 -2
- package/src/feature-libraries/default-schema/defaultEditBuilder.ts +3 -2
- package/src/feature-libraries/default-schema/schemaChecker.ts +7 -6
- package/src/feature-libraries/flex-tree/context.ts +17 -7
- package/src/feature-libraries/flex-tree/flexTreeTypes.ts +36 -15
- package/src/feature-libraries/flex-tree/index.ts +4 -0
- package/src/feature-libraries/flex-tree/lazyField.ts +8 -6
- package/src/feature-libraries/flex-tree/lazyNode.ts +6 -2
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +3 -2
- package/src/feature-libraries/index.ts +9 -0
- package/src/feature-libraries/mapTreeCursor.ts +103 -16
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +9 -5
- package/src/feature-libraries/treeCursorUtils.ts +21 -10
- package/src/index.ts +1 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +40 -22
- package/src/shared-tree/sharedTree.ts +9 -3
- package/src/shared-tree/tree.ts +5 -20
- package/src/shared-tree/treeAlpha.ts +17 -11
- package/src/shared-tree/treeCheckout.ts +6 -3
- package/src/simple-tree/api/configuration.ts +3 -3
- package/src/simple-tree/api/create.ts +49 -19
- package/src/simple-tree/api/customTree.ts +10 -0
- package/src/simple-tree/api/index.ts +1 -4
- package/src/simple-tree/api/schemaFactory.ts +62 -13
- package/src/simple-tree/api/treeNodeApi.ts +48 -27
- package/src/simple-tree/api/verboseTree.ts +15 -12
- package/src/simple-tree/core/getOrCreateNode.ts +4 -2
- package/src/simple-tree/core/index.ts +2 -3
- package/src/simple-tree/core/treeNodeKernel.ts +37 -54
- package/src/simple-tree/core/unhydratedFlexTree.ts +222 -261
- package/src/simple-tree/index.ts +3 -3
- package/src/simple-tree/node-kinds/array/arrayNode.ts +12 -13
- package/src/simple-tree/node-kinds/index.ts +0 -1
- package/src/simple-tree/node-kinds/map/mapNode.ts +6 -9
- package/src/simple-tree/node-kinds/object/index.ts +0 -1
- package/src/simple-tree/node-kinds/object/objectNode.ts +7 -49
- package/src/simple-tree/prepareForInsertion.ts +49 -42
- package/src/simple-tree/schemaTypes.ts +9 -8
- package/src/simple-tree/toStoredSchema.ts +7 -1
- package/src/simple-tree/{toMapTree.ts → unhydratedFlexTreeFromInsertable.ts} +134 -226
- package/src/treeFactory.ts +6 -1
- package/src/util/index.ts +1 -0
- package/src/util/utils.ts +7 -0
- package/dist/simple-tree/toMapTree.d.ts.map +0 -1
- package/dist/simple-tree/toMapTree.js.map +0 -1
- package/lib/simple-tree/toMapTree.d.ts.map +0 -1
- package/lib/simple-tree/toMapTree.js.map +0 -1
|
@@ -10,49 +10,46 @@ import { isFluidHandle } from "@fluidframework/runtime-utils/internal";
|
|
|
10
10
|
import {
|
|
11
11
|
EmptyKey,
|
|
12
12
|
type FieldKey,
|
|
13
|
-
type
|
|
13
|
+
type NodeData,
|
|
14
14
|
type TreeValue,
|
|
15
15
|
type ValueSchema,
|
|
16
|
-
type ExclusiveMapTree,
|
|
17
16
|
} from "../core/index.js";
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
valueSchemaAllows,
|
|
21
|
-
type NodeIdentifierManager,
|
|
22
|
-
} from "../feature-libraries/index.js";
|
|
23
|
-
import { brand, isReadonlyArray, find, hasSome, hasSingle } from "../util/index.js";
|
|
17
|
+
import { FieldKinds, isTreeValue, valueSchemaAllows } from "../feature-libraries/index.js";
|
|
18
|
+
import { brand, isReadonlyArray, hasSingle } from "../util/index.js";
|
|
24
19
|
|
|
25
20
|
import { nullSchema } from "./leafNodeSchema.js";
|
|
26
21
|
import {
|
|
27
|
-
type FieldSchema,
|
|
28
22
|
type ImplicitAllowedTypes,
|
|
29
23
|
normalizeAllowedTypes,
|
|
30
|
-
extractFieldProvider,
|
|
31
24
|
isConstant,
|
|
32
|
-
type FieldProvider,
|
|
33
25
|
type ImplicitFieldSchema,
|
|
34
26
|
normalizeFieldSchema,
|
|
35
27
|
FieldKind,
|
|
36
28
|
type TreeLeafValue,
|
|
29
|
+
extractFieldProvider,
|
|
30
|
+
type ContextualFieldProvider,
|
|
37
31
|
} from "./schemaTypes.js";
|
|
38
32
|
import {
|
|
39
33
|
getKernel,
|
|
40
|
-
getSimpleNodeSchemaFromInnerNode,
|
|
41
34
|
isTreeNode,
|
|
42
35
|
NodeKind,
|
|
43
|
-
type InnerNode,
|
|
44
36
|
type TreeNode,
|
|
45
37
|
type TreeNodeSchema,
|
|
46
38
|
type Unhydrated,
|
|
47
39
|
UnhydratedFlexTreeNode,
|
|
40
|
+
UnhydratedSequenceField,
|
|
48
41
|
} from "./core/index.js";
|
|
49
42
|
// Required to prevent the introduction of new circular dependencies
|
|
50
43
|
// TODO: Having the schema provide their own policy functions for compatibility which
|
|
51
|
-
//
|
|
44
|
+
// unhydratedFlexTreeFromInsertable invokes instead of manually handling each kind would remove this bad
|
|
52
45
|
// dependency, and reduce coupling.
|
|
53
46
|
// eslint-disable-next-line import/no-internal-modules
|
|
54
47
|
import { isObjectNodeSchema } from "./node-kinds/object/objectNodeTypes.js";
|
|
55
48
|
import type { IFluidHandle } from "@fluidframework/core-interfaces";
|
|
49
|
+
// eslint-disable-next-line import/no-internal-modules
|
|
50
|
+
import { createField, type UnhydratedFlexTreeField } from "./core/unhydratedFlexTree.js";
|
|
51
|
+
import { convertFieldKind } from "./toStoredSchema.js";
|
|
52
|
+
import { getUnhydratedContext } from "./createContext.js";
|
|
56
53
|
|
|
57
54
|
/**
|
|
58
55
|
* Module notes:
|
|
@@ -66,7 +63,7 @@ import type { IFluidHandle } from "@fluidframework/core-interfaces";
|
|
|
66
63
|
*/
|
|
67
64
|
|
|
68
65
|
/**
|
|
69
|
-
* Transforms an input {@link TypedNode} tree to
|
|
66
|
+
* Transforms an input {@link TypedNode} tree to an {@link UnhydratedFlexTreeNode}.
|
|
70
67
|
* @param data - The input tree to be converted.
|
|
71
68
|
* If the data is an unsupported value (e.g. NaN), a fallback value will be used when supported,
|
|
72
69
|
* otherwise an error will be thrown.
|
|
@@ -83,18 +80,18 @@ import type { IFluidHandle } from "@fluidframework/core-interfaces";
|
|
|
83
80
|
* If `context` is not provided, defaults which require a context will be left empty which can be out of schema.
|
|
84
81
|
*
|
|
85
82
|
* @param allowedTypes - The set of types allowed by the parent context. Used to validate the input tree.
|
|
86
|
-
* @
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* The resulting tree will be populated with any defaults from {@link FieldProvider}s in the schema.
|
|
85
|
+
*
|
|
86
|
+
* Often throws UsageErrors for invalid data, but may miss some cases.
|
|
87
|
+
*
|
|
88
|
+
* Output should comply with the provided view schema, but this is not explicitly validated:
|
|
89
|
+
* validation against stored schema (to guard against document corruption) is done elsewhere.
|
|
92
90
|
*/
|
|
93
|
-
export function
|
|
91
|
+
export function unhydratedFlexTreeFromInsertable<TIn extends InsertableContent | undefined>(
|
|
94
92
|
data: TIn,
|
|
95
93
|
allowedTypes: ImplicitFieldSchema,
|
|
96
|
-
|
|
97
|
-
): TIn extends undefined ? undefined : ExclusiveMapTree {
|
|
94
|
+
): TIn extends undefined ? undefined : UnhydratedFlexTreeNode {
|
|
98
95
|
const normalizedFieldSchema = normalizeFieldSchema(allowedTypes);
|
|
99
96
|
|
|
100
97
|
if (data === undefined) {
|
|
@@ -102,72 +99,63 @@ export function mapTreeFromNodeData<TIn extends InsertableContent | undefined>(
|
|
|
102
99
|
if (normalizedFieldSchema.kind !== FieldKind.Optional) {
|
|
103
100
|
throw new UsageError("Got undefined for non-optional field.");
|
|
104
101
|
}
|
|
105
|
-
return undefined as TIn extends undefined ? undefined :
|
|
102
|
+
return undefined as TIn extends undefined ? undefined : UnhydratedFlexTreeNode;
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
const flexTree: UnhydratedFlexTreeNode = unhydratedFlexTreeFromInsertableNode(
|
|
106
|
+
data,
|
|
107
|
+
normalizedFieldSchema.allowedTypeSet,
|
|
108
|
+
);
|
|
111
109
|
|
|
112
|
-
return
|
|
110
|
+
return flexTree as TIn extends undefined ? undefined : UnhydratedFlexTreeNode;
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
/**
|
|
116
|
-
* Copy content from `data` into a
|
|
117
|
-
* Does NOT generate and default values for fields.
|
|
118
|
-
* Often throws UsageErrors for invalid data, but may miss some cases.
|
|
119
|
-
* @remarks
|
|
120
|
-
* Output is likely out of schema even for valid input due to missing defaults.
|
|
114
|
+
* Copy content from `data` into a UnhydratedFlexTreeNode.
|
|
121
115
|
*/
|
|
122
|
-
function
|
|
116
|
+
function unhydratedFlexTreeFromInsertableNode(
|
|
123
117
|
data: InsertableContent,
|
|
124
118
|
allowedTypes: ReadonlySet<TreeNodeSchema>,
|
|
125
|
-
):
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (innerNode instanceof UnhydratedFlexTreeNode) {
|
|
131
|
-
if (!allowedTypes.has(getSimpleNodeSchemaFromInnerNode(innerNode))) {
|
|
132
|
-
throw new UsageError("Invalid schema for this context.");
|
|
133
|
-
}
|
|
134
|
-
// TODO: mapTreeFromNodeData modifies the trees it gets to add defaults.
|
|
135
|
-
// Using a cached value here can result in this tree having defaults applied to it more than once.
|
|
136
|
-
// This is unnecessary and inefficient, but should be a no-op if all calls provide the same context (which they might not).
|
|
137
|
-
// A cleaner design (avoiding this cast) might be to apply defaults eagerly if they don't need a context, and lazily (when hydrating) if they do.
|
|
138
|
-
// This could avoid having to mutate the map tree to apply defaults, removing the need for this cast.
|
|
139
|
-
return innerNode.mapTree;
|
|
140
|
-
} else {
|
|
119
|
+
): UnhydratedFlexTreeNode {
|
|
120
|
+
if (isTreeNode(data)) {
|
|
121
|
+
const kernel = getKernel(data);
|
|
122
|
+
const inner = kernel.getInnerNodeIfUnhydrated();
|
|
123
|
+
if (inner === undefined) {
|
|
141
124
|
// The node is already hydrated, meaning that it already got inserted into the tree previously
|
|
142
125
|
throw new UsageError("A node may not be inserted into the tree more than once");
|
|
126
|
+
} else {
|
|
127
|
+
if (!allowedTypes.has(kernel.schema)) {
|
|
128
|
+
throw new UsageError("Invalid schema for this context.");
|
|
129
|
+
}
|
|
130
|
+
return inner;
|
|
143
131
|
}
|
|
144
132
|
}
|
|
145
133
|
|
|
146
|
-
assert(!isTreeNode(data), 0xa23 /* data without an inner node cannot be TreeNode */);
|
|
147
|
-
|
|
148
134
|
const schema = getType(data, allowedTypes);
|
|
149
135
|
|
|
150
|
-
let result:
|
|
136
|
+
let result: FlexContent;
|
|
151
137
|
switch (schema.kind) {
|
|
152
138
|
case NodeKind.Leaf:
|
|
153
|
-
result =
|
|
139
|
+
result = leafToFlexContent(data, schema, allowedTypes);
|
|
154
140
|
break;
|
|
155
141
|
case NodeKind.Array:
|
|
156
|
-
result =
|
|
142
|
+
result = arrayToFlexContent(data, schema);
|
|
157
143
|
break;
|
|
158
144
|
case NodeKind.Map:
|
|
159
|
-
result =
|
|
145
|
+
result = mapToFlexContent(data, schema);
|
|
160
146
|
break;
|
|
161
147
|
case NodeKind.Object:
|
|
162
|
-
result =
|
|
148
|
+
result = objectToFlexContent(data, schema);
|
|
163
149
|
break;
|
|
164
150
|
default:
|
|
165
151
|
unreachableCase(schema.kind);
|
|
166
152
|
}
|
|
167
153
|
|
|
168
|
-
return result;
|
|
154
|
+
return new UnhydratedFlexTreeNode(...result, getUnhydratedContext(schema));
|
|
169
155
|
}
|
|
170
156
|
|
|
157
|
+
type FlexContent = [NodeData, Map<FieldKey, UnhydratedFlexTreeField>];
|
|
158
|
+
|
|
171
159
|
/**
|
|
172
160
|
* Transforms data under a Leaf schema.
|
|
173
161
|
* @param data - The tree data to be transformed. Must be a {@link TreeValue}.
|
|
@@ -175,11 +163,11 @@ function nodeDataToMapTree(
|
|
|
175
163
|
* @param allowedTypes - The allowed types specified by the parent.
|
|
176
164
|
* Used to determine which fallback values may be appropriate.
|
|
177
165
|
*/
|
|
178
|
-
function
|
|
166
|
+
function leafToFlexContent(
|
|
179
167
|
data: FactoryContent,
|
|
180
168
|
schema: TreeNodeSchema,
|
|
181
169
|
allowedTypes: ReadonlySet<TreeNodeSchema>,
|
|
182
|
-
):
|
|
170
|
+
): FlexContent {
|
|
183
171
|
assert(schema.kind === NodeKind.Leaf, 0x921 /* Expected a leaf schema. */);
|
|
184
172
|
if (!isTreeValue(data)) {
|
|
185
173
|
// This rule exists to protect against useless `toString` output like `[object Object]`.
|
|
@@ -196,11 +184,13 @@ function leafToMapTree(
|
|
|
196
184
|
0x84a /* Unsupported schema for provided primitive. */,
|
|
197
185
|
);
|
|
198
186
|
|
|
199
|
-
return
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
187
|
+
return [
|
|
188
|
+
{
|
|
189
|
+
value: mappedValue,
|
|
190
|
+
type: brand(mappedSchema.identifier),
|
|
191
|
+
},
|
|
192
|
+
new Map<FieldKey, UnhydratedFlexTreeField>(),
|
|
193
|
+
];
|
|
204
194
|
}
|
|
205
195
|
|
|
206
196
|
/**
|
|
@@ -253,10 +243,10 @@ function mapValueWithFallbacks(
|
|
|
253
243
|
* @param data - The tree data to be transformed.
|
|
254
244
|
* @param allowedTypes - The set of types allowed by the parent context. Used to validate the input tree.
|
|
255
245
|
*/
|
|
256
|
-
function
|
|
246
|
+
function arrayChildToFlexTree(
|
|
257
247
|
child: InsertableContent,
|
|
258
248
|
allowedTypes: ReadonlySet<TreeNodeSchema>,
|
|
259
|
-
):
|
|
249
|
+
): UnhydratedFlexTreeNode {
|
|
260
250
|
// We do not support undefined sequence entries.
|
|
261
251
|
// If we encounter an undefined entry, use null instead if supported by the schema, otherwise throw.
|
|
262
252
|
let childWithFallback = child;
|
|
@@ -267,18 +257,15 @@ function arrayChildToMapTree(
|
|
|
267
257
|
throw new TypeError(`Received unsupported array entry value: ${child}.`);
|
|
268
258
|
}
|
|
269
259
|
}
|
|
270
|
-
return
|
|
260
|
+
return unhydratedFlexTreeFromInsertableNode(childWithFallback, allowedTypes);
|
|
271
261
|
}
|
|
272
262
|
|
|
273
263
|
/**
|
|
274
264
|
* Transforms data under an Array schema.
|
|
275
265
|
* @param data - The tree data to be transformed. Must be an iterable.
|
|
276
266
|
* @param schema - The schema associated with the value.
|
|
277
|
-
* @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema
|
|
278
|
-
* validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will
|
|
279
|
-
* be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.
|
|
280
267
|
*/
|
|
281
|
-
function
|
|
268
|
+
function arrayToFlexContent(data: FactoryContent, schema: TreeNodeSchema): FlexContent {
|
|
282
269
|
assert(schema.kind === NodeKind.Array, 0x922 /* Expected an array schema. */);
|
|
283
270
|
if (!(typeof data === "object" && data !== null && Symbol.iterator in data)) {
|
|
284
271
|
throw new UsageError(`Input data is incompatible with Array schema: ${data}`);
|
|
@@ -287,27 +274,41 @@ function arrayToMapTree(data: FactoryContent, schema: TreeNodeSchema): Exclusive
|
|
|
287
274
|
const allowedChildTypes = normalizeAllowedTypes(schema.info as ImplicitAllowedTypes);
|
|
288
275
|
|
|
289
276
|
const mappedData = Array.from(data, (child) =>
|
|
290
|
-
|
|
277
|
+
arrayChildToFlexTree(child, allowedChildTypes),
|
|
291
278
|
);
|
|
292
279
|
|
|
293
|
-
|
|
294
|
-
const fieldsEntries = mappedData.length === 0 ? [] : ([[EmptyKey, mappedData]] as const);
|
|
280
|
+
const context = getUnhydratedContext(schema).flexContext;
|
|
295
281
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
282
|
+
// Array nodes have a single `EmptyKey` field:
|
|
283
|
+
const fieldsEntries =
|
|
284
|
+
mappedData.length === 0
|
|
285
|
+
? []
|
|
286
|
+
: ([
|
|
287
|
+
[
|
|
288
|
+
EmptyKey,
|
|
289
|
+
new UnhydratedSequenceField(
|
|
290
|
+
context,
|
|
291
|
+
FieldKinds.sequence.identifier,
|
|
292
|
+
EmptyKey,
|
|
293
|
+
mappedData,
|
|
294
|
+
),
|
|
295
|
+
],
|
|
296
|
+
] as const);
|
|
297
|
+
|
|
298
|
+
return [
|
|
299
|
+
{
|
|
300
|
+
type: brand(schema.identifier),
|
|
301
|
+
},
|
|
302
|
+
new Map(fieldsEntries),
|
|
303
|
+
];
|
|
300
304
|
}
|
|
301
305
|
|
|
302
306
|
/**
|
|
303
307
|
* Transforms data under a Map schema.
|
|
304
308
|
* @param data - The tree data to be transformed. Must be an iterable.
|
|
305
309
|
* @param schema - The schema associated with the value.
|
|
306
|
-
* @param schemaValidationPolicy - The stored schema and policy to be used for validation, if the policy says schema
|
|
307
|
-
* validation should happen. If it does, the input tree will be validated against this schema + policy, and an error will
|
|
308
|
-
* be thrown if the tree does not conform to the schema. If undefined, no validation against the stored schema is done.
|
|
309
310
|
*/
|
|
310
|
-
function
|
|
311
|
+
function mapToFlexContent(data: FactoryContent, schema: TreeNodeSchema): FlexContent {
|
|
311
312
|
assert(schema.kind === NodeKind.Map, 0x923 /* Expected a Map schema. */);
|
|
312
313
|
if (!(typeof data === "object" && data !== null)) {
|
|
313
314
|
throw new UsageError(`Input data is incompatible with Map schema: ${data}`);
|
|
@@ -323,7 +324,9 @@ function mapToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMa
|
|
|
323
324
|
Object.entries(data)
|
|
324
325
|
) as Iterable<readonly [string, InsertableContent]>;
|
|
325
326
|
|
|
326
|
-
const
|
|
327
|
+
const context = getUnhydratedContext(schema).flexContext;
|
|
328
|
+
|
|
329
|
+
const transformedFields = new Map<FieldKey, UnhydratedFlexTreeField>();
|
|
327
330
|
for (const item of fieldsIterator) {
|
|
328
331
|
if (!isReadonlyArray(item) || item.length !== 2 || typeof item[0] !== "string") {
|
|
329
332
|
throw new UsageError(`Input data is incompatible with map entry: ${item}`);
|
|
@@ -333,15 +336,18 @@ function mapToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMa
|
|
|
333
336
|
|
|
334
337
|
// Omit undefined values - an entry with an undefined value is equivalent to one that has been removed or omitted
|
|
335
338
|
if (value !== undefined) {
|
|
336
|
-
const
|
|
337
|
-
|
|
339
|
+
const child = unhydratedFlexTreeFromInsertableNode(value, allowedChildTypes);
|
|
340
|
+
const field = createField(context, FieldKinds.optional.identifier, brand(key), [child]);
|
|
341
|
+
transformedFields.set(brand(key), field);
|
|
338
342
|
}
|
|
339
343
|
}
|
|
340
344
|
|
|
341
|
-
return
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
+
return [
|
|
346
|
+
{
|
|
347
|
+
type: brand(schema.identifier),
|
|
348
|
+
},
|
|
349
|
+
transformedFields,
|
|
350
|
+
];
|
|
345
351
|
}
|
|
346
352
|
|
|
347
353
|
/**
|
|
@@ -349,7 +355,7 @@ function mapToMapTree(data: FactoryContent, schema: TreeNodeSchema): ExclusiveMa
|
|
|
349
355
|
* @param data - The tree data to be transformed. Must be a Record-like object.
|
|
350
356
|
* @param schema - The schema associated with the value.
|
|
351
357
|
*/
|
|
352
|
-
function
|
|
358
|
+
function objectToFlexContent(data: FactoryContent, schema: TreeNodeSchema): FlexContent {
|
|
353
359
|
assert(isObjectNodeSchema(schema), 0x924 /* Expected an Object schema. */);
|
|
354
360
|
if (
|
|
355
361
|
typeof data !== "object" ||
|
|
@@ -360,53 +366,59 @@ function objectToMapTree(data: FactoryContent, schema: TreeNodeSchema): Exclusiv
|
|
|
360
366
|
throw new UsageError(`Input data is incompatible with Object schema: ${data}`);
|
|
361
367
|
}
|
|
362
368
|
|
|
363
|
-
const fields = new Map<FieldKey,
|
|
369
|
+
const fields = new Map<FieldKey, UnhydratedFlexTreeField>();
|
|
370
|
+
const context = getUnhydratedContext(schema).flexContext;
|
|
364
371
|
|
|
365
|
-
// Loop through field keys without data.
|
|
366
|
-
// This does NOT apply defaults.
|
|
367
372
|
for (const [key, fieldInfo] of schema.flexKeyMap) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
373
|
+
const value = getFieldProperty(data, key);
|
|
374
|
+
|
|
375
|
+
let children: UnhydratedFlexTreeNode[] | ContextualFieldProvider;
|
|
376
|
+
if (value === undefined) {
|
|
377
|
+
const defaultProvider =
|
|
378
|
+
fieldInfo.schema.props?.defaultProvider ??
|
|
379
|
+
fail(0xbb1 /* missing field has no default provider */);
|
|
380
|
+
const fieldProvider = extractFieldProvider(defaultProvider);
|
|
381
|
+
children = isConstant(fieldProvider) ? fieldProvider() : fieldProvider;
|
|
382
|
+
} else {
|
|
383
|
+
children = [
|
|
384
|
+
unhydratedFlexTreeFromInsertableNode(value, fieldInfo.schema.allowedTypeSet),
|
|
385
|
+
];
|
|
371
386
|
}
|
|
387
|
+
|
|
388
|
+
const kind =
|
|
389
|
+
convertFieldKind.get(fieldInfo.schema.kind) ?? fail(0xbb2 /* Invalid field kind */);
|
|
390
|
+
fields.set(
|
|
391
|
+
fieldInfo.storedKey,
|
|
392
|
+
createField(context, kind.identifier, fieldInfo.storedKey, children),
|
|
393
|
+
);
|
|
372
394
|
}
|
|
373
395
|
|
|
374
|
-
return {
|
|
375
|
-
type: brand(schema.identifier),
|
|
376
|
-
fields,
|
|
377
|
-
};
|
|
396
|
+
return [{ type: brand(schema.identifier) }, fields];
|
|
378
397
|
}
|
|
379
398
|
|
|
380
399
|
/**
|
|
381
400
|
* Check {@link FactoryContentObject} for a property which could be store a field.
|
|
401
|
+
*
|
|
402
|
+
* @returns If the property exists, return its value. Otherwise, returns undefined.
|
|
382
403
|
* @remarks
|
|
383
404
|
* The currently policy is to only consider own properties.
|
|
384
405
|
* See {@link InsertableObjectFromSchemaRecord} for where this policy is documented in the public API.
|
|
385
406
|
*
|
|
386
|
-
* Explicit undefined
|
|
407
|
+
* Explicit undefined values are treated the same as missing properties to allow explicit use of undefined with defaulted identifiers.
|
|
408
|
+
*
|
|
409
|
+
* @privateRemarks
|
|
410
|
+
* If we ever want to have an optional field which defaults to something other than undefined, this will need changes.
|
|
411
|
+
* It would need to adjusting the handling of explicit undefined in contexts where undefined is allowed, and a default provider also exists.
|
|
387
412
|
*/
|
|
388
|
-
function
|
|
413
|
+
function getFieldProperty(
|
|
389
414
|
data: FactoryContentObject,
|
|
390
415
|
key: string | symbol,
|
|
391
|
-
):
|
|
392
|
-
readonly [P in string]: InsertableContent | undefined;
|
|
393
|
-
} {
|
|
416
|
+
): InsertableContent | undefined {
|
|
394
417
|
// This policy only allows own properties.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
function setFieldValue(
|
|
399
|
-
fields: Map<FieldKey, readonly MapTree[]>,
|
|
400
|
-
fieldValue: InsertableContent | undefined,
|
|
401
|
-
fieldSchema: FieldSchema,
|
|
402
|
-
flexKey: FieldKey,
|
|
403
|
-
): void {
|
|
404
|
-
if (fieldValue !== undefined) {
|
|
405
|
-
const mappedChildTree = nodeDataToMapTree(fieldValue, fieldSchema.allowedTypeSet);
|
|
406
|
-
|
|
407
|
-
assert(!fields.has(flexKey), 0x956 /* Keys must not be duplicated */);
|
|
408
|
-
fields.set(flexKey, [mappedChildTree]);
|
|
418
|
+
if (Object.hasOwnProperty.call(data, key)) {
|
|
419
|
+
return (data as Record<string, InsertableContent>)[key as string];
|
|
409
420
|
}
|
|
421
|
+
return undefined;
|
|
410
422
|
}
|
|
411
423
|
|
|
412
424
|
function getType(
|
|
@@ -421,10 +433,6 @@ function getType(
|
|
|
421
433
|
)}.`,
|
|
422
434
|
);
|
|
423
435
|
}
|
|
424
|
-
assert(
|
|
425
|
-
hasSome(possibleTypes),
|
|
426
|
-
0x84e /* data is incompatible with all types allowed by the schema */,
|
|
427
|
-
);
|
|
428
436
|
if (!hasSingle(possibleTypes)) {
|
|
429
437
|
throw new UsageError(
|
|
430
438
|
`The provided data is compatible with more than one type allowed by the schema.
|
|
@@ -563,11 +571,7 @@ function shallowCompatibilityTest(
|
|
|
563
571
|
// If the schema has a required key which is not present in the input object, reject it.
|
|
564
572
|
for (const [fieldKey, fieldSchema] of schema.fields) {
|
|
565
573
|
if (fieldSchema.requiresValue) {
|
|
566
|
-
if (
|
|
567
|
-
if (data[fieldKey] === undefined) {
|
|
568
|
-
return CompatibilityLevel.None;
|
|
569
|
-
}
|
|
570
|
-
} else {
|
|
574
|
+
if (getFieldProperty(data, fieldKey) === undefined) {
|
|
571
575
|
return CompatibilityLevel.None;
|
|
572
576
|
}
|
|
573
577
|
}
|
|
@@ -583,102 +587,6 @@ function allowsValue(schema: TreeNodeSchema, value: TreeValue): boolean {
|
|
|
583
587
|
return false;
|
|
584
588
|
}
|
|
585
589
|
|
|
586
|
-
/**
|
|
587
|
-
* Walk the given {@link ExclusiveMapTree} and deeply provide any field defaults for fields that are missing in the tree but present in the schema.
|
|
588
|
-
* @param mapTree - The tree to populate with defaults. This is borrowed: no references to it are kept by this function.
|
|
589
|
-
* @param allowedTypes - Some {@link TreeNodeSchema}, at least one of which the input tree must conform to
|
|
590
|
-
* @param context - An optional context for generating defaults.
|
|
591
|
-
* If present, all applicable defaults will be provided.
|
|
592
|
-
* If absent, only defaults produced by a {@link ConstantFieldProvider} will be provided, and defaults produced by a {@link ContextualFieldProvider} will be ignored.
|
|
593
|
-
* @remarks This function mutates the input tree by deeply adding new fields to the field maps where applicable.
|
|
594
|
-
*/
|
|
595
|
-
export function addDefaultsToMapTree(
|
|
596
|
-
mapTree: ExclusiveMapTree,
|
|
597
|
-
allowedTypes: ImplicitAllowedTypes,
|
|
598
|
-
context: NodeIdentifierManager | undefined,
|
|
599
|
-
): void {
|
|
600
|
-
const schema =
|
|
601
|
-
find(normalizeAllowedTypes(allowedTypes), (s) => s.identifier === mapTree.type) ??
|
|
602
|
-
fail(0xae1 /* MapTree is incompatible with schema */);
|
|
603
|
-
|
|
604
|
-
if (isObjectNodeSchema(schema)) {
|
|
605
|
-
for (const [_key, fieldInfo] of schema.flexKeyMap) {
|
|
606
|
-
const field = mapTree.fields.get(fieldInfo.storedKey);
|
|
607
|
-
if (field !== undefined) {
|
|
608
|
-
for (const child of field) {
|
|
609
|
-
addDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);
|
|
610
|
-
}
|
|
611
|
-
} else {
|
|
612
|
-
const defaultProvider = fieldInfo.schema.props?.defaultProvider;
|
|
613
|
-
if (defaultProvider !== undefined) {
|
|
614
|
-
const fieldProvider = extractFieldProvider(defaultProvider);
|
|
615
|
-
const data = provideDefault(fieldProvider, context);
|
|
616
|
-
if (data !== undefined) {
|
|
617
|
-
setFieldValue(mapTree.fields, data, fieldInfo.schema, fieldInfo.storedKey);
|
|
618
|
-
// call addDefaultsToMapTree on newly inserted default values
|
|
619
|
-
for (const child of mapTree.fields.get(fieldInfo.storedKey) ??
|
|
620
|
-
fail(0xae2 /* Expected field to be populated */)) {
|
|
621
|
-
addDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
switch (schema.kind) {
|
|
631
|
-
case NodeKind.Array:
|
|
632
|
-
case NodeKind.Map:
|
|
633
|
-
{
|
|
634
|
-
for (const field of mapTree.fields.values()) {
|
|
635
|
-
for (const child of field) {
|
|
636
|
-
addDefaultsToMapTree(child, schema.info as ImplicitAllowedTypes, context);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
break;
|
|
641
|
-
default:
|
|
642
|
-
assert(schema.kind === NodeKind.Leaf, 0x989 /* Unrecognized schema kind */);
|
|
643
|
-
break;
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
/**
|
|
648
|
-
* Provides the default value (which can be undefined, for example with optional fields), or undefined if a context is required but not provided.
|
|
649
|
-
* @privateRemarks
|
|
650
|
-
* It is a bit concerning that there is no way for the caller to know when undefined is returned if that is the default value, or a context was required.
|
|
651
|
-
* TODO: maybe better formalize the two stage defaulting (without then with context), or rework this design we only do one stage.
|
|
652
|
-
*/
|
|
653
|
-
function provideDefault(
|
|
654
|
-
fieldProvider: FieldProvider,
|
|
655
|
-
context: NodeIdentifierManager | undefined,
|
|
656
|
-
): InsertableContent | undefined {
|
|
657
|
-
if (context !== undefined) {
|
|
658
|
-
return fieldProvider(context);
|
|
659
|
-
} else {
|
|
660
|
-
if (isConstant(fieldProvider)) {
|
|
661
|
-
return fieldProvider();
|
|
662
|
-
} else {
|
|
663
|
-
// Leaving field empty despite it needing a default value since a context was required and none was provided.
|
|
664
|
-
// Caller better handle this case by providing the default at some other point in time when the context becomes known.
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* Retrieves the InnerNode associated with the given target via {@link setInnerNode}, if any.
|
|
671
|
-
* @remarks
|
|
672
|
-
* If `target` is a unhydrated node, returns its MapTreeNode.
|
|
673
|
-
* If `target` is a cooked node (or marinated but a FlexTreeNode exists) returns the FlexTreeNode.
|
|
674
|
-
* If the target is not a node, or a marinated node with no FlexTreeNode for its anchor, returns undefined.
|
|
675
|
-
*/
|
|
676
|
-
function tryGetInnerNode(target: unknown): InnerNode | undefined {
|
|
677
|
-
if (isTreeNode(target)) {
|
|
678
|
-
return getKernel(target).tryGetInnerNode();
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
|
|
682
590
|
/**
|
|
683
591
|
* Content which can be used to build a node.
|
|
684
592
|
* @remarks
|
package/src/treeFactory.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import { SharedTreeFactoryType, SharedTreeAttributes } from "./sharedTreeAttributes.js";
|
|
27
27
|
import type { ITree } from "./simple-tree/index.js";
|
|
28
28
|
import { Breakable } from "./util/index.js";
|
|
29
|
+
import { FluidClientVersion } from "./codec/index.js";
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* {@link ITreePrivate} extended with ISharedObject.
|
|
@@ -47,6 +48,10 @@ function treeKernelFactory(
|
|
|
47
48
|
if (args.idCompressor === undefined) {
|
|
48
49
|
throw new UsageError("IdCompressor must be enabled to use SharedTree");
|
|
49
50
|
}
|
|
51
|
+
const adjustedOptions = { ...options };
|
|
52
|
+
// TODO: get default from runtime once something like runtime.oldestCompatibleClient exists.
|
|
53
|
+
// Using default of 2.0 since that is the oldest version that supports SharedTree.
|
|
54
|
+
adjustedOptions.oldestCompatibleClient ??= FluidClientVersion.v2_0;
|
|
50
55
|
return new SharedTreeKernel(
|
|
51
56
|
new Breakable("SharedTree"),
|
|
52
57
|
args.sharedObject,
|
|
@@ -55,7 +60,7 @@ function treeKernelFactory(
|
|
|
55
60
|
args.lastSequenceNumber,
|
|
56
61
|
args.logger,
|
|
57
62
|
args.idCompressor,
|
|
58
|
-
|
|
63
|
+
adjustedOptions,
|
|
59
64
|
);
|
|
60
65
|
}
|
|
61
66
|
|
package/src/util/index.ts
CHANGED
package/src/util/utils.ts
CHANGED
|
@@ -98,6 +98,13 @@ export function hasSome<T>(array: readonly T[]): array is [T, ...T[]] {
|
|
|
98
98
|
return array.length > 0;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Returns true if and only if the given iterable has at least one element.
|
|
103
|
+
*/
|
|
104
|
+
export function iterableHasSome<T>(iterable: Iterable<T>): boolean {
|
|
105
|
+
return iterable[Symbol.iterator]().next().done === false;
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
/**
|
|
102
109
|
* Returns true if and only if the given array has exactly one element.
|
|
103
110
|
* @param array - The array to check.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toMapTree.d.ts","sourceRoot":"","sources":["../../src/simple-tree/toMapTree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAMN,KAAK,gBAAgB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGN,KAAK,qBAAqB,EAC1B,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAEN,KAAK,oBAAoB,EAKzB,KAAK,mBAAmB,EAIxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAMN,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,EAEf,MAAM,iBAAiB,CAAC;AAOzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAEpE;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,SAAS,iBAAiB,GAAG,SAAS,EAC5E,IAAI,EAAE,GAAG,EACT,YAAY,EAAE,mBAAmB,EACjC,OAAO,CAAC,EAAE,qBAAqB,GAC7B,GAAG,SAAS,SAAS,GAAG,SAAS,GAAG,gBAAgB,CAgBtD;AAwUD;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,EACzC,IAAI,EAAE,cAAc,GAClB,cAAc,EAAE,CAclB;AA6HD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,oBAAoB,EAClC,OAAO,EAAE,qBAAqB,GAAG,SAAS,GACxC,IAAI,CA8CN;AAqCD;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACvB,YAAY,GACZ,MAAM,GACN,MAAM,GACN,OAAO,GAEP,IAAI,GACJ,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,GAC9C,SAAS,iBAAiB,EAAE,GAC5B,oBAAoB,CAAC;AAExB;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,iBAAiB;CAC1C,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC"}
|