@fluidframework/tree 2.1.0-276985 → 2.1.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/.eslintrc.cjs +7 -0
- package/.vscode/Tree.code-workspace +9 -2
- package/CHANGELOG.md +38 -0
- package/README.md +55 -12
- package/api-report/tree.alpha.api.md +2 -1
- package/api-report/tree.beta.api.md +2 -1
- package/api-report/tree.public.api.md +2 -1
- package/beta.d.ts +1 -1
- package/dist/beta.d.ts +1 -1
- package/dist/core/forest/editableForest.d.ts +6 -3
- package/dist/core/forest/editableForest.d.ts.map +1 -1
- package/dist/core/forest/editableForest.js +16 -4
- package/dist/core/forest/editableForest.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/rebase/index.d.ts +1 -1
- package/dist/core/rebase/index.d.ts.map +1 -1
- package/dist/core/rebase/index.js +3 -1
- package/dist/core/rebase/index.js.map +1 -1
- package/dist/core/rebase/types.d.ts +2 -0
- package/dist/core/rebase/types.d.ts.map +1 -1
- package/dist/core/rebase/types.js +9 -1
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/tree/anchorSet.d.ts +1 -0
- package/dist/core/tree/anchorSet.d.ts.map +1 -1
- package/dist/core/tree/anchorSet.js +13 -0
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/core/tree/detachedFieldIndex.d.ts +48 -11
- package/dist/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndex.js +144 -20
- package/dist/core/tree/detachedFieldIndex.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodec.js +13 -4
- package/dist/core/tree/detachedFieldIndexCodec.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormat.d.ts +1 -1
- package/dist/core/tree/detachedFieldIndexFormat.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormat.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexTypes.d.ts +39 -4
- package/dist/core/tree/detachedFieldIndexTypes.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexTypes.js.map +1 -1
- package/dist/core/tree/index.d.ts +2 -1
- package/dist/core/tree/index.d.ts.map +1 -1
- package/dist/core/tree/index.js.map +1 -1
- package/dist/core/tree/visitDelta.d.ts +3 -1
- package/dist/core/tree/visitDelta.d.ts.map +1 -1
- package/dist/core/tree/visitDelta.js +31 -15
- package/dist/core/tree/visitDelta.js.map +1 -1
- package/dist/core/tree/visitorUtils.d.ts +3 -3
- package/dist/core/tree/visitorUtils.d.ts.map +1 -1
- package/dist/core/tree/visitorUtils.js +4 -4
- package/dist/core/tree/visitorUtils.js.map +1 -1
- package/dist/events/events.d.ts +4 -1
- package/dist/events/events.d.ts.map +1 -1
- package/dist/events/events.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -0
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/editableTreeBinder.js +1 -1
- package/dist/feature-libraries/editableTreeBinder.js.map +1 -1
- package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts +1 -10
- package/dist/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
- package/dist/feature-libraries/flex-map-tree/mapTreeNode.js +0 -72
- package/dist/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -51
- package/dist/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/flexTreeTypes.js +0 -2
- package/dist/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/dist/feature-libraries/flex-tree/index.d.ts +3 -2
- package/dist/feature-libraries/flex-tree/index.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/index.js +5 -1
- package/dist/feature-libraries/flex-tree/index.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyEntity.d.ts +1 -2
- package/dist/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.d.ts +1 -6
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +11 -32
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.d.ts +1 -5
- package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +0 -30
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +3 -3
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +6 -3
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +11 -0
- package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/dist/feature-libraries/modular-schema/discrepancies.d.ts +96 -0
- package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -0
- package/dist/feature-libraries/modular-schema/discrepancies.js +264 -0
- package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -0
- package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +9 -2
- 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 +3 -0
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +2 -1
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +3 -1
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +42 -26
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +51 -2
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +827 -245
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormat.js +2 -0
- package/dist/feature-libraries/modular-schema/modularChangeFormat.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +44 -1
- 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/node-key/index.d.ts +0 -1
- package/dist/feature-libraries/node-key/index.d.ts.map +1 -1
- package/dist/feature-libraries/node-key/index.js +1 -3
- package/dist/feature-libraries/node-key/index.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.d.ts +3 -2
- package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +5 -4
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +1 -0
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/sequence-field/index.d.ts +1 -1
- package/dist/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/index.js +1 -2
- package/dist/feature-libraries/sequence-field/index.js.map +1 -1
- package/dist/feature-libraries/sequence-field/invert.js +1 -1
- package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
- package/dist/feature-libraries/sequence-field/rebase.js +6 -1
- package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +1 -0
- package/dist/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.d.ts +2 -17
- package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +31 -39
- package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
- package/dist/feature-libraries/typed-schema/typedTreeSchema.d.ts +1 -0
- package/dist/feature-libraries/typed-schema/typedTreeSchema.d.ts.map +1 -1
- package/dist/feature-libraries/typed-schema/typedTreeSchema.js +2 -0
- package/dist/feature-libraries/typed-schema/typedTreeSchema.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.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/public.d.ts +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +4 -2
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +240 -184
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +5 -1
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +157 -90
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.js +1 -1
- package/dist/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/dist/shared-tree/treeApi.js +1 -1
- package/dist/shared-tree/treeApi.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +10 -1
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +47 -3
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree/treeView.d.ts.map +1 -1
- package/dist/shared-tree/treeView.js +7 -3
- package/dist/shared-tree/treeView.js.map +1 -1
- package/dist/shared-tree-core/branch.d.ts +6 -0
- package/dist/shared-tree-core/branch.d.ts.map +1 -1
- package/dist/shared-tree-core/branch.js +3 -0
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts +8 -6
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +271 -209
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/arrayNode.d.ts +4 -0
- package/dist/simple-tree/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/arrayNode.js +36 -19
- package/dist/simple-tree/arrayNode.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 +2 -1
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.d.ts +22 -1
- package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/leafNodeSchema.js +2 -1
- package/dist/simple-tree/leafNodeSchema.js.map +1 -1
- package/dist/simple-tree/mapNode.d.ts.map +1 -1
- package/dist/simple-tree/mapNode.js.map +1 -1
- 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/proxies.d.ts.map +1 -1
- package/dist/simple-tree/proxies.js +9 -25
- package/dist/simple-tree/proxies.js.map +1 -1
- package/dist/simple-tree/proxyBinding.d.ts +4 -0
- package/dist/simple-tree/proxyBinding.d.ts.map +1 -1
- package/dist/simple-tree/proxyBinding.js +23 -1
- package/dist/simple-tree/proxyBinding.js.map +1 -1
- package/dist/simple-tree/schemaFactory.d.ts +16 -1
- package/dist/simple-tree/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/schemaFactory.js +32 -4
- package/dist/simple-tree/schemaFactory.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +36 -1
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/toFlexSchema.d.ts +2 -2
- package/dist/simple-tree/toFlexSchema.d.ts.map +1 -1
- package/dist/simple-tree/toFlexSchema.js +3 -2
- package/dist/simple-tree/toFlexSchema.js.map +1 -1
- package/dist/simple-tree/tree.d.ts +4 -1
- package/dist/simple-tree/tree.d.ts.map +1 -1
- package/dist/simple-tree/tree.js +48 -1
- package/dist/simple-tree/tree.js.map +1 -1
- package/dist/simple-tree/treeNodeApi.d.ts +2 -75
- package/dist/simple-tree/treeNodeApi.d.ts.map +1 -1
- package/dist/simple-tree/treeNodeApi.js +17 -25
- package/dist/simple-tree/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/treeNodeKernel.d.ts +26 -0
- package/dist/simple-tree/treeNodeKernel.d.ts.map +1 -0
- package/dist/simple-tree/treeNodeKernel.js +83 -0
- package/dist/simple-tree/treeNodeKernel.js.map +1 -0
- package/dist/simple-tree/types.d.ts +95 -3
- package/dist/simple-tree/types.d.ts.map +1 -1
- package/dist/simple-tree/types.js +120 -21
- package/dist/simple-tree/types.js.map +1 -1
- package/dist/util/breakable.d.ts +83 -0
- package/dist/util/breakable.d.ts.map +1 -0
- package/dist/util/breakable.js +178 -0
- package/dist/util/breakable.js.map +1 -0
- package/dist/util/index.d.ts +3 -2
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +9 -2
- package/dist/util/index.js.map +1 -1
- package/dist/util/nestedMap.d.ts +17 -3
- package/dist/util/nestedMap.d.ts.map +1 -1
- package/dist/util/nestedMap.js +21 -1
- package/dist/util/nestedMap.js.map +1 -1
- package/dist/util/utils.d.ts +7 -0
- package/dist/util/utils.d.ts.map +1 -1
- package/dist/util/utils.js +15 -1
- package/dist/util/utils.js.map +1 -1
- package/internal.d.ts +1 -1
- package/lib/beta.d.ts +1 -1
- package/lib/core/forest/editableForest.d.ts +6 -3
- package/lib/core/forest/editableForest.d.ts.map +1 -1
- package/lib/core/forest/editableForest.js +17 -5
- package/lib/core/forest/editableForest.js.map +1 -1
- package/lib/core/index.d.ts +1 -1
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +1 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/rebase/index.d.ts +1 -1
- package/lib/core/rebase/index.d.ts.map +1 -1
- package/lib/core/rebase/index.js +1 -1
- package/lib/core/rebase/index.js.map +1 -1
- package/lib/core/rebase/types.d.ts +2 -0
- package/lib/core/rebase/types.d.ts.map +1 -1
- package/lib/core/rebase/types.js +7 -1
- package/lib/core/rebase/types.js.map +1 -1
- package/lib/core/tree/anchorSet.d.ts +1 -0
- package/lib/core/tree/anchorSet.d.ts.map +1 -1
- package/lib/core/tree/anchorSet.js +13 -0
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/core/tree/detachedFieldIndex.d.ts +48 -11
- package/lib/core/tree/detachedFieldIndex.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndex.js +145 -21
- package/lib/core/tree/detachedFieldIndex.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodec.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodec.js +13 -4
- package/lib/core/tree/detachedFieldIndexCodec.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormat.d.ts +1 -1
- package/lib/core/tree/detachedFieldIndexFormat.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormat.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexTypes.d.ts +39 -4
- package/lib/core/tree/detachedFieldIndexTypes.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexTypes.js.map +1 -1
- package/lib/core/tree/index.d.ts +2 -1
- package/lib/core/tree/index.d.ts.map +1 -1
- package/lib/core/tree/index.js.map +1 -1
- package/lib/core/tree/visitDelta.d.ts +3 -1
- package/lib/core/tree/visitDelta.d.ts.map +1 -1
- package/lib/core/tree/visitDelta.js +31 -15
- package/lib/core/tree/visitDelta.js.map +1 -1
- package/lib/core/tree/visitorUtils.d.ts +3 -3
- package/lib/core/tree/visitorUtils.d.ts.map +1 -1
- package/lib/core/tree/visitorUtils.js +4 -4
- package/lib/core/tree/visitorUtils.js.map +1 -1
- package/lib/events/events.d.ts +4 -1
- package/lib/events/events.d.ts.map +1 -1
- package/lib/events/events.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -0
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/editableTreeBinder.js +1 -1
- package/lib/feature-libraries/editableTreeBinder.js.map +1 -1
- package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts +1 -10
- package/lib/feature-libraries/flex-map-tree/mapTreeNode.d.ts.map +1 -1
- package/lib/feature-libraries/flex-map-tree/mapTreeNode.js +2 -74
- package/lib/feature-libraries/flex-map-tree/mapTreeNode.js.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts +1 -51
- package/lib/feature-libraries/flex-tree/flexTreeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/flexTreeTypes.js +0 -2
- package/lib/feature-libraries/flex-tree/flexTreeTypes.js.map +1 -1
- package/lib/feature-libraries/flex-tree/index.d.ts +3 -2
- package/lib/feature-libraries/flex-tree/index.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/index.js +2 -1
- package/lib/feature-libraries/flex-tree/index.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyEntity.d.ts +1 -2
- package/lib/feature-libraries/flex-tree/lazyEntity.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.d.ts +1 -6
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +13 -34
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.d.ts +1 -5
- package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +3 -33
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +3 -3
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +3 -3
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +11 -0
- package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
- package/lib/feature-libraries/modular-schema/discrepancies.d.ts +96 -0
- package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -0
- package/lib/feature-libraries/modular-schema/discrepancies.js +260 -0
- package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -0
- package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +9 -2
- 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 +3 -0
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +2 -1
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js +1 -0
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +42 -26
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +51 -2
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +826 -247
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormat.js +2 -0
- package/lib/feature-libraries/modular-schema/modularChangeFormat.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +44 -1
- 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/node-key/index.d.ts +0 -1
- package/lib/feature-libraries/node-key/index.d.ts.map +1 -1
- package/lib/feature-libraries/node-key/index.js +0 -1
- package/lib/feature-libraries/node-key/index.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.d.ts +3 -2
- package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +5 -4
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +1 -0
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/sequence-field/index.d.ts +1 -1
- package/lib/feature-libraries/sequence-field/index.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/index.js +1 -1
- package/lib/feature-libraries/sequence-field/index.js.map +1 -1
- package/lib/feature-libraries/sequence-field/invert.js +1 -1
- package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
- package/lib/feature-libraries/sequence-field/rebase.js +6 -1
- package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js +2 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldChangeHandler.js.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.d.ts +2 -17
- package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +31 -39
- package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
- package/lib/feature-libraries/typed-schema/typedTreeSchema.d.ts +1 -0
- package/lib/feature-libraries/typed-schema/typedTreeSchema.d.ts.map +1 -1
- package/lib/feature-libraries/typed-schema/typedTreeSchema.js +4 -2
- package/lib/feature-libraries/typed-schema/typedTreeSchema.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.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +4 -2
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +242 -185
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +5 -1
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +158 -90
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.js +1 -1
- package/lib/shared-tree/sharedTreeChangeEnricher.js.map +1 -1
- package/lib/shared-tree/treeApi.js +1 -1
- package/lib/shared-tree/treeApi.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +10 -1
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +47 -3
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree/treeView.d.ts.map +1 -1
- package/lib/shared-tree/treeView.js +4 -0
- package/lib/shared-tree/treeView.js.map +1 -1
- package/lib/shared-tree-core/branch.d.ts +6 -0
- package/lib/shared-tree-core/branch.d.ts.map +1 -1
- package/lib/shared-tree-core/branch.js +3 -0
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts +8 -6
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +273 -210
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/arrayNode.d.ts +4 -0
- package/lib/simple-tree/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/arrayNode.js +39 -22
- package/lib/simple-tree/arrayNode.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 +1 -1
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.d.ts +22 -1
- package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/leafNodeSchema.js +1 -1
- package/lib/simple-tree/leafNodeSchema.js.map +1 -1
- package/lib/simple-tree/mapNode.d.ts.map +1 -1
- package/lib/simple-tree/mapNode.js.map +1 -1
- package/lib/simple-tree/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/objectNode.js +3 -2
- package/lib/simple-tree/objectNode.js.map +1 -1
- package/lib/simple-tree/proxies.d.ts.map +1 -1
- package/lib/simple-tree/proxies.js +9 -25
- package/lib/simple-tree/proxies.js.map +1 -1
- package/lib/simple-tree/proxyBinding.d.ts +4 -0
- package/lib/simple-tree/proxyBinding.d.ts.map +1 -1
- package/lib/simple-tree/proxyBinding.js +19 -0
- package/lib/simple-tree/proxyBinding.js.map +1 -1
- package/lib/simple-tree/schemaFactory.d.ts +16 -1
- package/lib/simple-tree/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/schemaFactory.js +30 -3
- package/lib/simple-tree/schemaFactory.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +36 -1
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/toFlexSchema.d.ts +2 -2
- package/lib/simple-tree/toFlexSchema.d.ts.map +1 -1
- package/lib/simple-tree/toFlexSchema.js +3 -2
- package/lib/simple-tree/toFlexSchema.js.map +1 -1
- package/lib/simple-tree/tree.d.ts +4 -1
- package/lib/simple-tree/tree.d.ts.map +1 -1
- package/lib/simple-tree/tree.js +44 -0
- package/lib/simple-tree/tree.js.map +1 -1
- package/lib/simple-tree/treeNodeApi.d.ts +2 -75
- package/lib/simple-tree/treeNodeApi.d.ts.map +1 -1
- package/lib/simple-tree/treeNodeApi.js +20 -28
- package/lib/simple-tree/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/treeNodeKernel.d.ts +26 -0
- package/lib/simple-tree/treeNodeKernel.d.ts.map +1 -0
- package/lib/simple-tree/treeNodeKernel.js +79 -0
- package/lib/simple-tree/treeNodeKernel.js.map +1 -0
- package/lib/simple-tree/types.d.ts +95 -3
- package/lib/simple-tree/types.d.ts.map +1 -1
- package/lib/simple-tree/types.js +121 -22
- package/lib/simple-tree/types.js.map +1 -1
- package/lib/util/breakable.d.ts +83 -0
- package/lib/util/breakable.d.ts.map +1 -0
- package/lib/util/breakable.js +171 -0
- package/lib/util/breakable.js.map +1 -0
- package/lib/util/index.d.ts +3 -2
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +3 -2
- package/lib/util/index.js.map +1 -1
- package/lib/util/nestedMap.d.ts +17 -3
- package/lib/util/nestedMap.d.ts.map +1 -1
- package/lib/util/nestedMap.js +19 -0
- package/lib/util/nestedMap.js.map +1 -1
- package/lib/util/utils.d.ts +7 -0
- package/lib/util/utils.d.ts.map +1 -1
- package/lib/util/utils.js +13 -0
- package/lib/util/utils.js.map +1 -1
- package/package.json +29 -27
- package/src/core/forest/editableForest.ts +25 -4
- package/src/core/index.ts +2 -0
- package/src/core/rebase/index.ts +2 -0
- package/src/core/rebase/types.ts +17 -0
- package/src/core/tree/anchorSet.ts +14 -0
- package/src/core/tree/detachedFieldIndex.ts +217 -35
- package/src/core/tree/detachedFieldIndexCodec.ts +17 -8
- package/src/core/tree/detachedFieldIndexFormat.ts +1 -1
- package/src/core/tree/detachedFieldIndexTypes.ts +41 -5
- package/src/core/tree/index.ts +2 -1
- package/src/core/tree/visitDelta.ts +58 -16
- package/src/core/tree/visitorUtils.ts +7 -4
- package/src/events/events.ts +4 -2
- package/src/feature-libraries/default-schema/defaultEditBuilder.ts +1 -1
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -0
- package/src/feature-libraries/editableTreeBinder.ts +1 -1
- package/src/feature-libraries/flex-map-tree/mapTreeNode.ts +1 -95
- package/src/feature-libraries/flex-tree/flexTreeTypes.ts +0 -62
- package/src/feature-libraries/flex-tree/index.ts +7 -2
- package/src/feature-libraries/flex-tree/lazyEntity.ts +0 -3
- package/src/feature-libraries/flex-tree/lazyField.ts +15 -47
- package/src/feature-libraries/flex-tree/lazyNode.ts +1 -48
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +1 -0
- package/src/feature-libraries/index.ts +4 -2
- package/src/feature-libraries/modular-schema/crossFieldQueries.ts +18 -0
- package/src/feature-libraries/modular-schema/discrepancies.ts +395 -0
- package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +10 -2
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +3 -0
- package/src/feature-libraries/modular-schema/index.ts +2 -0
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +81 -35
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1521 -444
- package/src/feature-libraries/modular-schema/modularChangeFormat.ts +2 -0
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +51 -0
- package/src/feature-libraries/node-key/index.ts +0 -1
- package/src/feature-libraries/object-forest/objectForest.ts +7 -3
- package/src/feature-libraries/optional-field/optionalField.ts +1 -0
- package/src/feature-libraries/sequence-field/index.ts +0 -2
- package/src/feature-libraries/sequence-field/invert.ts +1 -1
- package/src/feature-libraries/sequence-field/rebase.ts +7 -1
- package/src/feature-libraries/sequence-field/sequenceFieldChangeHandler.ts +2 -1
- package/src/feature-libraries/sequence-field/utils.ts +37 -85
- package/src/feature-libraries/typed-schema/typedTreeSchema.ts +10 -0
- package/src/index.ts +0 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +6 -2
- package/src/shared-tree/sharedTree.ts +12 -1
- package/src/shared-tree/sharedTreeChangeEnricher.ts +1 -1
- package/src/shared-tree/treeApi.ts +1 -1
- package/src/shared-tree/treeCheckout.ts +60 -5
- package/src/shared-tree/treeView.ts +5 -0
- package/src/shared-tree-core/branch.ts +10 -0
- package/src/shared-tree-core/sharedTreeCore.ts +25 -6
- package/src/simple-tree/arrayNode.ts +50 -23
- package/src/simple-tree/index.ts +3 -3
- package/src/simple-tree/leafNodeSchema.ts +1 -1
- package/src/simple-tree/mapNode.ts +2 -2
- package/src/simple-tree/objectNode.ts +9 -3
- package/src/simple-tree/proxies.ts +10 -33
- package/src/simple-tree/proxyBinding.ts +23 -0
- package/src/simple-tree/schemaFactory.ts +37 -2
- package/src/simple-tree/schemaTypes.ts +36 -1
- package/src/simple-tree/toFlexSchema.ts +5 -4
- package/src/simple-tree/tree.ts +68 -4
- package/src/simple-tree/treeNodeApi.ts +29 -111
- package/src/simple-tree/treeNodeKernel.ts +91 -0
- package/src/simple-tree/types.ts +292 -31
- package/src/util/breakable.ts +214 -0
- package/src/util/index.ts +11 -0
- package/src/util/nestedMap.ts +33 -3
- package/src/util/utils.ts +17 -0
- package/dist/feature-libraries/node-key/nodeKeyIndex.d.ts +0 -41
- package/dist/feature-libraries/node-key/nodeKeyIndex.d.ts.map +0 -1
- package/dist/feature-libraries/node-key/nodeKeyIndex.js +0 -101
- package/dist/feature-libraries/node-key/nodeKeyIndex.js.map +0 -1
- package/lib/feature-libraries/node-key/nodeKeyIndex.d.ts +0 -41
- package/lib/feature-libraries/node-key/nodeKeyIndex.d.ts.map +0 -1
- package/lib/feature-libraries/node-key/nodeKeyIndex.js +0 -97
- package/lib/feature-libraries/node-key/nodeKeyIndex.js.map +0 -1
- package/src/feature-libraries/node-key/nodeKeyIndex.ts +0 -132
package/src/simple-tree/types.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { assert } from "@fluidframework/core-utils/internal";
|
|
|
9
9
|
import {
|
|
10
10
|
NodeKind,
|
|
11
11
|
type TreeNodeSchema,
|
|
12
|
+
type TreeNodeSchemaClass,
|
|
12
13
|
type WithType,
|
|
13
14
|
typeNameSymbol,
|
|
14
15
|
} from "./schemaTypes.js";
|
|
@@ -23,7 +24,7 @@ import { isTreeNode } from "./proxies.js";
|
|
|
23
24
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
24
25
|
import { getFlexSchema } from "./toFlexSchema.js";
|
|
25
26
|
import { fail } from "../util/index.js";
|
|
26
|
-
import { setFlexNode } from "./proxyBinding.js";
|
|
27
|
+
import { getFlexNode, createKernel, setFlexNode } from "./proxyBinding.js";
|
|
27
28
|
import { tryGetSchema } from "./treeNodeApi.js";
|
|
28
29
|
|
|
29
30
|
/**
|
|
@@ -37,6 +38,81 @@ import { tryGetSchema } from "./treeNodeApi.js";
|
|
|
37
38
|
*/
|
|
38
39
|
export type Unhydrated<T> = T;
|
|
39
40
|
|
|
41
|
+
/**
|
|
42
|
+
* A collection of events that can be emitted by a {@link TreeNode}.
|
|
43
|
+
*
|
|
44
|
+
* @privateRemarks
|
|
45
|
+
* TODO: add a way to subscribe to a specific field (for nodeChanged and treeChanged).
|
|
46
|
+
* Probably have object node and map node specific APIs for this.
|
|
47
|
+
*
|
|
48
|
+
* TODO: ensure that subscription API for fields aligns with API for subscribing to the root.
|
|
49
|
+
*
|
|
50
|
+
* TODO: add more wider area (avoid needing tons of nodeChanged registration) events for use-cases other than treeChanged.
|
|
51
|
+
* Some ideas:
|
|
52
|
+
*
|
|
53
|
+
* - treeChanged, but with some subtrees/fields/paths excluded
|
|
54
|
+
* - helper to batch several nodeChanged calls to a treeChanged scope
|
|
55
|
+
* - parent change (ex: registration on the parent field for a specific index: maybe allow it for a range. Ex: node event takes optional field and optional index range?)
|
|
56
|
+
* - new content inserted into subtree. Either provide event for this and/or enough info to treeChanged to find and search the new sub-trees.
|
|
57
|
+
* Add separate (non event related) API to efficiently scan tree for given set of types (using low level cursor and schema based filtering)
|
|
58
|
+
* to allow efficiently searching for new content (and initial content) of a given type.
|
|
59
|
+
*
|
|
60
|
+
* @sealed @public
|
|
61
|
+
*/
|
|
62
|
+
export interface TreeChangeEvents {
|
|
63
|
+
/**
|
|
64
|
+
* Emitted by a node after a batch of changes has been applied to the tree, if a change affected the node, where a
|
|
65
|
+
* change is:
|
|
66
|
+
*
|
|
67
|
+
* - For an object node, when the value of one of its properties changes (i.e., the property's value is set
|
|
68
|
+
* to something else, including `undefined`).
|
|
69
|
+
*
|
|
70
|
+
* - For an array node, when an element is added, removed, or moved.
|
|
71
|
+
*
|
|
72
|
+
* - For a map node, when an entry is added, updated, or removed.
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
* This event is not emitted when:
|
|
76
|
+
*
|
|
77
|
+
* - Properties of a child node change. Notably, updates to an array node or a map node (like adding or removing
|
|
78
|
+
* elements/entries) will emit this event on the array/map node itself, but not on the node that contains the
|
|
79
|
+
* array/map node as one of its properties.
|
|
80
|
+
*
|
|
81
|
+
* - The node is moved to a different location in the tree or removed from the tree.
|
|
82
|
+
* In this case the event is emitted on the _parent_ node, not the node itself.
|
|
83
|
+
*
|
|
84
|
+
* For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in
|
|
85
|
+
* the client that made the original edit.
|
|
86
|
+
*
|
|
87
|
+
* When it is emitted, the tree is guaranteed to be in-schema.
|
|
88
|
+
*
|
|
89
|
+
* @privateRemarks
|
|
90
|
+
* This event occurs whenever the apparent contents of the node instance change, regardless of what caused the change.
|
|
91
|
+
* For example, it will fire when the local client reassigns a child, when part of a remote edit is applied to the
|
|
92
|
+
* node, or when the node has to be updated due to resolution of a merge conflict
|
|
93
|
+
* (for example a previously applied local change might be undone, then reapplied differently or not at all).
|
|
94
|
+
*/
|
|
95
|
+
nodeChanged(): void;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Emitted by a node after a batch of changes has been applied to the tree, when something changed anywhere in the
|
|
99
|
+
* subtree rooted at it.
|
|
100
|
+
*
|
|
101
|
+
* @remarks
|
|
102
|
+
* This event is not emitted when the node itself is moved to a different location in the tree or removed from the tree.
|
|
103
|
+
* In that case it is emitted on the _parent_ node, not the node itself.
|
|
104
|
+
*
|
|
105
|
+
* The node itself is part of the subtree, so this event will be emitted even if the only changes are to the properties
|
|
106
|
+
* of the node itself.
|
|
107
|
+
*
|
|
108
|
+
* For remote edits, this event is not guaranteed to occur in the same order or quantity that it did in
|
|
109
|
+
* the client that made the original edit.
|
|
110
|
+
*
|
|
111
|
+
* When it is emitted, the tree is guaranteed to be in-schema.
|
|
112
|
+
*/
|
|
113
|
+
treeChanged(): void;
|
|
114
|
+
}
|
|
115
|
+
|
|
40
116
|
/**
|
|
41
117
|
* A non-{@link NodeKind.Leaf|leaf} SharedTree node. Includes objects, arrays, and maps.
|
|
42
118
|
*
|
|
@@ -208,51 +284,65 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
208
284
|
* Also used to detect if oneTimeSetup has run.
|
|
209
285
|
*
|
|
210
286
|
* @privateRemarks
|
|
211
|
-
* This defaults to
|
|
287
|
+
* This defaults to "default", which is used to trigger an error if not overridden in the derived class.
|
|
212
288
|
*
|
|
213
289
|
* The value of this on TreeNodeValid must only be overridden by base classes and never modified.
|
|
214
290
|
* Ways to enforce this immutability prevent it from being overridden,
|
|
215
291
|
* so code modifying constructorCached should be extra careful to avoid accidentally modifying the base/inherited value.
|
|
216
292
|
*/
|
|
217
|
-
protected static constructorCached:
|
|
293
|
+
protected static constructorCached: MostDerivedData | "default" | undefined = "default";
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Indicate that `this` is the most derived version of a schema, and thus the only one allowed to be used (other than by being subclassed a single time).
|
|
297
|
+
*/
|
|
298
|
+
public static markMostDerived(this: typeof TreeNodeValid & TreeNodeSchema): MostDerivedData {
|
|
299
|
+
assert(this.constructorCached !== "default", 0x95f /* invalid schema class */);
|
|
300
|
+
|
|
301
|
+
if (this.constructorCached === undefined) {
|
|
302
|
+
// Set the constructorCached on the layer of the prototype chain that declared it.
|
|
303
|
+
// This is necessary to ensure there is only one subclass of that type used:
|
|
304
|
+
// if constructorCached was simply set on `schema`,
|
|
305
|
+
// then a base classes between `schema` (exclusive) and where `constructorCached` is set (inclusive) and other subclasses of them
|
|
306
|
+
// would not see the stored `constructorCached`, and the validation above against multiple derived classes would not work.
|
|
307
|
+
|
|
308
|
+
// This is not just an alias of `this`, but a reference to the item in the prototype chain being walked, which happens to start at `this`.
|
|
309
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
310
|
+
let schemaBase: typeof TreeNodeValid = this;
|
|
311
|
+
while (!Object.prototype.hasOwnProperty.call(schemaBase, "constructorCached")) {
|
|
312
|
+
schemaBase = Reflect.getPrototypeOf(schemaBase) as typeof TreeNodeValid;
|
|
313
|
+
}
|
|
314
|
+
assert(schemaBase.constructorCached === undefined, 0x962 /* overwriting wrong cache */);
|
|
315
|
+
schemaBase.constructorCached = { constructor: this, oneTimeInitialized: false };
|
|
316
|
+
assert(
|
|
317
|
+
this.constructorCached === schemaBase.constructorCached,
|
|
318
|
+
0x9b5 /* Inheritance should work */,
|
|
319
|
+
);
|
|
320
|
+
return this.constructorCached;
|
|
321
|
+
} else if (this.constructorCached.constructor === this) {
|
|
322
|
+
return this.constructorCached;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
throw new UsageError(
|
|
326
|
+
`Two schema classes were used (${this.name} and ${
|
|
327
|
+
this.constructorCached.constructor.name
|
|
328
|
+
}) which derived from the same SchemaFactory generated class (${JSON.stringify(
|
|
329
|
+
this.identifier,
|
|
330
|
+
)}). This is invalid.`,
|
|
331
|
+
);
|
|
332
|
+
}
|
|
218
333
|
|
|
219
334
|
public constructor(input: TInput | InternalTreeNode) {
|
|
220
335
|
super();
|
|
221
336
|
const schema = this.constructor as typeof TreeNodeValid & TreeNodeSchema;
|
|
222
|
-
|
|
223
|
-
if (
|
|
224
|
-
if (schema.constructorCached !== undefined) {
|
|
225
|
-
assert(
|
|
226
|
-
schema.constructorCached !== TreeNodeValid,
|
|
227
|
-
0x960 /* Schema class schema must override static constructorCached member */,
|
|
228
|
-
);
|
|
229
|
-
throw new UsageError(
|
|
230
|
-
`Two schema classes were instantiated (${schema.name} and ${schema.constructorCached.name}) which derived from the same SchemaFactory generated class. This is invalid`,
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
337
|
+
const cache = schema.markMostDerived();
|
|
338
|
+
if (!cache.oneTimeInitialized) {
|
|
234
339
|
const flexSchema = getFlexSchema(schema);
|
|
235
340
|
assert(
|
|
236
341
|
tryGetSimpleNodeSchema(flexSchema) === schema,
|
|
237
342
|
0x961 /* Schema class not properly configured */,
|
|
238
343
|
);
|
|
239
344
|
schema.oneTimeSetup();
|
|
240
|
-
|
|
241
|
-
// This is necessary to ensure there is only one subclass of that type used:
|
|
242
|
-
// if constructorCached was simply set on `schema`,
|
|
243
|
-
// then a base classes between `schema` (exclusive) and where `constructorCached` is set (inclusive) and other subclasses of them
|
|
244
|
-
// would not see the stored `constructorCached`, and the validation above against multiple derived classes would not work.
|
|
245
|
-
{
|
|
246
|
-
let schemaBase: typeof TreeNodeValid = schema;
|
|
247
|
-
while (!Object.prototype.hasOwnProperty.call(schemaBase, "constructorCached")) {
|
|
248
|
-
schemaBase = Reflect.getPrototypeOf(schemaBase) as typeof TreeNodeValid;
|
|
249
|
-
}
|
|
250
|
-
assert(
|
|
251
|
-
schemaBase.constructorCached === undefined,
|
|
252
|
-
0x962 /* overwriting wrong cache */,
|
|
253
|
-
);
|
|
254
|
-
schemaBase.constructorCached = schema;
|
|
255
|
-
}
|
|
345
|
+
cache.oneTimeInitialized = true;
|
|
256
346
|
}
|
|
257
347
|
|
|
258
348
|
if (isTreeNode(input)) {
|
|
@@ -271,6 +361,7 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
271
361
|
);
|
|
272
362
|
|
|
273
363
|
const result = schema.prepareInstance(this, node);
|
|
364
|
+
createKernel(result);
|
|
274
365
|
setFlexNode(result, node);
|
|
275
366
|
return result;
|
|
276
367
|
}
|
|
@@ -278,6 +369,22 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
278
369
|
// Class objects are functions (callable), so we need a strong way to distinguish between `schema` and `() => schema` when used as a `LazyItem`.
|
|
279
370
|
markEager(TreeNodeValid);
|
|
280
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Data cached about the most derived type in a schema's class hierarchy.
|
|
374
|
+
* @remarks
|
|
375
|
+
* The most derived type is the only one allowed to be referenced by other schema or constructed as a node.
|
|
376
|
+
* It has to be discovered lazily (when a node is constructed or when a {@link TreeViewConfiguration} is made),
|
|
377
|
+
* since JavaScript provides no way to find derived classes, or inject static class initialization time logic into base classes.
|
|
378
|
+
* Additionally since schema can reference other schema through lazy references which might be forward or recursive references,
|
|
379
|
+
* this can not be evaluated for one schema when referenced by another schema.
|
|
380
|
+
*
|
|
381
|
+
* See {@link TreeNodeValid.constructorCached} and {@link TreeNodeValid.markMostDerived}.
|
|
382
|
+
*/
|
|
383
|
+
export interface MostDerivedData {
|
|
384
|
+
readonly constructor: typeof TreeNodeValid & TreeNodeSchema;
|
|
385
|
+
oneTimeInitialized: boolean;
|
|
386
|
+
}
|
|
387
|
+
|
|
281
388
|
/**
|
|
282
389
|
* A node type internal to `@fluidframework/tree`.
|
|
283
390
|
* @remarks
|
|
@@ -293,3 +400,157 @@ export function toFlexTreeNode(node: InternalTreeNode): FlexTreeNode {
|
|
|
293
400
|
assert(isFlexTreeNode(node), 0x963 /* Invalid InternalTreeNode */);
|
|
294
401
|
return node;
|
|
295
402
|
}
|
|
403
|
+
|
|
404
|
+
// #region NodeJS custom inspect for TreeNodes.
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Used to customize "inspect" behavior in NodeJS.
|
|
408
|
+
* See https://nodejs.org/api/util.html#utilinspectcustom for details.
|
|
409
|
+
*
|
|
410
|
+
* VS-Code's debugger also uses this to inspect objects,
|
|
411
|
+
* see https://github.com/microsoft/vscode-js-debug/blob/64df2686c92bac402909dee5c3c389bbb7a81f6d/src/adapter/templates/getStringyProps.ts#L11 for details.
|
|
412
|
+
*/
|
|
413
|
+
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Node inspecting function for use with {@link customInspectSymbol}.
|
|
417
|
+
*/
|
|
418
|
+
function inspectNodeFunction(
|
|
419
|
+
this: TreeNodeValid<unknown>,
|
|
420
|
+
depth: number,
|
|
421
|
+
options?: unknown,
|
|
422
|
+
inspect?: unknown,
|
|
423
|
+
): unknown {
|
|
424
|
+
// TODO: replicated from tryGetSchema to avoid cycle.
|
|
425
|
+
// This case could be optimized, for example by placing the simple schema in a symbol on tree nodes.
|
|
426
|
+
const schema = tryGetSimpleNodeSchema(getFlexNode(this).schema) as TreeNodeSchemaClass;
|
|
427
|
+
const title = `${schema.name}: ${NodeKind[schema.kind]} Node (${schema.identifier})`;
|
|
428
|
+
|
|
429
|
+
if (depth < 2) {
|
|
430
|
+
const short = shortContent(this);
|
|
431
|
+
if (short !== undefined) {
|
|
432
|
+
return `${title} ${short}`;
|
|
433
|
+
}
|
|
434
|
+
return title;
|
|
435
|
+
}
|
|
436
|
+
const content = `${title} ${JSON.stringify(this)}`;
|
|
437
|
+
return content;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* If the node has no items, a short JSON string for it.
|
|
442
|
+
*/
|
|
443
|
+
function shortContent(node: TreeNodeValid<unknown>): string | undefined {
|
|
444
|
+
if (Object.values(node).length === 0) {
|
|
445
|
+
return JSON.stringify(node);
|
|
446
|
+
}
|
|
447
|
+
return undefined;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Add inherited non-enumerable symbol for NodeJS inspection to all nodes.
|
|
452
|
+
*
|
|
453
|
+
* See {@link customInspectSymbol}.
|
|
454
|
+
*/
|
|
455
|
+
Object.defineProperty(TreeNodeValid.prototype, customInspectSymbol, {
|
|
456
|
+
value: inspectNodeFunction,
|
|
457
|
+
enumerable: false,
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// #endregion
|
|
461
|
+
|
|
462
|
+
// #region Browser custom debug format for TreeNodes
|
|
463
|
+
|
|
464
|
+
// This section has side-effects, so including it in this file ensures its loaded whenever TreeNodes could exist.
|
|
465
|
+
// Supported in at least Chrome and FireFox, more details at https://firefox-source-docs.mozilla.org/devtools-user/custom_formatters/index.html
|
|
466
|
+
// For this to work the browser's dev tools generally have to "Enable custom formatters".
|
|
467
|
+
|
|
468
|
+
// This formatter is inspired by https://github.com/andrewdavey/immutable-devtools/blob/master/src/createFormatters.js which provides a similar formatter for the immutable.js library.
|
|
469
|
+
|
|
470
|
+
const globals = typeof window === "undefined" ? globalThis : window;
|
|
471
|
+
const formatters = ((
|
|
472
|
+
globals as { devtoolsFormatters?: DevtoolsFormatter.DevtoolsFormatter[] }
|
|
473
|
+
).devtoolsFormatters ??= []);
|
|
474
|
+
|
|
475
|
+
const nodeFormatter: DevtoolsFormatter.DevtoolsFormatter = {
|
|
476
|
+
header(object, config) {
|
|
477
|
+
if (isTreeNode(object)) {
|
|
478
|
+
return ["span", `${inspectNodeFunction.call(object, 1)}`];
|
|
479
|
+
}
|
|
480
|
+
return null;
|
|
481
|
+
},
|
|
482
|
+
body(object, config): DevtoolsFormatter.Item {
|
|
483
|
+
const children: DevtoolsFormatter.Item[] = [];
|
|
484
|
+
for (const [key, value] of Object.entries(object as TreeNode)) {
|
|
485
|
+
children.push(["li", ["span", `${key}: `], formattedReference(value)]);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// TODO:
|
|
489
|
+
// for array nodes, this isn't great since (at least in FireFox) the list items show up with a prefixed number starting from 1.
|
|
490
|
+
// This looks messy when followed by the array index.
|
|
491
|
+
// Find a way to hide the list index.
|
|
492
|
+
// { style: 'list-style-type: none` } did not seem to work.
|
|
493
|
+
|
|
494
|
+
return ["ol", ...children];
|
|
495
|
+
},
|
|
496
|
+
hasBody(object, config) {
|
|
497
|
+
return shortContent(object as TreeNodeValid<undefined>) === undefined;
|
|
498
|
+
},
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
function formattedReference(
|
|
502
|
+
object: unknown,
|
|
503
|
+
config?: DevtoolsFormatter.ObjectConfig,
|
|
504
|
+
): DevtoolsFormatter.Item {
|
|
505
|
+
if (typeof object === "undefined") {
|
|
506
|
+
return ["span", "undefined"];
|
|
507
|
+
} else if (object === "null") {
|
|
508
|
+
return ["span", "null"];
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return ["object", { object, config }];
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
formatters.push(nodeFormatter);
|
|
515
|
+
|
|
516
|
+
// #endregion
|
|
517
|
+
|
|
518
|
+
// These types are based on https://github.com/BenjaminAster/Better-TypeScript/blob/main/types/devtools-formatters.d.ts
|
|
519
|
+
// however the original package causes multiple compile errors due to some of its other types it used, so the relevant part has been extracted and adjusted to better match our conventions.
|
|
520
|
+
declare namespace DevtoolsFormatter {
|
|
521
|
+
type ObjectConfig = Record<string | symbol, unknown>;
|
|
522
|
+
|
|
523
|
+
type ElementTagName = "div" | "span" | "ol" | "li" | "table" | "tr" | "td";
|
|
524
|
+
|
|
525
|
+
type ElementTemplate = StyledElementTemplate | UnstyledElementTemplate;
|
|
526
|
+
|
|
527
|
+
type StyledElementTemplate = readonly [
|
|
528
|
+
ElementTagName,
|
|
529
|
+
{
|
|
530
|
+
style?: string;
|
|
531
|
+
},
|
|
532
|
+
...Item[],
|
|
533
|
+
];
|
|
534
|
+
|
|
535
|
+
type UnstyledElementTemplate = readonly [ElementTagName, ...Item[]];
|
|
536
|
+
|
|
537
|
+
type ObjectReference = readonly [
|
|
538
|
+
"object",
|
|
539
|
+
{
|
|
540
|
+
object: unknown;
|
|
541
|
+
config?: ObjectConfig;
|
|
542
|
+
},
|
|
543
|
+
];
|
|
544
|
+
|
|
545
|
+
type Item = string | ElementTemplate | ObjectReference;
|
|
546
|
+
|
|
547
|
+
interface DevtoolsFormatter {
|
|
548
|
+
header(
|
|
549
|
+
object?: unknown,
|
|
550
|
+
config?: ObjectConfig,
|
|
551
|
+
// eslint-disable-next-line @rushstack/no-new-null
|
|
552
|
+
): Item | null;
|
|
553
|
+
hasBody(object?: unknown, config?: ObjectConfig): boolean;
|
|
554
|
+
body(object?: unknown, config?: ObjectConfig): Item;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
7
|
+
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An object which can enter a "broken" state where trying to use it is a UsageError.
|
|
11
|
+
*/
|
|
12
|
+
export class Breakable {
|
|
13
|
+
private brokenBy?: Error;
|
|
14
|
+
|
|
15
|
+
public constructor(private readonly name: string) {}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Throws if the object is in the broken state.
|
|
19
|
+
* @remarks
|
|
20
|
+
* Can use {@link throwIfBroken} to apply this to a method.
|
|
21
|
+
*/
|
|
22
|
+
public use(): void {
|
|
23
|
+
if (this.brokenBy !== undefined) {
|
|
24
|
+
throw new UsageError(
|
|
25
|
+
`Invalid use of ${this.name} after it was put into an invalid state by another error.\nOriginal Error:\n${this.brokenBy}`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Puts this object into the broken state, and throws an error.
|
|
32
|
+
*
|
|
33
|
+
* @throws If already broken by a different error, throws a UsageError, otherwise throws `brokenBy`.
|
|
34
|
+
*/
|
|
35
|
+
public break(brokenBy: Error): never {
|
|
36
|
+
// If already broken by this error, let it bubble up without rethrowing a modified version.
|
|
37
|
+
// This prevents internal errors like asserts getting rethrown as different errors when wrapped with multiple call to `{@link Breakable.run}` or `{@link breakingMethod}`.
|
|
38
|
+
if (this.brokenBy !== brokenBy) {
|
|
39
|
+
this.use();
|
|
40
|
+
this.brokenBy = brokenBy;
|
|
41
|
+
}
|
|
42
|
+
throw brokenBy;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* {@link Breakable.break}, except tolerates `unknown` to be more easily used by catch blocks.
|
|
47
|
+
* @privateRemarks
|
|
48
|
+
* If there is a use-case, this should be made public.
|
|
49
|
+
*/
|
|
50
|
+
private rethrowCaught(brokenBy: unknown): never {
|
|
51
|
+
if (brokenBy instanceof Error) {
|
|
52
|
+
this.break(brokenBy);
|
|
53
|
+
}
|
|
54
|
+
this.break(
|
|
55
|
+
new Error(`Non-error thrown breaking ${this.name}. Thrown value: "${brokenBy}"`),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Runs code which should break the object if it throws.
|
|
61
|
+
* @remarks
|
|
62
|
+
* This also throws if already broken like {@link Breakable.use}.
|
|
63
|
+
* Any exceptions this catches are re-thrown.
|
|
64
|
+
* Can use {@link breakingMethod} to apply this to a method.
|
|
65
|
+
*/
|
|
66
|
+
public run<TResult>(breaker: () => TResult): TResult {
|
|
67
|
+
this.use();
|
|
68
|
+
try {
|
|
69
|
+
return breaker();
|
|
70
|
+
} catch (error: unknown) {
|
|
71
|
+
this.rethrowCaught(error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Clears the existing broken state.
|
|
77
|
+
* @remarks
|
|
78
|
+
* This is rarely safe to to: it is only ok when all objects using this breaker are known to not have been left in an invalid state.
|
|
79
|
+
* This is pretty much only safe in tests which just were checking a specific error was thrown, and which know that error closepath is actually exception safe.
|
|
80
|
+
*/
|
|
81
|
+
public clearError(): void {
|
|
82
|
+
assert(this.brokenBy !== undefined, 0x9b6 /* No error to clear */);
|
|
83
|
+
this.brokenBy = undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Marks an object as being able to be in a broken state (unknown/unspecified/broken state due to unhandled exception).
|
|
89
|
+
* @remarks
|
|
90
|
+
* See decorators {@link breakingMethod} and {@link throwIfBroken} for ease of use.
|
|
91
|
+
*/
|
|
92
|
+
export interface WithBreakable {
|
|
93
|
+
readonly breaker: Breakable;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Decorator for methods which should break the object when they throw.
|
|
98
|
+
* @remarks
|
|
99
|
+
* This also throws if already broken like {@link throwIfBroken}.
|
|
100
|
+
* See {@link Breakable.run} for details.
|
|
101
|
+
*
|
|
102
|
+
* This should be used on methods which modify data that could result in an unsupported/broken state if an exception is thrown while modifying.
|
|
103
|
+
* It is ok for breakingMethods to call each-other.
|
|
104
|
+
* @privateRemarks
|
|
105
|
+
* Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.
|
|
106
|
+
*/
|
|
107
|
+
export function breakingMethod<
|
|
108
|
+
Target extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return),
|
|
109
|
+
This extends WithBreakable,
|
|
110
|
+
Args extends never[],
|
|
111
|
+
Return,
|
|
112
|
+
>(target: Target, context?: ClassMethodDecoratorContext<This, Target>): Target {
|
|
113
|
+
function replacementMethod(this: This, ...args: Args): Return {
|
|
114
|
+
if (this.breaker === undefined) {
|
|
115
|
+
// This case is necessary for when wrapping methods which are invoked inside the constructor of the base class before `breaker` is set.
|
|
116
|
+
// Since the constructor throwing does not return an object, failing to put it into a broken state is not too bad.
|
|
117
|
+
// However when more than just the constructed object should be broken, this can result in missing a break.
|
|
118
|
+
return target.call(this, ...args);
|
|
119
|
+
}
|
|
120
|
+
return this.breaker.run(() => {
|
|
121
|
+
return target.call(this, ...args);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
markBreaker(replacementMethod);
|
|
125
|
+
nameFunctionFrom(replacementMethod, target);
|
|
126
|
+
return replacementMethod as Target;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Decorator for methods which should throw if the object is in a broken state.
|
|
131
|
+
* @remarks
|
|
132
|
+
* This should be used on methods which read data that could be invalid when the object is broken.
|
|
133
|
+
* @privateRemarks
|
|
134
|
+
* Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.
|
|
135
|
+
*/
|
|
136
|
+
export function throwIfBroken<
|
|
137
|
+
Target extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return),
|
|
138
|
+
This extends WithBreakable,
|
|
139
|
+
Args extends never[],
|
|
140
|
+
Return,
|
|
141
|
+
>(target: Target, context: ClassMethodDecoratorContext<This, Target>): Target {
|
|
142
|
+
function replacementMethod(this: This, ...args: Args): Return {
|
|
143
|
+
this.breaker.use();
|
|
144
|
+
return target.call(this, ...args);
|
|
145
|
+
}
|
|
146
|
+
markBreaker(replacementMethod);
|
|
147
|
+
nameFunctionFrom(replacementMethod, target);
|
|
148
|
+
return replacementMethod as Target;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
152
|
+
type PossiblyNamedFunction = Function & { displayName?: undefined | string };
|
|
153
|
+
|
|
154
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
155
|
+
function nameFunctionFrom(toName: Function, nameFrom: Function): void {
|
|
156
|
+
(toName as PossiblyNamedFunction).displayName =
|
|
157
|
+
(nameFrom as PossiblyNamedFunction).displayName ?? nameFrom.name;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const isBreakerSymbol: unique symbol = Symbol("isBreaker");
|
|
161
|
+
|
|
162
|
+
// Accepting any function like value is desired and safe here as this does not call the provided function.
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
164
|
+
function markBreaker(f: Function): void {
|
|
165
|
+
(f as unknown as Record<typeof isBreakerSymbol, true>)[isBreakerSymbol] = true;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Accepting any function like value is desired and safe here as this does not call the provided function.
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
170
|
+
function isBreaker(f: Function): boolean {
|
|
171
|
+
return isBreakerSymbol in (f as unknown as Record<typeof isBreakerSymbol, true>);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Decorator for classes which should break when their methods throw.
|
|
176
|
+
* @remarks
|
|
177
|
+
* Applies {@link breakingMethod} to all methods declared directly by class or its base classes.
|
|
178
|
+
* Does not include those on derived classes.
|
|
179
|
+
* Does not include getters or setters, or value properties.
|
|
180
|
+
* Methods already marked as {@link breakingMethod} or {@link throwIfBroken} are unaffected.
|
|
181
|
+
*/
|
|
182
|
+
export function breakingClass<Target extends abstract new (...args: any[]) => WithBreakable>(
|
|
183
|
+
target: Target,
|
|
184
|
+
context: ClassDecoratorContext<Target>,
|
|
185
|
+
): Target {
|
|
186
|
+
abstract class DecoratedBreakable extends target {}
|
|
187
|
+
|
|
188
|
+
// Keep track of what keys we have seen,
|
|
189
|
+
// since we visit most derived properties first and need to avoid wrapping base properties overriding more derived ones.
|
|
190
|
+
const overriddenKeys: Set<string | symbol> = new Set();
|
|
191
|
+
|
|
192
|
+
let prototype: object | null = target.prototype;
|
|
193
|
+
while (prototype !== null) {
|
|
194
|
+
for (const key of Reflect.ownKeys(prototype)) {
|
|
195
|
+
if (!overriddenKeys.has(key)) {
|
|
196
|
+
overriddenKeys.add(key);
|
|
197
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(prototype, key);
|
|
198
|
+
if (descriptor !== undefined) {
|
|
199
|
+
// Method
|
|
200
|
+
if (typeof descriptor.value === "function") {
|
|
201
|
+
if (!isBreaker(descriptor.value)) {
|
|
202
|
+
// This does not affect the original class, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor
|
|
203
|
+
descriptor.value = breakingMethod(descriptor.value);
|
|
204
|
+
Object.defineProperty(DecoratedBreakable.prototype, key, descriptor);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
prototype = Reflect.getPrototypeOf(prototype);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return DecoratedBreakable;
|
|
214
|
+
}
|
package/src/util/index.ts
CHANGED
|
@@ -24,11 +24,13 @@ export {
|
|
|
24
24
|
getOrDefaultInNestedMap,
|
|
25
25
|
forEachInNestedMap,
|
|
26
26
|
type NestedMap,
|
|
27
|
+
type ReadonlyNestedMap,
|
|
27
28
|
SizedNestedMap,
|
|
28
29
|
populateNestedMap,
|
|
29
30
|
setInNestedMap,
|
|
30
31
|
tryAddToNestedMap,
|
|
31
32
|
tryGetFromNestedMap,
|
|
33
|
+
mapNestedMap,
|
|
32
34
|
nestedMapToFlatList,
|
|
33
35
|
nestedMapFromFlatList,
|
|
34
36
|
} from "./nestedMap.js";
|
|
@@ -67,6 +69,7 @@ export {
|
|
|
67
69
|
JsonCompatibleReadOnlySchema,
|
|
68
70
|
makeArray,
|
|
69
71
|
mapIterable,
|
|
72
|
+
filterIterable,
|
|
70
73
|
type Mutable,
|
|
71
74
|
type Populated,
|
|
72
75
|
type RecursiveReadonly,
|
|
@@ -125,3 +128,11 @@ export {
|
|
|
125
128
|
type IdAllocationState,
|
|
126
129
|
fakeIdAllocator,
|
|
127
130
|
} from "./idAllocator.js";
|
|
131
|
+
|
|
132
|
+
export {
|
|
133
|
+
Breakable,
|
|
134
|
+
type WithBreakable,
|
|
135
|
+
breakingMethod,
|
|
136
|
+
throwIfBroken,
|
|
137
|
+
breakingClass,
|
|
138
|
+
} from "./breakable.js";
|