@fluidframework/tree 2.22.1 → 2.23.0-325054
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/extensions.json +1 -0
- package/.vscode/settings.json +1 -0
- package/CHANGELOG.md +47 -0
- package/api-report/tree.alpha.api.md +169 -10
- package/api-report/tree.beta.api.md +101 -9
- package/api-report/tree.legacy.alpha.api.md +101 -9
- package/api-report/tree.legacy.public.api.md +101 -9
- package/api-report/tree.public.api.md +101 -9
- package/dist/alpha.d.ts +20 -0
- package/dist/beta.d.ts +15 -0
- package/dist/codec/codec.js +3 -3
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/discriminatedUnions.d.ts.map +1 -1
- package/dist/codec/discriminatedUnions.js +1 -1
- package/dist/codec/discriminatedUnions.js.map +1 -1
- package/dist/core/schema-stored/schema.d.ts.map +1 -1
- package/dist/core/schema-stored/schema.js +3 -3
- package/dist/core/schema-stored/schema.js.map +1 -1
- package/dist/core/tree/anchorSet.d.ts.map +1 -1
- package/dist/core/tree/anchorSet.js +18 -13
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/core/tree/treeTextFormat.js +1 -1
- package/dist/core/tree/treeTextFormat.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +11 -8
- package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +2 -2
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +3 -3
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +2 -2
- package/dist/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeShape.js +2 -2
- package/dist/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js +3 -3
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/emptyChunk.js +14 -14
- package/dist/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js +6 -4
- package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/default-schema/schemaChecker.js +1 -1
- package/dist/feature-libraries/default-schema/schemaChecker.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +4 -3
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +5 -4
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
- package/dist/feature-libraries/indexing/anchorTreeIndex.js +1 -1
- package/dist/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.js +6 -4
- package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/dist/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/isNeverTree.js +4 -4
- package/dist/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +10 -11
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/node-key/mockNodeKeyManager.js +1 -1
- package/dist/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/schema-index/codec.js +1 -1
- package/dist/feature-libraries/schema-index/codec.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +1 -1
- package/dist/feature-libraries/sequence-field/compose.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/sequenceFieldCodecV1.js +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +1 -1
- package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
- package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
- package/dist/feature-libraries/treeCursorUtils.js +6 -4
- package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/jsonDomainSchema.d.ts +113 -0
- package/dist/jsonDomainSchema.d.ts.map +1 -0
- package/dist/jsonDomainSchema.js +101 -0
- package/dist/jsonDomainSchema.js.map +1 -0
- package/dist/legacy.d.ts +15 -0
- 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 +15 -0
- package/dist/serializableDomainSchema.d.ts +108 -0
- package/dist/serializableDomainSchema.d.ts.map +1 -0
- package/dist/serializableDomainSchema.js +90 -0
- package/dist/serializableDomainSchema.js.map +1 -0
- package/dist/shared-tree/index.d.ts +1 -1
- package/dist/shared-tree/index.d.ts.map +1 -1
- package/dist/shared-tree/index.js.map +1 -1
- package/dist/shared-tree/schematizeTree.js +1 -1
- package/dist/shared-tree/schematizeTree.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +37 -20
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +17 -17
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.js +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/dist/shared-tree/treeApiAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeApiAlpha.js +4 -4
- package/dist/shared-tree/treeApiAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.js +1 -1
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/editManager.d.ts +11 -2
- package/dist/shared-tree-core/editManager.d.ts.map +1 -1
- package/dist/shared-tree-core/editManager.js +70 -34
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/resubmitMachine.d.ts +2 -0
- package/dist/shared-tree-core/resubmitMachine.d.ts.map +1 -1
- package/dist/shared-tree-core/resubmitMachine.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts +10 -3
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +42 -7
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/api/component.d.ts +30 -0
- package/dist/simple-tree/api/component.d.ts.map +1 -0
- package/dist/simple-tree/api/component.js +26 -0
- package/dist/simple-tree/api/component.js.map +1 -0
- package/dist/simple-tree/api/customTree.js +3 -3
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +2 -1
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +3 -1
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.js +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +0 -8
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +4 -25
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
- package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/dist/simple-tree/api/simpleTreeIndex.js +3 -3
- package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js +2 -3
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.js +7 -18
- package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.d.ts +127 -19
- package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.js +17 -0
- package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
- package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/dist/simple-tree/api/verboseTree.js +5 -4
- package/dist/simple-tree/api/verboseTree.js.map +1 -1
- package/dist/simple-tree/api/view.js +1 -1
- package/dist/simple-tree/api/view.js.map +1 -1
- package/dist/simple-tree/arrayNode.d.ts +1 -1
- package/dist/simple-tree/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/arrayNode.js +2 -2
- package/dist/simple-tree/arrayNode.js.map +1 -1
- package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
- package/dist/simple-tree/core/getOrCreateNode.js +1 -1
- package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
- package/dist/simple-tree/core/schemaCaching.js +1 -1
- package/dist/simple-tree/core/schemaCaching.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +6 -6
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +5 -5
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/flexList.d.ts +4 -5
- package/dist/simple-tree/flexList.d.ts.map +1 -1
- package/dist/simple-tree/flexList.js +1 -14
- package/dist/simple-tree/flexList.js.map +1 -1
- package/dist/simple-tree/index.d.ts +4 -4
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +6 -2
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/objectNode.d.ts +25 -2
- package/dist/simple-tree/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/objectNode.js +4 -2
- package/dist/simple-tree/objectNode.js.map +1 -1
- package/dist/simple-tree/proxies.js +1 -1
- package/dist/simple-tree/proxies.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +211 -9
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js +83 -2
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/toMapTree.js +3 -3
- package/dist/simple-tree/toMapTree.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +3 -6
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/dist/simple-tree/treeNodeValid.d.ts +7 -1
- package/dist/simple-tree/treeNodeValid.d.ts.map +1 -1
- package/dist/simple-tree/treeNodeValid.js +18 -7
- package/dist/simple-tree/treeNodeValid.js.map +1 -1
- package/dist/util/idAllocator.js +1 -1
- package/dist/util/idAllocator.js.map +1 -1
- package/dist/util/index.d.ts +2 -2
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +5 -4
- package/dist/util/index.js.map +1 -1
- package/dist/util/nestedMap.d.ts +2 -10
- package/dist/util/nestedMap.d.ts.map +1 -1
- package/dist/util/nestedMap.js +9 -28
- package/dist/util/nestedMap.js.map +1 -1
- package/dist/util/utils.d.ts +23 -6
- package/dist/util/utils.d.ts.map +1 -1
- package/dist/util/utils.js +46 -13
- package/dist/util/utils.js.map +1 -1
- package/lib/alpha.d.ts +20 -0
- package/lib/beta.d.ts +15 -0
- package/lib/codec/codec.js +3 -3
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/discriminatedUnions.d.ts.map +1 -1
- package/lib/codec/discriminatedUnions.js +1 -1
- package/lib/codec/discriminatedUnions.js.map +1 -1
- package/lib/core/schema-stored/schema.d.ts.map +1 -1
- package/lib/core/schema-stored/schema.js +3 -3
- package/lib/core/schema-stored/schema.js.map +1 -1
- package/lib/core/tree/anchorSet.d.ts.map +1 -1
- package/lib/core/tree/anchorSet.js +19 -14
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/core/tree/treeTextFormat.js +1 -1
- package/lib/core/tree/treeTextFormat.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +11 -8
- package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +2 -2
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +3 -3
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js +2 -2
- package/lib/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +4 -3
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeShape.js +2 -2
- package/lib/feature-libraries/chunked-forest/codec/nodeShape.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js +3 -3
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncoding.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/emptyChunk.js +14 -14
- package/lib/feature-libraries/chunked-forest/emptyChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js +6 -4
- package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/default-schema/schemaChecker.js +1 -1
- package/lib/feature-libraries/default-schema/schemaChecker.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +4 -3
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +5 -4
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/indexing/anchorTreeIndex.d.ts.map +1 -1
- package/lib/feature-libraries/indexing/anchorTreeIndex.js +1 -1
- package/lib/feature-libraries/indexing/anchorTreeIndex.js.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.js +6 -4
- package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/lib/feature-libraries/modular-schema/isNeverTree.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/isNeverTree.js +4 -4
- package/lib/feature-libraries/modular-schema/isNeverTree.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +11 -12
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/node-key/mockNodeKeyManager.js +1 -1
- package/lib/feature-libraries/node-key/mockNodeKeyManager.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/schema-index/codec.js +1 -1
- package/lib/feature-libraries/schema-index/codec.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +1 -1
- package/lib/feature-libraries/sequence-field/compose.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/sequenceFieldCodecV1.js +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +1 -1
- package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
- package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
- package/lib/feature-libraries/treeCursorUtils.js +6 -4
- package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
- package/lib/index.d.ts +4 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/jsonDomainSchema.d.ts +113 -0
- package/lib/jsonDomainSchema.d.ts.map +1 -0
- package/lib/jsonDomainSchema.js +98 -0
- package/lib/jsonDomainSchema.js.map +1 -0
- package/lib/legacy.d.ts +15 -0
- 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 +15 -0
- package/lib/serializableDomainSchema.d.ts +108 -0
- package/lib/serializableDomainSchema.d.ts.map +1 -0
- package/lib/serializableDomainSchema.js +87 -0
- package/lib/serializableDomainSchema.js.map +1 -0
- package/lib/shared-tree/index.d.ts +1 -1
- package/lib/shared-tree/index.d.ts.map +1 -1
- package/lib/shared-tree/index.js.map +1 -1
- package/lib/shared-tree/schematizeTree.js +1 -1
- package/lib/shared-tree/schematizeTree.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +37 -20
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +18 -18
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.js +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/lib/shared-tree/treeApiAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeApiAlpha.js +4 -4
- package/lib/shared-tree/treeApiAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.js +1 -1
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/editManager.d.ts +11 -2
- package/lib/shared-tree-core/editManager.d.ts.map +1 -1
- package/lib/shared-tree-core/editManager.js +70 -34
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/resubmitMachine.d.ts +2 -0
- package/lib/shared-tree-core/resubmitMachine.d.ts.map +1 -1
- package/lib/shared-tree-core/resubmitMachine.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts +10 -3
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +42 -7
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/api/component.d.ts +30 -0
- package/lib/simple-tree/api/component.d.ts.map +1 -0
- package/lib/simple-tree/api/component.js +23 -0
- package/lib/simple-tree/api/component.js.map +1 -0
- package/lib/simple-tree/api/customTree.js +3 -3
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +2 -1
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -0
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.js +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +0 -8
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +2 -22
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.d.ts +1 -1
- package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
- package/lib/simple-tree/api/simpleTreeIndex.js +3 -3
- package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js +3 -4
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.d.ts.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.js +9 -20
- package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.d.ts +127 -19
- package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.js +15 -1
- package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
- package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/lib/simple-tree/api/verboseTree.js +5 -4
- package/lib/simple-tree/api/verboseTree.js.map +1 -1
- package/lib/simple-tree/api/view.js +1 -1
- package/lib/simple-tree/api/view.js.map +1 -1
- package/lib/simple-tree/arrayNode.d.ts +1 -1
- package/lib/simple-tree/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/arrayNode.js +2 -2
- package/lib/simple-tree/arrayNode.js.map +1 -1
- package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
- package/lib/simple-tree/core/getOrCreateNode.js +1 -1
- package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
- package/lib/simple-tree/core/schemaCaching.js +1 -1
- package/lib/simple-tree/core/schemaCaching.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +6 -6
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +5 -5
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/flexList.d.ts +4 -5
- package/lib/simple-tree/flexList.d.ts.map +1 -1
- package/lib/simple-tree/flexList.js +0 -12
- package/lib/simple-tree/flexList.js.map +1 -1
- package/lib/simple-tree/index.d.ts +4 -4
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +2 -2
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/objectNode.d.ts +25 -2
- package/lib/simple-tree/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/objectNode.js +4 -2
- package/lib/simple-tree/objectNode.js.map +1 -1
- package/lib/simple-tree/proxies.js +1 -1
- package/lib/simple-tree/proxies.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +211 -9
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js +81 -3
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/toMapTree.js +3 -3
- package/lib/simple-tree/toMapTree.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +5 -8
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/lib/simple-tree/treeNodeValid.d.ts +7 -1
- package/lib/simple-tree/treeNodeValid.d.ts.map +1 -1
- package/lib/simple-tree/treeNodeValid.js +18 -7
- package/lib/simple-tree/treeNodeValid.js.map +1 -1
- package/lib/util/idAllocator.js +1 -1
- package/lib/util/idAllocator.js.map +1 -1
- package/lib/util/index.d.ts +2 -2
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +2 -2
- package/lib/util/index.js.map +1 -1
- package/lib/util/nestedMap.d.ts +2 -10
- package/lib/util/nestedMap.d.ts.map +1 -1
- package/lib/util/nestedMap.js +5 -23
- package/lib/util/nestedMap.js.map +1 -1
- package/lib/util/utils.d.ts +23 -6
- package/lib/util/utils.d.ts.map +1 -1
- package/lib/util/utils.js +42 -11
- package/lib/util/utils.js.map +1 -1
- package/package.json +27 -23
- package/src/codec/codec.ts +3 -3
- package/src/codec/discriminatedUnions.ts +2 -1
- package/src/core/schema-stored/schema.ts +5 -3
- package/src/core/tree/anchorSet.ts +37 -26
- package/src/core/tree/treeTextFormat.ts +1 -1
- package/src/feature-libraries/chunked-forest/basicChunk.ts +11 -8
- package/src/feature-libraries/chunked-forest/chunkTree.ts +2 -2
- package/src/feature-libraries/chunked-forest/chunkedForest.ts +3 -3
- package/src/feature-libraries/chunked-forest/codec/chunkEncodingGeneric.ts +2 -2
- package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +4 -3
- package/src/feature-libraries/chunked-forest/codec/nodeShape.ts +2 -2
- package/src/feature-libraries/chunked-forest/codec/schemaBasedEncoding.ts +4 -3
- package/src/feature-libraries/chunked-forest/emptyChunk.ts +14 -14
- package/src/feature-libraries/chunked-forest/uniformChunk.ts +6 -4
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -1
- package/src/feature-libraries/default-schema/schemaChecker.ts +1 -1
- package/src/feature-libraries/flex-tree/lazyField.ts +6 -8
- package/src/feature-libraries/flex-tree/lazyNode.ts +6 -4
- package/src/feature-libraries/indexing/anchorTreeIndex.ts +2 -1
- package/src/feature-libraries/modular-schema/comparison.ts +7 -5
- package/src/feature-libraries/modular-schema/isNeverTree.ts +6 -4
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +4 -4
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +16 -12
- package/src/feature-libraries/node-key/mockNodeKeyManager.ts +1 -1
- package/src/feature-libraries/object-forest/objectForest.ts +1 -1
- package/src/feature-libraries/schema-index/codec.ts +1 -1
- package/src/feature-libraries/sequence-field/compose.ts +1 -1
- package/src/feature-libraries/sequence-field/invert.ts +1 -1
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV1.ts +1 -1
- package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +1 -1
- package/src/feature-libraries/sequence-field/utils.ts +1 -1
- package/src/feature-libraries/treeCursorUtils.ts +6 -4
- package/src/index.ts +22 -1
- package/src/jsonDomainSchema.ts +129 -0
- package/src/packageVersion.ts +1 -1
- package/src/serializableDomainSchema.ts +121 -0
- package/src/shared-tree/index.ts +0 -1
- package/src/shared-tree/schematizeTree.ts +1 -1
- package/src/shared-tree/sharedTree.ts +31 -41
- package/src/shared-tree/sharedTreeChangeFamily.ts +1 -1
- package/src/shared-tree/treeApiAlpha.ts +12 -4
- package/src/shared-tree/treeCheckout.ts +1 -1
- package/src/shared-tree-core/editManager.ts +85 -47
- package/src/shared-tree-core/resubmitMachine.ts +2 -0
- package/src/shared-tree-core/sharedTreeCore.ts +62 -14
- package/src/simple-tree/api/component.ts +42 -0
- package/src/simple-tree/api/customTree.ts +3 -3
- package/src/simple-tree/api/index.ts +7 -0
- package/src/simple-tree/api/schemaCreationUtilities.ts +1 -1
- package/src/simple-tree/api/schemaFactory.ts +1 -28
- package/src/simple-tree/api/schemaFactoryRecursive.ts +1 -1
- package/src/simple-tree/api/simpleTreeIndex.ts +3 -3
- package/src/simple-tree/api/tree.ts +3 -3
- package/src/simple-tree/api/treeNodeApi.ts +10 -18
- package/src/simple-tree/api/typesUnsafe.ts +193 -18
- package/src/simple-tree/api/verboseTree.ts +8 -4
- package/src/simple-tree/api/view.ts +1 -1
- package/src/simple-tree/arrayNode.ts +2 -2
- package/src/simple-tree/core/getOrCreateNode.ts +2 -1
- package/src/simple-tree/core/schemaCaching.ts +1 -1
- package/src/simple-tree/core/treeNodeKernel.ts +9 -6
- package/src/simple-tree/core/unhydratedFlexTree.ts +7 -5
- package/src/simple-tree/flexList.ts +4 -14
- package/src/simple-tree/index.ts +25 -1
- package/src/simple-tree/objectNode.ts +50 -5
- package/src/simple-tree/proxies.ts +1 -1
- package/src/simple-tree/schemaTypes.ts +322 -23
- package/src/simple-tree/toMapTree.ts +3 -3
- package/src/simple-tree/toStoredSchema.ts +5 -7
- package/src/simple-tree/treeNodeValid.ts +21 -7
- package/src/util/idAllocator.ts +1 -1
- package/src/util/index.ts +3 -2
- package/src/util/nestedMap.ts +9 -33
- package/src/util/utils.ts +52 -12
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
type ImplicitAllowedTypes,
|
|
28
28
|
FieldKind,
|
|
29
29
|
type NodeSchemaMetadata,
|
|
30
|
+
type GetTypes,
|
|
31
|
+
type SchemaUnionToIntersection,
|
|
30
32
|
} from "./schemaTypes.js";
|
|
31
33
|
import {
|
|
32
34
|
type TreeNodeSchema,
|
|
@@ -56,11 +58,51 @@ import { getUnhydratedContext } from "./createContext.js";
|
|
|
56
58
|
* @system @public
|
|
57
59
|
*/
|
|
58
60
|
export type ObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
// Due to https://github.com/microsoft/TypeScript/issues/43826 we can not set the desired setter type,
|
|
62
|
+
// but we can at least remove the setter (by setting the key to never) when there should be no setter.
|
|
63
|
+
-readonly [Property in keyof T as [
|
|
64
|
+
AssignableTreeFieldFromImplicitField<T[Property & string]>,
|
|
65
|
+
// If the types we want to allow setting to are just never or undefined, remove the setter
|
|
66
|
+
] extends [never | undefined]
|
|
67
|
+
? never
|
|
68
|
+
: Property]: AssignableTreeFieldFromImplicitField<T[Property & string]>;
|
|
69
|
+
} & {
|
|
70
|
+
readonly [Property in keyof T]: TreeFieldFromImplicitField<T[Property & string]>;
|
|
62
71
|
};
|
|
63
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Type of content that can be assigned to a field of the given schema.
|
|
75
|
+
*
|
|
76
|
+
* @see {@link Input}
|
|
77
|
+
*
|
|
78
|
+
* @typeparam TSchemaInput - Schema to process.
|
|
79
|
+
* @typeparam TSchema - Do not specify: default value used as an implementation detail.
|
|
80
|
+
* @system @public
|
|
81
|
+
*/
|
|
82
|
+
export type AssignableTreeFieldFromImplicitField<
|
|
83
|
+
TSchemaInput extends ImplicitFieldSchema,
|
|
84
|
+
TSchema = SchemaUnionToIntersection<TSchemaInput>,
|
|
85
|
+
> = [TSchema] extends [FieldSchema<infer Kind, infer Types>]
|
|
86
|
+
? ApplyKindAssignment<GetTypes<Types>["readWrite"], Kind>
|
|
87
|
+
: [TSchema] extends [ImplicitAllowedTypes]
|
|
88
|
+
? GetTypes<TSchema>["readWrite"]
|
|
89
|
+
: never;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Suitable for assignment.
|
|
93
|
+
*
|
|
94
|
+
* @see {@link Input}
|
|
95
|
+
* @system @public
|
|
96
|
+
*/
|
|
97
|
+
export type ApplyKindAssignment<T, Kind extends FieldKind> = [Kind] extends [
|
|
98
|
+
FieldKind.Required,
|
|
99
|
+
]
|
|
100
|
+
? T
|
|
101
|
+
: [Kind] extends [FieldKind.Optional]
|
|
102
|
+
? T | undefined
|
|
103
|
+
: // Unknown, non-exact and identifier fields are not assignable.
|
|
104
|
+
never;
|
|
105
|
+
|
|
64
106
|
/**
|
|
65
107
|
* A {@link TreeNode} which modules a JavaScript object.
|
|
66
108
|
* @remarks
|
|
@@ -262,7 +304,7 @@ function createProxyHandler(
|
|
|
262
304
|
// For some reason, the getOwnPropertyDescriptor is not passed in the receiver, so use a weak map.
|
|
263
305
|
// If a refactoring is done to associated flex tree data with the target not the proxy, this extra map could be removed,
|
|
264
306
|
// and the design would be more compatible with proxyless nodes.
|
|
265
|
-
const proxy = targetToProxy.get(target) ?? fail(
|
|
307
|
+
const proxy = targetToProxy.get(target) ?? fail(0xadd /* missing proxy */);
|
|
266
308
|
const field = getOrCreateInnerNode(proxy).tryGetField(fieldInfo.storedKey);
|
|
267
309
|
|
|
268
310
|
const p: PropertyDescriptor = {
|
|
@@ -311,7 +353,7 @@ export function setField(
|
|
|
311
353
|
}
|
|
312
354
|
|
|
313
355
|
default:
|
|
314
|
-
fail(
|
|
356
|
+
fail(0xade /* invalid FieldKind */);
|
|
315
357
|
}
|
|
316
358
|
}
|
|
317
359
|
|
|
@@ -340,6 +382,9 @@ export function objectSchema<
|
|
|
340
382
|
metadata?: NodeSchemaMetadata<TCustomMetadata>,
|
|
341
383
|
): ObjectNodeSchema<TName, T, ImplicitlyConstructable, TCustomMetadata> &
|
|
342
384
|
ObjectNodeSchemaInternalData {
|
|
385
|
+
// Field set can't be modified after since derived data is stored in maps.
|
|
386
|
+
Object.freeze(info);
|
|
387
|
+
|
|
343
388
|
// Ensure no collisions between final set of property keys, and final set of stored keys (including those
|
|
344
389
|
// implicitly derived from property keys)
|
|
345
390
|
assertUniqueKeys(identifier, info);
|
|
@@ -16,19 +16,23 @@ import {
|
|
|
16
16
|
compareSets,
|
|
17
17
|
type requireTrue,
|
|
18
18
|
type areOnlyKeys,
|
|
19
|
+
getOrCreate,
|
|
19
20
|
} from "../util/index.js";
|
|
20
|
-
import
|
|
21
|
-
Unhydrated,
|
|
22
|
-
NodeKind,
|
|
23
|
-
TreeNodeSchema,
|
|
24
|
-
TreeNodeSchemaClass,
|
|
25
|
-
TreeNode,
|
|
26
|
-
TreeNodeSchemaCore,
|
|
27
|
-
TreeNodeSchemaNonClass,
|
|
21
|
+
import {
|
|
22
|
+
type Unhydrated,
|
|
23
|
+
type NodeKind,
|
|
24
|
+
type TreeNodeSchema,
|
|
25
|
+
type TreeNodeSchemaClass,
|
|
26
|
+
type TreeNode,
|
|
27
|
+
type TreeNodeSchemaCore,
|
|
28
|
+
type TreeNodeSchemaNonClass,
|
|
29
|
+
inPrototypeChain,
|
|
28
30
|
} from "./core/index.js";
|
|
29
31
|
import type { FieldKey } from "../core/index.js";
|
|
30
32
|
import type { InsertableContent } from "./toMapTree.js";
|
|
31
33
|
import { isLazy, type FlexListToUnion, type LazyItem } from "./flexList.js";
|
|
34
|
+
import { LeafNodeSchema } from "./leafNodeSchema.js";
|
|
35
|
+
import { TreeNodeValid } from "./treeNodeValid.js";
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
38
|
* Returns true if the given schema is a {@link TreeNodeSchemaClass}, or otherwise false if it is a {@link TreeNodeSchemaNonClass}.
|
|
@@ -69,6 +73,8 @@ export function isTreeNodeSchemaClass<
|
|
|
69
73
|
* way to declare and manipulate unordered sets of types in TypeScript.
|
|
70
74
|
*
|
|
71
75
|
* Not intended for direct use outside of package.
|
|
76
|
+
* @privateRemarks
|
|
77
|
+
* Code reading data from this should use `normalizeAllowedTypes` to ensure consistent handling, caching, nice errors etc.
|
|
72
78
|
* @system @public
|
|
73
79
|
*/
|
|
74
80
|
export type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];
|
|
@@ -379,6 +385,8 @@ export function normalizeAllowedTypes(
|
|
|
379
385
|
): ReadonlySet<TreeNodeSchema> {
|
|
380
386
|
const normalized = new Set<TreeNodeSchema>();
|
|
381
387
|
if (isReadonlyArray(types)) {
|
|
388
|
+
// Types array must not be modified after it is normalized since that would result if the user of the normalized data having wrong (out of date) content.
|
|
389
|
+
Object.freeze(types);
|
|
382
390
|
for (const lazyType of types) {
|
|
383
391
|
normalized.add(evaluateLazySchema(lazyType));
|
|
384
392
|
}
|
|
@@ -469,16 +477,59 @@ function areMetadataEqual(
|
|
|
469
477
|
return a?.custom === b?.custom && a?.description === b?.description;
|
|
470
478
|
}
|
|
471
479
|
|
|
472
|
-
|
|
473
|
-
|
|
480
|
+
const cachedLazyItem = new WeakMap<() => unknown, unknown>();
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Returns the schema referenced by the {@link LazyItem}.
|
|
484
|
+
* @remarks
|
|
485
|
+
* Caches results to handle {@link LazyItem} which compute their resulting schema.
|
|
486
|
+
* @alpha
|
|
487
|
+
*/
|
|
488
|
+
export function evaluateLazySchema<T extends TreeNodeSchema>(value: LazyItem<T>): T {
|
|
489
|
+
const evaluatedSchema = isLazy(value)
|
|
490
|
+
? (getOrCreate(cachedLazyItem, value, value) as T)
|
|
491
|
+
: value;
|
|
474
492
|
if (evaluatedSchema === undefined) {
|
|
475
493
|
throw new UsageError(
|
|
476
494
|
`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated.`,
|
|
477
495
|
);
|
|
478
496
|
}
|
|
497
|
+
markSchemaMostDerived(evaluatedSchema);
|
|
479
498
|
return evaluatedSchema;
|
|
480
499
|
}
|
|
481
500
|
|
|
501
|
+
/**
|
|
502
|
+
* Indicates that a schema is the "most derived" version which is allowed to be used, see {@link MostDerivedData}.
|
|
503
|
+
* Calling helps with error messages about invalid schema usage (using more than one type from single schema factor produced type,
|
|
504
|
+
* and thus calling this for one than one subclass).
|
|
505
|
+
* @remarks
|
|
506
|
+
* Helper for invoking {@link TreeNodeValid.markMostDerived} for any {@link TreeNodeSchema} if it needed.
|
|
507
|
+
*/
|
|
508
|
+
export function markSchemaMostDerived(
|
|
509
|
+
schema: TreeNodeSchema,
|
|
510
|
+
oneTimeInitialize = false,
|
|
511
|
+
): void {
|
|
512
|
+
if (schema instanceof LeafNodeSchema) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (!inPrototypeChain(schema, TreeNodeValid)) {
|
|
517
|
+
// Use JSON.stringify to quote and escape identifier string.
|
|
518
|
+
throw new UsageError(
|
|
519
|
+
`Schema for ${JSON.stringify(
|
|
520
|
+
schema.identifier,
|
|
521
|
+
)} does not extend a SchemaFactory generated class. This is invalid.`,
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
const schemaValid = schema as typeof TreeNodeValid & TreeNodeSchema;
|
|
526
|
+
if (oneTimeInitialize) {
|
|
527
|
+
schemaValid.oneTimeInitialize();
|
|
528
|
+
} else {
|
|
529
|
+
schemaValid.markMostDerived();
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
482
533
|
/**
|
|
483
534
|
* Types of {@link TreeNode|TreeNodes} or {@link TreeLeafValue|TreeLeafValues} allowed at a location in a tree.
|
|
484
535
|
* @remarks
|
|
@@ -508,6 +559,8 @@ function evaluateLazySchema(value: LazyItem<TreeNodeSchema>): TreeNodeSchema {
|
|
|
508
559
|
* class A extends sf.array("example", [() => B]) {}
|
|
509
560
|
* class B extends sf.array("Inner", sf.number) {}
|
|
510
561
|
* ```
|
|
562
|
+
* @privateRemarks
|
|
563
|
+
* Code reading data from this should use `normalizeAllowedTypes` to ensure consistent handling, caching, nice errors etc.
|
|
511
564
|
* @public
|
|
512
565
|
*/
|
|
513
566
|
export type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;
|
|
@@ -546,13 +599,27 @@ export type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = Fie
|
|
|
546
599
|
*/
|
|
547
600
|
export type InsertableTreeFieldFromImplicitField<
|
|
548
601
|
TSchemaInput extends ImplicitFieldSchema,
|
|
549
|
-
TSchema =
|
|
602
|
+
TSchema = [TSchemaInput] extends [CustomizedSchemaTyping<unknown, CustomTypes>]
|
|
603
|
+
? TSchemaInput
|
|
604
|
+
: SchemaUnionToIntersection<TSchemaInput>,
|
|
550
605
|
> = [TSchema] extends [FieldSchema<infer Kind, infer Types>]
|
|
551
606
|
? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>
|
|
552
607
|
: [TSchema] extends [ImplicitAllowedTypes]
|
|
553
608
|
? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>
|
|
554
609
|
: never;
|
|
555
610
|
|
|
611
|
+
/**
|
|
612
|
+
* {@link UnionToIntersection} except it does not distribute over {@link CustomizedSchemaTyping}s when the original type is a union.
|
|
613
|
+
* @privateRemarks
|
|
614
|
+
* This is a workaround for TypeScript distributing over intersections over unions when distributing extends over unions.
|
|
615
|
+
* @system @public
|
|
616
|
+
*/
|
|
617
|
+
export type SchemaUnionToIntersection<T> = [T] extends [
|
|
618
|
+
CustomizedSchemaTyping<unknown, CustomTypes>,
|
|
619
|
+
]
|
|
620
|
+
? T
|
|
621
|
+
: UnionToIntersection<T>;
|
|
622
|
+
|
|
556
623
|
/**
|
|
557
624
|
* {@inheritdoc (UnsafeUnknownSchema:type)}
|
|
558
625
|
* @alpha
|
|
@@ -575,22 +642,228 @@ export const UnsafeUnknownSchema: unique symbol = Symbol("UnsafeUnknownSchema");
|
|
|
575
642
|
* Any APIs which use this must produce UsageErrors when out of schema data is encountered, and never produce unrecoverable errors,
|
|
576
643
|
* or silently accept invalid data.
|
|
577
644
|
* This is currently only type exported from the package: the symbol is just used as a way to get a named type.
|
|
645
|
+
*
|
|
646
|
+
* TODO: This takes a very different approach than `customizeSchemaTyping` which applies to allowed types.
|
|
647
|
+
* Maybe generalize that to apply to field schema as well and replace this with it?
|
|
578
648
|
* @alpha
|
|
579
649
|
*/
|
|
580
650
|
export type UnsafeUnknownSchema = typeof UnsafeUnknownSchema;
|
|
581
651
|
|
|
652
|
+
/**
|
|
653
|
+
* {@inheritdoc (CustomizedTyping:type)}
|
|
654
|
+
* @system @public
|
|
655
|
+
*/
|
|
656
|
+
export const CustomizedTyping: unique symbol = Symbol("CustomizedTyping");
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* A type brand used by {@link customizeSchemaTyping}.
|
|
660
|
+
* @system @public
|
|
661
|
+
*/
|
|
662
|
+
export type CustomizedTyping = typeof CustomizedTyping;
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Collection of schema aware types.
|
|
666
|
+
* @remarks
|
|
667
|
+
* This type is only used as a type constraint.
|
|
668
|
+
* It's fields are similar to an unordered set of generic type parameters.
|
|
669
|
+
* {@link customizeSchemaTyping} applies this to {@link ImplicitAllowedTypes} via {@link CustomizedSchemaTyping}.
|
|
670
|
+
* @sealed @public
|
|
671
|
+
*/
|
|
672
|
+
export interface CustomTypes {
|
|
673
|
+
/**
|
|
674
|
+
* Type used for inserting values.
|
|
675
|
+
*/
|
|
676
|
+
readonly input: unknown;
|
|
677
|
+
/**
|
|
678
|
+
* Type used for the read+write property on object nodes.
|
|
679
|
+
*
|
|
680
|
+
* Set to never to disable setter.
|
|
681
|
+
* @remarks
|
|
682
|
+
* Due to https://github.com/microsoft/TypeScript/issues/43826 we cannot set the desired setter type.
|
|
683
|
+
* Instead we can only control the types of the read+write property and the type of a readonly property.
|
|
684
|
+
*
|
|
685
|
+
* For recursive types using {@link SchemaFactory.objectRecursive}, support for using `never` to remove setters is limited:
|
|
686
|
+
* When the customized schema is wrapped in an {@link FieldSchema}, the setter will not be fully removed.
|
|
687
|
+
*/
|
|
688
|
+
readonly readWrite: TreeLeafValue | TreeNode;
|
|
689
|
+
/**
|
|
690
|
+
* Type for reading data.
|
|
691
|
+
* @remarks
|
|
692
|
+
* See limitation for read+write properties on ObjectNodes in {@link CustomTypes.readWrite}.
|
|
693
|
+
*/
|
|
694
|
+
readonly output: TreeLeafValue | TreeNode;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Type annotation which overrides the default schema derived types with customized ones.
|
|
699
|
+
* @remarks
|
|
700
|
+
* See {@link customizeSchemaTyping} for more information.
|
|
701
|
+
* @system @public
|
|
702
|
+
*/
|
|
703
|
+
export type CustomizedSchemaTyping<TSchema, TCustom extends CustomTypes> = TSchema & {
|
|
704
|
+
[CustomizedTyping]: TCustom;
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Default strict policy.
|
|
709
|
+
*
|
|
710
|
+
* @typeparam TSchema - The schema to process
|
|
711
|
+
* @typeparam TInput - Internal: do not specify.
|
|
712
|
+
* @typeparam TOutput - Internal: do not specify.
|
|
713
|
+
* @remarks
|
|
714
|
+
* Handles input types contravariantly so any input which might be invalid is rejected.
|
|
715
|
+
* @sealed @public
|
|
716
|
+
*/
|
|
717
|
+
export interface StrictTypes<
|
|
718
|
+
TSchema extends ImplicitAllowedTypes,
|
|
719
|
+
TInput = DefaultInsertableTreeNodeFromImplicitAllowedTypes<TSchema>,
|
|
720
|
+
TOutput extends TreeNode | TreeLeafValue = DefaultTreeNodeFromImplicitAllowedTypes<TSchema>,
|
|
721
|
+
> {
|
|
722
|
+
input: TInput;
|
|
723
|
+
readWrite: TInput extends never ? never : TOutput;
|
|
724
|
+
output: TOutput;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Customizes the types associated with `TSchema`
|
|
729
|
+
* @remarks
|
|
730
|
+
* By default, the types used when constructing, reading and writing tree nodes are derived from the schema.
|
|
731
|
+
* In some cases, it may be desirable to override these types with carefully selected alternatives.
|
|
732
|
+
* This utility allows for that customization.
|
|
733
|
+
* Note that this customization is only used for typing, and does not affect the runtime behavior at all.
|
|
734
|
+
*
|
|
735
|
+
* This can be used for a wide variety of purposes, including (but not limited to):
|
|
736
|
+
*
|
|
737
|
+
* 1. Implementing better typing for a runtime extensible set of types (e.g. a polymorphic collection).
|
|
738
|
+
* This is commonly needed when implementing containers which don't directly reference their child types, and can be done using {@link Customizer.simplified}.
|
|
739
|
+
* 2. Adding type brands to specific values to increase type safety.
|
|
740
|
+
* This can be done using {@link Customizer.simplified}.
|
|
741
|
+
* 3. Adding some (compile time only) constraints to values, like enum style unions.
|
|
742
|
+
* This can be done using {@link Customizer.simplified}.
|
|
743
|
+
* 4. Making fields readonly (for the current client).
|
|
744
|
+
* This can be done using {@link Customizer.custom} with `{ readWrite: never; }`.
|
|
745
|
+
* 5. Opting into more [compleat and less sound](https://en.wikipedia.org/wiki/Soundness#Relation_to_completeness) typing.
|
|
746
|
+
* {@link Customizer.relaxed} is an example of this.
|
|
747
|
+
*
|
|
748
|
+
* For this customization to be used, the resulting schema must be used as `ImplicitAllowedTypes`.
|
|
749
|
+
* For example applying this to a single type, then using that type in an array of allowed types will have no effect:
|
|
750
|
+
* in such a case the customization must instead be applied to the array of allowed types.
|
|
751
|
+
* @privateRemarks
|
|
752
|
+
* Once this API is more stable/final, the examples in tests such as openPolymorphism.spec.ts and schemaFactory.examples.spec.ts
|
|
753
|
+
* should be copied into examples here, or somehow linked.
|
|
754
|
+
* @alpha
|
|
755
|
+
*/
|
|
756
|
+
export function customizeSchemaTyping<const TSchema extends ImplicitAllowedTypes>(
|
|
757
|
+
schema: TSchema,
|
|
758
|
+
): Customizer<TSchema> {
|
|
759
|
+
// This function just does type branding, and duplicating the typing here to avoid any would just make it harder to maintain not easier:
|
|
760
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
761
|
+
const f = (): any => schema;
|
|
762
|
+
return { strict: f, relaxed: f, simplified: f, simplifiedUnrestricted: f, custom: f };
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Utility for customizing the types used for data matching a given schema.
|
|
767
|
+
* @sealed @alpha
|
|
768
|
+
*/
|
|
769
|
+
export interface Customizer<TSchema extends ImplicitAllowedTypes> {
|
|
770
|
+
/**
|
|
771
|
+
* The default {@link StrictTypes}, explicitly applied.
|
|
772
|
+
*/
|
|
773
|
+
strict(): CustomizedSchemaTyping<TSchema, StrictTypes<TSchema>>;
|
|
774
|
+
/**
|
|
775
|
+
* Relaxed policy: allows possible invalid edits (which will err at runtime) when schema is not exact.
|
|
776
|
+
* @remarks
|
|
777
|
+
* Handles input types covariantly so any input which might be valid with the schema is allowed
|
|
778
|
+
* instead of the default strict policy of only inputs with all possible schema are allowed.
|
|
779
|
+
*
|
|
780
|
+
* This only modifies the typing shallowly: the typing of children are not effected.
|
|
781
|
+
*/
|
|
782
|
+
relaxed(): CustomizedSchemaTyping<
|
|
783
|
+
TSchema,
|
|
784
|
+
{
|
|
785
|
+
input: TreeNodeSchema extends TSchema
|
|
786
|
+
? InsertableContent
|
|
787
|
+
: // This intentionally distributes unions over the conditional to get covariant type handling.
|
|
788
|
+
TSchema extends TreeNodeSchema
|
|
789
|
+
? InsertableTypedNode<TSchema>
|
|
790
|
+
: // This intentionally distributes unions over the conditional to get covariant type handling.
|
|
791
|
+
TSchema extends AllowedTypes
|
|
792
|
+
? TSchema[number] extends LazyItem<infer TSchemaInner extends TreeNodeSchema>
|
|
793
|
+
? InsertableTypedNode<TSchemaInner, TSchemaInner>
|
|
794
|
+
: never
|
|
795
|
+
: never;
|
|
796
|
+
readWrite: TreeNodeFromImplicitAllowedTypes<TSchema>;
|
|
797
|
+
output: TreeNodeFromImplicitAllowedTypes<TSchema>;
|
|
798
|
+
}
|
|
799
|
+
>;
|
|
800
|
+
/**
|
|
801
|
+
* Replace typing with a single substitute which allowed types must implement.
|
|
802
|
+
* @remarks
|
|
803
|
+
* This is generally type safe for reading the tree, but allows instances of `T` other than those listed in the schema to be assigned,
|
|
804
|
+
* which can be out of schema and err at runtime in the same way {@link Customizer.relaxed} does.
|
|
805
|
+
* Until with {@link Customizer.relaxed}, implicit construction is disabled, meaning all nodes must be explicitly constructed (and thus implement `T`) before being inserted.
|
|
806
|
+
*/
|
|
807
|
+
simplified<T extends TreeNodeFromImplicitAllowedTypes<TSchema>>(): CustomizedSchemaTyping<
|
|
808
|
+
TSchema,
|
|
809
|
+
{
|
|
810
|
+
input: T;
|
|
811
|
+
readWrite: T;
|
|
812
|
+
output: T;
|
|
813
|
+
}
|
|
814
|
+
>;
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* The same as {@link Customizer} except that more T values are allowed, even ones not known to be implemented by `TSchema`.
|
|
818
|
+
*/
|
|
819
|
+
simplifiedUnrestricted<T extends TreeNode | TreeLeafValue>(): CustomizedSchemaTyping<
|
|
820
|
+
TSchema,
|
|
821
|
+
{
|
|
822
|
+
input: T;
|
|
823
|
+
readWrite: T;
|
|
824
|
+
output: T;
|
|
825
|
+
}
|
|
826
|
+
>;
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Fully arbitrary customization.
|
|
830
|
+
* Provided types override existing types.
|
|
831
|
+
*/
|
|
832
|
+
custom<T extends Partial<CustomTypes>>(): CustomizedSchemaTyping<
|
|
833
|
+
TSchema,
|
|
834
|
+
{
|
|
835
|
+
// Check if property is provided. This check is needed to early out missing values so if undefined is allowed,
|
|
836
|
+
// not providing the field doesn't overwrite the corresponding type with undefined.
|
|
837
|
+
// TODO: test this case
|
|
838
|
+
[Property in keyof CustomTypes]: Property extends keyof T
|
|
839
|
+
? T[Property] extends CustomTypes[Property]
|
|
840
|
+
? T[Property]
|
|
841
|
+
: GetTypes<TSchema>[Property]
|
|
842
|
+
: GetTypes<TSchema>[Property];
|
|
843
|
+
}
|
|
844
|
+
>;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* Fetch types associated with a schema, or use the default if not customized.
|
|
849
|
+
* @system @public
|
|
850
|
+
*/
|
|
851
|
+
export type GetTypes<TSchema extends ImplicitAllowedTypes> = [TSchema] extends [
|
|
852
|
+
CustomizedSchemaTyping<unknown, infer TCustom>,
|
|
853
|
+
]
|
|
854
|
+
? TCustom
|
|
855
|
+
: StrictTypes<TSchema>;
|
|
856
|
+
|
|
582
857
|
/**
|
|
583
858
|
* Content which could be inserted into a tree.
|
|
584
859
|
*
|
|
585
860
|
* @see {@link Input}
|
|
586
861
|
* @remarks
|
|
587
|
-
*
|
|
862
|
+
* Alias of {@link InsertableTreeNodeFromImplicitAllowedTypes} with a shorter name.
|
|
588
863
|
* @alpha
|
|
589
864
|
*/
|
|
590
|
-
export type Insertable<TSchema extends ImplicitAllowedTypes
|
|
591
|
-
TSchema
|
|
592
|
-
? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>
|
|
593
|
-
: InsertableContent;
|
|
865
|
+
export type Insertable<TSchema extends ImplicitAllowedTypes> =
|
|
866
|
+
InsertableTreeNodeFromImplicitAllowedTypes<TSchema>;
|
|
594
867
|
|
|
595
868
|
/**
|
|
596
869
|
* Content which could be inserted into a field within a tree.
|
|
@@ -664,10 +937,22 @@ export type ApplyKindInput<T, Kind extends FieldKind, DefaultsAreOptional extend
|
|
|
664
937
|
|
|
665
938
|
/**
|
|
666
939
|
* Type of tree node for a field of the given schema.
|
|
940
|
+
*
|
|
941
|
+
* @typeparam TSchema - Schema to process.
|
|
942
|
+
* @remarks
|
|
943
|
+
* Defaults to {@link DefaultTreeNodeFromImplicitAllowedTypes}.
|
|
667
944
|
* @public
|
|
668
945
|
*/
|
|
669
946
|
export type TreeNodeFromImplicitAllowedTypes<
|
|
670
947
|
TSchema extends ImplicitAllowedTypes = TreeNodeSchema,
|
|
948
|
+
> = GetTypes<TSchema>["output"];
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Default type of tree node for a field of the given schema.
|
|
952
|
+
* @system @public
|
|
953
|
+
*/
|
|
954
|
+
export type DefaultTreeNodeFromImplicitAllowedTypes<
|
|
955
|
+
TSchema extends ImplicitAllowedTypes = TreeNodeSchema,
|
|
671
956
|
> = TSchema extends TreeNodeSchema
|
|
672
957
|
? NodeFromSchema<TSchema>
|
|
673
958
|
: TSchema extends AllowedTypes
|
|
@@ -727,6 +1012,17 @@ export type TreeNodeFromImplicitAllowedTypes<
|
|
|
727
1012
|
*/
|
|
728
1013
|
export type Input<T extends never> = T;
|
|
729
1014
|
|
|
1015
|
+
/**
|
|
1016
|
+
* Type of content that can be inserted into the tree for a node of the given schema.
|
|
1017
|
+
*
|
|
1018
|
+
* @typeparam TSchema - Schema to process.
|
|
1019
|
+
* @remarks
|
|
1020
|
+
* Defaults to {@link DefaultInsertableTreeNodeFromImplicitAllowedTypes}.
|
|
1021
|
+
* @public
|
|
1022
|
+
*/
|
|
1023
|
+
export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> =
|
|
1024
|
+
GetTypes<TSchema>["input"];
|
|
1025
|
+
|
|
730
1026
|
/**
|
|
731
1027
|
* Type of content that can be inserted into the tree for a node of the given schema.
|
|
732
1028
|
*
|
|
@@ -736,14 +1032,15 @@ export type Input<T extends never> = T;
|
|
|
736
1032
|
*
|
|
737
1033
|
* @privateRemarks
|
|
738
1034
|
* This is a bit overly conservative, since cases like `A | [A]` give never and could give `A`.
|
|
739
|
-
* @public
|
|
1035
|
+
* @system @public
|
|
740
1036
|
*/
|
|
741
|
-
export type
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
1037
|
+
export type DefaultInsertableTreeNodeFromImplicitAllowedTypes<
|
|
1038
|
+
TSchema extends ImplicitAllowedTypes,
|
|
1039
|
+
> = [TSchema] extends [TreeNodeSchema]
|
|
1040
|
+
? InsertableTypedNode<TSchema>
|
|
1041
|
+
: [TSchema] extends [AllowedTypes]
|
|
1042
|
+
? InsertableTreeNodeFromAllowedTypes<TSchema>
|
|
1043
|
+
: never;
|
|
747
1044
|
|
|
748
1045
|
/**
|
|
749
1046
|
* Type of content that can be inserted into the tree for a node of the given schema.
|
|
@@ -793,6 +1090,8 @@ export type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchemaC
|
|
|
793
1090
|
* One special case this makes is if the result of NodeFromSchema contains TreeNode, this must be an under constrained schema, so the result is set to never.
|
|
794
1091
|
* Note that applying UnionToIntersection on the result of NodeFromSchema<T> does not work since it breaks booleans.
|
|
795
1092
|
*
|
|
1093
|
+
* Some internal code may use second parameter to opt out of contravariant behavior, but this is not a stable API.
|
|
1094
|
+
*
|
|
796
1095
|
* @public
|
|
797
1096
|
*/
|
|
798
1097
|
export type InsertableTypedNode<
|
|
@@ -196,7 +196,7 @@ function nodeDataToMapTree(
|
|
|
196
196
|
result = objectToMapTree(data, schema);
|
|
197
197
|
break;
|
|
198
198
|
default:
|
|
199
|
-
fail(
|
|
199
|
+
fail(0xae0 /* Unrecognized schema kind */);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
return result;
|
|
@@ -642,7 +642,7 @@ export function addDefaultsToMapTree(
|
|
|
642
642
|
): void {
|
|
643
643
|
const schema =
|
|
644
644
|
find(normalizeAllowedTypes(allowedTypes), (s) => s.identifier === mapTree.type) ??
|
|
645
|
-
fail(
|
|
645
|
+
fail(0xae1 /* MapTree is incompatible with schema */);
|
|
646
646
|
|
|
647
647
|
if (isObjectNodeSchema(schema)) {
|
|
648
648
|
for (const [_key, fieldInfo] of schema.flexKeyMap) {
|
|
@@ -660,7 +660,7 @@ export function addDefaultsToMapTree(
|
|
|
660
660
|
setFieldValue(mapTree.fields, data, fieldInfo.schema, fieldInfo.storedKey);
|
|
661
661
|
// call addDefaultsToMapTree on newly inserted default values
|
|
662
662
|
for (const child of mapTree.fields.get(fieldInfo.storedKey) ??
|
|
663
|
-
fail(
|
|
663
|
+
fail(0xae2 /* Expected field to be populated */)) {
|
|
664
664
|
addDefaultsToMapTree(child, fieldInfo.schema.allowedTypes, context);
|
|
665
665
|
}
|
|
666
666
|
}
|
|
@@ -20,18 +20,18 @@ import {
|
|
|
20
20
|
type TreeTypeSet,
|
|
21
21
|
} from "../core/index.js";
|
|
22
22
|
import { FieldKinds, type FlexFieldKind } from "../feature-libraries/index.js";
|
|
23
|
-
import { brand, fail, getOrCreate
|
|
23
|
+
import { brand, fail, getOrCreate } from "../util/index.js";
|
|
24
24
|
import { NodeKind, type TreeNodeSchema } from "./core/index.js";
|
|
25
25
|
import {
|
|
26
26
|
FieldKind,
|
|
27
27
|
FieldSchema,
|
|
28
|
+
normalizeAllowedTypes,
|
|
28
29
|
type ImplicitAllowedTypes,
|
|
29
30
|
type ImplicitFieldSchema,
|
|
30
31
|
} from "./schemaTypes.js";
|
|
31
32
|
import { walkFieldSchema } from "./walkFieldSchema.js";
|
|
32
33
|
import { LeafNodeSchema } from "./leafNodeSchema.js";
|
|
33
34
|
import { isObjectNodeSchema } from "./objectNodeTypes.js";
|
|
34
|
-
import { normalizeFlexListEager } from "./flexList.js";
|
|
35
35
|
|
|
36
36
|
const viewToStoredCache = new WeakMap<ImplicitFieldSchema, TreeStoredSchema>();
|
|
37
37
|
|
|
@@ -71,7 +71,8 @@ export function convertField(schema: ImplicitFieldSchema): TreeFieldStoredSchema
|
|
|
71
71
|
let kind: FieldKindIdentifier;
|
|
72
72
|
let allowedTypes: ImplicitAllowedTypes;
|
|
73
73
|
if (schema instanceof FieldSchema) {
|
|
74
|
-
kind =
|
|
74
|
+
kind =
|
|
75
|
+
convertFieldKind.get(schema.kind)?.identifier ?? fail(0xae3 /* Invalid field kind */);
|
|
75
76
|
allowedTypes = schema.allowedTypes;
|
|
76
77
|
} else {
|
|
77
78
|
kind = FieldKinds.required.identifier;
|
|
@@ -91,10 +92,7 @@ const convertFieldKind = new Map<FieldKind, FlexFieldKind>([
|
|
|
91
92
|
* Normalizes an {@link ImplicitAllowedTypes} into an {@link TreeTypeSet}.
|
|
92
93
|
*/
|
|
93
94
|
export function convertAllowedTypes(schema: ImplicitAllowedTypes): TreeTypeSet {
|
|
94
|
-
|
|
95
|
-
return new Set(normalizeFlexListEager(schema).map((item) => brand(item.identifier)));
|
|
96
|
-
}
|
|
97
|
-
return new Set([brand(schema.identifier)]);
|
|
95
|
+
return new Set([...normalizeAllowedTypes(schema)].map((item) => brand(item.identifier)));
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
/**
|
|
@@ -58,15 +58,17 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
58
58
|
instance: TreeNodeValid<T>,
|
|
59
59
|
input: T,
|
|
60
60
|
): UnhydratedFlexTreeNode {
|
|
61
|
-
return fail(
|
|
61
|
+
return fail(0xae4 /* Schema must override buildRawNode */);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
65
|
* Schema classes can override to provide a callback that is called once when the first node is constructed.
|
|
66
66
|
* This is a good place to perform extra validation and cache schema derived data needed for the implementation of the node.
|
|
67
|
+
* @remarks
|
|
68
|
+
* It is valid to dereference LazyItem schema references in this function (or anything that runs after it).
|
|
67
69
|
*/
|
|
68
70
|
protected static oneTimeSetup<T>(this: typeof TreeNodeValid<T>): Context {
|
|
69
|
-
fail(
|
|
71
|
+
fail(0xae5 /* Missing oneTimeSetup */);
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
/**
|
|
@@ -119,6 +121,9 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
119
121
|
return this.constructorCached;
|
|
120
122
|
}
|
|
121
123
|
|
|
124
|
+
// If users trying to diagnose the cause of this error becomes a common issue, more information could be captured.
|
|
125
|
+
// The call stack to when a schema is first marked most derived could be captured in debug builds and stored in the `MostDerivedData` object:
|
|
126
|
+
// This could then be included in the error to aid in debugging this error.
|
|
122
127
|
throw new UsageError(
|
|
123
128
|
`Two schema classes were used (${this.name} and ${
|
|
124
129
|
this.constructorCached.constructor.name
|
|
@@ -143,7 +148,7 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
143
148
|
}
|
|
144
149
|
|
|
145
150
|
/**
|
|
146
|
-
*
|
|
151
|
+
* See {@link TreeNodeSchemaCore.createFromInsertable}.
|
|
147
152
|
*/
|
|
148
153
|
public static createFromInsertable<TInput, TOut, TThis extends new (args: TInput) => TOut>(
|
|
149
154
|
this: TThis,
|
|
@@ -152,13 +157,22 @@ export abstract class TreeNodeValid<TInput> extends TreeNode {
|
|
|
152
157
|
return new this(input);
|
|
153
158
|
}
|
|
154
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Idempotent initialization function that pre-caches data and can dereference lazy schema references.
|
|
162
|
+
*/
|
|
163
|
+
public static oneTimeInitialize(
|
|
164
|
+
this: typeof TreeNodeValid & TreeNodeSchema,
|
|
165
|
+
): Required<MostDerivedData> {
|
|
166
|
+
const cache = this.markMostDerived();
|
|
167
|
+
cache.oneTimeInitialized ??= this.oneTimeSetup();
|
|
168
|
+
// Typescript fails to narrow the type of `oneTimeInitialized` to `Context` here, so use a cast:
|
|
169
|
+
return cache as MostDerivedData & { oneTimeInitialized: Context };
|
|
170
|
+
}
|
|
171
|
+
|
|
155
172
|
public constructor(input: TInput | InternalTreeNode) {
|
|
156
173
|
super(privateToken);
|
|
157
174
|
const schema = this.constructor as typeof TreeNodeValid & TreeNodeSchema;
|
|
158
|
-
const cache = schema.
|
|
159
|
-
if (cache.oneTimeInitialized === undefined) {
|
|
160
|
-
cache.oneTimeInitialized = schema.oneTimeSetup();
|
|
161
|
-
}
|
|
175
|
+
const cache = schema.oneTimeInitialize();
|
|
162
176
|
|
|
163
177
|
if (isTreeNode(input)) {
|
|
164
178
|
// TODO: update this once we have better support for deep-copying and move operations.
|