@fluidframework/tree 2.53.1 → 2.60.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 +0 -19
- package/.mocharc.customBenchmarks.cjs +1 -9
- package/CHANGELOG.md +56 -0
- package/api-report/tree.alpha.api.md +50 -36
- package/api-report/tree.beta.api.md +15 -1
- package/api-report/{tree.legacy.alpha.api.md → tree.legacy.beta.api.md} +5 -5
- package/api-report/tree.legacy.public.api.md +1 -1
- package/api-report/tree.public.api.md +1 -1
- package/dist/alpha.d.ts +8 -2
- package/dist/beta.d.ts +3 -0
- package/dist/codec/codec.d.ts +43 -6
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +22 -2
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/index.d.ts +1 -1
- package/dist/codec/index.d.ts.map +1 -1
- package/dist/codec/index.js +4 -1
- package/dist/codec/index.js.map +1 -1
- package/dist/external-utilities/index.d.ts +1 -1
- package/dist/external-utilities/index.d.ts.map +1 -1
- package/dist/external-utilities/index.js +2 -1
- package/dist/external-utilities/index.js.map +1 -1
- package/dist/external-utilities/typeboxValidator.d.ts +6 -1
- package/dist/external-utilities/typeboxValidator.d.ts.map +1 -1
- package/dist/external-utilities/typeboxValidator.js +7 -1
- package/dist/external-utilities/typeboxValidator.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +10 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +28 -5
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +19 -2
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +10 -2
- package/dist/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +59 -4
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +9 -2
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +46 -8
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js +91 -16
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format.d.ts +14 -0
- package/dist/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format.js +10 -1
- package/dist/feature-libraries/chunked-forest/codec/format.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/index.d.ts +1 -1
- package/dist/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/index.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +8 -3
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +17 -6
- package/dist/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/index.d.ts +1 -1
- package/dist/feature-libraries/chunked-forest/index.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/index.js.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.js +3 -0
- package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts +13 -8
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +76 -38
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +178 -0
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -0
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +322 -0
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -0
- package/dist/feature-libraries/forest-summary/index.d.ts +1 -1
- package/dist/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/index.js +2 -1
- package/dist/feature-libraries/forest-summary/index.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +1 -1
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +2 -1
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts +6 -9
- package/dist/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
- package/dist/feature-libraries/treeCompressionUtils.d.ts +15 -0
- package/dist/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
- package/dist/feature-libraries/treeCompressionUtils.js +16 -1
- package/dist/feature-libraries/treeCompressionUtils.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/jsonDomainSchema.d.ts +1 -1
- package/dist/jsonDomainSchema.d.ts.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +23 -6
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +4 -1
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.d.ts +2 -2
- package/dist/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/dist/shared-tree/tree.d.ts.map +1 -1
- package/dist/shared-tree/tree.js +3 -0
- package/dist/shared-tree/tree.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts +9 -11
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +2 -2
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +13 -0
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/sharedTreeAttributes.d.ts +2 -2
- package/dist/sharedTreeAttributes.js +2 -2
- package/dist/sharedTreeAttributes.js.map +1 -1
- package/dist/simple-tree/api/conciseTree.d.ts.map +1 -1
- package/dist/simple-tree/api/conciseTree.js +1 -1
- package/dist/simple-tree/api/conciseTree.js.map +1 -1
- package/dist/simple-tree/api/customTree.d.ts +39 -11
- package/dist/simple-tree/api/customTree.d.ts.map +1 -1
- package/dist/simple-tree/api/customTree.js +79 -19
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/getJsonSchema.d.ts +7 -2
- package/dist/simple-tree/api/getJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/getJsonSchema.js +1 -0
- package/dist/simple-tree/api/getJsonSchema.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 +4 -1
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.d.ts +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 +9 -6
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +8 -7
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts +13 -17
- package/dist/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactoryAlpha.js +21 -25
- package/dist/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/dist/simple-tree/api/schemaFactoryBeta.d.ts +20 -0
- package/dist/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -0
- package/dist/simple-tree/api/schemaFactoryBeta.js +26 -0
- package/dist/simple-tree/api/schemaFactoryBeta.js.map +1 -0
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts +0 -2
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +6 -3
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/transactionTypes.d.ts +1 -0
- package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
- package/dist/simple-tree/api/transactionTypes.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +68 -74
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/dist/simple-tree/api/verboseTree.js +3 -3
- package/dist/simple-tree/api/verboseTree.js.map +1 -1
- package/dist/simple-tree/core/simpleNodeSchemaBase.d.ts +6 -0
- package/dist/simple-tree/core/simpleNodeSchemaBase.d.ts.map +1 -1
- package/dist/simple-tree/core/simpleNodeSchemaBase.js.map +1 -1
- package/dist/simple-tree/fieldSchema.d.ts +3 -4
- package/dist/simple-tree/fieldSchema.d.ts.map +1 -1
- package/dist/simple-tree/fieldSchema.js +0 -3
- package/dist/simple-tree/fieldSchema.js.map +1 -1
- package/dist/simple-tree/index.d.ts +1 -1
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +4 -2
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/record/recordNode.js +2 -3
- package/dist/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/dist/simple-tree/simpleSchema.d.ts +12 -0
- package/dist/simple-tree/simpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/simpleSchema.js.map +1 -1
- package/dist/simple-tree/toStoredSchema.d.ts +0 -3
- package/dist/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/dist/simple-tree/toStoredSchema.js +0 -3
- package/dist/simple-tree/toStoredSchema.js.map +1 -1
- package/dist/tableSchema.d.ts +11 -80
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +200 -117
- package/dist/tableSchema.js.map +1 -1
- package/dist/treeFactory.d.ts +1 -2
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +1 -2
- package/dist/treeFactory.js.map +1 -1
- package/lib/alpha.d.ts +8 -2
- package/lib/beta.d.ts +3 -0
- package/lib/codec/codec.d.ts +43 -6
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +19 -1
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/index.d.ts +1 -1
- package/lib/codec/index.d.ts.map +1 -1
- package/lib/codec/index.js +1 -1
- package/lib/codec/index.js.map +1 -1
- package/lib/external-utilities/index.d.ts +1 -1
- package/lib/external-utilities/index.d.ts.map +1 -1
- package/lib/external-utilities/index.js +1 -1
- package/lib/external-utilities/index.js.map +1 -1
- package/lib/external-utilities/typeboxValidator.d.ts +6 -1
- package/lib/external-utilities/typeboxValidator.d.ts.map +1 -1
- package/lib/external-utilities/typeboxValidator.js +6 -0
- package/lib/external-utilities/typeboxValidator.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +10 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +27 -5
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts +19 -2
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js +10 -2
- package/lib/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +59 -4
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +10 -3
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +46 -8
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js +87 -14
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format.d.ts +14 -0
- package/lib/feature-libraries/chunked-forest/codec/format.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format.js +9 -0
- package/lib/feature-libraries/chunked-forest/codec/format.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/index.d.ts +1 -1
- package/lib/feature-libraries/chunked-forest/codec/index.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/index.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts +8 -3
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js +18 -7
- package/lib/feature-libraries/chunked-forest/codec/schemaBasedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/index.d.ts +1 -1
- package/lib/feature-libraries/chunked-forest/index.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/index.js.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.js +3 -0
- package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts +13 -8
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +75 -37
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +178 -0
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -0
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +318 -0
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -0
- package/lib/feature-libraries/forest-summary/index.d.ts +1 -1
- package/lib/feature-libraries/forest-summary/index.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/index.js +1 -1
- package/lib/feature-libraries/forest-summary/index.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +1 -1
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +1 -1
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +3 -3
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts +6 -9
- package/lib/feature-libraries/modular-schema/modularChangeFormat.d.ts.map +1 -1
- package/lib/feature-libraries/treeCompressionUtils.d.ts +15 -0
- package/lib/feature-libraries/treeCompressionUtils.d.ts.map +1 -1
- package/lib/feature-libraries/treeCompressionUtils.js +15 -0
- package/lib/feature-libraries/treeCompressionUtils.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -4
- package/lib/index.js.map +1 -1
- package/lib/jsonDomainSchema.d.ts +1 -1
- package/lib/jsonDomainSchema.d.ts.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +23 -6
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +4 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.d.ts +2 -2
- package/lib/shared-tree/sharedTreeChangeFamily.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFamily.js.map +1 -1
- package/lib/shared-tree/tree.d.ts.map +1 -1
- package/lib/shared-tree/tree.js +3 -0
- package/lib/shared-tree/tree.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts +9 -11
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +2 -2
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.d.ts.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +13 -0
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/sharedTreeAttributes.d.ts +2 -2
- package/lib/sharedTreeAttributes.js +2 -2
- package/lib/sharedTreeAttributes.js.map +1 -1
- package/lib/simple-tree/api/conciseTree.d.ts.map +1 -1
- package/lib/simple-tree/api/conciseTree.js +2 -2
- package/lib/simple-tree/api/conciseTree.js.map +1 -1
- package/lib/simple-tree/api/customTree.d.ts +39 -11
- package/lib/simple-tree/api/customTree.d.ts.map +1 -1
- package/lib/simple-tree/api/customTree.js +79 -19
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/getJsonSchema.d.ts +7 -2
- package/lib/simple-tree/api/getJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/getJsonSchema.js +1 -0
- package/lib/simple-tree/api/getJsonSchema.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 +2 -1
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.d.ts +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 +9 -6
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +6 -6
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts +13 -17
- package/lib/simple-tree/api/schemaFactoryAlpha.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactoryAlpha.js +22 -26
- package/lib/simple-tree/api/schemaFactoryAlpha.js.map +1 -1
- package/lib/simple-tree/api/schemaFactoryBeta.d.ts +20 -0
- package/lib/simple-tree/api/schemaFactoryBeta.d.ts.map +1 -0
- package/lib/simple-tree/api/schemaFactoryBeta.js +22 -0
- package/lib/simple-tree/api/schemaFactoryBeta.js.map +1 -0
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts +0 -2
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +6 -3
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/transactionTypes.d.ts +1 -0
- package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
- package/lib/simple-tree/api/transactionTypes.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +68 -74
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/api/verboseTree.d.ts.map +1 -1
- package/lib/simple-tree/api/verboseTree.js +4 -4
- package/lib/simple-tree/api/verboseTree.js.map +1 -1
- package/lib/simple-tree/core/simpleNodeSchemaBase.d.ts +6 -0
- package/lib/simple-tree/core/simpleNodeSchemaBase.d.ts.map +1 -1
- package/lib/simple-tree/core/simpleNodeSchemaBase.js.map +1 -1
- package/lib/simple-tree/fieldSchema.d.ts +3 -4
- package/lib/simple-tree/fieldSchema.d.ts.map +1 -1
- package/lib/simple-tree/fieldSchema.js +0 -3
- package/lib/simple-tree/fieldSchema.js.map +1 -1
- package/lib/simple-tree/index.d.ts +1 -1
- 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/node-kinds/record/recordNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/record/recordNode.js +2 -3
- package/lib/simple-tree/node-kinds/record/recordNode.js.map +1 -1
- package/lib/simple-tree/simpleSchema.d.ts +12 -0
- package/lib/simple-tree/simpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/simpleSchema.js.map +1 -1
- package/lib/simple-tree/toStoredSchema.d.ts +0 -3
- package/lib/simple-tree/toStoredSchema.d.ts.map +1 -1
- package/lib/simple-tree/toStoredSchema.js +0 -3
- package/lib/simple-tree/toStoredSchema.js.map +1 -1
- package/lib/tableSchema.d.ts +11 -80
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +201 -118
- package/lib/tableSchema.js.map +1 -1
- package/lib/treeFactory.d.ts +1 -2
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +1 -2
- package/lib/treeFactory.js.map +1 -1
- package/package.json +21 -21
- package/src/codec/codec.ts +52 -7
- package/src/codec/index.ts +4 -0
- package/src/external-utilities/index.ts +1 -1
- package/src/external-utilities/typeboxValidator.ts +7 -1
- package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +38 -4
- package/src/feature-libraries/chunked-forest/codec/chunkDecodingGeneric.ts +10 -3
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +96 -8
- package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +123 -19
- package/src/feature-libraries/chunked-forest/codec/format.ts +11 -0
- package/src/feature-libraries/chunked-forest/codec/index.ts +4 -0
- package/src/feature-libraries/chunked-forest/codec/schemaBasedEncode.ts +28 -3
- package/src/feature-libraries/chunked-forest/index.ts +2 -0
- package/src/feature-libraries/forest-summary/codec.ts +3 -0
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +118 -50
- package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +511 -0
- package/src/feature-libraries/forest-summary/index.ts +1 -1
- package/src/feature-libraries/index.ts +5 -1
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +8 -4
- package/src/feature-libraries/treeCompressionUtils.ts +19 -0
- package/src/index.ts +6 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +1 -1
- package/src/shared-tree/sharedTree.ts +37 -4
- package/src/shared-tree/sharedTreeChangeFamily.ts +2 -2
- package/src/shared-tree/tree.ts +3 -0
- package/src/shared-tree/treeAlpha.ts +10 -11
- package/src/shared-tree/treeCheckout.ts +2 -2
- package/src/shared-tree-core/sharedTreeCore.ts +17 -0
- package/src/sharedTreeAttributes.ts +2 -2
- package/src/simple-tree/api/conciseTree.ts +2 -1
- package/src/simple-tree/api/customTree.ts +102 -32
- package/src/simple-tree/api/getJsonSchema.ts +7 -2
- package/src/simple-tree/api/index.ts +3 -0
- package/src/simple-tree/api/schemaCreationUtilities.ts +1 -1
- package/src/simple-tree/api/schemaFactory.ts +21 -14
- package/src/simple-tree/api/schemaFactoryAlpha.ts +29 -30
- package/src/simple-tree/api/schemaFactoryBeta.ts +28 -0
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +7 -3
- package/src/simple-tree/api/transactionTypes.ts +1 -0
- package/src/simple-tree/api/tree.ts +75 -81
- package/src/simple-tree/api/verboseTree.ts +42 -39
- package/src/simple-tree/core/simpleNodeSchemaBase.ts +6 -0
- package/src/simple-tree/fieldSchema.ts +3 -4
- package/src/simple-tree/index.ts +3 -0
- package/src/simple-tree/node-kinds/record/recordNode.ts +2 -3
- package/src/simple-tree/simpleSchema.ts +12 -0
- package/src/simple-tree/toStoredSchema.ts +0 -3
- package/src/tableSchema.ts +261 -243
- package/src/treeFactory.ts +1 -2
package/src/codec/codec.ts
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import type { ErasedType } from "@fluidframework/core-interfaces/internal";
|
|
6
7
|
import { IsoBuffer, bufferToString } from "@fluid-internal/client-utils";
|
|
7
8
|
import { assert, fail } from "@fluidframework/core-utils/internal";
|
|
8
9
|
import type { Static, TAnySchema, TSchema } from "@sinclair/typebox";
|
|
9
10
|
|
|
10
11
|
import type { ChangeEncodingContext } from "../core/index.js";
|
|
11
12
|
import type { JsonCompatibleReadOnly } from "../util/index.js";
|
|
13
|
+
import { noopValidator } from "./noopValidator.js";
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Translates decoded data to encoded data.
|
|
@@ -44,6 +46,46 @@ export interface SchemaValidationFunction<Schema extends TSchema> {
|
|
|
44
46
|
check(data: unknown): data is Static<Schema>;
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
/**
|
|
50
|
+
* A kind of validator for SharedTree's internal data formats.
|
|
51
|
+
* @remarks
|
|
52
|
+
* Assuming no data corruption or type confusion, such validation should never fail.
|
|
53
|
+
* Any client version compatibility issues should instead be detected by the data format versioning which Shared Tree does internally independent of data format validation.
|
|
54
|
+
* However, persisted data can sometimes be corrupted, bugs can produce invalid data, or users can mix up which data is compatible with which APIs.
|
|
55
|
+
* In such cases, a format validator can help catch issues.
|
|
56
|
+
*
|
|
57
|
+
* Current options are {@link FormatValidatorNoOp} and {@link FormatValidatorBasic}.
|
|
58
|
+
* @privateRemarks
|
|
59
|
+
* Implement using {@link toFormatValidator}.
|
|
60
|
+
* Consume using {@link extractJsonValidator}.
|
|
61
|
+
*
|
|
62
|
+
* Exposing this as the stable API entry point (instead of {@link JsonValidator}) means that we avoid leaking the reference to TypeBox to the API surface.
|
|
63
|
+
* Additionally, if we adopt non JSON formats, we can just update the validators as needed without breaking the API.
|
|
64
|
+
* This also allows us to avoid stabilizing or documenting how handles interact with JSON validation since that is not exposed through this type.
|
|
65
|
+
* @sealed @alpha
|
|
66
|
+
*/
|
|
67
|
+
export interface FormatValidator extends ErasedType<"FormatValidator"> {}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A {@link FormatValidator} which does no validation.
|
|
71
|
+
* @alpha
|
|
72
|
+
*/
|
|
73
|
+
export const FormatValidatorNoOp = toFormatValidator(noopValidator);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Type erase a {@link JsonValidator} to a {@link FormatValidator}.
|
|
77
|
+
*/
|
|
78
|
+
export function toFormatValidator(factory: JsonValidator): FormatValidator {
|
|
79
|
+
return factory as unknown as FormatValidator;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Un-type-erase the {@link FormatValidator}.
|
|
84
|
+
*/
|
|
85
|
+
export function extractJsonValidator(input: FormatValidator | JsonValidator): JsonValidator {
|
|
86
|
+
return input as unknown as JsonValidator;
|
|
87
|
+
}
|
|
88
|
+
|
|
47
89
|
/**
|
|
48
90
|
* JSON schema validator compliant with draft 6 schema. See https://json-schema.org.
|
|
49
91
|
* @alpha @input
|
|
@@ -69,19 +111,22 @@ export interface JsonValidator {
|
|
|
69
111
|
*/
|
|
70
112
|
export interface ICodecOptions {
|
|
71
113
|
/**
|
|
72
|
-
* {@link
|
|
114
|
+
* {@link FormatValidator} which SharedTree uses to validate persisted data it reads & writes
|
|
73
115
|
* matches the expected encoded format (i.e. the wire format for ops and summaries).
|
|
74
|
-
*
|
|
75
|
-
* See {@link
|
|
116
|
+
* @remarks
|
|
117
|
+
* See {@link FormatValidatorNoOp} and {@link FormatValidatorBasic} for out-of-the-box implementations.
|
|
76
118
|
*
|
|
77
119
|
* This option is not "on-by-default" because JSON schema validation comes with a small but noticeable
|
|
78
120
|
* runtime performance cost, and popular schema validation libraries have relatively large bundle size.
|
|
79
121
|
*
|
|
80
|
-
* SharedTree users are still encouraged to use a non-trivial validator (i.e. not `
|
|
122
|
+
* SharedTree users are still encouraged to use a non-trivial validator (i.e. not `FormatValidatorNoOp`)
|
|
81
123
|
* whenever reasonable: it gives better fail-fast behavior when unexpected encoded data is found,
|
|
82
124
|
* which reduces the risk of unrecoverable data corruption.
|
|
125
|
+
*
|
|
126
|
+
* Use of {@link JsonValidator} here is deprecated and will be removed:
|
|
127
|
+
* it is recommended to use {@link FormatValidator} instead.
|
|
83
128
|
*/
|
|
84
|
-
readonly jsonValidator: JsonValidator;
|
|
129
|
+
readonly jsonValidator: JsonValidator | FormatValidator;
|
|
85
130
|
}
|
|
86
131
|
|
|
87
132
|
/**
|
|
@@ -326,12 +371,12 @@ export function withSchemaValidation<
|
|
|
326
371
|
>(
|
|
327
372
|
schema: EncodedSchema,
|
|
328
373
|
codec: IJsonCodec<TInMemoryFormat, TEncodedFormat, TValidate, TContext>,
|
|
329
|
-
validator?: JsonValidator,
|
|
374
|
+
validator?: JsonValidator | FormatValidator,
|
|
330
375
|
): IJsonCodec<TInMemoryFormat, TEncodedFormat, TValidate, TContext> {
|
|
331
376
|
if (!validator) {
|
|
332
377
|
return codec;
|
|
333
378
|
}
|
|
334
|
-
const compiledFormat = validator.compile(schema);
|
|
379
|
+
const compiledFormat = extractJsonValidator(validator).compile(schema);
|
|
335
380
|
return {
|
|
336
381
|
encode: (obj: TInMemoryFormat, context: TContext): TEncodedFormat => {
|
|
337
382
|
const encoded = codec.encode(obj, context);
|
package/src/codec/index.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { Static, TSchema } from "@sinclair/typebox";
|
|
|
8
8
|
// eslint-disable-next-line import/no-internal-modules
|
|
9
9
|
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
10
10
|
|
|
11
|
-
import type
|
|
11
|
+
import { toFormatValidator, type JsonValidator } from "../codec/index.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* A {@link JsonValidator} implementation which uses TypeBox's JSON schema validator.
|
|
@@ -29,3 +29,9 @@ export const typeboxValidator: JsonValidator = {
|
|
|
29
29
|
};
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A {@link FormatValidator} implementation which uses TypeBox's JSON schema validator.
|
|
35
|
+
* @alpha
|
|
36
|
+
*/
|
|
37
|
+
export const FormatValidatorBasic = toFormatValidator(typeboxValidator);
|
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
Value,
|
|
18
18
|
TreeChunk,
|
|
19
19
|
} from "../../../core/index.js";
|
|
20
|
-
import { assertValidIndex } from "../../../util/index.js";
|
|
20
|
+
import { assertValidIndex, brand } from "../../../util/index.js";
|
|
21
21
|
import { BasicChunk } from "../basicChunk.js";
|
|
22
22
|
import { emptyChunk } from "../emptyChunk.js";
|
|
23
23
|
import { SequenceChunk } from "../sequenceChunk.js";
|
|
@@ -41,12 +41,14 @@ import {
|
|
|
41
41
|
type EncodedAnyShape,
|
|
42
42
|
type EncodedChunkShape,
|
|
43
43
|
type EncodedFieldBatch,
|
|
44
|
+
type EncodedIncrementalChunkShape,
|
|
44
45
|
type EncodedInlineArrayShape,
|
|
45
46
|
type EncodedNestedArrayShape,
|
|
46
47
|
type EncodedNodeShape,
|
|
47
48
|
type EncodedValueShape,
|
|
48
49
|
SpecialField,
|
|
49
50
|
} from "./format.js";
|
|
51
|
+
import type { IncrementalDecoder } from "./codecs.js";
|
|
50
52
|
|
|
51
53
|
export interface IdDecodingContext {
|
|
52
54
|
idCompressor: IIdCompressor;
|
|
@@ -61,10 +63,11 @@ export interface IdDecodingContext {
|
|
|
61
63
|
export function decode(
|
|
62
64
|
chunk: EncodedFieldBatch,
|
|
63
65
|
idDecodingContext: { idCompressor: IIdCompressor; originatorId: SessionId },
|
|
66
|
+
incrementalDecoder?: IncrementalDecoder,
|
|
64
67
|
): TreeChunk[] {
|
|
65
68
|
return genericDecode(
|
|
66
69
|
decoderLibrary,
|
|
67
|
-
new DecoderContext(chunk.identifiers, chunk.shapes, idDecodingContext),
|
|
70
|
+
new DecoderContext(chunk.identifiers, chunk.shapes, idDecodingContext, incrementalDecoder),
|
|
68
71
|
chunk,
|
|
69
72
|
anyDecoder,
|
|
70
73
|
);
|
|
@@ -87,6 +90,9 @@ const decoderLibrary = new DiscriminatedUnionDispatcher<
|
|
|
87
90
|
d(shape: EncodedAnyShape): ChunkDecoder {
|
|
88
91
|
return anyDecoder;
|
|
89
92
|
},
|
|
93
|
+
e(shape: EncodedIncrementalChunkShape, cache): ChunkDecoder {
|
|
94
|
+
return new IncrementalChunkDecoder(cache);
|
|
95
|
+
},
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
/**
|
|
@@ -228,6 +234,34 @@ export class InlineArrayDecoder implements ChunkDecoder {
|
|
|
228
234
|
}
|
|
229
235
|
}
|
|
230
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Decoder for {@link EncodedIncrementalChunkShape}s.
|
|
239
|
+
*/
|
|
240
|
+
export class IncrementalChunkDecoder implements ChunkDecoder {
|
|
241
|
+
public constructor(private readonly cache: DecoderContext<EncodedChunkShape>) {}
|
|
242
|
+
public decode(_: readonly ChunkDecoder[], stream: StreamCursor): TreeChunk {
|
|
243
|
+
assert(
|
|
244
|
+
this.cache.incrementalDecoder !== undefined,
|
|
245
|
+
0xc27 /* incremental decoder not available for incremental field decoding */,
|
|
246
|
+
);
|
|
247
|
+
const chunkReferenceId = readStreamNumber(stream);
|
|
248
|
+
const batch = this.cache.incrementalDecoder.getEncodedIncrementalChunk(
|
|
249
|
+
brand(chunkReferenceId),
|
|
250
|
+
);
|
|
251
|
+
assert(batch !== undefined, 0xc28 /* Incremental chunk data missing */);
|
|
252
|
+
// The incremental chunk data is self-describing, i.e., it contain its own shapes list and identifier table.
|
|
253
|
+
// Use these to create a new decoder context to be used to decode the incremental chunk's data.
|
|
254
|
+
const context = new DecoderContext(
|
|
255
|
+
batch.identifiers,
|
|
256
|
+
batch.shapes,
|
|
257
|
+
this.cache.idDecodingContext,
|
|
258
|
+
this.cache.incrementalDecoder,
|
|
259
|
+
);
|
|
260
|
+
const chunks = genericDecode(decoderLibrary, context, batch, anyDecoder);
|
|
261
|
+
return aggregateChunks(chunks);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
231
265
|
/**
|
|
232
266
|
* Decoder for {@link EncodedAnyShape}s.
|
|
233
267
|
*/
|
|
@@ -300,8 +334,8 @@ export class NodeDecoder implements ChunkDecoder {
|
|
|
300
334
|
}
|
|
301
335
|
}
|
|
302
336
|
|
|
303
|
-
for (const
|
|
304
|
-
const [key, content] =
|
|
337
|
+
for (const decoder of this.fieldDecoders) {
|
|
338
|
+
const [key, content] = decoder(decoders, stream);
|
|
305
339
|
addField(key, content);
|
|
306
340
|
}
|
|
307
341
|
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from "./chunkCodecUtilities.js";
|
|
18
18
|
import type { IdDecodingContext } from "./chunkDecoding.js";
|
|
19
19
|
import type { EncodedFieldBatchGeneric, IdentifierOrIndex } from "./formatGeneric.js";
|
|
20
|
+
import type { IncrementalDecoder } from "./codecs.js";
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* General purpose shape based tree decoder which gets its support for specific shapes from the caller.
|
|
@@ -50,13 +51,19 @@ export function decode<TEncodedShape extends object, TContext>(
|
|
|
50
51
|
* Shared data for use in constructing decoders.
|
|
51
52
|
*/
|
|
52
53
|
export class DecoderContext<TEncodedShape = unknown> {
|
|
53
|
-
/**
|
|
54
|
-
* @param identifiers - identifier substitution table (use to replace numeric identifier indexes with the actual identifiers from this table).
|
|
55
|
-
*/
|
|
56
54
|
public constructor(
|
|
55
|
+
/**
|
|
56
|
+
* Identifier substitution table (use to replace numeric identifier indexes with the actual identifiers from this table).
|
|
57
|
+
*/
|
|
57
58
|
public readonly identifiers: readonly string[],
|
|
58
59
|
public readonly shapes: readonly TEncodedShape[],
|
|
59
60
|
public readonly idDecodingContext: IdDecodingContext,
|
|
61
|
+
/**
|
|
62
|
+
* To be used to decode incremental chunks, if any.
|
|
63
|
+
* @remarks
|
|
64
|
+
* See {@link IncrementalDecoder} for more information.
|
|
65
|
+
*/
|
|
66
|
+
public readonly incrementalDecoder: IncrementalDecoder | undefined,
|
|
60
67
|
) {}
|
|
61
68
|
|
|
62
69
|
public identifier<T extends string & BrandedType<string, string>>(
|
|
@@ -12,9 +12,24 @@ import {
|
|
|
12
12
|
type IJsonCodec,
|
|
13
13
|
makeVersionedValidatedCodec,
|
|
14
14
|
} from "../../../codec/index.js";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
import {
|
|
16
|
+
CursorLocationType,
|
|
17
|
+
type FieldKey,
|
|
18
|
+
type ITreeCursorSynchronous,
|
|
19
|
+
type SchemaAndPolicy,
|
|
20
|
+
type TreeChunk,
|
|
21
|
+
type TreeNodeSchemaIdentifier,
|
|
22
|
+
} from "../../../core/index.js";
|
|
23
|
+
import {
|
|
24
|
+
brandedNumberType,
|
|
25
|
+
type Brand,
|
|
26
|
+
type JsonCompatibleReadOnly,
|
|
27
|
+
} from "../../../util/index.js";
|
|
28
|
+
import {
|
|
29
|
+
TreeCompressionStrategy,
|
|
30
|
+
TreeCompressionStrategyExtended,
|
|
31
|
+
type TreeCompressionStrategyPrivate,
|
|
32
|
+
} from "../../treeCompressionUtils.js";
|
|
18
33
|
|
|
19
34
|
import { decode } from "./chunkDecoding.js";
|
|
20
35
|
import type { FieldBatch } from "./fieldBatch.js";
|
|
@@ -22,11 +37,75 @@ import { EncodedFieldBatch, validVersions } from "./format.js";
|
|
|
22
37
|
import { schemaCompressedEncode } from "./schemaBasedEncode.js";
|
|
23
38
|
import { uncompressedEncode } from "./uncompressedEncode.js";
|
|
24
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Reference ID for a chunk that is incrementally encoded.
|
|
42
|
+
*/
|
|
43
|
+
export type ChunkReferenceId = Brand<number, "forest.ChunkReferenceId">;
|
|
44
|
+
const ChunkReferenceId = brandedNumberType<ChunkReferenceId>({ multipleOf: 1, minimum: 0 });
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Properties for incremental encoding.
|
|
48
|
+
* Fields that support incremental encoding will encode their chunks separately by calling `encodeIncrementalField`.
|
|
49
|
+
* @remarks
|
|
50
|
+
* This supports features like incremental summarization where the summary from these fields can be re-used if
|
|
51
|
+
* unchanged between summaries.
|
|
52
|
+
* Note that each of these chunks that are incrementally encoded is fully self-describing (contain its own shapes
|
|
53
|
+
* list and identifier table) and does not rely on context from its parent.
|
|
54
|
+
*/
|
|
55
|
+
export interface IncrementalEncoder {
|
|
56
|
+
/**
|
|
57
|
+
* Returns whether a field should be incrementally encoded.
|
|
58
|
+
* @param nodeIdentifier - The identifier of the node containing the field.
|
|
59
|
+
* @param fieldKey - The key of the field to check.
|
|
60
|
+
*/
|
|
61
|
+
shouldEncodeFieldIncrementally(
|
|
62
|
+
nodeIdentifier: TreeNodeSchemaIdentifier,
|
|
63
|
+
fieldKey: FieldKey,
|
|
64
|
+
): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Called to encode an incremental field at the cursor.
|
|
67
|
+
* The chunks for this field are encoded separately from the main buffer.
|
|
68
|
+
* @param cursor - The cursor pointing to the field to encode.
|
|
69
|
+
* @param chunkEncoder - A function that encodes the contents of the passed chunk in the field.
|
|
70
|
+
* @returns The reference IDs of the encoded chunks in the field.
|
|
71
|
+
* This is used to retrieve the encoded chunks later.
|
|
72
|
+
*/
|
|
73
|
+
encodeIncrementalField(
|
|
74
|
+
cursor: ITreeCursorSynchronous,
|
|
75
|
+
chunkEncoder: (chunk: TreeChunk) => EncodedFieldBatch,
|
|
76
|
+
): ChunkReferenceId[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Properties for incremental decoding.
|
|
81
|
+
*
|
|
82
|
+
* Fields that had their chunks incrementally encoded will retrieve them by calling `getEncodedIncrementalChunk`.
|
|
83
|
+
* @remarks
|
|
84
|
+
* See {@link IncrementalEncoder} for more details.
|
|
85
|
+
*/
|
|
86
|
+
export interface IncrementalDecoder {
|
|
87
|
+
/**
|
|
88
|
+
* Called to get the encoded contents of an chunk in an incremental field with the given reference ID.
|
|
89
|
+
* @param referenceId - The reference ID of the chunk to retrieve.
|
|
90
|
+
* @returns The encoded contents of the chunk.
|
|
91
|
+
*/
|
|
92
|
+
getEncodedIncrementalChunk: (referenceId: ChunkReferenceId) => EncodedFieldBatch;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Combines the properties of {@link IncrementalEncoder} and {@link IncrementalDecoder}.
|
|
96
|
+
*/
|
|
97
|
+
export interface IncrementalEncoderDecoder extends IncrementalEncoder, IncrementalDecoder {}
|
|
98
|
+
|
|
25
99
|
export interface FieldBatchEncodingContext {
|
|
26
|
-
readonly encodeType:
|
|
100
|
+
readonly encodeType: TreeCompressionStrategyPrivate;
|
|
27
101
|
readonly idCompressor: IIdCompressor;
|
|
28
102
|
readonly originatorId: SessionId;
|
|
29
103
|
readonly schema?: SchemaAndPolicy;
|
|
104
|
+
/**
|
|
105
|
+
* An encoder / decoder for encoding and decoding of incremental fields.
|
|
106
|
+
* This will be defined if incremental encoding is supported and enabled.
|
|
107
|
+
*/
|
|
108
|
+
readonly incrementalEncoderDecoder?: IncrementalEncoderDecoder;
|
|
30
109
|
}
|
|
31
110
|
/**
|
|
32
111
|
* @remarks
|
|
@@ -78,6 +157,7 @@ export function makeFieldBatchCodec(
|
|
|
78
157
|
case TreeCompressionStrategy.Uncompressed:
|
|
79
158
|
encoded = uncompressedEncode(data);
|
|
80
159
|
break;
|
|
160
|
+
case TreeCompressionStrategyExtended.CompressedIncremental:
|
|
81
161
|
case TreeCompressionStrategy.Compressed:
|
|
82
162
|
// eslint-disable-next-line unicorn/prefer-ternary
|
|
83
163
|
if (context.schema !== undefined) {
|
|
@@ -86,6 +166,10 @@ export function makeFieldBatchCodec(
|
|
|
86
166
|
context.schema.policy,
|
|
87
167
|
data,
|
|
88
168
|
context.idCompressor,
|
|
169
|
+
// Incremental encoding is only supported for CompressedIncremental.
|
|
170
|
+
context.encodeType === TreeCompressionStrategyExtended.CompressedIncremental
|
|
171
|
+
? context.incrementalEncoderDecoder
|
|
172
|
+
: undefined,
|
|
89
173
|
);
|
|
90
174
|
} else {
|
|
91
175
|
// TODO: consider enabling a somewhat compressed but not schema accelerated encode.
|
|
@@ -102,10 +186,14 @@ export function makeFieldBatchCodec(
|
|
|
102
186
|
},
|
|
103
187
|
decode: (data: EncodedFieldBatch, context: FieldBatchEncodingContext): FieldBatch => {
|
|
104
188
|
// TODO: consider checking data is in schema.
|
|
105
|
-
return decode(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
189
|
+
return decode(
|
|
190
|
+
data,
|
|
191
|
+
{
|
|
192
|
+
idCompressor: context.idCompressor,
|
|
193
|
+
originatorId: context.originatorId,
|
|
194
|
+
},
|
|
195
|
+
context.incrementalEncoderDecoder,
|
|
196
|
+
).map((chunk) => chunk.cursor());
|
|
109
197
|
},
|
|
110
198
|
});
|
|
111
199
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type FieldKey,
|
|
12
12
|
type FieldKindIdentifier,
|
|
13
13
|
type ITreeCursorSynchronous,
|
|
14
|
+
type TreeChunk,
|
|
14
15
|
type TreeFieldStoredSchema,
|
|
15
16
|
type TreeNodeSchemaIdentifier,
|
|
16
17
|
type Value,
|
|
@@ -35,9 +36,10 @@ import {
|
|
|
35
36
|
SpecialField,
|
|
36
37
|
version,
|
|
37
38
|
} from "./format.js";
|
|
39
|
+
import type { ChunkReferenceId, IncrementalEncoder } from "./codecs.js";
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
|
-
* Encode data from `FieldBatch` into an `
|
|
42
|
+
* Encode data from `FieldBatch` into an `EncodedFieldBatch`.
|
|
41
43
|
*
|
|
42
44
|
* Optimized for encoded size and encoding performance.
|
|
43
45
|
*
|
|
@@ -347,22 +349,48 @@ export class InlineArrayEncoder
|
|
|
347
349
|
}
|
|
348
350
|
}
|
|
349
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Encodes the shape for a nested array as {@link EncodedNestedArray} shape.
|
|
354
|
+
*/
|
|
355
|
+
export class NestedArrayShape extends ShapeGeneric<EncodedChunkShape> {
|
|
356
|
+
/**
|
|
357
|
+
* @param innerShape - The shape of each item in this nested array.
|
|
358
|
+
*/
|
|
359
|
+
public constructor(public readonly innerShape: Shape) {
|
|
360
|
+
super();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
public encodeShape(
|
|
364
|
+
identifiers: DeduplicationTable<string>,
|
|
365
|
+
shapes: DeduplicationTable<Shape>,
|
|
366
|
+
): EncodedChunkShape {
|
|
367
|
+
const shape: EncodedNestedArrayShape =
|
|
368
|
+
shapes.valueToIndex.get(this.innerShape) ??
|
|
369
|
+
fail(0xb4f /* index for shape not found in table */);
|
|
370
|
+
return {
|
|
371
|
+
a: shape,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
public countReferencedShapesAndIdentifiers(
|
|
376
|
+
identifiers: Counter<string>,
|
|
377
|
+
shapeDiscovered: (shape: Shape) => void,
|
|
378
|
+
): void {
|
|
379
|
+
shapeDiscovered(this.innerShape);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
350
383
|
/**
|
|
351
384
|
* Encodes a field as a nested array with the {@link EncodedNestedArrayShape} shape.
|
|
352
385
|
* @remarks
|
|
353
|
-
* The fact this is also a Shape is an implementation detail
|
|
386
|
+
* The fact this is also exposes a Shape is an implementation detail: it allows the shape it uses to be itself
|
|
354
387
|
* which is an easy way to keep all the related code together without extra objects.
|
|
355
388
|
*/
|
|
356
|
-
export class NestedArrayEncoder
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
public constructor(public readonly inner: NodeEncoder) {
|
|
363
|
-
super();
|
|
364
|
-
this.shape = this;
|
|
365
|
-
}
|
|
389
|
+
export class NestedArrayEncoder implements FieldEncoder {
|
|
390
|
+
public constructor(
|
|
391
|
+
public readonly innerEncoder: NodeEncoder,
|
|
392
|
+
public readonly shape: NestedArrayShape = new NestedArrayShape(innerEncoder.shape),
|
|
393
|
+
) {}
|
|
366
394
|
|
|
367
395
|
public encodeField(
|
|
368
396
|
cursor: ITreeCursorSynchronous,
|
|
@@ -374,7 +402,7 @@ export class NestedArrayEncoder
|
|
|
374
402
|
const length = cursor.getFieldLength();
|
|
375
403
|
forEachNode(cursor, () => {
|
|
376
404
|
const before = buffer.length;
|
|
377
|
-
this.
|
|
405
|
+
this.innerEncoder.encodeNode(cursor, context, buffer);
|
|
378
406
|
allNonZeroSize &&= buffer.length - before !== 0;
|
|
379
407
|
});
|
|
380
408
|
if (buffer.length === 0) {
|
|
@@ -389,27 +417,77 @@ export class NestedArrayEncoder
|
|
|
389
417
|
outputBuffer.push(buffer);
|
|
390
418
|
}
|
|
391
419
|
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Encodes a chunk with the {@link EncodedIncrementalChunkShape} shape.
|
|
424
|
+
* This chunks will be encoded separately, i.e., the contents of the chunk will not be part of the main buffer.
|
|
425
|
+
* A reference to the chunk will be stored in the main buffer as an {@link ChunkReferenceId}.
|
|
426
|
+
*/
|
|
427
|
+
export class IncrementalChunkShape extends ShapeGeneric<EncodedChunkShape> {
|
|
428
|
+
/**
|
|
429
|
+
* Encodes all the nodes in the chunk at the cursor position using `InlineArrayShape`.
|
|
430
|
+
*/
|
|
431
|
+
public static encodeChunk(chunk: TreeChunk, context: EncoderContext): BufferFormat {
|
|
432
|
+
const chunkOutputBuffer: BufferFormat = [];
|
|
433
|
+
const nodesEncoder = asNodesEncoder(anyNodeEncoder);
|
|
434
|
+
const chunkCursor = chunk.cursor();
|
|
435
|
+
chunkCursor.firstNode();
|
|
436
|
+
const chunkLength = chunkCursor.chunkLength;
|
|
437
|
+
for (let index = 0; index < chunkLength; index++) {
|
|
438
|
+
nodesEncoder.encodeNodes(chunkCursor, context, chunkOutputBuffer);
|
|
439
|
+
}
|
|
440
|
+
assert(
|
|
441
|
+
chunkCursor.mode === CursorLocationType.Fields,
|
|
442
|
+
0xc29 /* should return to fields mode when finished encoding */,
|
|
443
|
+
);
|
|
444
|
+
return chunkOutputBuffer;
|
|
445
|
+
}
|
|
392
446
|
|
|
393
447
|
public encodeShape(
|
|
394
448
|
identifiers: DeduplicationTable<string>,
|
|
395
449
|
shapes: DeduplicationTable<Shape>,
|
|
396
450
|
): EncodedChunkShape {
|
|
397
|
-
const shape: EncodedNestedArrayShape =
|
|
398
|
-
shapes.valueToIndex.get(this.inner.shape) ??
|
|
399
|
-
fail(0xb4f /* index for shape not found in table */);
|
|
400
451
|
return {
|
|
401
|
-
|
|
452
|
+
e: 0 /* EncodedIncrementalChunkShape */,
|
|
402
453
|
};
|
|
403
454
|
}
|
|
404
455
|
|
|
405
456
|
public countReferencedShapesAndIdentifiers(
|
|
406
457
|
identifiers: Counter<string>,
|
|
407
458
|
shapeDiscovered: (shape: Shape) => void,
|
|
408
|
-
): void {
|
|
409
|
-
|
|
459
|
+
): void {}
|
|
460
|
+
|
|
461
|
+
public get shape(): this {
|
|
462
|
+
return this;
|
|
410
463
|
}
|
|
411
464
|
}
|
|
412
465
|
|
|
466
|
+
/**
|
|
467
|
+
* Encodes an incremental field whose chunks are encoded separately and referenced by their {@link ChunkReferenceId}.
|
|
468
|
+
* The shape of the content of this field is {@link NestedShape} where the items in the array are
|
|
469
|
+
* the {@link ChunkReferenceId}s of the encoded chunks.
|
|
470
|
+
*/
|
|
471
|
+
export const incrementalFieldEncoder: FieldEncoder = {
|
|
472
|
+
encodeField(
|
|
473
|
+
cursor: ITreeCursorSynchronous,
|
|
474
|
+
context: EncoderContext,
|
|
475
|
+
outputBuffer: BufferFormat,
|
|
476
|
+
): void {
|
|
477
|
+
assert(
|
|
478
|
+
context.shouldEncodeIncrementally,
|
|
479
|
+
0xc2a /* incremental encoding must be enabled to use IncrementalFieldShape */,
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
const chunkReferenceIds = context.encodeIncrementalField(cursor, (chunk: TreeChunk) =>
|
|
483
|
+
IncrementalChunkShape.encodeChunk(chunk, context),
|
|
484
|
+
);
|
|
485
|
+
outputBuffer.push(chunkReferenceIds);
|
|
486
|
+
},
|
|
487
|
+
|
|
488
|
+
shape: new NestedArrayShape(new IncrementalChunkShape() /* innerShape */),
|
|
489
|
+
};
|
|
490
|
+
|
|
413
491
|
/**
|
|
414
492
|
* Encode `value` with `shape` into `outputBuffer`.
|
|
415
493
|
*
|
|
@@ -448,6 +526,7 @@ export function encodeValue(
|
|
|
448
526
|
/**
|
|
449
527
|
* Provides common contextual information during encoding, like schema and policy settings.
|
|
450
528
|
* Also, provides a cache to avoid duplicating equivalent shapes during a batch of encode operations.
|
|
529
|
+
* @remarks
|
|
451
530
|
* To avoid Shape duplication, any Shapes used in the encoding should either be:
|
|
452
531
|
* - Singletons defined in a static scope.
|
|
453
532
|
* - Cached in this object for future reuse such that all equivalent Shapes are deduplicated.
|
|
@@ -461,6 +540,7 @@ export class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {
|
|
|
461
540
|
private readonly fieldEncoderFromPolicy: FieldEncoderPolicy,
|
|
462
541
|
public readonly fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,
|
|
463
542
|
public readonly idCompressor: IIdCompressor,
|
|
543
|
+
private readonly incrementalEncoder: IncrementalEncoder | undefined,
|
|
464
544
|
) {}
|
|
465
545
|
|
|
466
546
|
public nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder {
|
|
@@ -476,6 +556,30 @@ export class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {
|
|
|
476
556
|
public nestedArrayEncoder(inner: NodeEncoder): NestedArrayEncoder {
|
|
477
557
|
return getOrCreate(this.nestedArrayEncoders, inner, () => new NestedArrayEncoder(inner));
|
|
478
558
|
}
|
|
559
|
+
|
|
560
|
+
public get shouldEncodeIncrementally(): boolean {
|
|
561
|
+
return this.incrementalEncoder !== undefined;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* {@link IncrementalEncoder.encodeIncrementalField}
|
|
566
|
+
*/
|
|
567
|
+
public encodeIncrementalField(
|
|
568
|
+
cursor: ITreeCursorSynchronous,
|
|
569
|
+
encoder: (chunk: TreeChunk) => BufferFormat,
|
|
570
|
+
): ChunkReferenceId[] {
|
|
571
|
+
assert(
|
|
572
|
+
this.incrementalEncoder !== undefined,
|
|
573
|
+
0xc2b /* incremental encoding must be enabled */,
|
|
574
|
+
);
|
|
575
|
+
// Encoder for the chunk that encodes its data using the provided encoder function and
|
|
576
|
+
// updates the encoded data for shapes and identifiers.
|
|
577
|
+
const chunkEncoder = (chunk: TreeChunk): EncodedFieldBatch => {
|
|
578
|
+
const chunkOutputBuffer = encoder(chunk);
|
|
579
|
+
return updateShapesAndIdentifiersEncoding(version, [chunkOutputBuffer]);
|
|
580
|
+
};
|
|
581
|
+
return this.incrementalEncoder.encodeIncrementalField(cursor, chunkEncoder);
|
|
582
|
+
}
|
|
479
583
|
}
|
|
480
584
|
|
|
481
585
|
export interface NodeEncodeBuilder {
|
|
@@ -47,6 +47,12 @@ export const EncodedInlineArrayShape = Type.Object(
|
|
|
47
47
|
*/
|
|
48
48
|
export const EncodedAnyShape = Type.Literal(0);
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Encoded content is a {@link ChunkReferenceId}.
|
|
52
|
+
* This represents the shape of a chunk that is encoded separately and is referenced by its {@link ChunkReferenceId}.
|
|
53
|
+
*/
|
|
54
|
+
export const EncodedIncrementalChunkShape = Type.Literal(0);
|
|
55
|
+
|
|
50
56
|
/**
|
|
51
57
|
* Content of the encoded field is specified by the Shape referenced by the ShapeIndex.
|
|
52
58
|
* This is a tuple for conciseness.
|
|
@@ -185,6 +191,10 @@ export const EncodedChunkShape = Type.Object(
|
|
|
185
191
|
* {@link EncodedAnyShape} union member.
|
|
186
192
|
*/
|
|
187
193
|
d: Type.Optional(EncodedAnyShape),
|
|
194
|
+
/**
|
|
195
|
+
* {@link EncodedIncrementalChunkShape} union member.
|
|
196
|
+
*/
|
|
197
|
+
e: Type.Optional(EncodedIncrementalChunkShape),
|
|
188
198
|
},
|
|
189
199
|
unionOptions,
|
|
190
200
|
);
|
|
@@ -195,6 +205,7 @@ export type EncodedNestedArrayShape = Static<typeof EncodedNestedArrayShape>;
|
|
|
195
205
|
export type EncodedInlineArrayShape = Static<typeof EncodedInlineArrayShape>;
|
|
196
206
|
export type EncodedNodeShape = Static<typeof EncodedNodeShape>;
|
|
197
207
|
export type EncodedAnyShape = Static<typeof EncodedAnyShape>;
|
|
208
|
+
export type EncodedIncrementalChunkShape = Static<typeof EncodedIncrementalChunkShape>;
|
|
198
209
|
|
|
199
210
|
export const EncodedFieldBatch = EncodedFieldBatchGeneric(version, EncodedChunkShape);
|
|
200
211
|
export type EncodedFieldBatch = Static<typeof EncodedFieldBatch>;
|