@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxyBinding.js","sourceRoot":"","sources":["../../src/simple-tree/proxyBinding.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { type AnchorNode, type AnchorSet, type UpPath, anchorSlot } from \"../core/index.js\";\nimport {\n\tContextSlot,\n\ttype FlexTreeNodeSchema,\n\ttype FlexMapNodeSchema,\n\ttype FlexObjectNodeSchema,\n\ttype FlexTreeMapNode,\n\ttype FlexTreeNode,\n\ttype FlexTreeObjectNode,\n\tassertFlexTreeEntityNotFreed,\n\tflexTreeSlot,\n\ttype FieldKinds,\n\ttype FlexFieldSchema,\n\ttype MapTreeNode,\n\tisMapTreeNode,\n} from \"../feature-libraries/index.js\";\nimport { fail } from \"../util/index.js\";\nimport type { WithType } from \"./schemaTypes.js\";\nimport type { TreeArrayNode } from \"./arrayNode.js\";\nimport type { TreeNode } from \"./types.js\";\n// TODO: decide how to deal with dependencies on flex-tree implementation.\n// eslint-disable-next-line import/no-internal-modules\nimport { makeTree } from \"../feature-libraries/flex-tree/lazyNode.js\";\nimport type { TreeMapNode } from \"./mapNode.js\";\n\n// This file contains various maps and helpers for supporting proxy binding (a.k.a. proxy hydration).\n// See ./ProxyBinding.md for a high-level overview of the process.\n\n/**\n * An anchor slot which associates an anchor with its corresponding node proxy, if there is one.\n */\nconst proxySlot = anchorSlot<TreeNode>();\n\n// The following records are maintained as WeakMaps, rather than a private symbol (e.g. like `targetSymbol`) on the node proxy itself.\n// The map behaves essentially the same, except that performing a lookup in the map will not perform a property read/get on the key object (as is the case with a symbol).\n// Since `SharedTreeNodes` are proxies with non-trivial `get` traps, this choice is meant to prevent the confusion of the lookup passing through multiple objects\n// via the trap, or the trap not properly handling the special symbol, etc.\n\n/** A reverse mapping of {@link proxySlot} that is updated at the same time. */\nconst proxyToAnchorNode = new WeakMap<TreeNode, AnchorNode>();\n\n// Map unhydrated nodes to and from their underlying flex tree implementation.\n// These maps are populated after a user calls `const proxy = new Foo({})` but before `proxy` is inserted into the tree and queried.\nconst proxyToMapTreeNode = new WeakMap<TreeNode, MapTreeNode>();\nconst mapTreeNodeToProxy = new WeakMap<MapTreeNode, TreeNode>();\n/** Used by `anchorProxy` as an optimization to ensure that only one anchor is remembered at a time for a given anchor node */\nconst anchorForgetters = new WeakMap<TreeNode, () => void>();\n\n/**\n * Creates an anchor node and associates it with the given proxy.\n * @privateRemarks Use `forgetters` to cleanup the anchor allocated by this function once the anchor is no longer needed.\n * In practice, this happens when either the anchor node is destroyed, or another anchor to the same node is created by a new flex node.\n */\nexport function anchorProxy(anchors: AnchorSet, path: UpPath, proxy: TreeNode): AnchorNode {\n\tassert(!anchorForgetters.has(proxy), 0x91c /* Proxy anchor should not be set twice */);\n\tconst anchor = anchors.track(path);\n\tconst anchorNode = anchors.locate(anchor) ?? fail(\"Expected anchor node to be present\");\n\tbindProxyToAnchorNode(proxy, anchorNode);\n\tconst forget = (): void => {\n\t\tif (anchors.locate(anchor)) {\n\t\t\tanchors.forget(anchor);\n\t\t}\n\t\tanchorForgetters.delete(proxy);\n\t\toff();\n\t};\n\tanchorForgetters.set(proxy, forget);\n\tconst off = anchorNode.on(\"afterDestroy\", forget);\n\treturn anchorNode;\n}\n\n/**\n * Retrieves the flex node associated with the given target via {@link setFlexNode}.\n * @remarks Fails if the flex node has not been set.\n */\nexport function getFlexNode(\n\tproxy: TypedNode<FlexObjectNodeSchema>,\n\tallowFreed?: true,\n): FlexTreeObjectNode;\nexport function getFlexNode(proxy: TreeArrayNode, allowFreed?: true): FlexTreeNode;\nexport function getFlexNode(\n\tproxy: TreeMapNode,\n\tallowFreed?: true,\n): FlexTreeMapNode<FlexMapNodeSchema<string, FlexFieldSchema<typeof FieldKinds.optional>>>;\nexport function getFlexNode(proxy: TreeNode, allowFreed?: true): FlexTreeNode;\nexport function getFlexNode(proxy: TreeNode, allowFreed = false): FlexTreeNode {\n\tconst anchorNode = proxyToAnchorNode.get(proxy);\n\tif (anchorNode !== undefined) {\n\t\t// The proxy is bound to an anchor node, but it may or may not have an actual flex node yet\n\t\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\t\tif (flexNode !== undefined) {\n\t\t\treturn flexNode; // If it does have a flex node, return it...\n\t\t} // ...otherwise, the flex node must be created\n\t\tconst context = anchorNode.anchorSet.slots.get(ContextSlot) ?? fail(\"missing context\");\n\t\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\t\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\t\tconst newFlexNode = makeTree(context, cursor);\n\t\tcursor.free();\n\t\t// Calling this is a performance improvement, however, do this only after demand to avoid momentarily having no anchors to anchorNode\n\t\tanchorForgetters?.get(proxy)?.();\n\t\tif (!allowFreed) {\n\t\t\tassertFlexTreeEntityNotFreed(newFlexNode);\n\t\t}\n\t\treturn newFlexNode;\n\t}\n\n\treturn proxyToMapTreeNode.get(proxy) ?? fail(\"Expected raw tree node for proxy\");\n}\n\n/**\n * Retrieves the flex node associated with the given target via {@link setFlexNode}, if any.\n */\nexport function tryGetFlexNode(target: unknown): FlexTreeNode | undefined {\n\t// Calling 'WeakMap.get()' with primitives (numbers, strings, etc.) will return undefined.\n\t// This is in contrast to 'WeakMap.set()', which will throw a TypeError if given a non-object key.\n\treturn (\n\t\tproxyToAnchorNode.get(target as TreeNode)?.slots.get(flexTreeSlot) ??\n\t\tproxyToMapTreeNode.get(target as TreeNode)\n\t);\n}\n\n/**\n * Retrieves the proxy associated with the given flex node via {@link setFlexNode}, if any.\n */\nexport function tryGetProxy(flexNode: FlexTreeNode): TreeNode | undefined {\n\tif (isMapTreeNode(flexNode)) {\n\t\treturn mapTreeNodeToProxy.get(flexNode);\n\t}\n\treturn flexNode.anchorNode.slots.get(proxySlot);\n}\n\n/**\n * Associate the given proxy and the given flex node.\n * @returns The proxy\n * @remarks\n * This creates a 1:1 mapping between the proxy and tree node.\n * Either can be retrieved from the other via {@link getFlexNode}/{@link tryGetFlexNode} or {@link tryGetProxy}.\n * If the given proxy is already mapped to an flex node, the existing mapping will be overwritten.\n * If the given flex node is already mapped to a different proxy, this function will fail.\n */\nexport function setFlexNode<TProxy extends TreeNode>(\n\tproxy: TProxy,\n\tflexNode: FlexTreeNode,\n): TProxy {\n\tconst existingFlexNode = proxyToAnchorNode.get(proxy)?.slots.get(flexTreeSlot);\n\tassert(\n\t\texistingFlexNode === undefined,\n\t\t0x91d /* Cannot associate a flex node with multiple targets */,\n\t);\n\tif (isMapTreeNode(flexNode)) {\n\t\tproxyToMapTreeNode.set(proxy, flexNode);\n\t\tmapTreeNodeToProxy.set(flexNode, proxy);\n\t} else {\n\t\tassert(\n\t\t\ttryGetProxy(flexNode) === undefined,\n\t\t\t0x7f5 /* Cannot associate an flex node with multiple targets */,\n\t\t);\n\t\tbindProxyToAnchorNode(proxy, flexNode.anchorNode);\n\t}\n\treturn proxy;\n}\n\n/**\n * Bi-directionally associates the given proxy to the given anchor node.\n * @remarks Cleans up mappings to raw flex nodes - it is assumed that they are no longer needed once the proxy has an anchor node.\n */\nfunction bindProxyToAnchorNode(proxy: TreeNode, anchorNode: AnchorNode): void {\n\t// If the proxy currently has a raw node, forget it\n\tconst mapTreeNode = proxyToMapTreeNode.get(proxy);\n\tif (mapTreeNode !== undefined) {\n\t\tproxyToMapTreeNode.delete(proxy);\n\t\tmapTreeNodeToProxy.delete(mapTreeNode);\n\t}\n\t// Once a proxy has been associated with an anchor node, it should never change to another anchor node\n\tassert(\n\t\t!proxyToAnchorNode.has(proxy),\n\t\t0x91e /* Proxy has already been bound to a different anchor node */,\n\t);\n\tproxyToAnchorNode.set(proxy, anchorNode);\n\t// However, it's fine for an anchor node to rotate through different proxies when the content at that place in the tree is replaced.\n\tanchorNode.slots.set(proxySlot, proxy);\n}\n\n/**\n * Given a node's schema, return the corresponding object in the proxy-based API.\n */\ntype TypedNode<TSchema extends FlexTreeNodeSchema> = TreeNode & WithType<TSchema[\"name\"]>;\n"]}
|
|
1
|
+
{"version":3,"file":"proxyBinding.js","sourceRoot":"","sources":["../../src/simple-tree/proxyBinding.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { type AnchorNode, type AnchorSet, type UpPath, anchorSlot } from \"../core/index.js\";\nimport {\n\tContextSlot,\n\ttype FlexTreeNodeSchema,\n\ttype FlexMapNodeSchema,\n\ttype FlexObjectNodeSchema,\n\ttype FlexTreeMapNode,\n\ttype FlexTreeNode,\n\ttype FlexTreeObjectNode,\n\tassertFlexTreeEntityNotFreed,\n\tflexTreeSlot,\n\ttype FieldKinds,\n\ttype FlexFieldSchema,\n\ttype MapTreeNode,\n\tisMapTreeNode,\n} from \"../feature-libraries/index.js\";\nimport { fail } from \"../util/index.js\";\nimport type { WithType } from \"./schemaTypes.js\";\nimport type { TreeArrayNode } from \"./arrayNode.js\";\nimport type { TreeNode } from \"./types.js\";\n// TODO: decide how to deal with dependencies on flex-tree implementation.\n// eslint-disable-next-line import/no-internal-modules\nimport { makeTree } from \"../feature-libraries/flex-tree/lazyNode.js\";\nimport type { TreeMapNode } from \"./mapNode.js\";\nimport { TreeNodeKernel } from \"./treeNodeKernel.js\";\n\n// This file contains various maps and helpers for supporting proxy binding (a.k.a. proxy hydration).\n// See ./ProxyBinding.md for a high-level overview of the process.\n\n/**\n * An anchor slot which associates an anchor with its corresponding node proxy, if there is one.\n */\nconst proxySlot = anchorSlot<TreeNode>();\n\n// The following records are maintained as WeakMaps, rather than a private symbol (e.g. like `targetSymbol`) on the node proxy itself.\n// The map behaves essentially the same, except that performing a lookup in the map will not perform a property read/get on the key object (as is the case with a symbol).\n// Since `SharedTreeNodes` are proxies with non-trivial `get` traps, this choice is meant to prevent the confusion of the lookup passing through multiple objects\n// via the trap, or the trap not properly handling the special symbol, etc.\n\n/** A reverse mapping of {@link proxySlot} that is updated at the same time. */\nconst proxyToAnchorNode = new WeakMap<TreeNode, AnchorNode>();\n\n// Map unhydrated nodes to and from their underlying flex tree implementation.\n// These maps are populated after a user calls `const proxy = new Foo({})` but before `proxy` is inserted into the tree and queried.\nconst proxyToMapTreeNode = new WeakMap<TreeNode, MapTreeNode>();\nconst mapTreeNodeToProxy = new WeakMap<MapTreeNode, TreeNode>();\n/** Used by `anchorProxy` as an optimization to ensure that only one anchor is remembered at a time for a given anchor node */\nconst anchorForgetters = new WeakMap<TreeNode, () => void>();\n\n/**\n * Creates an anchor node and associates it with the given proxy.\n * @privateRemarks Use `forgetters` to cleanup the anchor allocated by this function once the anchor is no longer needed.\n * In practice, this happens when either the anchor node is destroyed, or another anchor to the same node is created by a new flex node.\n */\nexport function anchorProxy(anchors: AnchorSet, path: UpPath, proxy: TreeNode): AnchorNode {\n\tassert(!anchorForgetters.has(proxy), 0x91c /* Proxy anchor should not be set twice */);\n\tconst anchor = anchors.track(path);\n\tconst anchorNode = anchors.locate(anchor) ?? fail(\"Expected anchor node to be present\");\n\tbindProxyToAnchorNode(proxy, anchorNode);\n\tconst forget = (): void => {\n\t\tif (anchors.locate(anchor)) {\n\t\t\tanchors.forget(anchor);\n\t\t}\n\t\tanchorForgetters.delete(proxy);\n\t\toff();\n\t};\n\tanchorForgetters.set(proxy, forget);\n\tconst off = anchorNode.on(\"afterDestroy\", forget);\n\treturn anchorNode;\n}\n\n/**\n * Retrieves the flex node associated with the given target via {@link setFlexNode}.\n * @remarks Fails if the flex node has not been set.\n */\nexport function getFlexNode(\n\tproxy: TypedNode<FlexObjectNodeSchema>,\n\tallowFreed?: true,\n): FlexTreeObjectNode;\nexport function getFlexNode(proxy: TreeArrayNode, allowFreed?: true): FlexTreeNode;\nexport function getFlexNode(\n\tproxy: TreeMapNode,\n\tallowFreed?: true,\n): FlexTreeMapNode<FlexMapNodeSchema<string, FlexFieldSchema<typeof FieldKinds.optional>>>;\nexport function getFlexNode(proxy: TreeNode, allowFreed?: true): FlexTreeNode;\nexport function getFlexNode(proxy: TreeNode, allowFreed = false): FlexTreeNode {\n\tconst anchorNode = proxyToAnchorNode.get(proxy);\n\tif (anchorNode !== undefined) {\n\t\t// The proxy is bound to an anchor node, but it may or may not have an actual flex node yet\n\t\tconst flexNode = anchorNode.slots.get(flexTreeSlot);\n\t\tif (flexNode !== undefined) {\n\t\t\treturn flexNode; // If it does have a flex node, return it...\n\t\t} // ...otherwise, the flex node must be created\n\t\tconst context = anchorNode.anchorSet.slots.get(ContextSlot) ?? fail(\"missing context\");\n\t\tconst cursor = context.checkout.forest.allocateCursor(\"getFlexNode\");\n\t\tcontext.checkout.forest.moveCursorToPath(anchorNode, cursor);\n\t\tconst newFlexNode = makeTree(context, cursor);\n\t\tcursor.free();\n\t\t// Calling this is a performance improvement, however, do this only after demand to avoid momentarily having no anchors to anchorNode\n\t\tanchorForgetters?.get(proxy)?.();\n\t\tif (!allowFreed) {\n\t\t\tassertFlexTreeEntityNotFreed(newFlexNode);\n\t\t}\n\t\treturn newFlexNode;\n\t}\n\n\treturn proxyToMapTreeNode.get(proxy) ?? fail(\"Expected raw tree node for proxy\");\n}\n\n/**\n * Retrieves the flex node associated with the given target via {@link setFlexNode}, if any.\n */\nexport function tryGetFlexNode(target: unknown): FlexTreeNode | undefined {\n\t// Calling 'WeakMap.get()' with primitives (numbers, strings, etc.) will return undefined.\n\t// This is in contrast to 'WeakMap.set()', which will throw a TypeError if given a non-object key.\n\treturn (\n\t\tproxyToAnchorNode.get(target as TreeNode)?.slots.get(flexTreeSlot) ??\n\t\tproxyToMapTreeNode.get(target as TreeNode)\n\t);\n}\n\n/**\n * Retrieves the proxy associated with the given flex node via {@link setFlexNode}, if any.\n */\nexport function tryGetProxy(flexNode: FlexTreeNode): TreeNode | undefined {\n\tif (isMapTreeNode(flexNode)) {\n\t\treturn mapTreeNodeToProxy.get(flexNode);\n\t}\n\treturn flexNode.anchorNode.slots.get(proxySlot);\n}\n\n/**\n * Associate the given proxy and the given flex node.\n * @returns The proxy\n * @remarks\n * This creates a 1:1 mapping between the proxy and tree node.\n * Either can be retrieved from the other via {@link getFlexNode}/{@link tryGetFlexNode} or {@link tryGetProxy}.\n * If the given proxy is already mapped to an flex node, the existing mapping will be overwritten.\n * If the given flex node is already mapped to a different proxy, this function will fail.\n */\nexport function setFlexNode<TProxy extends TreeNode>(\n\tproxy: TProxy,\n\tflexNode: FlexTreeNode,\n): TProxy {\n\tconst existingFlexNode = proxyToAnchorNode.get(proxy)?.slots.get(flexTreeSlot);\n\tassert(\n\t\texistingFlexNode === undefined,\n\t\t0x91d /* Cannot associate a flex node with multiple targets */,\n\t);\n\tif (isMapTreeNode(flexNode)) {\n\t\tproxyToMapTreeNode.set(proxy, flexNode);\n\t\tmapTreeNodeToProxy.set(flexNode, proxy);\n\t} else {\n\t\tassert(\n\t\t\ttryGetProxy(flexNode) === undefined,\n\t\t\t0x7f5 /* Cannot associate an flex node with multiple targets */,\n\t\t);\n\t\tbindProxyToAnchorNode(proxy, flexNode.anchorNode);\n\t}\n\treturn proxy;\n}\n\n/**\n * Bi-directionally associates the given proxy to the given anchor node.\n * @remarks Cleans up mappings to raw flex nodes - it is assumed that they are no longer needed once the proxy has an anchor node.\n */\nfunction bindProxyToAnchorNode(proxy: TreeNode, anchorNode: AnchorNode): void {\n\t// If the proxy currently has a raw node, forget it\n\tconst mapTreeNode = proxyToMapTreeNode.get(proxy);\n\tif (mapTreeNode !== undefined) {\n\t\tproxyToMapTreeNode.delete(proxy);\n\t\tmapTreeNodeToProxy.delete(mapTreeNode);\n\t}\n\t// Once a proxy has been associated with an anchor node, it should never change to another anchor node\n\tassert(\n\t\t!proxyToAnchorNode.has(proxy),\n\t\t0x91e /* Proxy has already been bound to a different anchor node */,\n\t);\n\tproxyToAnchorNode.set(proxy, anchorNode);\n\t// However, it's fine for an anchor node to rotate through different proxies when the content at that place in the tree is replaced.\n\tanchorNode.slots.set(proxySlot, proxy);\n\tgetKernel(proxy).hydrate(anchorNode);\n}\n\n/**\n * Given a node's schema, return the corresponding object in the proxy-based API.\n */\ntype TypedNode<TSchema extends FlexTreeNodeSchema> = TreeNode & WithType<TSchema[\"name\"]>;\n\nexport function createKernel(node: TreeNode): void {\n\ttreeNodeToKernel.set(node, new TreeNodeKernel(node));\n}\n\nexport function getKernel(node: TreeNode): TreeNodeKernel {\n\tconst kernel = treeNodeToKernel.get(node);\n\tassert(kernel !== undefined, 0x9b1 /* Expected tree node to have kernel */);\n\treturn kernel;\n}\n\nexport function tryDisposeTreeNode(anchorNode: AnchorNode): void {\n\tconst treeNode = anchorNode.slots.get(proxySlot);\n\tif (treeNode !== undefined) {\n\t\tconst kernel = treeNodeToKernel.get(treeNode);\n\t\tassert(kernel !== undefined, 0x9b2 /* Expected tree node to have kernel */);\n\t\tkernel.dispose();\n\t}\n}\n\nconst treeNodeToKernel = new WeakMap<TreeNode, TreeNodeKernel>();\n"]}
|
|
@@ -78,6 +78,13 @@ export type ScopedSchemaName<TScope extends string | undefined, TName extends nu
|
|
|
78
78
|
*/
|
|
79
79
|
export declare class SchemaFactory<out TScope extends string | undefined = string | undefined, TName extends number | string = string> {
|
|
80
80
|
readonly scope: TScope;
|
|
81
|
+
/**
|
|
82
|
+
* TODO:
|
|
83
|
+
* If users of this generate the same name because two different schema with the same identifier were used,
|
|
84
|
+
* the second use can get a cache hit, and reference the wrong schema.
|
|
85
|
+
* Such usage should probably return a distinct type or error but currently does not.
|
|
86
|
+
* The use of markSchemaMostDerived in structuralName at least ensure an error in the case where the collision is from two types extending the same schema factor class.
|
|
87
|
+
*/
|
|
81
88
|
private readonly structuralTypes;
|
|
82
89
|
/**
|
|
83
90
|
* Construct a SchemaFactory with a given scope.
|
|
@@ -141,7 +148,7 @@ export declare class SchemaFactory<out TScope extends string | undefined = strin
|
|
|
141
148
|
*/
|
|
142
149
|
readonly handle: TreeNodeSchema<"com.fluidframework.leaf.handle", NodeKind.Leaf, _dummyImport<unknown>, _dummyImport<unknown>>;
|
|
143
150
|
/**
|
|
144
|
-
* Define a {@link
|
|
151
|
+
* Define a {@link TreeNodeSchemaClass} for a {@link TreeObjectNode}.
|
|
145
152
|
*
|
|
146
153
|
* @param name - Unique identifier for this schema within this factory's scope.
|
|
147
154
|
* @param fields - Schema for fields of the object node's schema. Defines what children can be placed under each key.
|
|
@@ -359,4 +366,12 @@ export declare class SchemaFactory<out TScope extends string | undefined = strin
|
|
|
359
366
|
}, false, T>;
|
|
360
367
|
}
|
|
361
368
|
export declare function structuralName<const T extends string>(collectionName: T, allowedTypes: TreeNodeSchema | readonly TreeNodeSchema[]): `${T}<${string}>`;
|
|
369
|
+
/**
|
|
370
|
+
* Indicates that a schema is the "most derived" version which is allowed to be used, see {@link MostDerivedData}.
|
|
371
|
+
* Calling helps with error messages about invalid schema usage (using more than one type from single schema factor produced type,
|
|
372
|
+
* and thus calling this for one than one subclass).
|
|
373
|
+
* @remarks
|
|
374
|
+
* Helper for invoking {@link TreeNodeValid.markMostDerived} for any {@link TreeNodeSchema} if it needed.
|
|
375
|
+
*/
|
|
376
|
+
export declare function markSchemaMostDerived(schema: TreeNodeSchema): void;
|
|
362
377
|
//# sourceMappingURL=schemaFactory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaFactory.d.ts","sourceRoot":"","sources":["../../src/simple-tree/schemaFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,YAAY,IAAI,YAAY,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"schemaFactory.d.ts","sourceRoot":"","sources":["../../src/simple-tree/schemaFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.structuralName = exports.SchemaFactory = exports.schemaFromValue = void 0;
|
|
7
|
+
exports.markSchemaMostDerived = exports.structuralName = exports.SchemaFactory = exports.schemaFromValue = void 0;
|
|
8
8
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
|
+
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
10
|
+
const internal_3 = require("@fluidframework/runtime-utils/internal");
|
|
9
11
|
const index_js_1 = require("../feature-libraries/index.js");
|
|
10
12
|
const index_js_2 = require("../util/index.js");
|
|
11
13
|
const leafNodeSchema_js_1 = require("./leafNodeSchema.js");
|
|
12
14
|
const schemaTypes_js_1 = require("./schemaTypes.js");
|
|
13
15
|
const arrayNode_js_1 = require("./arrayNode.js");
|
|
14
|
-
const internal_2 = require("@fluidframework/runtime-utils/internal");
|
|
15
16
|
const objectNode_js_1 = require("./objectNode.js");
|
|
16
17
|
const mapNode_js_1 = require("./mapNode.js");
|
|
17
18
|
const schemaFactoryRecursive_js_1 = require("./schemaFactoryRecursive.js");
|
|
19
|
+
const types_js_1 = require("./types.js");
|
|
18
20
|
/**
|
|
19
21
|
* Gets the leaf domain schema compatible with a given {@link TreeValue}.
|
|
20
22
|
*/
|
|
@@ -30,7 +32,7 @@ function schemaFromValue(value) {
|
|
|
30
32
|
if (value === null) {
|
|
31
33
|
return leafNodeSchema_js_1.nullSchema;
|
|
32
34
|
}
|
|
33
|
-
(0, internal_1.assert)((0,
|
|
35
|
+
(0, internal_1.assert)((0, internal_3.isFluidHandle)(value), 0x87e /* invalid TreeValue */);
|
|
34
36
|
return leafNodeSchema_js_1.handleSchema;
|
|
35
37
|
}
|
|
36
38
|
default:
|
|
@@ -114,6 +116,13 @@ class SchemaFactory {
|
|
|
114
116
|
*/
|
|
115
117
|
constructor(scope) {
|
|
116
118
|
this.scope = scope;
|
|
119
|
+
/**
|
|
120
|
+
* TODO:
|
|
121
|
+
* If users of this generate the same name because two different schema with the same identifier were used,
|
|
122
|
+
* the second use can get a cache hit, and reference the wrong schema.
|
|
123
|
+
* Such usage should probably return a distinct type or error but currently does not.
|
|
124
|
+
* The use of markSchemaMostDerived in structuralName at least ensure an error in the case where the collision is from two types extending the same schema factor class.
|
|
125
|
+
*/
|
|
117
126
|
this.structuralTypes = new Map();
|
|
118
127
|
/**
|
|
119
128
|
* {@link TreeNodeSchema} for holding a JavaScript `string`.
|
|
@@ -166,7 +175,7 @@ class SchemaFactory {
|
|
|
166
175
|
return (this.scope === undefined ? `${name}` : `${this.scope}.${name}`);
|
|
167
176
|
}
|
|
168
177
|
/**
|
|
169
|
-
* Define a {@link
|
|
178
|
+
* Define a {@link TreeNodeSchemaClass} for a {@link TreeObjectNode}.
|
|
170
179
|
*
|
|
171
180
|
* @param name - Unique identifier for this schema within this factory's scope.
|
|
172
181
|
* @param fields - Schema for fields of the object node's schema. Defines what children can be placed under each key.
|
|
@@ -338,6 +347,7 @@ function structuralName(collectionName, allowedTypes) {
|
|
|
338
347
|
const names = allowedTypes.map((t) => {
|
|
339
348
|
// Ensure that lazy types (functions) don't slip through here.
|
|
340
349
|
(0, internal_1.assert)(!(0, index_js_1.isLazy)(t), 0x83d /* invalid type provided */);
|
|
350
|
+
markSchemaMostDerived(t);
|
|
341
351
|
return t.identifier;
|
|
342
352
|
});
|
|
343
353
|
// Ensure name is order independent
|
|
@@ -350,4 +360,22 @@ function structuralName(collectionName, allowedTypes) {
|
|
|
350
360
|
return `${collectionName}<${inner}>`;
|
|
351
361
|
}
|
|
352
362
|
exports.structuralName = structuralName;
|
|
363
|
+
/**
|
|
364
|
+
* Indicates that a schema is the "most derived" version which is allowed to be used, see {@link MostDerivedData}.
|
|
365
|
+
* Calling helps with error messages about invalid schema usage (using more than one type from single schema factor produced type,
|
|
366
|
+
* and thus calling this for one than one subclass).
|
|
367
|
+
* @remarks
|
|
368
|
+
* Helper for invoking {@link TreeNodeValid.markMostDerived} for any {@link TreeNodeSchema} if it needed.
|
|
369
|
+
*/
|
|
370
|
+
function markSchemaMostDerived(schema) {
|
|
371
|
+
if (schema instanceof leafNodeSchema_js_1.LeafNodeSchema) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
if (!(0, types_js_1.inPrototypeChain)(schema, types_js_1.TreeNodeValid)) {
|
|
375
|
+
// Use JSON.stringify to quote and escape identifier string.
|
|
376
|
+
throw new internal_2.UsageError(`Schema for ${JSON.stringify(schema.identifier)} does not extend a SchemaFactory generated class. This is invalid.`);
|
|
377
|
+
}
|
|
378
|
+
schema.markMostDerived();
|
|
379
|
+
}
|
|
380
|
+
exports.markSchemaMostDerived = markSchemaMostDerived;
|
|
353
381
|
//# sourceMappingURL=schemaFactory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaFactory.js","sourceRoot":"","sources":["../../src/simple-tree/schemaFactory.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\n// Include this unused import to avoid TypeScript generating an inline import for IFluidHandle in the d.ts file\n// which degrades the API-Extractor report quality since API-Extractor can not tell the inline import is the same as the non-inline one.\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport type { IFluidHandle as _dummyImport } from \"@fluidframework/core-interfaces\";\n\nimport type { TreeValue } from \"../core/index.js\";\nimport { type NodeKeyManager, type Unenforced, isLazy } from \"../feature-libraries/index.js\";\nimport {\n\ttype RestrictiveReadonlyRecord,\n\tgetOrCreate,\n\tisReadonlyArray,\n} from \"../util/index.js\";\n\nimport {\n\tbooleanSchema,\n\thandleSchema,\n\tnullSchema,\n\tnumberSchema,\n\tstringSchema,\n} from \"./leafNodeSchema.js\";\nimport {\n\tFieldKind,\n\ttype FieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype ImplicitFieldSchema,\n\ttype InsertableTreeNodeFromImplicitAllowedTypes,\n\ttype NodeKind,\n\ttype TreeNodeSchema,\n\ttype TreeNodeSchemaClass,\n\ttype WithType,\n\ttype FieldProps,\n\tcreateFieldSchema,\n\ttype DefaultProvider,\n\tgetDefaultProvider,\n} from \"./schemaTypes.js\";\nimport { type TreeArrayNode, arraySchema } from \"./arrayNode.js\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\nimport {\n\ttype InsertableObjectFromSchemaRecord,\n\ttype TreeObjectNode,\n\tobjectSchema,\n} from \"./objectNode.js\";\nimport { type TreeMapNode, mapSchema } from \"./mapNode.js\";\nimport type {\n\tFieldSchemaUnsafe,\n\t// Adding these unused imports makes the generated d.ts file produced by TypeScript stop breaking API-Extractor's rollup generation.\n\t// Without this import, TypeScript generates inline `import(\"../..\")` statements in the d.ts file,\n\t// which API-Extractor leaves as is when generating the rollup, leaving them pointing at the wrong directory.\n\t// API-Extractor issue: https://github.com/microsoft/rushstack/issues/4507\n\t// eslint-disable-next-line unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars\n\tFieldHasDefaultUnsafe,\n\t// eslint-disable-next-line unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars\n\tInsertableTreeFieldFromImplicitFieldUnsafe,\n\tInsertableObjectFromSchemaRecordUnsafe,\n\tInsertableTreeNodeFromImplicitAllowedTypesUnsafe,\n\tTreeArrayNodeUnsafe,\n\tTreeMapNodeUnsafe,\n\tTreeObjectNodeUnsafe,\n} from \"./typesUnsafe.js\";\nimport { createFieldSchemaUnsafe } from \"./schemaFactoryRecursive.js\";\n/**\n * Gets the leaf domain schema compatible with a given {@link TreeValue}.\n */\nexport function schemaFromValue(value: TreeValue): TreeNodeSchema {\n\tswitch (typeof value) {\n\t\tcase \"boolean\":\n\t\t\treturn booleanSchema;\n\t\tcase \"number\":\n\t\t\treturn numberSchema;\n\t\tcase \"string\":\n\t\t\treturn stringSchema;\n\t\tcase \"object\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn nullSchema;\n\t\t\t}\n\t\t\tassert(isFluidHandle(value), 0x87e /* invalid TreeValue */);\n\t\t\treturn handleSchema;\n\t\t}\n\t\tdefault:\n\t\t\tunreachableCase(value);\n\t}\n}\n\n/**\n * The name of a schema produced by {@link SchemaFactory}, including its optional scope prefix.\n *\n * @public\n */\nexport type ScopedSchemaName<\n\tTScope extends string | undefined,\n\tTName extends number | string,\n> = TScope extends undefined ? `${TName}` : `${TScope}.${TName}`;\n// > = `${TScope extends undefined ? \"\" : `${TScope}.`}${TName}`;\n\n// TODO:\n// SchemaFactory.array references should link to the correct overloads, however the syntax for this does not seems to work currently for methods unless the they are not qualified with the class.\n// API-Extractor requires such links to be qualified with the class, so it can't work.\n// Since linking the overload set as a whole also doesn't work, these have been made non-links for now.\n/**\n * Creates various types of {@link TreeNodeSchema|schema} for {@link TreeNode}s.\n *\n * @typeParam TScope - Scope added as a prefix to the name of every schema produced by this factory.\n * @typeParam TName - Type of names used to identify each schema produced in this factory.\n * Typically this is just `string` but it is also possible to use `string` or `number` based enums if you prefer to identify your types that way.\n *\n * @remarks\n * All schema produced by this factory get a {@link TreeNodeSchemaCore.identifier|unique identifier} by combining the {@link SchemaFactory.scope} with the schema's `Name`.\n * The `Name` part may be explicitly provided as a parameter, or inferred as a structural combination of the provided types.\n * The APIs which use this second approach, structural naming, also deduplicate all equivalent calls.\n * Therefor two calls to `array(allowedTypes)` with the same allowedTypes will return the same {@link TreeNodeSchema} instance.\n * On the other hand, two calls to `array(name, allowedTypes)` will always return different {@link TreeNodeSchema} instances\n * and it is an error to use both in the same tree (since their identifiers are not unique).\n *\n * Note:\n * POJO stands for Plain Old JavaScript Object.\n * This means an object that works like a `{}` style object literal.\n * In this case it means the prototype is `Object.prototype` and acts like a set of key value pairs (data, not methods).\n * The usage below generalizes this to include array and map like objects as well.\n *\n * There are two ways to use these APIs:\n * | | Customizable | POJO Emulation |\n * | ------------------- | ------------ |--------------- |\n * | Declaration | `class X extends schemaFactory.object(\"x\", {}) {}` | `const X = schemaFactory.object(\"x\", {}); type X = NodeFromSchema<typeof X>; `\n * | Allows adding \"local\" (non-persisted) members | Yes. Members (including methods) can be added to class. | No. Attempting to set non-field members will error. |\n * | Prototype | The user defined class | `Object.prototype`, `Map.prototype` or `Array.prototype` depending on node kind |\n * | Structurally named Schema | Not Supported | Supported |\n * | Explicitly named Objects | Supported | Supported |\n * | Explicitly named Maps and Arrays | Supported: Both declaration approaches can be used | Not Supported |\n * | node.js assert.deepEqual | Compares like class instances: equal to other nodes of the same type with the same content, including custom local fields. | Compares like plain objects: equal to plain JavaScript objects with the same fields, and other nodes with the same fields, even if the types are different. |\n * | IntelliSense | Shows and links to user defined class by name: `X` | Shows internal type generation logic: `object & TreeNode & ObjectFromSchemaRecord<{}> & WithType<\"test.x\">` |\n * | Recursion | Supported with special declaration patterns. | Unsupported: Generated d.ts files replace recursive references with `any`, breaking use of recursive schema across compilation boundaries |\n *\n * Note that while \"POJO Emulation\" nodes act a lot like POJO objects, they are not true POJO objects:\n *\n * - Adding new arbitrary fields will error, as well some cases of invalid edits.\n *\n * - They are implemented using proxies.\n *\n * - They have state that is not exposed via enumerable own properties, including a {@link TreeNodeSchema}.\n * This makes libraries like node.js `assert.deepEqual` fail to detect differences in type.\n *\n * - Assigning members has side effects (in this case editing the persisted/shared tree).\n *\n * - Not all operations implied by the prototype will work correctly: stick to the APIs explicitly declared in the TypeScript types.\n *\n * @privateRemarks\n * It's perfectly possible to make `POJO Emulation` mode (or even just hiding the prototype) selectable even when using the custom user class declaration syntax.\n * When doing this, it's still possible to make `instanceof` perform correctly.\n * Allowing (or banning) custom/out-of-schema properties on the class is also possible in both modes: it could be orthogonal.\n * Also for consistency, if keeping the current approach to detecting `POJO Emulation` mode it might make sense to make explicitly named Maps and Arrays do the detection the same as how object does it.\n *\n * @sealed @public\n */\nexport class SchemaFactory<\n\tout TScope extends string | undefined = string | undefined,\n\tTName extends number | string = string,\n> {\n\tprivate readonly structuralTypes: Map<string, TreeNodeSchema> = new Map();\n\n\t/**\n\t * Construct a SchemaFactory with a given scope.\n\t * @remarks\n\t * There are no restrictions on mixing schema from different schema factories:\n\t * this is encouraged when a single schema references schema from different libraries.\n\t * If each library exporting schema picks its own globally unique scope for its SchemaFactory,\n\t * then all schema an application might depend on, directly or transitively,\n\t * will end up with a unique fully qualified name which is required to refer to it in persisted data and errors.\n\t *\n\t * @param scope - Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder.\n\t * Use of [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 is recommended to avoid collisions.\n\t * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions.\n\t */\n\tpublic constructor(public readonly scope: TScope) {}\n\n\tprivate scoped<Name extends TName | string>(name: Name): ScopedSchemaName<TScope, Name> {\n\t\treturn (\n\t\t\tthis.scope === undefined ? `${name}` : `${this.scope}.${name}`\n\t\t) as ScopedSchemaName<TScope, Name>;\n\t}\n\n\t/**\n\t * {@link TreeNodeSchema} for holding a JavaScript `string`.\n\t *\n\t * @remarks\n\t * Strings containing unpaired UTF-16 surrogate pair code units may not be handled correctly.\n\t *\n\t * These limitations come from the use of UTF-8 encoding of the strings, which requires them to be valid unicode.\n\t * JavaScript does not make this requirement for its strings so not all possible JavaScript strings are supported.\n\t * @privateRemarks\n\t * TODO:\n\t * We should be much more clear about what happens if you use problematic values.\n\t * We should validate and/or normalize them when inserting content.\n\t */\n\tpublic readonly string = stringSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for holding a JavaScript `number`.\n\t *\n\t * @remarks\n\t * The number is a [double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) value, however there are some exceptions:\n\t * - `NaN`, and the infinities are converted to `null` (and may therefore only be used where `null` is allowed by the schema).\n\t * - `-0` may be converted to `0` in some cases.\n\t *\n\t * These limitations match the limitations of JSON.\n\t * @privateRemarks\n\t * TODO:\n\t * We should be much more clear about what happens if you use problematic values.\n\t * We should validate and/or normalize them when inserting content.\n\t */\n\tpublic readonly number = numberSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for holding a boolean.\n\t */\n\tpublic readonly boolean = booleanSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for JavaScript `null`.\n\t *\n\t * @remarks\n\t * There are good [reasons to avoid using null](https://www.npmjs.com/package/%40rushstack/eslint-plugin#rushstackno-new-null) in JavaScript, however sometimes it is desired.\n\t * This {@link TreeNodeSchema} node provides the option to include nulls in trees when desired.\n\t * Unless directly inter-operating with existing data using null, consider other approaches, like wrapping the value in an optional field, or using a more specifically named empty object node.\n\t */\n\tpublic readonly null = nullSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for holding an {@link @fluidframework/core-interfaces#(IFluidHandle:interface)}.\n\t */\n\tpublic readonly handle = handleSchema;\n\n\t/**\n\t * Define a {@link TreeNodeSchema} for a {@link TreeObjectNode}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t * @param fields - Schema for fields of the object node's schema. Defines what children can be placed under each key.\n\t */\n\tpublic object<\n\t\tconst Name extends TName,\n\t\tconst T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>,\n\t>(\n\t\tname: Name,\n\t\tfields: T,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Object,\n\t\tTreeObjectNode<T, ScopedSchemaName<TScope, Name>>,\n\t\tobject & InsertableObjectFromSchemaRecord<T>,\n\t\ttrue,\n\t\tT\n\t> {\n\t\treturn objectSchema(this.scoped(name), fields, true);\n\t}\n\n\t/**\n\t * Define a structurally typed {@link TreeNodeSchema} for a {@link TreeMapNode}.\n\t *\n\t * @remarks\n\t * The unique identifier for this Map is defined as a function of the provided types.\n\t * It is still scoped to this SchemaBuilder, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing.\n\t * This does not support recursive types.\n\t *\n\t * If using these structurally named maps, other types in this schema builder should avoid names of the form `Map<${string}>`.\n\t *\n\t * @example\n\t * The returned schema should be used as a schema directly:\n\t * ```typescript\n\t * const MyMap = factory.map(factory.number);\n\t * type MyMap = NodeFromSchema<typeof MyMap>;\n\t * ```\n\t * Or inline:\n\t * ```typescript\n\t * factory.object(\"Foo\", {myMap: factory.map(factory.number)});\n\t * ```\n\t * @privateRemarks\n\t * See note on array.\n\t */\n\tpublic map<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(\n\t\tallowedTypes: T,\n\t): TreeNodeSchema<\n\t\tScopedSchemaName<TScope, `Map<${string}>`>,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T> & WithType<ScopedSchemaName<TScope, `Map<${string}>`>>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\t/**\n\t * Define a {@link TreeNodeSchema} for a {@link TreeMapNode}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t *\n\t * @example\n\t * ```typescript\n\t * class NamedMap extends factory.map(\"name\", factory.number) {}\n\t * ```\n\t */\n\tpublic map<Name extends TName, const T extends ImplicitAllowedTypes>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\tpublic map<const T extends ImplicitAllowedTypes>(\n\t\tnameOrAllowedTypes: TName | ((T & TreeNodeSchema) | readonly TreeNodeSchema[]),\n\t\tallowedTypes?: T,\n\t): TreeNodeSchema<\n\t\tstring,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\ttrue,\n\t\tT\n\t> {\n\t\tif (allowedTypes === undefined) {\n\t\t\tconst types = nameOrAllowedTypes as (T & TreeNodeSchema) | readonly TreeNodeSchema[];\n\t\t\tconst fullName = structuralName(\"Map\", types);\n\t\t\treturn getOrCreate(\n\t\t\t\tthis.structuralTypes,\n\t\t\t\tfullName,\n\t\t\t\t() =>\n\t\t\t\t\tthis.namedMap(\n\t\t\t\t\t\tfullName as TName,\n\t\t\t\t\t\tnameOrAllowedTypes as T,\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t) as TreeNodeSchema,\n\t\t\t) as TreeNodeSchemaClass<\n\t\t\t\tstring,\n\t\t\t\tNodeKind.Map,\n\t\t\t\tTreeMapNode<T>,\n\t\t\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\t\t\ttrue,\n\t\t\t\tT\n\t\t\t>;\n\t\t}\n\t\treturn this.namedMap(nameOrAllowedTypes as TName, allowedTypes, true, true);\n\t}\n\n\t/**\n\t * Define a {@link TreeNodeSchema} for a {@link (TreeMapNode:interface)}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t */\n\tprivate namedMap<\n\t\tName extends TName | string,\n\t\tconst T extends ImplicitAllowedTypes,\n\t\tconst ImplicitlyConstructable extends boolean,\n\t>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t\tcustomizable: boolean,\n\t\timplicitlyConstructable: ImplicitlyConstructable,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\tImplicitlyConstructable,\n\t\tT\n\t> {\n\t\treturn mapSchema(\n\t\t\tthis.scoped(name),\n\t\t\tallowedTypes,\n\t\t\timplicitlyConstructable,\n\t\t\t// The current policy is customizable nodes don't get fake prototypes.\n\t\t\t!customizable,\n\t\t);\n\t}\n\n\t/**\n\t * Define a structurally typed {@link TreeNodeSchema} for a {@link (TreeArrayNode:interface)}.\n\t *\n\t * @remarks\n\t * The identifier for this Array is defined as a function of the provided types.\n\t * It is still scoped to this SchemaFactory, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing.\n\t * This does not support recursive types.\n\t *\n\t * If using these structurally named arrays, other types in this schema builder should avoid names of the form `Array<${string}>`.\n\t *\n\t * @example\n\t * The returned schema should be used as a schema directly:\n\t * ```typescript\n\t * const MyArray = factory.array(factory.number);\n\t * type MyArray = NodeFromSchema<typeof MyArray>;\n\t * ```\n\t * Or inline:\n\t * ```typescript\n\t * factory.object(\"Foo\", {myArray: factory.array(factory.number)});\n\t * ```\n\t * @privateRemarks\n\t * The name produced at the type level here is not as specific as it could be, however doing type level sorting and escaping is a real mess.\n\t * There are cases where not having this full type provided will be less than ideal since TypeScript's structural types.\n\t * For example attempts to narrow unions of structural arrays by name won't work.\n\t * Planned future changes to move to a class based schema system as well as factor function based node construction should mostly avoid these issues,\n\t * though there may still be some problematic cases even after that work is done.\n\t *\n\t * The return value is a class, but its the type is intentionally not specific enough to indicate it is a class.\n\t * This prevents callers of this from sub-classing it, which is unlikely to work well (due to the ease of accidentally giving two different calls o this different subclasses)\n\t * when working with structural typing.\n\t *\n\t * {@label STRUCTURAL}\n\t */\n\tpublic array<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(\n\t\tallowedTypes: T,\n\t): TreeNodeSchema<\n\t\tScopedSchemaName<TScope, `Array<${string}>`>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T> & WithType<ScopedSchemaName<TScope, `Array<${string}>`>>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\t/**\n\t * Define (and add to this library) a {@link TreeNodeSchemaClass} for a {@link (TreeArrayNode:interface)}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t *\n\t * @example\n\t * ```typescript\n\t * class NamedArray extends factory.array(\"name\", factory.number) {}\n\t * ```\n\t *\n\t * {@label NAMED}\n\t */\n\tpublic array<const Name extends TName, const T extends ImplicitAllowedTypes>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\tpublic array<const T extends ImplicitAllowedTypes>(\n\t\tnameOrAllowedTypes: TName | ((T & TreeNodeSchema) | readonly TreeNodeSchema[]),\n\t\tallowedTypes?: T,\n\t): TreeNodeSchema<\n\t\tScopedSchemaName<TScope, string>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\ttrue,\n\t\tT\n\t> {\n\t\tif (allowedTypes === undefined) {\n\t\t\tconst types = nameOrAllowedTypes as (T & TreeNodeSchema) | readonly TreeNodeSchema[];\n\t\t\tconst fullName = structuralName(\"Array\", types);\n\t\t\treturn getOrCreate(this.structuralTypes, fullName, () =>\n\t\t\t\tthis.namedArray(fullName, nameOrAllowedTypes as T, false, true),\n\t\t\t) as TreeNodeSchemaClass<\n\t\t\t\tScopedSchemaName<TScope, string>,\n\t\t\t\tNodeKind.Array,\n\t\t\t\tTreeArrayNode<T>,\n\t\t\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\t\t\ttrue,\n\t\t\t\tT\n\t\t\t>;\n\t\t}\n\t\treturn this.namedArray(nameOrAllowedTypes as TName, allowedTypes, true, true);\n\t}\n\n\t/**\n\t * Define a {@link TreeNodeSchema} for a {@link (TreeArrayNode:interface)}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t *\n\t * @remarks\n\t * This is not intended to be used directly, use the overload of `array` which takes a name instead.\n\t * This is only public to work around a compiler limitation.\n\t */\n\tprivate namedArray<\n\t\tName extends TName | string,\n\t\tconst T extends ImplicitAllowedTypes,\n\t\tconst ImplicitlyConstructable extends boolean,\n\t>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t\tcustomizable: boolean,\n\t\timplicitlyConstructable: ImplicitlyConstructable,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T> & WithType<ScopedSchemaName<TScope, string>>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\tImplicitlyConstructable,\n\t\tT\n\t> {\n\t\treturn arraySchema(this.scoped(name), allowedTypes, implicitlyConstructable, customizable);\n\t}\n\n\t/**\n\t * Make a field optional instead of the default, which is required.\n\t *\n\t * @param t - The types allowed under the field.\n\t * @param props - Optional properties to associate with the field.\n\t */\n\tpublic optional<const T extends ImplicitAllowedTypes>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchema<FieldKind.Optional, T> {\n\t\tconst defaultOptionalProvider: DefaultProvider = getDefaultProvider(() => {\n\t\t\treturn undefined;\n\t\t});\n\t\treturn createFieldSchema(FieldKind.Optional, t, {\n\t\t\tdefaultProvider: defaultOptionalProvider,\n\t\t\t...props,\n\t\t});\n\t}\n\n\t/**\n\t * Make a field explicitly required.\n\t *\n\t * @param t - The types allowed under the field.\n\t * @param props - Optional properties to associate with the field.\n\t *\n\t * @remarks\n\t * Fields are required by default, but this API can be used to make the required nature explicit in the schema,\n\t * and allows associating custom {@link FieldProps | properties} with the field.\n\t */\n\tpublic required<const T extends ImplicitAllowedTypes>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchema<FieldKind.Required, T> {\n\t\treturn createFieldSchema(FieldKind.Required, t, props);\n\t}\n\n\t/**\n\t * {@link SchemaFactory.optional} except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of {@link SchemaFactory.optional} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\tpublic optionalRecursive<const T extends Unenforced<ImplicitAllowedTypes>>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchemaUnsafe<FieldKind.Optional, T> {\n\t\treturn createFieldSchemaUnsafe(FieldKind.Optional, t, props);\n\t}\n\n\t/**\n\t * {@link SchemaFactory.required} except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of {@link SchemaFactory.required} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\tpublic requiredRecursive<const T extends Unenforced<ImplicitAllowedTypes>>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchemaUnsafe<FieldKind.Required, T> {\n\t\treturn createFieldSchemaUnsafe(FieldKind.Required, t, props);\n\t}\n\n\t/**\n\t * A special field which holds a unique identifier for an object node.\n\t * @remarks\n\t * The value of this field, a \"node identifier\", uniquely identifies a node among all other nodes in the tree.\n\t * Node identifiers are strings, and can therefore be used as lookup keys in maps or written to a database.\n\t * When the node is constructed, the identifier field does not need to be populated.\n\t * The SharedTree will provide an identifier for the node automatically.\n\t * An identifier provided automatically by the SharedTree has the following properties:\n\t * - It is a UUID.\n\t * - It is compressed to a space-efficient representation when stored in the document.\n\t * - A compressed form of the identifier can be accessed at runtime via the `Tree.shortId()` API.\n\t * - It will error if read (and will not be present in the object's iterable properties) before the node has been inserted into the tree.\n\t *\n\t * However, a user may alternatively supply their own string as the identifier if desired (for example, if importing identifiers from another system).\n\t * In that case, it is up to the user to ensure that the identifier is unique within the current tree - no other node should have the same identifier at the same time.\n\t * If the identifier is not unique, it may be read, but may cause libraries or features which operate over node identifiers to misbehave.\n\t * User-supplied identifiers may be read immediately, even before insertion into the tree.\n\t *\n\t * A node may have more than one identifier field (though note that this precludes the use of the `Tree.shortId()` API).\n\t */\n\tpublic get identifier(): FieldSchema<FieldKind.Identifier, typeof this.string> {\n\t\tconst defaultIdentifierProvider: DefaultProvider = getDefaultProvider(\n\t\t\t(nodeKeyManager: NodeKeyManager) => {\n\t\t\t\treturn nodeKeyManager.stabilizeNodeKey(nodeKeyManager.generateLocalNodeKey());\n\t\t\t},\n\t\t);\n\t\treturn createFieldSchema(FieldKind.Identifier, this.string, {\n\t\t\tdefaultProvider: defaultIdentifierProvider,\n\t\t});\n\t}\n\n\t/**\n\t * {@link SchemaFactory.object} except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of {@link SchemaFactory.object} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t *\n\t * Additionally `ImplicitlyConstructable` is disabled (forcing use of constructor) to avoid\n\t * `error TS2589: Type instantiation is excessively deep and possibly infinite.`\n\t * which otherwise gets reported at sometimes incorrect source locations that vary based on incremental builds.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\tpublic objectRecursive<\n\t\tconst Name extends TName,\n\t\tconst T extends Unenforced<RestrictiveReadonlyRecord<string, ImplicitFieldSchema>>,\n\t>(name: Name, t: T) {\n\t\ttype TScopedName = ScopedSchemaName<TScope, Name>;\n\t\treturn this.object(\n\t\t\tname,\n\t\t\tt as T & RestrictiveReadonlyRecord<string, ImplicitFieldSchema>,\n\t\t) as unknown as TreeNodeSchemaClass<\n\t\t\tTScopedName,\n\t\t\tNodeKind.Object,\n\t\t\tTreeObjectNodeUnsafe<T, TScopedName>,\n\t\t\tobject & InsertableObjectFromSchemaRecordUnsafe<T>,\n\t\t\tfalse,\n\t\t\tT\n\t\t>;\n\t}\n\n\t/**\n\t * `SchemaFactory.array` except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of `SchemaFactory.array` uses the same workarounds as {@link SchemaFactory.objectRecursive}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\tpublic arrayRecursive<\n\t\tconst Name extends TName,\n\t\tconst T extends Unenforced<ImplicitAllowedTypes>,\n\t>(name: Name, allowedTypes: T) {\n\t\tconst RecursiveArray = this.namedArray(\n\t\t\tname,\n\t\t\tallowedTypes as T & ImplicitAllowedTypes,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t);\n\n\t\treturn RecursiveArray as TreeNodeSchemaClass<\n\t\t\tScopedSchemaName<TScope, Name>,\n\t\t\tNodeKind.Array,\n\t\t\tTreeArrayNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\t\t{\n\t\t\t\t/**\n\t\t\t\t * Iterator for the iterable of content for this node.\n\t\t\t\t * @privateRemarks\n\t\t\t\t * Wrapping the constructor parameter for recursive arrays and maps in an inlined object type avoids (for unknown reasons)\n\t\t\t\t * the following compile error when declaring the recursive schema:\n\t\t\t\t * `Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.`\n\t\t\t\t * To benefit from this without impacting the API, the definition of `Iterable` has been inlined as such an object.\n\t\t\t\t *\n\t\t\t\t * If this workaround is kept, ideally this comment would be deduplicated with the other instance of it.\n\t\t\t\t * Unfortunately attempts to do this failed to avoid the compile error this was introduced to solve.\n\t\t\t\t */\n\t\t\t\t[Symbol.iterator](): Iterator<InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>>;\n\t\t\t},\n\t\t\tfalse,\n\t\t\tT\n\t\t>;\n\t}\n\n\t/**\n\t * `SchemaFactory.map` except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of `SchemaFactory.map` uses the same workarounds as {@link SchemaFactory.objectRecursive}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\tpublic mapRecursive<Name extends TName, const T extends Unenforced<ImplicitAllowedTypes>>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t) {\n\t\tconst MapSchema = this.namedMap(\n\t\t\tname,\n\t\t\tallowedTypes as T & ImplicitAllowedTypes,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t);\n\n\t\treturn MapSchema as TreeNodeSchemaClass<\n\t\t\tScopedSchemaName<TScope, Name>,\n\t\t\tNodeKind.Map,\n\t\t\tTreeMapNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\t\t{\n\t\t\t\t/**\n\t\t\t\t * Iterator for the iterable of content for this node.\n\t\t\t\t * @privateRemarks\n\t\t\t\t * Wrapping the constructor parameter for recursive arrays and maps in an inlined object type avoids (for unknown reasons)\n\t\t\t\t * the following compile error when declaring the recursive schema:\n\t\t\t\t * `Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.`\n\t\t\t\t * To benefit from this without impacting the API, the definition of `Iterable` has been inlined as such an object.\n\t\t\t\t *\n\t\t\t\t * If this workaround is kept, ideally this comment would be deduplicated with the other instance of it.\n\t\t\t\t * Unfortunately attempts to do this failed to avoid the compile error this was introduced to solve.\n\t\t\t\t */\n\t\t\t\t[Symbol.iterator](): Iterator<\n\t\t\t\t\t[string, InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>]\n\t\t\t\t>;\n\t\t\t},\n\t\t\tfalse,\n\t\t\tT\n\t\t>;\n\t}\n}\n\nexport function structuralName<const T extends string>(\n\tcollectionName: T,\n\tallowedTypes: TreeNodeSchema | readonly TreeNodeSchema[],\n): `${T}<${string}>` {\n\tlet inner: string;\n\tif (!isReadonlyArray(allowedTypes)) {\n\t\treturn structuralName(collectionName, [allowedTypes]);\n\t} else {\n\t\tconst names = allowedTypes.map((t): string => {\n\t\t\t// Ensure that lazy types (functions) don't slip through here.\n\t\t\tassert(!isLazy(t), 0x83d /* invalid type provided */);\n\t\t\treturn t.identifier;\n\t\t});\n\t\t// Ensure name is order independent\n\t\tnames.sort();\n\t\t// Ensure name can't have collisions by quoting and escaping any quotes in the names of types.\n\t\t// Using JSON is a simple way to accomplish this.\n\t\t// The outer `[]` around the result are also needed so that a single type name \"Any\" would not collide with the \"any\" case above.\n\t\tinner = JSON.stringify(names);\n\t}\n\treturn `${collectionName}<${inner}>`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"schemaFactory.js","sourceRoot":"","sources":["../../src/simple-tree/schemaFactory.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\n// Include this unused import to avoid TypeScript generating an inline import for IFluidHandle in the d.ts file\n// which degrades the API-Extractor report quality since API-Extractor can not tell the inline import is the same as the non-inline one.\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport type { IFluidHandle as _dummyImport } from \"@fluidframework/core-interfaces\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { isFluidHandle } from \"@fluidframework/runtime-utils/internal\";\n\nimport type { TreeValue } from \"../core/index.js\";\nimport { type NodeKeyManager, type Unenforced, isLazy } from \"../feature-libraries/index.js\";\nimport {\n\ttype RestrictiveReadonlyRecord,\n\tgetOrCreate,\n\tisReadonlyArray,\n} from \"../util/index.js\";\n\nimport {\n\tbooleanSchema,\n\thandleSchema,\n\tLeafNodeSchema,\n\tnullSchema,\n\tnumberSchema,\n\tstringSchema,\n} from \"./leafNodeSchema.js\";\nimport {\n\tFieldKind,\n\ttype FieldSchema,\n\ttype ImplicitAllowedTypes,\n\ttype ImplicitFieldSchema,\n\ttype InsertableTreeNodeFromImplicitAllowedTypes,\n\ttype NodeKind,\n\ttype TreeNodeSchema,\n\ttype TreeNodeSchemaClass,\n\ttype WithType,\n\ttype FieldProps,\n\tcreateFieldSchema,\n\ttype DefaultProvider,\n\tgetDefaultProvider,\n} from \"./schemaTypes.js\";\nimport { type TreeArrayNode, arraySchema } from \"./arrayNode.js\";\nimport {\n\ttype InsertableObjectFromSchemaRecord,\n\ttype TreeObjectNode,\n\tobjectSchema,\n} from \"./objectNode.js\";\nimport { type TreeMapNode, mapSchema } from \"./mapNode.js\";\nimport type {\n\tFieldSchemaUnsafe,\n\t// Adding these unused imports makes the generated d.ts file produced by TypeScript stop breaking API-Extractor's rollup generation.\n\t// Without this import, TypeScript generates inline `import(\"../..\")` statements in the d.ts file,\n\t// which API-Extractor leaves as is when generating the rollup, leaving them pointing at the wrong directory.\n\t// API-Extractor issue: https://github.com/microsoft/rushstack/issues/4507\n\t// eslint-disable-next-line unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars\n\tFieldHasDefaultUnsafe,\n\t// eslint-disable-next-line unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars\n\tInsertableTreeFieldFromImplicitFieldUnsafe,\n\tInsertableObjectFromSchemaRecordUnsafe,\n\tInsertableTreeNodeFromImplicitAllowedTypesUnsafe,\n\tTreeArrayNodeUnsafe,\n\tTreeMapNodeUnsafe,\n\tTreeObjectNodeUnsafe,\n} from \"./typesUnsafe.js\";\nimport { createFieldSchemaUnsafe } from \"./schemaFactoryRecursive.js\";\nimport { inPrototypeChain, TreeNodeValid } from \"./types.js\";\n/**\n * Gets the leaf domain schema compatible with a given {@link TreeValue}.\n */\nexport function schemaFromValue(value: TreeValue): TreeNodeSchema {\n\tswitch (typeof value) {\n\t\tcase \"boolean\":\n\t\t\treturn booleanSchema;\n\t\tcase \"number\":\n\t\t\treturn numberSchema;\n\t\tcase \"string\":\n\t\t\treturn stringSchema;\n\t\tcase \"object\": {\n\t\t\tif (value === null) {\n\t\t\t\treturn nullSchema;\n\t\t\t}\n\t\t\tassert(isFluidHandle(value), 0x87e /* invalid TreeValue */);\n\t\t\treturn handleSchema;\n\t\t}\n\t\tdefault:\n\t\t\tunreachableCase(value);\n\t}\n}\n\n/**\n * The name of a schema produced by {@link SchemaFactory}, including its optional scope prefix.\n *\n * @public\n */\nexport type ScopedSchemaName<\n\tTScope extends string | undefined,\n\tTName extends number | string,\n> = TScope extends undefined ? `${TName}` : `${TScope}.${TName}`;\n// > = `${TScope extends undefined ? \"\" : `${TScope}.`}${TName}`;\n\n// TODO:\n// SchemaFactory.array references should link to the correct overloads, however the syntax for this does not seems to work currently for methods unless the they are not qualified with the class.\n// API-Extractor requires such links to be qualified with the class, so it can't work.\n// Since linking the overload set as a whole also doesn't work, these have been made non-links for now.\n/**\n * Creates various types of {@link TreeNodeSchema|schema} for {@link TreeNode}s.\n *\n * @typeParam TScope - Scope added as a prefix to the name of every schema produced by this factory.\n * @typeParam TName - Type of names used to identify each schema produced in this factory.\n * Typically this is just `string` but it is also possible to use `string` or `number` based enums if you prefer to identify your types that way.\n *\n * @remarks\n * All schema produced by this factory get a {@link TreeNodeSchemaCore.identifier|unique identifier} by combining the {@link SchemaFactory.scope} with the schema's `Name`.\n * The `Name` part may be explicitly provided as a parameter, or inferred as a structural combination of the provided types.\n * The APIs which use this second approach, structural naming, also deduplicate all equivalent calls.\n * Therefor two calls to `array(allowedTypes)` with the same allowedTypes will return the same {@link TreeNodeSchema} instance.\n * On the other hand, two calls to `array(name, allowedTypes)` will always return different {@link TreeNodeSchema} instances\n * and it is an error to use both in the same tree (since their identifiers are not unique).\n *\n * Note:\n * POJO stands for Plain Old JavaScript Object.\n * This means an object that works like a `{}` style object literal.\n * In this case it means the prototype is `Object.prototype` and acts like a set of key value pairs (data, not methods).\n * The usage below generalizes this to include array and map like objects as well.\n *\n * There are two ways to use these APIs:\n * | | Customizable | POJO Emulation |\n * | ------------------- | ------------ |--------------- |\n * | Declaration | `class X extends schemaFactory.object(\"x\", {}) {}` | `const X = schemaFactory.object(\"x\", {}); type X = NodeFromSchema<typeof X>; `\n * | Allows adding \"local\" (non-persisted) members | Yes. Members (including methods) can be added to class. | No. Attempting to set non-field members will error. |\n * | Prototype | The user defined class | `Object.prototype`, `Map.prototype` or `Array.prototype` depending on node kind |\n * | Structurally named Schema | Not Supported | Supported |\n * | Explicitly named Objects | Supported | Supported |\n * | Explicitly named Maps and Arrays | Supported: Both declaration approaches can be used | Not Supported |\n * | node.js assert.deepEqual | Compares like class instances: equal to other nodes of the same type with the same content, including custom local fields. | Compares like plain objects: equal to plain JavaScript objects with the same fields, and other nodes with the same fields, even if the types are different. |\n * | IntelliSense | Shows and links to user defined class by name: `X` | Shows internal type generation logic: `object & TreeNode & ObjectFromSchemaRecord<{}> & WithType<\"test.x\">` |\n * | Recursion | Supported with special declaration patterns. | Unsupported: Generated d.ts files replace recursive references with `any`, breaking use of recursive schema across compilation boundaries |\n *\n * Note that while \"POJO Emulation\" nodes act a lot like POJO objects, they are not true POJO objects:\n *\n * - Adding new arbitrary fields will error, as well some cases of invalid edits.\n *\n * - They are implemented using proxies.\n *\n * - They have state that is not exposed via enumerable own properties, including a {@link TreeNodeSchema}.\n * This makes libraries like node.js `assert.deepEqual` fail to detect differences in type.\n *\n * - Assigning members has side effects (in this case editing the persisted/shared tree).\n *\n * - Not all operations implied by the prototype will work correctly: stick to the APIs explicitly declared in the TypeScript types.\n *\n * @privateRemarks\n * It's perfectly possible to make `POJO Emulation` mode (or even just hiding the prototype) selectable even when using the custom user class declaration syntax.\n * When doing this, it's still possible to make `instanceof` perform correctly.\n * Allowing (or banning) custom/out-of-schema properties on the class is also possible in both modes: it could be orthogonal.\n * Also for consistency, if keeping the current approach to detecting `POJO Emulation` mode it might make sense to make explicitly named Maps and Arrays do the detection the same as how object does it.\n *\n * @sealed @public\n */\nexport class SchemaFactory<\n\tout TScope extends string | undefined = string | undefined,\n\tTName extends number | string = string,\n> {\n\t/**\n\t * TODO:\n\t * If users of this generate the same name because two different schema with the same identifier were used,\n\t * the second use can get a cache hit, and reference the wrong schema.\n\t * Such usage should probably return a distinct type or error but currently does not.\n\t * The use of markSchemaMostDerived in structuralName at least ensure an error in the case where the collision is from two types extending the same schema factor class.\n\t */\n\tprivate readonly structuralTypes: Map<string, TreeNodeSchema> = new Map();\n\n\t/**\n\t * Construct a SchemaFactory with a given scope.\n\t * @remarks\n\t * There are no restrictions on mixing schema from different schema factories:\n\t * this is encouraged when a single schema references schema from different libraries.\n\t * If each library exporting schema picks its own globally unique scope for its SchemaFactory,\n\t * then all schema an application might depend on, directly or transitively,\n\t * will end up with a unique fully qualified name which is required to refer to it in persisted data and errors.\n\t *\n\t * @param scope - Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder.\n\t * Use of [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 is recommended to avoid collisions.\n\t * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions.\n\t */\n\tpublic constructor(public readonly scope: TScope) {}\n\n\tprivate scoped<Name extends TName | string>(name: Name): ScopedSchemaName<TScope, Name> {\n\t\treturn (\n\t\t\tthis.scope === undefined ? `${name}` : `${this.scope}.${name}`\n\t\t) as ScopedSchemaName<TScope, Name>;\n\t}\n\n\t/**\n\t * {@link TreeNodeSchema} for holding a JavaScript `string`.\n\t *\n\t * @remarks\n\t * Strings containing unpaired UTF-16 surrogate pair code units may not be handled correctly.\n\t *\n\t * These limitations come from the use of UTF-8 encoding of the strings, which requires them to be valid unicode.\n\t * JavaScript does not make this requirement for its strings so not all possible JavaScript strings are supported.\n\t * @privateRemarks\n\t * TODO:\n\t * We should be much more clear about what happens if you use problematic values.\n\t * We should validate and/or normalize them when inserting content.\n\t */\n\tpublic readonly string = stringSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for holding a JavaScript `number`.\n\t *\n\t * @remarks\n\t * The number is a [double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) value, however there are some exceptions:\n\t * - `NaN`, and the infinities are converted to `null` (and may therefore only be used where `null` is allowed by the schema).\n\t * - `-0` may be converted to `0` in some cases.\n\t *\n\t * These limitations match the limitations of JSON.\n\t * @privateRemarks\n\t * TODO:\n\t * We should be much more clear about what happens if you use problematic values.\n\t * We should validate and/or normalize them when inserting content.\n\t */\n\tpublic readonly number = numberSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for holding a boolean.\n\t */\n\tpublic readonly boolean = booleanSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for JavaScript `null`.\n\t *\n\t * @remarks\n\t * There are good [reasons to avoid using null](https://www.npmjs.com/package/%40rushstack/eslint-plugin#rushstackno-new-null) in JavaScript, however sometimes it is desired.\n\t * This {@link TreeNodeSchema} node provides the option to include nulls in trees when desired.\n\t * Unless directly inter-operating with existing data using null, consider other approaches, like wrapping the value in an optional field, or using a more specifically named empty object node.\n\t */\n\tpublic readonly null = nullSchema;\n\n\t/**\n\t * {@link TreeNodeSchema} for holding an {@link @fluidframework/core-interfaces#(IFluidHandle:interface)}.\n\t */\n\tpublic readonly handle = handleSchema;\n\n\t/**\n\t * Define a {@link TreeNodeSchemaClass} for a {@link TreeObjectNode}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t * @param fields - Schema for fields of the object node's schema. Defines what children can be placed under each key.\n\t */\n\tpublic object<\n\t\tconst Name extends TName,\n\t\tconst T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>,\n\t>(\n\t\tname: Name,\n\t\tfields: T,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Object,\n\t\tTreeObjectNode<T, ScopedSchemaName<TScope, Name>>,\n\t\tobject & InsertableObjectFromSchemaRecord<T>,\n\t\ttrue,\n\t\tT\n\t> {\n\t\treturn objectSchema(this.scoped(name), fields, true);\n\t}\n\n\t/**\n\t * Define a structurally typed {@link TreeNodeSchema} for a {@link TreeMapNode}.\n\t *\n\t * @remarks\n\t * The unique identifier for this Map is defined as a function of the provided types.\n\t * It is still scoped to this SchemaBuilder, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing.\n\t * This does not support recursive types.\n\t *\n\t * If using these structurally named maps, other types in this schema builder should avoid names of the form `Map<${string}>`.\n\t *\n\t * @example\n\t * The returned schema should be used as a schema directly:\n\t * ```typescript\n\t * const MyMap = factory.map(factory.number);\n\t * type MyMap = NodeFromSchema<typeof MyMap>;\n\t * ```\n\t * Or inline:\n\t * ```typescript\n\t * factory.object(\"Foo\", {myMap: factory.map(factory.number)});\n\t * ```\n\t * @privateRemarks\n\t * See note on array.\n\t */\n\tpublic map<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(\n\t\tallowedTypes: T,\n\t): TreeNodeSchema<\n\t\tScopedSchemaName<TScope, `Map<${string}>`>,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T> & WithType<ScopedSchemaName<TScope, `Map<${string}>`>>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\t/**\n\t * Define a {@link TreeNodeSchema} for a {@link TreeMapNode}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t *\n\t * @example\n\t * ```typescript\n\t * class NamedMap extends factory.map(\"name\", factory.number) {}\n\t * ```\n\t */\n\tpublic map<Name extends TName, const T extends ImplicitAllowedTypes>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\tpublic map<const T extends ImplicitAllowedTypes>(\n\t\tnameOrAllowedTypes: TName | ((T & TreeNodeSchema) | readonly TreeNodeSchema[]),\n\t\tallowedTypes?: T,\n\t): TreeNodeSchema<\n\t\tstring,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\ttrue,\n\t\tT\n\t> {\n\t\tif (allowedTypes === undefined) {\n\t\t\tconst types = nameOrAllowedTypes as (T & TreeNodeSchema) | readonly TreeNodeSchema[];\n\t\t\tconst fullName = structuralName(\"Map\", types);\n\t\t\treturn getOrCreate(\n\t\t\t\tthis.structuralTypes,\n\t\t\t\tfullName,\n\t\t\t\t() =>\n\t\t\t\t\tthis.namedMap(\n\t\t\t\t\t\tfullName as TName,\n\t\t\t\t\t\tnameOrAllowedTypes as T,\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t) as TreeNodeSchema,\n\t\t\t) as TreeNodeSchemaClass<\n\t\t\t\tstring,\n\t\t\t\tNodeKind.Map,\n\t\t\t\tTreeMapNode<T>,\n\t\t\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\t\t\ttrue,\n\t\t\t\tT\n\t\t\t>;\n\t\t}\n\t\treturn this.namedMap(nameOrAllowedTypes as TName, allowedTypes, true, true);\n\t}\n\n\t/**\n\t * Define a {@link TreeNodeSchema} for a {@link (TreeMapNode:interface)}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t */\n\tprivate namedMap<\n\t\tName extends TName | string,\n\t\tconst T extends ImplicitAllowedTypes,\n\t\tconst ImplicitlyConstructable extends boolean,\n\t>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t\tcustomizable: boolean,\n\t\timplicitlyConstructable: ImplicitlyConstructable,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Map,\n\t\tTreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\tIterable<[string, InsertableTreeNodeFromImplicitAllowedTypes<T>]>,\n\t\tImplicitlyConstructable,\n\t\tT\n\t> {\n\t\treturn mapSchema(\n\t\t\tthis.scoped(name),\n\t\t\tallowedTypes,\n\t\t\timplicitlyConstructable,\n\t\t\t// The current policy is customizable nodes don't get fake prototypes.\n\t\t\t!customizable,\n\t\t);\n\t}\n\n\t/**\n\t * Define a structurally typed {@link TreeNodeSchema} for a {@link (TreeArrayNode:interface)}.\n\t *\n\t * @remarks\n\t * The identifier for this Array is defined as a function of the provided types.\n\t * It is still scoped to this SchemaFactory, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing.\n\t * This does not support recursive types.\n\t *\n\t * If using these structurally named arrays, other types in this schema builder should avoid names of the form `Array<${string}>`.\n\t *\n\t * @example\n\t * The returned schema should be used as a schema directly:\n\t * ```typescript\n\t * const MyArray = factory.array(factory.number);\n\t * type MyArray = NodeFromSchema<typeof MyArray>;\n\t * ```\n\t * Or inline:\n\t * ```typescript\n\t * factory.object(\"Foo\", {myArray: factory.array(factory.number)});\n\t * ```\n\t * @privateRemarks\n\t * The name produced at the type level here is not as specific as it could be, however doing type level sorting and escaping is a real mess.\n\t * There are cases where not having this full type provided will be less than ideal since TypeScript's structural types.\n\t * For example attempts to narrow unions of structural arrays by name won't work.\n\t * Planned future changes to move to a class based schema system as well as factor function based node construction should mostly avoid these issues,\n\t * though there may still be some problematic cases even after that work is done.\n\t *\n\t * The return value is a class, but its the type is intentionally not specific enough to indicate it is a class.\n\t * This prevents callers of this from sub-classing it, which is unlikely to work well (due to the ease of accidentally giving two different calls o this different subclasses)\n\t * when working with structural typing.\n\t *\n\t * {@label STRUCTURAL}\n\t */\n\tpublic array<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(\n\t\tallowedTypes: T,\n\t): TreeNodeSchema<\n\t\tScopedSchemaName<TScope, `Array<${string}>`>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T> & WithType<ScopedSchemaName<TScope, `Array<${string}>`>>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\t/**\n\t * Define (and add to this library) a {@link TreeNodeSchemaClass} for a {@link (TreeArrayNode:interface)}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t *\n\t * @example\n\t * ```typescript\n\t * class NamedArray extends factory.array(\"name\", factory.number) {}\n\t * ```\n\t *\n\t * {@label NAMED}\n\t */\n\tpublic array<const Name extends TName, const T extends ImplicitAllowedTypes>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\ttrue,\n\t\tT\n\t>;\n\n\tpublic array<const T extends ImplicitAllowedTypes>(\n\t\tnameOrAllowedTypes: TName | ((T & TreeNodeSchema) | readonly TreeNodeSchema[]),\n\t\tallowedTypes?: T,\n\t): TreeNodeSchema<\n\t\tScopedSchemaName<TScope, string>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\ttrue,\n\t\tT\n\t> {\n\t\tif (allowedTypes === undefined) {\n\t\t\tconst types = nameOrAllowedTypes as (T & TreeNodeSchema) | readonly TreeNodeSchema[];\n\t\t\tconst fullName = structuralName(\"Array\", types);\n\t\t\treturn getOrCreate(this.structuralTypes, fullName, () =>\n\t\t\t\tthis.namedArray(fullName, nameOrAllowedTypes as T, false, true),\n\t\t\t) as TreeNodeSchemaClass<\n\t\t\t\tScopedSchemaName<TScope, string>,\n\t\t\t\tNodeKind.Array,\n\t\t\t\tTreeArrayNode<T>,\n\t\t\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\t\t\ttrue,\n\t\t\t\tT\n\t\t\t>;\n\t\t}\n\t\treturn this.namedArray(nameOrAllowedTypes as TName, allowedTypes, true, true);\n\t}\n\n\t/**\n\t * Define a {@link TreeNodeSchema} for a {@link (TreeArrayNode:interface)}.\n\t *\n\t * @param name - Unique identifier for this schema within this factory's scope.\n\t *\n\t * @remarks\n\t * This is not intended to be used directly, use the overload of `array` which takes a name instead.\n\t * This is only public to work around a compiler limitation.\n\t */\n\tprivate namedArray<\n\t\tName extends TName | string,\n\t\tconst T extends ImplicitAllowedTypes,\n\t\tconst ImplicitlyConstructable extends boolean,\n\t>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t\tcustomizable: boolean,\n\t\timplicitlyConstructable: ImplicitlyConstructable,\n\t): TreeNodeSchemaClass<\n\t\tScopedSchemaName<TScope, Name>,\n\t\tNodeKind.Array,\n\t\tTreeArrayNode<T> & WithType<ScopedSchemaName<TScope, string>>,\n\t\tIterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>,\n\t\tImplicitlyConstructable,\n\t\tT\n\t> {\n\t\treturn arraySchema(this.scoped(name), allowedTypes, implicitlyConstructable, customizable);\n\t}\n\n\t/**\n\t * Make a field optional instead of the default, which is required.\n\t *\n\t * @param t - The types allowed under the field.\n\t * @param props - Optional properties to associate with the field.\n\t */\n\tpublic optional<const T extends ImplicitAllowedTypes>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchema<FieldKind.Optional, T> {\n\t\tconst defaultOptionalProvider: DefaultProvider = getDefaultProvider(() => {\n\t\t\treturn undefined;\n\t\t});\n\t\treturn createFieldSchema(FieldKind.Optional, t, {\n\t\t\tdefaultProvider: defaultOptionalProvider,\n\t\t\t...props,\n\t\t});\n\t}\n\n\t/**\n\t * Make a field explicitly required.\n\t *\n\t * @param t - The types allowed under the field.\n\t * @param props - Optional properties to associate with the field.\n\t *\n\t * @remarks\n\t * Fields are required by default, but this API can be used to make the required nature explicit in the schema,\n\t * and allows associating custom {@link FieldProps | properties} with the field.\n\t */\n\tpublic required<const T extends ImplicitAllowedTypes>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchema<FieldKind.Required, T> {\n\t\treturn createFieldSchema(FieldKind.Required, t, props);\n\t}\n\n\t/**\n\t * {@link SchemaFactory.optional} except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of {@link SchemaFactory.optional} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\tpublic optionalRecursive<const T extends Unenforced<ImplicitAllowedTypes>>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchemaUnsafe<FieldKind.Optional, T> {\n\t\treturn createFieldSchemaUnsafe(FieldKind.Optional, t, props);\n\t}\n\n\t/**\n\t * {@link SchemaFactory.required} except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of {@link SchemaFactory.required} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\tpublic requiredRecursive<const T extends Unenforced<ImplicitAllowedTypes>>(\n\t\tt: T,\n\t\tprops?: Omit<FieldProps, \"defaultProvider\">,\n\t): FieldSchemaUnsafe<FieldKind.Required, T> {\n\t\treturn createFieldSchemaUnsafe(FieldKind.Required, t, props);\n\t}\n\n\t/**\n\t * A special field which holds a unique identifier for an object node.\n\t * @remarks\n\t * The value of this field, a \"node identifier\", uniquely identifies a node among all other nodes in the tree.\n\t * Node identifiers are strings, and can therefore be used as lookup keys in maps or written to a database.\n\t * When the node is constructed, the identifier field does not need to be populated.\n\t * The SharedTree will provide an identifier for the node automatically.\n\t * An identifier provided automatically by the SharedTree has the following properties:\n\t * - It is a UUID.\n\t * - It is compressed to a space-efficient representation when stored in the document.\n\t * - A compressed form of the identifier can be accessed at runtime via the `Tree.shortId()` API.\n\t * - It will error if read (and will not be present in the object's iterable properties) before the node has been inserted into the tree.\n\t *\n\t * However, a user may alternatively supply their own string as the identifier if desired (for example, if importing identifiers from another system).\n\t * In that case, it is up to the user to ensure that the identifier is unique within the current tree - no other node should have the same identifier at the same time.\n\t * If the identifier is not unique, it may be read, but may cause libraries or features which operate over node identifiers to misbehave.\n\t * User-supplied identifiers may be read immediately, even before insertion into the tree.\n\t *\n\t * A node may have more than one identifier field (though note that this precludes the use of the `Tree.shortId()` API).\n\t */\n\tpublic get identifier(): FieldSchema<FieldKind.Identifier, typeof this.string> {\n\t\tconst defaultIdentifierProvider: DefaultProvider = getDefaultProvider(\n\t\t\t(nodeKeyManager: NodeKeyManager) => {\n\t\t\t\treturn nodeKeyManager.stabilizeNodeKey(nodeKeyManager.generateLocalNodeKey());\n\t\t\t},\n\t\t);\n\t\treturn createFieldSchema(FieldKind.Identifier, this.string, {\n\t\t\tdefaultProvider: defaultIdentifierProvider,\n\t\t});\n\t}\n\n\t/**\n\t * {@link SchemaFactory.object} except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of {@link SchemaFactory.object} has fewer type constraints to work around TypeScript limitations, see {@link Unenforced}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t *\n\t * Additionally `ImplicitlyConstructable` is disabled (forcing use of constructor) to avoid\n\t * `error TS2589: Type instantiation is excessively deep and possibly infinite.`\n\t * which otherwise gets reported at sometimes incorrect source locations that vary based on incremental builds.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\tpublic objectRecursive<\n\t\tconst Name extends TName,\n\t\tconst T extends Unenforced<RestrictiveReadonlyRecord<string, ImplicitFieldSchema>>,\n\t>(name: Name, t: T) {\n\t\ttype TScopedName = ScopedSchemaName<TScope, Name>;\n\t\treturn this.object(\n\t\t\tname,\n\t\t\tt as T & RestrictiveReadonlyRecord<string, ImplicitFieldSchema>,\n\t\t) as unknown as TreeNodeSchemaClass<\n\t\t\tTScopedName,\n\t\t\tNodeKind.Object,\n\t\t\tTreeObjectNodeUnsafe<T, TScopedName>,\n\t\t\tobject & InsertableObjectFromSchemaRecordUnsafe<T>,\n\t\t\tfalse,\n\t\t\tT\n\t\t>;\n\t}\n\n\t/**\n\t * `SchemaFactory.array` except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of `SchemaFactory.array` uses the same workarounds as {@link SchemaFactory.objectRecursive}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\tpublic arrayRecursive<\n\t\tconst Name extends TName,\n\t\tconst T extends Unenforced<ImplicitAllowedTypes>,\n\t>(name: Name, allowedTypes: T) {\n\t\tconst RecursiveArray = this.namedArray(\n\t\t\tname,\n\t\t\tallowedTypes as T & ImplicitAllowedTypes,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t);\n\n\t\treturn RecursiveArray as TreeNodeSchemaClass<\n\t\t\tScopedSchemaName<TScope, Name>,\n\t\t\tNodeKind.Array,\n\t\t\tTreeArrayNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\t\t{\n\t\t\t\t/**\n\t\t\t\t * Iterator for the iterable of content for this node.\n\t\t\t\t * @privateRemarks\n\t\t\t\t * Wrapping the constructor parameter for recursive arrays and maps in an inlined object type avoids (for unknown reasons)\n\t\t\t\t * the following compile error when declaring the recursive schema:\n\t\t\t\t * `Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.`\n\t\t\t\t * To benefit from this without impacting the API, the definition of `Iterable` has been inlined as such an object.\n\t\t\t\t *\n\t\t\t\t * If this workaround is kept, ideally this comment would be deduplicated with the other instance of it.\n\t\t\t\t * Unfortunately attempts to do this failed to avoid the compile error this was introduced to solve.\n\t\t\t\t */\n\t\t\t\t[Symbol.iterator](): Iterator<InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>>;\n\t\t\t},\n\t\t\tfalse,\n\t\t\tT\n\t\t>;\n\t}\n\n\t/**\n\t * `SchemaFactory.map` except tweaked to work better for recursive types.\n\t * Use with {@link ValidateRecursiveSchema} for improved type safety.\n\t * @remarks\n\t * This version of `SchemaFactory.map` uses the same workarounds as {@link SchemaFactory.objectRecursive}.\n\t * See {@link ValidateRecursiveSchema} for additional information about using recursive schema.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\tpublic mapRecursive<Name extends TName, const T extends Unenforced<ImplicitAllowedTypes>>(\n\t\tname: Name,\n\t\tallowedTypes: T,\n\t) {\n\t\tconst MapSchema = this.namedMap(\n\t\t\tname,\n\t\t\tallowedTypes as T & ImplicitAllowedTypes,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t);\n\n\t\treturn MapSchema as TreeNodeSchemaClass<\n\t\t\tScopedSchemaName<TScope, Name>,\n\t\t\tNodeKind.Map,\n\t\t\tTreeMapNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>>,\n\t\t\t{\n\t\t\t\t/**\n\t\t\t\t * Iterator for the iterable of content for this node.\n\t\t\t\t * @privateRemarks\n\t\t\t\t * Wrapping the constructor parameter for recursive arrays and maps in an inlined object type avoids (for unknown reasons)\n\t\t\t\t * the following compile error when declaring the recursive schema:\n\t\t\t\t * `Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.`\n\t\t\t\t * To benefit from this without impacting the API, the definition of `Iterable` has been inlined as such an object.\n\t\t\t\t *\n\t\t\t\t * If this workaround is kept, ideally this comment would be deduplicated with the other instance of it.\n\t\t\t\t * Unfortunately attempts to do this failed to avoid the compile error this was introduced to solve.\n\t\t\t\t */\n\t\t\t\t[Symbol.iterator](): Iterator<\n\t\t\t\t\t[string, InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>]\n\t\t\t\t>;\n\t\t\t},\n\t\t\tfalse,\n\t\t\tT\n\t\t>;\n\t}\n}\n\nexport function structuralName<const T extends string>(\n\tcollectionName: T,\n\tallowedTypes: TreeNodeSchema | readonly TreeNodeSchema[],\n): `${T}<${string}>` {\n\tlet inner: string;\n\tif (!isReadonlyArray(allowedTypes)) {\n\t\treturn structuralName(collectionName, [allowedTypes]);\n\t} else {\n\t\tconst names = allowedTypes.map((t): string => {\n\t\t\t// Ensure that lazy types (functions) don't slip through here.\n\t\t\tassert(!isLazy(t), 0x83d /* invalid type provided */);\n\t\t\tmarkSchemaMostDerived(t);\n\t\t\treturn t.identifier;\n\t\t});\n\t\t// Ensure name is order independent\n\t\tnames.sort();\n\t\t// Ensure name can't have collisions by quoting and escaping any quotes in the names of types.\n\t\t// Using JSON is a simple way to accomplish this.\n\t\t// The outer `[]` around the result are also needed so that a single type name \"Any\" would not collide with the \"any\" case above.\n\t\tinner = JSON.stringify(names);\n\t}\n\treturn `${collectionName}<${inner}>`;\n}\n\n/**\n * Indicates that a schema is the \"most derived\" version which is allowed to be used, see {@link MostDerivedData}.\n * Calling helps with error messages about invalid schema usage (using more than one type from single schema factor produced type,\n * and thus calling this for one than one subclass).\n * @remarks\n * Helper for invoking {@link TreeNodeValid.markMostDerived} for any {@link TreeNodeSchema} if it needed.\n */\nexport function markSchemaMostDerived(schema: TreeNodeSchema): void {\n\tif (schema instanceof LeafNodeSchema) {\n\t\treturn;\n\t}\n\n\tif (!inPrototypeChain(schema, TreeNodeValid)) {\n\t\t// Use JSON.stringify to quote and escape identifier string.\n\t\tthrow new UsageError(\n\t\t\t`Schema for ${JSON.stringify(\n\t\t\t\tschema.identifier,\n\t\t\t)} does not extend a SchemaFactory generated class. This is invalid.`,\n\t\t);\n\t}\n\n\t(schema as typeof TreeNodeValid & TreeNodeSchema).markMostDerived();\n}\n"]}
|
|
@@ -39,6 +39,41 @@ export interface TreeNodeSchemaNonClass<out Name extends string = string, out Ki
|
|
|
39
39
|
*
|
|
40
40
|
* Using classes in this way allows introducing a named type and a named value at the same time, helping keep the runtime and compile time information together and easy to refer to un a uniform way.
|
|
41
41
|
* Additionally, this works around https://github.com/microsoft/TypeScript/issues/55832 which causes similar patterns with less explicit types to infer "any" in the d.ts file.
|
|
42
|
+
*
|
|
43
|
+
* When sub-classing a a `TreeNodeSchemaClass`, some extra rules must be followed:
|
|
44
|
+
*
|
|
45
|
+
* - Only ever use a single class from the schema's class hierarchy within a document and its schema.
|
|
46
|
+
* For example, if using {@link SchemaFactory.object} you can do:
|
|
47
|
+
* ```typescript
|
|
48
|
+
* // Recommended "customizable" object schema pattern.
|
|
49
|
+
* class Good extends schemaFactory.object("A", {
|
|
50
|
+
* exampleField: schemaFactory.number,
|
|
51
|
+
* }) {
|
|
52
|
+
* public exampleCustomMethod(): void {
|
|
53
|
+
* this.exampleField++;
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
* But should avoid:
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // This by itself is ok, and opts into "POJO mode".
|
|
60
|
+
* const base = schemaFactory.object("A", {});
|
|
61
|
+
* // This is a bad pattern since it leaves two classes in scope which derive from the same SchemaFactory defined class.
|
|
62
|
+
* // If both get used, its an error!
|
|
63
|
+
* class Invalid extends base {}
|
|
64
|
+
* ```
|
|
65
|
+
* - Do not modify the constructor input parameter types or values:
|
|
66
|
+
* ```typescript
|
|
67
|
+
* class Invalid extends schemaFactory.object("A", {
|
|
68
|
+
* exampleField: schemaFactory.number,
|
|
69
|
+
* }) {
|
|
70
|
+
* // This Modifies the type of the constructor input.
|
|
71
|
+
* // This is unsupported due to programmatic access to the constructor being used internally.
|
|
72
|
+
* public constructor(a: number) {
|
|
73
|
+
* super({ exampleField: a });
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
42
77
|
* @sealed @public
|
|
43
78
|
*/
|
|
44
79
|
export interface TreeNodeSchemaClass<out Name extends string = string, out Kind extends NodeKind = NodeKind, out TNode = unknown, in TInsertable = never, out ImplicitlyConstructable extends boolean = boolean, out Info = unknown> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {
|
|
@@ -46,7 +81,7 @@ export interface TreeNodeSchemaClass<out Name extends string = string, out Kind
|
|
|
46
81
|
* Constructs an {@link Unhydrated} node with this schema.
|
|
47
82
|
* @remarks
|
|
48
83
|
* This constructor is also used internally to construct hydrated nodes with a different parameter type.
|
|
49
|
-
*
|
|
84
|
+
* Therefore, overriding this constructor with different argument types is not type-safe and is not supported.
|
|
50
85
|
* @sealed
|
|
51
86
|
*/
|
|
52
87
|
new (data: TInsertable | InternalTreeNode): Unhydrated<TNode>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaTypes.d.ts","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAIhF,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,KAAK,WAAW,EAA0B,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,CACzB,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5B,IAAI,SAAS,QAAQ,GAAG,QAAQ,EAChC,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,KAAK,EACd,uBAAuB,SAAS,OAAO,GAAG,OAAO,EACjD,IAAI,GAAG,OAAO,IAEZ,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,IAAI,CAAC,GAC7E,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,IAAI,CAAC,CAAC;AAEpF;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB,CACtC,GAAG,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,EAChC,GAAG,CAAC,IAAI,SAAS,QAAQ,GAAG,QAAQ,EACpC,GAAG,CAAC,KAAK,GAAG,OAAO,EACnB,EAAE,CAAC,WAAW,GAAG,KAAK,EACtB,GAAG,CAAC,uBAAuB,SAAS,OAAO,GAAG,OAAO,EACrD,GAAG,CAAC,IAAI,GAAG,OAAO,CACjB,SAAQ,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,CAAC;IACtE,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,KAAK,CAAC;CACjC;AAED
|
|
1
|
+
{"version":3,"file":"schemaTypes.d.ts","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaTypes.js","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,kEAA2D;AAC3D,uEAAsE;AAEtE,4DAKuC;AACvC,+CAA4E;AAwH5E;;;;;GAKG;AACH,IAAY,SAmBX;AAnBD,WAAY,SAAS;IACpB;;;;OAIG;IACH,iDAAQ,CAAA;IACR;;;;OAIG;IACH,iDAAQ,CAAA;IACR;;;;OAIG;IACH,qDAAU,CAAA;AACX,CAAC,EAnBW,SAAS,yBAAT,SAAS,QAmBpB;AAED;;;;;GAKG;AACH,IAAY,QAmBX;AAnBD,WAAY,QAAQ;IACnB;;OAEG;IACH,qCAAG,CAAA;IACH;;OAEG;IACH,yCAAK,CAAA;IACL;;;;OAIG;IACH,2CAAM,CAAA;IACN;;OAEG;IACH,uCAAI,CAAA;AACL,CAAC,EAnBW,QAAQ,wBAAR,QAAQ,QAmBnB;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAAC,OAAe,EAAE,WAAgC;IAC7E,OAAO,IAAA,gBAAK,EAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,CAAC;AAC5D,CAAC;AAFD,oCAEC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,WAAgC;IACpE,OAAO,WAAW,YAAY,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAChF,CAAC;AAFD,oDAEC;AAiFD;;GAEG;AACH,SAAgB,UAAU,CACzB,aAA4B;IAE5B,OAAO,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC;AACnC,CAAC;AAJD,gCAIC;AAUD,SAAgB,oBAAoB,CAAC,KAAsB;IAC1D,OAAO,KAAiC,CAAC;AAC1C,CAAC;AAFD,oDAEC;AAED,SAAgB,kBAAkB,CAAC,KAAoB;IACtD,OAAO,KAAmC,CAAC;AAC5C,CAAC;AAFD,gDAEC;AAcD;;;;;;;;;;GAUG;AACH,MAAa,WAAW;IAsBvB;;;OAGG;IACH,IAAW,cAAc;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;IAC7B,CAAC;IAED;IACC;;;OAGG;IACa,IAAU;IAC1B;;OAEG;IACa,YAAmB;IACnC;;OAEG;IACa,KAAkB;QARlB,SAAI,GAAJ,IAAI,CAAM;QAIV,iBAAY,GAAZ,YAAY,CAAO;QAInB,UAAK,GAAL,KAAK,CAAa;QAElC,IAAI,CAAC,SAAS,GAAG,IAAI,eAAI,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3E,CAAC;CACD;AA/CD,kCA+CC;AA3CA;IACC,yBAAiB,GAAG,CAInB,IAAW,EACX,YAAoB,EACpB,KAAkB,EACjB,EAAE,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC,GAAA,CAAA;AAoCF;;GAEG;AACH,SAAgB,oBAAoB,CAAC,MAA2B;IAC/D,OAAO,MAAM,YAAY,WAAW;QACnC,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,IAAA,yBAAiB,EAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAJD,oDAIC;AACD;;;;;;GAMG;AACH,SAAgB,qBAAqB,CACpC,KAA2B;IAE3B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,IAAI,IAAA,0BAAe,EAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC9B,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC;SAAM,CAAC;QACP,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,UAAU,CAAC;AACnB,CAAC;AAZD,sDAYC;AAED,SAAS,kBAAkB,CAAC,KAA+B;IAC1D,MAAM,eAAe,GAAG,IAAA,iBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACxD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,qBAAU,CACnB,iHAAiH,CACjH,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACxB,CAAC;AA0HD;;;;;;;;;;;;GAYG;AACU,QAAA,cAAc,GAAkB,MAAM,CAAC,eAAe,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ErasedType, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { Lazy } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype LazyItem,\n\ttype NodeKeyManager,\n\tisLazy,\n\ttype FlexListToUnion,\n} from \"../feature-libraries/index.js\";\nimport { type MakeNominal, brand, isReadonlyArray } from \"../util/index.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport type { FieldKey } from \"../core/index.js\";\nimport type { InsertableContent } from \"./proxies.js\";\n\n/**\n * Schema for a tree node.\n * @typeParam Name - The full (including scope) name/identifier for the schema.\n * @typeParam Kind - Which kind of node this schema is for.\n * @typeParam TNode - API for nodes that use this schema.\n * @typeParam TBuild - Data which can be used to construct an {@link Unhydrated} node of this type.\n * @typeParam Info - Data used when defining this schema.\n * @remarks\n * Captures the schema both as runtime data and compile time type information.\n * @sealed @public\n */\nexport type TreeNodeSchema<\n\tName extends string = string,\n\tKind extends NodeKind = NodeKind,\n\tTNode = unknown,\n\tTBuild = never,\n\tImplicitlyConstructable extends boolean = boolean,\n\tInfo = unknown,\n> =\n\t| TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>\n\t| TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>;\n\n/**\n * Schema which is not a class.\n * @remarks\n * This is used for schema which cannot have their instances constructed using constructors, like leaf schema.\n * @privateRemarks\n * Non-class based schema can have issues with recursive types due to https://github.com/microsoft/TypeScript/issues/55832.\n * @sealed @public\n */\nexport interface TreeNodeSchemaNonClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\tcreate(data: TInsertable): TNode;\n}\n\n/**\n * Tree node schema which is implemented using a class.\n * @remarks\n * Instances of this class are nodes in the tree.\n * This is also a constructor so that it can be subclassed.\n *\n * Using classes in this way allows introducing a named type and a named value at the same time, helping keep the runtime and compile time information together and easy to refer to un a uniform way.\n * Additionally, this works around https://github.com/microsoft/TypeScript/issues/55832 which causes similar patterns with less explicit types to infer \"any\" in the d.ts file.\n * @sealed @public\n */\nexport interface TreeNodeSchemaClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\t/**\n\t * Constructs an {@link Unhydrated} node with this schema.\n\t * @remarks\n\t * This constructor is also used internally to construct hydrated nodes with a different parameter type.\n\t * Therefor overriding this constructor is not type-safe and is not supported.\n\t * @sealed\n\t */\n\tnew (data: TInsertable | InternalTreeNode): Unhydrated<TNode>;\n}\n\n/**\n * Data common to all tree node schema.\n * @remarks\n * Implementation detail of {@link TreeNodeSchema} which should be accessed instead of referring to this type directly.\n * @sealed @public\n */\nexport interface TreeNodeSchemaCore<\n\tout Name extends string,\n\tout Kind extends NodeKind,\n\tout ImplicitlyConstructable extends boolean,\n\tout Info = unknown,\n> {\n\treadonly identifier: Name;\n\treadonly kind: Kind;\n\n\t/**\n\t * Data used to define this schema.\n\t *\n\t * @remarks\n\t * The format depends on the kind of node it is for.\n\t * For example, the \"object\" node kind could store the field schema here.\n\t */\n\treadonly info: Info;\n\n\t/**\n\t * When constructing insertable content,\n\t * data that could be passed to the node's constructor can be used instead of an {@link Unhydrated} node\n\t * iff implicitlyConstructable is true.\n\t * @privateRemarks\n\t * Currently the logic for traversing insertable content,\n\t * both to build trees and to hydrate them does not defer to the schema classes to handle the policy,\n\t * so if their constructors differ from what is supported, some cases will not work.\n\t * Setting this to false adjusts the insertable types to disallow cases which could be impacted by these inconsistencies.\n\t */\n\treadonly implicitlyConstructable: ImplicitlyConstructable;\n}\n\n/**\n * Types for use in fields.\n * @remarks\n * Type constraint used in schema declaration APIs.\n * Not intended for direct use outside of package.\n * @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Kind of a field on a node.\n * @remarks\n * More kinds may be added over time, so do not assume this is an exhaustive set.\n * @public\n */\nexport enum FieldKind {\n\t/**\n\t * A field which can be empty or filled.\n\t * @remarks\n\t * Allows 0 or one child.\n\t */\n\tOptional,\n\t/**\n\t * A field which must always be filled.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tRequired,\n\t/**\n\t * A special field used for node identifiers.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tIdentifier,\n}\n\n/**\n * Kind of tree node.\n * @remarks\n * More kinds may be added over time, so do not assume this is an exhaustive set.\n * @public\n */\nexport enum NodeKind {\n\t/**\n\t * A node which serves as a map, storing children under string keys.\n\t */\n\tMap,\n\t/**\n\t * A node which serves as an array, storing children in an ordered sequence.\n\t */\n\tArray,\n\t/**\n\t * A node which stores a heterogenous collection of children in named fields.\n\t * @remarks\n\t * Each field gets its own schema.\n\t */\n\tObject,\n\t/**\n\t * A node which stores a single leaf value.\n\t */\n\tLeaf,\n}\n\n/**\n * Maps from a view key to its corresponding {@link FieldProps.key | stored key} for the provided\n * {@link ImplicitFieldSchema | field schema}.\n *\n * @remarks\n * If an explicit stored key was specified in the schema, it will be used.\n * Otherwise, the stored key is the same as the view key.\n */\nexport function getStoredKey(viewKey: string, fieldSchema: ImplicitFieldSchema): FieldKey {\n\treturn brand(getExplicitStoredKey(fieldSchema) ?? viewKey);\n}\n\n/**\n * Gets the {@link FieldProps.key | stored key} specified by the schema, if one was explicitly specified.\n * Otherwise, returns undefined.\n */\nexport function getExplicitStoredKey(fieldSchema: ImplicitFieldSchema): string | undefined {\n\treturn fieldSchema instanceof FieldSchema ? fieldSchema.props?.key : undefined;\n}\n\n/**\n * Additional information to provide to a {@link FieldSchema}.\n *\n * @public\n */\nexport interface FieldProps {\n\t/**\n\t * The unique identifier of a field, used in the persisted form of the tree.\n\t *\n\t * @remarks\n\t * If not explicitly set via the schema, this is the same as the schema's property key.\n\t *\n\t * Specifying a stored key that differs from the property key is particularly useful in refactoring scenarios.\n\t * To update the developer-facing API, while maintaining backwards compatibility with existing SharedTree data,\n\t * you can change the property key and specify the previous property key as the stored key.\n\t *\n\t * Notes:\n\t *\n\t * - Stored keys have no impact on standard JavaScript behavior, on tree nodes. For example, `Object.keys`\n\t * will always return the property keys specified in the schema, ignoring any stored keys that differ from\n\t * the property keys.\n\t *\n\t * - When specifying stored keys in an object schema, you must ensure that the final set of stored keys\n\t * (accounting for those implicitly derived from property keys) contains no duplicates.\n\t * This is validated at runtime.\n\t *\n\t * @example Refactoring code without breaking compatibility with existing data\n\t *\n\t * Consider some existing object schema:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \txPosition: schemaFactory.number,\n\t * \tyPosition: schemaFactory.number,\n\t * \tzPosition: schemaFactory.optional(schemaFactory.number),\n\t * });\n\t * ```\n\t *\n\t * Developers using nodes of this type would access the the `xPosition` property as `point.xPosition`.\n\t *\n\t * We would like to refactor the schema to omit \"Position\" from the property keys, but application data has\n\t * already been persisted using the original property keys. To maintain compatibility with existing data,\n\t * we can refactor the schema as follows:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \tx: schemaFactory.required(schemaFactory.number, { key: \"xPosition\" }),\n\t * \ty: schemaFactory.required(schemaFactory.number, { key: \"yPosition\" }),\n\t * \tz: schemaFactory.optional(schemaFactory.number, { key: \"zPosition\" }),\n\t * });\n\t * ```\n\t *\n\t * Now, developers can access the `x` property as `point.x`, while existing data can still be collaborated on.\n\t *\n\t * @defaultValue If not specified, the key that is persisted is the property key that was specified in the schema.\n\t */\n\treadonly key?: string;\n\t/**\n\t * A default provider used for fields which were not provided any values.\n\t * @privateRemarks\n\t * We are using an erased type here, as we want to expose this API but `InsertableContent` and `NodeKeyManager` are not public.\n\t */\n\treadonly defaultProvider?: DefaultProvider;\n}\n\n/**\n * A {@link FieldProvider} which requires additional context in order to produce its content\n */\nexport type ContextualFieldProvider = (\n\tcontext: NodeKeyManager,\n) => InsertableContent | undefined;\n/**\n * A {@link FieldProvider} which can produce its content in a vacuum\n */\nexport type ConstantFieldProvider = () => InsertableContent | undefined;\n/**\n * A function which produces content for a field every time that it is called\n */\nexport type FieldProvider = ContextualFieldProvider | ConstantFieldProvider;\n/**\n * Returns true if the given {@link FieldProvider} is a {@link ConstantFieldProvider}\n */\nexport function isConstant(\n\tfieldProvider: FieldProvider,\n): fieldProvider is ConstantFieldProvider {\n\treturn fieldProvider.length === 0;\n}\n\n/**\n * Provides a default value for a field.\n * @remarks\n * If present in a `FieldSchema`, when constructing new tree content that field can be omitted, and a default will be provided.\n * @sealed @public\n */\nexport interface DefaultProvider extends ErasedType<\"@fluidframework/tree.FieldProvider\"> {}\n\nexport function extractFieldProvider(input: DefaultProvider): FieldProvider {\n\treturn input as unknown as FieldProvider;\n}\n\nexport function getDefaultProvider(input: FieldProvider): DefaultProvider {\n\treturn input as unknown as DefaultProvider;\n}\n\n/**\n * Package internal construction API.\n */\nexport let createFieldSchema: <\n\tKind extends FieldKind = FieldKind,\n\tTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n>(\n\tkind: Kind,\n\tallowedTypes: Types,\n\tprops?: FieldProps,\n) => FieldSchema<Kind, Types>;\n\n/**\n * All policy for a specific field,\n * including functionality that does not have to be kept consistent across versions or deterministic.\n *\n * This can include policy for how to use this schema for \"view\" purposes, and well as how to expose editing APIs.\n * Use {@link SchemaFactory} to create the FieldSchema instances, for example {@link SchemaFactory.optional}.\n * @privateRemarks\n * Public access to the constructor is removed to prevent creating expressible but unsupported (or not stable) configurations.\n * {@link createFieldSchema} can be used internally to create instances.\n * @sealed @public\n */\nexport class FieldSchema<\n\tout Kind extends FieldKind = FieldKind,\n\tout Types extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n> {\n\tstatic {\n\t\tcreateFieldSchema = <\n\t\t\tKind2 extends FieldKind = FieldKind,\n\t\t\tTypes2 extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\t\t>(\n\t\t\tkind: Kind2,\n\t\t\tallowedTypes: Types2,\n\t\t\tprops?: FieldProps,\n\t\t) => new FieldSchema(kind, allowedTypes, props);\n\t}\n\t/**\n\t * This class is used with instanceof, and therefore should have nominal typing.\n\t * This field enforces that.\n\t */\n\tprotected _typeCheck?: MakeNominal;\n\n\tprivate readonly lazyTypes: Lazy<ReadonlySet<TreeNodeSchema>>;\n\n\t/**\n\t * What types of tree nodes are allowed in this field.\n\t * @remarks Counterpart to {@link FieldSchema.allowedTypes}, with any lazy definitions evaluated.\n\t */\n\tpublic get allowedTypeSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyTypes.value;\n\t}\n\n\tprivate constructor(\n\t\t/**\n\t\t * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.\n\t\t * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.\n\t\t */\n\t\tpublic readonly kind: Kind,\n\t\t/**\n\t\t * What types of tree nodes are allowed in this field.\n\t\t */\n\t\tpublic readonly allowedTypes: Types,\n\t\t/**\n\t\t * Optional properties associated with the field.\n\t\t */\n\t\tpublic readonly props?: FieldProps,\n\t) {\n\t\tthis.lazyTypes = new Lazy(() => normalizeAllowedTypes(this.allowedTypes));\n\t}\n}\n\n/**\n * Normalizes a {@link ImplicitFieldSchema} to a {@link FieldSchema}.\n */\nexport function normalizeFieldSchema(schema: ImplicitFieldSchema): FieldSchema {\n\treturn schema instanceof FieldSchema\n\t\t? schema\n\t\t: createFieldSchema(FieldKind.Required, schema);\n}\n/**\n * Normalizes a {@link ImplicitAllowedTypes} to a set of {@link TreeNodeSchema}s, by eagerly evaluating any\n * lazy schema declarations.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAllowedTypes(\n\ttypes: ImplicitAllowedTypes,\n): ReadonlySet<TreeNodeSchema> {\n\tconst normalized = new Set<TreeNodeSchema>();\n\tif (isReadonlyArray(types)) {\n\t\tfor (const lazyType of types) {\n\t\t\tnormalized.add(evaluateLazySchema(lazyType));\n\t\t}\n\t} else {\n\t\tnormalized.add(evaluateLazySchema(types));\n\t}\n\treturn normalized;\n}\n\nfunction evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {\n\tconst evaluatedSchema = isLazy(value) ? value() : value;\n\tif (evaluatedSchema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,\n\t\t);\n\t}\n\treturn evaluatedSchema;\n}\n\n/**\n * Types allowed in a field.\n * @remarks\n * Implicitly treats a single type as an array of one type.\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Schema for a field of a tree node.\n * @remarks\n * Implicitly treats {@link ImplicitAllowedTypes} as a Required field of that type.\n * @public\n */\nexport type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes;\n\n/**\n * Converts ImplicitFieldSchema to the corresponding tree node's field type.\n * @public\n */\nexport type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> =\n\tTSchema extends FieldSchema<infer Kind, infer Types>\n\t\t? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind, false>\n\t\t: TSchema extends ImplicitAllowedTypes\n\t\t\t? TreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a field of the given schema.\n * @public\n */\nexport type InsertableTreeFieldFromImplicitField<\n\tTSchema extends ImplicitFieldSchema = FieldSchema,\n> = TSchema extends FieldSchema<infer Kind, infer Types>\n\t? ApplyKind<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>\n\t: TSchema extends ImplicitAllowedTypes\n\t\t? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t: unknown;\n\n/**\n * Suitable for output.\n * For input must error on side of excluding undefined instead.\n * @public\n */\nexport type ApplyKind<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = {\n\t[FieldKind.Required]: T;\n\t[FieldKind.Optional]: T | undefined;\n\t[FieldKind.Identifier]: DefaultsAreOptional extends true ? T | undefined : T;\n}[Kind];\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? NodeFromSchema<FlexListToUnion<TSchema>>\n\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? InsertableTypedNode<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? InsertableTypedNode<FlexListToUnion<TSchema>>\n\t\t: never;\n\n/**\n * Takes in `TreeNodeSchema[]` and returns a TypedNode union.\n * @public\n */\nexport type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tinfer TNode\n>\n\t? TNode\n\t: never;\n\n/**\n * Data which can be used as a node to be inserted.\n * Either an unhydrated node, or content to build a new node.\n * @public\n */\nexport type InsertableTypedNode<T extends TreeNodeSchema> =\n\t| (T extends { implicitlyConstructable: true } ? NodeBuilderData<T> : never)\n\t| Unhydrated<NodeFromSchema<T>>;\n\n/**\n * Given a node's schema, return the corresponding object from which the node could be built.\n * @privateRemarks\n * Currently this assumes factory functions take exactly one argument.\n * This could be changed if needed.\n *\n * These factory functions can also take a FlexTreeNode, but this is not exposed in the public facing types.\n * @public\n */\nexport type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tunknown,\n\tinfer TBuild\n>\n\t? TBuild\n\t: never;\n\n/**\n * Value that may be stored as a leaf node.\n * @public\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type TreeLeafValue = number | string | boolean | IFluidHandle | null;\n\n/**\n * The type of a {@link TreeNode}.\n * For more information about the type, use `Tree.schema(theNode)` instead.\n * @remarks\n * This symbol mainly exists on nodes to allow TypeScript to provide more accurate type checking.\n * `Tree.is` and `Tree.schema` provide a superset of this information in more friendly ways.\n *\n * This symbol should not manually be added to objects as doing so allows the object to be invalidly used where nodes are expected.\n * Instead construct a real node of the desired type using its constructor.\n * @privateRemarks\n * This prevents non-nodes from being accidentally used as nodes, as well as allows the type checker to distinguish different node types.\n * @public\n */\nexport const typeNameSymbol: unique symbol = Symbol(\"TreeNode Type\");\n\n/**\n * Adds a type symbol to a type for stronger typing.\n * @remarks\n * An implementation detail of {@link TreeNode}'s strong typing setup: not intended for direct use outside of this package.\n * @sealed @public\n */\nexport interface WithType<TName extends string = string> {\n\t/**\n\t * Type symbol, marking a type in a way to increase type safety via strong type checking.\n\t */\n\tget [typeNameSymbol](): TName;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"schemaTypes.js","sourceRoot":"","sources":["../../src/simple-tree/schemaTypes.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ErasedType, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { Lazy } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype LazyItem,\n\ttype NodeKeyManager,\n\tisLazy,\n\ttype FlexListToUnion,\n} from \"../feature-libraries/index.js\";\nimport { type MakeNominal, brand, isReadonlyArray } from \"../util/index.js\";\nimport type { InternalTreeNode, Unhydrated } from \"./types.js\";\nimport type { FieldKey } from \"../core/index.js\";\nimport type { InsertableContent } from \"./proxies.js\";\n\n/**\n * Schema for a tree node.\n * @typeParam Name - The full (including scope) name/identifier for the schema.\n * @typeParam Kind - Which kind of node this schema is for.\n * @typeParam TNode - API for nodes that use this schema.\n * @typeParam TBuild - Data which can be used to construct an {@link Unhydrated} node of this type.\n * @typeParam Info - Data used when defining this schema.\n * @remarks\n * Captures the schema both as runtime data and compile time type information.\n * @sealed @public\n */\nexport type TreeNodeSchema<\n\tName extends string = string,\n\tKind extends NodeKind = NodeKind,\n\tTNode = unknown,\n\tTBuild = never,\n\tImplicitlyConstructable extends boolean = boolean,\n\tInfo = unknown,\n> =\n\t| TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>\n\t| TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable, Info>;\n\n/**\n * Schema which is not a class.\n * @remarks\n * This is used for schema which cannot have their instances constructed using constructors, like leaf schema.\n * @privateRemarks\n * Non-class based schema can have issues with recursive types due to https://github.com/microsoft/TypeScript/issues/55832.\n * @sealed @public\n */\nexport interface TreeNodeSchemaNonClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\tcreate(data: TInsertable): TNode;\n}\n\n/**\n * Tree node schema which is implemented using a class.\n * @remarks\n * Instances of this class are nodes in the tree.\n * This is also a constructor so that it can be subclassed.\n *\n * Using classes in this way allows introducing a named type and a named value at the same time, helping keep the runtime and compile time information together and easy to refer to un a uniform way.\n * Additionally, this works around https://github.com/microsoft/TypeScript/issues/55832 which causes similar patterns with less explicit types to infer \"any\" in the d.ts file.\n *\n * When sub-classing a a `TreeNodeSchemaClass`, some extra rules must be followed:\n *\n * - Only ever use a single class from the schema's class hierarchy within a document and its schema.\n * For example, if using {@link SchemaFactory.object} you can do:\n * ```typescript\n * // Recommended \"customizable\" object schema pattern.\n * class Good extends schemaFactory.object(\"A\", {\n * \texampleField: schemaFactory.number,\n * }) {\n * \tpublic exampleCustomMethod(): void {\n * \t\tthis.exampleField++;\n * \t}\n * }\n * ```\n * But should avoid:\n * ```typescript\n * // This by itself is ok, and opts into \"POJO mode\".\n * const base = schemaFactory.object(\"A\", {});\n * // This is a bad pattern since it leaves two classes in scope which derive from the same SchemaFactory defined class.\n * // If both get used, its an error!\n * class Invalid extends base {}\n * ```\n * - Do not modify the constructor input parameter types or values:\n * ```typescript\n * class Invalid extends schemaFactory.object(\"A\", {\n * \texampleField: schemaFactory.number,\n * }) {\n * \t// This Modifies the type of the constructor input.\n * \t// This is unsupported due to programmatic access to the constructor being used internally.\n * \tpublic constructor(a: number) {\n * \t\tsuper({ exampleField: a });\n * \t}\n * }\n * ```\n * @sealed @public\n */\nexport interface TreeNodeSchemaClass<\n\tout Name extends string = string,\n\tout Kind extends NodeKind = NodeKind,\n\tout TNode = unknown,\n\tin TInsertable = never,\n\tout ImplicitlyConstructable extends boolean = boolean,\n\tout Info = unknown,\n> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable, Info> {\n\t/**\n\t * Constructs an {@link Unhydrated} node with this schema.\n\t * @remarks\n\t * This constructor is also used internally to construct hydrated nodes with a different parameter type.\n\t * Therefore, overriding this constructor with different argument types is not type-safe and is not supported.\n\t * @sealed\n\t */\n\tnew (data: TInsertable | InternalTreeNode): Unhydrated<TNode>;\n}\n\n/**\n * Data common to all tree node schema.\n * @remarks\n * Implementation detail of {@link TreeNodeSchema} which should be accessed instead of referring to this type directly.\n * @sealed @public\n */\nexport interface TreeNodeSchemaCore<\n\tout Name extends string,\n\tout Kind extends NodeKind,\n\tout ImplicitlyConstructable extends boolean,\n\tout Info = unknown,\n> {\n\treadonly identifier: Name;\n\treadonly kind: Kind;\n\n\t/**\n\t * Data used to define this schema.\n\t *\n\t * @remarks\n\t * The format depends on the kind of node it is for.\n\t * For example, the \"object\" node kind could store the field schema here.\n\t */\n\treadonly info: Info;\n\n\t/**\n\t * When constructing insertable content,\n\t * data that could be passed to the node's constructor can be used instead of an {@link Unhydrated} node\n\t * iff implicitlyConstructable is true.\n\t * @privateRemarks\n\t * Currently the logic for traversing insertable content,\n\t * both to build trees and to hydrate them does not defer to the schema classes to handle the policy,\n\t * so if their constructors differ from what is supported, some cases will not work.\n\t * Setting this to false adjusts the insertable types to disallow cases which could be impacted by these inconsistencies.\n\t */\n\treadonly implicitlyConstructable: ImplicitlyConstructable;\n}\n\n/**\n * Types for use in fields.\n * @remarks\n * Type constraint used in schema declaration APIs.\n * Not intended for direct use outside of package.\n * @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Kind of a field on a node.\n * @remarks\n * More kinds may be added over time, so do not assume this is an exhaustive set.\n * @public\n */\nexport enum FieldKind {\n\t/**\n\t * A field which can be empty or filled.\n\t * @remarks\n\t * Allows 0 or one child.\n\t */\n\tOptional,\n\t/**\n\t * A field which must always be filled.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tRequired,\n\t/**\n\t * A special field used for node identifiers.\n\t * @remarks\n\t * Only allows exactly one child.\n\t */\n\tIdentifier,\n}\n\n/**\n * Kind of tree node.\n * @remarks\n * More kinds may be added over time, so do not assume this is an exhaustive set.\n * @public\n */\nexport enum NodeKind {\n\t/**\n\t * A node which serves as a map, storing children under string keys.\n\t */\n\tMap,\n\t/**\n\t * A node which serves as an array, storing children in an ordered sequence.\n\t */\n\tArray,\n\t/**\n\t * A node which stores a heterogenous collection of children in named fields.\n\t * @remarks\n\t * Each field gets its own schema.\n\t */\n\tObject,\n\t/**\n\t * A node which stores a single leaf value.\n\t */\n\tLeaf,\n}\n\n/**\n * Maps from a view key to its corresponding {@link FieldProps.key | stored key} for the provided\n * {@link ImplicitFieldSchema | field schema}.\n *\n * @remarks\n * If an explicit stored key was specified in the schema, it will be used.\n * Otherwise, the stored key is the same as the view key.\n */\nexport function getStoredKey(viewKey: string, fieldSchema: ImplicitFieldSchema): FieldKey {\n\treturn brand(getExplicitStoredKey(fieldSchema) ?? viewKey);\n}\n\n/**\n * Gets the {@link FieldProps.key | stored key} specified by the schema, if one was explicitly specified.\n * Otherwise, returns undefined.\n */\nexport function getExplicitStoredKey(fieldSchema: ImplicitFieldSchema): string | undefined {\n\treturn fieldSchema instanceof FieldSchema ? fieldSchema.props?.key : undefined;\n}\n\n/**\n * Additional information to provide to a {@link FieldSchema}.\n *\n * @public\n */\nexport interface FieldProps {\n\t/**\n\t * The unique identifier of a field, used in the persisted form of the tree.\n\t *\n\t * @remarks\n\t * If not explicitly set via the schema, this is the same as the schema's property key.\n\t *\n\t * Specifying a stored key that differs from the property key is particularly useful in refactoring scenarios.\n\t * To update the developer-facing API, while maintaining backwards compatibility with existing SharedTree data,\n\t * you can change the property key and specify the previous property key as the stored key.\n\t *\n\t * Notes:\n\t *\n\t * - Stored keys have no impact on standard JavaScript behavior, on tree nodes. For example, `Object.keys`\n\t * will always return the property keys specified in the schema, ignoring any stored keys that differ from\n\t * the property keys.\n\t *\n\t * - When specifying stored keys in an object schema, you must ensure that the final set of stored keys\n\t * (accounting for those implicitly derived from property keys) contains no duplicates.\n\t * This is validated at runtime.\n\t *\n\t * @example Refactoring code without breaking compatibility with existing data\n\t *\n\t * Consider some existing object schema:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \txPosition: schemaFactory.number,\n\t * \tyPosition: schemaFactory.number,\n\t * \tzPosition: schemaFactory.optional(schemaFactory.number),\n\t * });\n\t * ```\n\t *\n\t * Developers using nodes of this type would access the the `xPosition` property as `point.xPosition`.\n\t *\n\t * We would like to refactor the schema to omit \"Position\" from the property keys, but application data has\n\t * already been persisted using the original property keys. To maintain compatibility with existing data,\n\t * we can refactor the schema as follows:\n\t *\n\t * ```TypeScript\n\t * class Point extends schemaFactory.object(\"Point\", {\n\t * \tx: schemaFactory.required(schemaFactory.number, { key: \"xPosition\" }),\n\t * \ty: schemaFactory.required(schemaFactory.number, { key: \"yPosition\" }),\n\t * \tz: schemaFactory.optional(schemaFactory.number, { key: \"zPosition\" }),\n\t * });\n\t * ```\n\t *\n\t * Now, developers can access the `x` property as `point.x`, while existing data can still be collaborated on.\n\t *\n\t * @defaultValue If not specified, the key that is persisted is the property key that was specified in the schema.\n\t */\n\treadonly key?: string;\n\t/**\n\t * A default provider used for fields which were not provided any values.\n\t * @privateRemarks\n\t * We are using an erased type here, as we want to expose this API but `InsertableContent` and `NodeKeyManager` are not public.\n\t */\n\treadonly defaultProvider?: DefaultProvider;\n}\n\n/**\n * A {@link FieldProvider} which requires additional context in order to produce its content\n */\nexport type ContextualFieldProvider = (\n\tcontext: NodeKeyManager,\n) => InsertableContent | undefined;\n/**\n * A {@link FieldProvider} which can produce its content in a vacuum\n */\nexport type ConstantFieldProvider = () => InsertableContent | undefined;\n/**\n * A function which produces content for a field every time that it is called\n */\nexport type FieldProvider = ContextualFieldProvider | ConstantFieldProvider;\n/**\n * Returns true if the given {@link FieldProvider} is a {@link ConstantFieldProvider}\n */\nexport function isConstant(\n\tfieldProvider: FieldProvider,\n): fieldProvider is ConstantFieldProvider {\n\treturn fieldProvider.length === 0;\n}\n\n/**\n * Provides a default value for a field.\n * @remarks\n * If present in a `FieldSchema`, when constructing new tree content that field can be omitted, and a default will be provided.\n * @sealed @public\n */\nexport interface DefaultProvider extends ErasedType<\"@fluidframework/tree.FieldProvider\"> {}\n\nexport function extractFieldProvider(input: DefaultProvider): FieldProvider {\n\treturn input as unknown as FieldProvider;\n}\n\nexport function getDefaultProvider(input: FieldProvider): DefaultProvider {\n\treturn input as unknown as DefaultProvider;\n}\n\n/**\n * Package internal construction API.\n */\nexport let createFieldSchema: <\n\tKind extends FieldKind = FieldKind,\n\tTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n>(\n\tkind: Kind,\n\tallowedTypes: Types,\n\tprops?: FieldProps,\n) => FieldSchema<Kind, Types>;\n\n/**\n * All policy for a specific field,\n * including functionality that does not have to be kept consistent across versions or deterministic.\n *\n * This can include policy for how to use this schema for \"view\" purposes, and well as how to expose editing APIs.\n * Use {@link SchemaFactory} to create the FieldSchema instances, for example {@link SchemaFactory.optional}.\n * @privateRemarks\n * Public access to the constructor is removed to prevent creating expressible but unsupported (or not stable) configurations.\n * {@link createFieldSchema} can be used internally to create instances.\n * @sealed @public\n */\nexport class FieldSchema<\n\tout Kind extends FieldKind = FieldKind,\n\tout Types extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n> {\n\tstatic {\n\t\tcreateFieldSchema = <\n\t\t\tKind2 extends FieldKind = FieldKind,\n\t\t\tTypes2 extends ImplicitAllowedTypes = ImplicitAllowedTypes,\n\t\t>(\n\t\t\tkind: Kind2,\n\t\t\tallowedTypes: Types2,\n\t\t\tprops?: FieldProps,\n\t\t) => new FieldSchema(kind, allowedTypes, props);\n\t}\n\t/**\n\t * This class is used with instanceof, and therefore should have nominal typing.\n\t * This field enforces that.\n\t */\n\tprotected _typeCheck?: MakeNominal;\n\n\tprivate readonly lazyTypes: Lazy<ReadonlySet<TreeNodeSchema>>;\n\n\t/**\n\t * What types of tree nodes are allowed in this field.\n\t * @remarks Counterpart to {@link FieldSchema.allowedTypes}, with any lazy definitions evaluated.\n\t */\n\tpublic get allowedTypeSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyTypes.value;\n\t}\n\n\tprivate constructor(\n\t\t/**\n\t\t * The {@link https://en.wikipedia.org/wiki/Kind_(type_theory) | kind } of this field.\n\t\t * Determines the multiplicity, viewing and editing APIs as well as the merge resolution policy.\n\t\t */\n\t\tpublic readonly kind: Kind,\n\t\t/**\n\t\t * What types of tree nodes are allowed in this field.\n\t\t */\n\t\tpublic readonly allowedTypes: Types,\n\t\t/**\n\t\t * Optional properties associated with the field.\n\t\t */\n\t\tpublic readonly props?: FieldProps,\n\t) {\n\t\tthis.lazyTypes = new Lazy(() => normalizeAllowedTypes(this.allowedTypes));\n\t}\n}\n\n/**\n * Normalizes a {@link ImplicitFieldSchema} to a {@link FieldSchema}.\n */\nexport function normalizeFieldSchema(schema: ImplicitFieldSchema): FieldSchema {\n\treturn schema instanceof FieldSchema\n\t\t? schema\n\t\t: createFieldSchema(FieldKind.Required, schema);\n}\n/**\n * Normalizes a {@link ImplicitAllowedTypes} to a set of {@link TreeNodeSchema}s, by eagerly evaluating any\n * lazy schema declarations.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAllowedTypes(\n\ttypes: ImplicitAllowedTypes,\n): ReadonlySet<TreeNodeSchema> {\n\tconst normalized = new Set<TreeNodeSchema>();\n\tif (isReadonlyArray(types)) {\n\t\tfor (const lazyType of types) {\n\t\t\tnormalized.add(evaluateLazySchema(lazyType));\n\t\t}\n\t} else {\n\t\tnormalized.add(evaluateLazySchema(types));\n\t}\n\treturn normalized;\n}\n\nfunction evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {\n\tconst evaluatedSchema = isLazy(value) ? value() : value;\n\tif (evaluatedSchema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,\n\t\t);\n\t}\n\treturn evaluatedSchema;\n}\n\n/**\n * Types allowed in a field.\n * @remarks\n * Implicitly treats a single type as an array of one type.\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Schema for a field of a tree node.\n * @remarks\n * Implicitly treats {@link ImplicitAllowedTypes} as a Required field of that type.\n * @public\n */\nexport type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes;\n\n/**\n * Converts ImplicitFieldSchema to the corresponding tree node's field type.\n * @public\n */\nexport type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> =\n\tTSchema extends FieldSchema<infer Kind, infer Types>\n\t\t? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind, false>\n\t\t: TSchema extends ImplicitAllowedTypes\n\t\t\t? TreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a field of the given schema.\n * @public\n */\nexport type InsertableTreeFieldFromImplicitField<\n\tTSchema extends ImplicitFieldSchema = FieldSchema,\n> = TSchema extends FieldSchema<infer Kind, infer Types>\n\t? ApplyKind<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>\n\t: TSchema extends ImplicitAllowedTypes\n\t\t? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>\n\t\t: unknown;\n\n/**\n * Suitable for output.\n * For input must error on side of excluding undefined instead.\n * @public\n */\nexport type ApplyKind<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = {\n\t[FieldKind.Required]: T;\n\t[FieldKind.Optional]: T | undefined;\n\t[FieldKind.Identifier]: DefaultsAreOptional extends true ? T | undefined : T;\n}[Kind];\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? NodeFromSchema<FlexListToUnion<TSchema>>\n\t\t: unknown;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? InsertableTypedNode<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? InsertableTypedNode<FlexListToUnion<TSchema>>\n\t\t: never;\n\n/**\n * Takes in `TreeNodeSchema[]` and returns a TypedNode union.\n * @public\n */\nexport type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tinfer TNode\n>\n\t? TNode\n\t: never;\n\n/**\n * Data which can be used as a node to be inserted.\n * Either an unhydrated node, or content to build a new node.\n * @public\n */\nexport type InsertableTypedNode<T extends TreeNodeSchema> =\n\t| (T extends { implicitlyConstructable: true } ? NodeBuilderData<T> : never)\n\t| Unhydrated<NodeFromSchema<T>>;\n\n/**\n * Given a node's schema, return the corresponding object from which the node could be built.\n * @privateRemarks\n * Currently this assumes factory functions take exactly one argument.\n * This could be changed if needed.\n *\n * These factory functions can also take a FlexTreeNode, but this is not exposed in the public facing types.\n * @public\n */\nexport type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<\n\tstring,\n\tNodeKind,\n\tunknown,\n\tinfer TBuild\n>\n\t? TBuild\n\t: never;\n\n/**\n * Value that may be stored as a leaf node.\n * @public\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type TreeLeafValue = number | string | boolean | IFluidHandle | null;\n\n/**\n * The type of a {@link TreeNode}.\n * For more information about the type, use `Tree.schema(theNode)` instead.\n * @remarks\n * This symbol mainly exists on nodes to allow TypeScript to provide more accurate type checking.\n * `Tree.is` and `Tree.schema` provide a superset of this information in more friendly ways.\n *\n * This symbol should not manually be added to objects as doing so allows the object to be invalidly used where nodes are expected.\n * Instead construct a real node of the desired type using its constructor.\n * @privateRemarks\n * This prevents non-nodes from being accidentally used as nodes, as well as allows the type checker to distinguish different node types.\n * @public\n */\nexport const typeNameSymbol: unique symbol = Symbol(\"TreeNode Type\");\n\n/**\n * Adds a type symbol to a type for stronger typing.\n * @remarks\n * An implementation detail of {@link TreeNode}'s strong typing setup: not intended for direct use outside of this package.\n * @sealed @public\n */\nexport interface WithType<TName extends string = string> {\n\t/**\n\t * Type symbol, marking a type in a way to increase type safety via strong type checking.\n\t */\n\tget [typeNameSymbol](): TName;\n}\n"]}
|