@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
|
@@ -4,16 +4,71 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { IIdCompressor, SessionId } from "@fluidframework/id-compressor";
|
|
6
6
|
import { type FluidClientVersion, type ICodecOptions, type IJsonCodec } from "../../../codec/index.js";
|
|
7
|
-
import { type SchemaAndPolicy } from "../../../core/index.js";
|
|
8
|
-
import type
|
|
9
|
-
import {
|
|
7
|
+
import { type FieldKey, type ITreeCursorSynchronous, type SchemaAndPolicy, type TreeChunk, type TreeNodeSchemaIdentifier } from "../../../core/index.js";
|
|
8
|
+
import { type Brand, type JsonCompatibleReadOnly } from "../../../util/index.js";
|
|
9
|
+
import { type TreeCompressionStrategyPrivate } from "../../treeCompressionUtils.js";
|
|
10
10
|
import type { FieldBatch } from "./fieldBatch.js";
|
|
11
11
|
import { EncodedFieldBatch } from "./format.js";
|
|
12
|
+
/**
|
|
13
|
+
* Reference ID for a chunk that is incrementally encoded.
|
|
14
|
+
*/
|
|
15
|
+
export type ChunkReferenceId = Brand<number, "forest.ChunkReferenceId">;
|
|
16
|
+
/**
|
|
17
|
+
* Properties for incremental encoding.
|
|
18
|
+
* Fields that support incremental encoding will encode their chunks separately by calling `encodeIncrementalField`.
|
|
19
|
+
* @remarks
|
|
20
|
+
* This supports features like incremental summarization where the summary from these fields can be re-used if
|
|
21
|
+
* unchanged between summaries.
|
|
22
|
+
* Note that each of these chunks that are incrementally encoded is fully self-describing (contain its own shapes
|
|
23
|
+
* list and identifier table) and does not rely on context from its parent.
|
|
24
|
+
*/
|
|
25
|
+
export interface IncrementalEncoder {
|
|
26
|
+
/**
|
|
27
|
+
* Returns whether a field should be incrementally encoded.
|
|
28
|
+
* @param nodeIdentifier - The identifier of the node containing the field.
|
|
29
|
+
* @param fieldKey - The key of the field to check.
|
|
30
|
+
*/
|
|
31
|
+
shouldEncodeFieldIncrementally(nodeIdentifier: TreeNodeSchemaIdentifier, fieldKey: FieldKey): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Called to encode an incremental field at the cursor.
|
|
34
|
+
* The chunks for this field are encoded separately from the main buffer.
|
|
35
|
+
* @param cursor - The cursor pointing to the field to encode.
|
|
36
|
+
* @param chunkEncoder - A function that encodes the contents of the passed chunk in the field.
|
|
37
|
+
* @returns The reference IDs of the encoded chunks in the field.
|
|
38
|
+
* This is used to retrieve the encoded chunks later.
|
|
39
|
+
*/
|
|
40
|
+
encodeIncrementalField(cursor: ITreeCursorSynchronous, chunkEncoder: (chunk: TreeChunk) => EncodedFieldBatch): ChunkReferenceId[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Properties for incremental decoding.
|
|
44
|
+
*
|
|
45
|
+
* Fields that had their chunks incrementally encoded will retrieve them by calling `getEncodedIncrementalChunk`.
|
|
46
|
+
* @remarks
|
|
47
|
+
* See {@link IncrementalEncoder} for more details.
|
|
48
|
+
*/
|
|
49
|
+
export interface IncrementalDecoder {
|
|
50
|
+
/**
|
|
51
|
+
* Called to get the encoded contents of an chunk in an incremental field with the given reference ID.
|
|
52
|
+
* @param referenceId - The reference ID of the chunk to retrieve.
|
|
53
|
+
* @returns The encoded contents of the chunk.
|
|
54
|
+
*/
|
|
55
|
+
getEncodedIncrementalChunk: (referenceId: ChunkReferenceId) => EncodedFieldBatch;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Combines the properties of {@link IncrementalEncoder} and {@link IncrementalDecoder}.
|
|
59
|
+
*/
|
|
60
|
+
export interface IncrementalEncoderDecoder extends IncrementalEncoder, IncrementalDecoder {
|
|
61
|
+
}
|
|
12
62
|
export interface FieldBatchEncodingContext {
|
|
13
|
-
readonly encodeType:
|
|
63
|
+
readonly encodeType: TreeCompressionStrategyPrivate;
|
|
14
64
|
readonly idCompressor: IIdCompressor;
|
|
15
65
|
readonly originatorId: SessionId;
|
|
16
66
|
readonly schema?: SchemaAndPolicy;
|
|
67
|
+
/**
|
|
68
|
+
* An encoder / decoder for encoding and decoding of incremental fields.
|
|
69
|
+
* This will be defined if incremental encoding is supported and enabled.
|
|
70
|
+
*/
|
|
71
|
+
readonly incrementalEncoderDecoder?: IncrementalEncoderDecoder;
|
|
17
72
|
}
|
|
18
73
|
/**
|
|
19
74
|
* @remarks
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codecs.d.ts","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/codecs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE9E,OAAO,EACN,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,MAAM,yBAAyB,CAAC;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"codecs.d.ts","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/codecs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE9E,OAAO,EACN,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAEN,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,wBAAwB,EAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEN,KAAK,KAAK,EACV,KAAK,sBAAsB,EAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAGN,KAAK,8BAA8B,EACnC,MAAM,+BAA+B,CAAC;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAiB,MAAM,aAAa,CAAC;AAI/D;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;AAGxE;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;OAIG;IACH,8BAA8B,CAC7B,cAAc,EAAE,wBAAwB,EACxC,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC;IACX;;;;;;;OAOG;IACH,sBAAsB,CACrB,MAAM,EAAE,sBAAsB,EAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,iBAAiB,GACnD,gBAAgB,EAAE,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;OAIG;IACH,0BAA0B,EAAE,CAAC,WAAW,EAAE,gBAAgB,KAAK,iBAAiB,CAAC;CACjF;AACD;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB,EAAE,kBAAkB;CAAG;AAE5F,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,UAAU,EAAE,8BAA8B,CAAC;IACpD,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,yBAAyB,CAAC,EAAE,yBAAyB,CAAC;CAC/D;AACD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,CACvC,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,yBAAyB,CACzB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,yCAAyC,CACxD,sBAAsB,EAAE,kBAAkB,GACxC,MAAM,CAGR;AAED,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,MAAM,GAClB,eAAe,CA+DjB"}
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
|
|
6
6
|
import { makeVersionedValidatedCodec, } from "../../../codec/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { brandedNumberType, } from "../../../util/index.js";
|
|
8
|
+
import { TreeCompressionStrategy, TreeCompressionStrategyExtended, } from "../../treeCompressionUtils.js";
|
|
8
9
|
import { decode } from "./chunkDecoding.js";
|
|
9
10
|
import { EncodedFieldBatch, validVersions } from "./format.js";
|
|
10
11
|
import { schemaCompressedEncode } from "./schemaBasedEncode.js";
|
|
11
12
|
import { uncompressedEncode } from "./uncompressedEncode.js";
|
|
13
|
+
const ChunkReferenceId = brandedNumberType({ multipleOf: 1, minimum: 0 });
|
|
12
14
|
/**
|
|
13
15
|
* Get the write version for {@link makeFieldBatchCodec} based on the `oldestCompatibleClient` version.
|
|
14
16
|
* @privateRemarks
|
|
@@ -35,10 +37,15 @@ export function makeFieldBatchCodec(options, writeVersion) {
|
|
|
35
37
|
case TreeCompressionStrategy.Uncompressed:
|
|
36
38
|
encoded = uncompressedEncode(data);
|
|
37
39
|
break;
|
|
40
|
+
case TreeCompressionStrategyExtended.CompressedIncremental:
|
|
38
41
|
case TreeCompressionStrategy.Compressed:
|
|
39
42
|
// eslint-disable-next-line unicorn/prefer-ternary
|
|
40
43
|
if (context.schema !== undefined) {
|
|
41
|
-
encoded = schemaCompressedEncode(context.schema.schema, context.schema.policy, data, context.idCompressor
|
|
44
|
+
encoded = schemaCompressedEncode(context.schema.schema, context.schema.policy, data, context.idCompressor,
|
|
45
|
+
// Incremental encoding is only supported for CompressedIncremental.
|
|
46
|
+
context.encodeType === TreeCompressionStrategyExtended.CompressedIncremental
|
|
47
|
+
? context.incrementalEncoderDecoder
|
|
48
|
+
: undefined);
|
|
42
49
|
}
|
|
43
50
|
else {
|
|
44
51
|
// TODO: consider enabling a somewhat compressed but not schema accelerated encode.
|
|
@@ -56,7 +63,7 @@ export function makeFieldBatchCodec(options, writeVersion) {
|
|
|
56
63
|
return decode(data, {
|
|
57
64
|
idCompressor: context.idCompressor,
|
|
58
65
|
originatorId: context.originatorId,
|
|
59
|
-
}).map((chunk) => chunk.cursor());
|
|
66
|
+
}, context.incrementalEncoderDecoder).map((chunk) => chunk.cursor());
|
|
60
67
|
},
|
|
61
68
|
});
|
|
62
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/codecs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAG9E,OAAO,EAIN,2BAA2B,GAC3B,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/codecs.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type { IIdCompressor, SessionId } from \"@fluidframework/id-compressor\";\n\nimport {\n\ttype FluidClientVersion,\n\ttype ICodecOptions,\n\ttype IJsonCodec,\n\tmakeVersionedValidatedCodec,\n} from \"../../../codec/index.js\";\nimport {\n\tCursorLocationType,\n\ttype FieldKey,\n\ttype ITreeCursorSynchronous,\n\ttype SchemaAndPolicy,\n\ttype TreeChunk,\n\ttype TreeNodeSchemaIdentifier,\n} from \"../../../core/index.js\";\nimport {\n\tbrandedNumberType,\n\ttype Brand,\n\ttype JsonCompatibleReadOnly,\n} from \"../../../util/index.js\";\nimport {\n\tTreeCompressionStrategy,\n\tTreeCompressionStrategyExtended,\n\ttype TreeCompressionStrategyPrivate,\n} from \"../../treeCompressionUtils.js\";\n\nimport { decode } from \"./chunkDecoding.js\";\nimport type { FieldBatch } from \"./fieldBatch.js\";\nimport { EncodedFieldBatch, validVersions } from \"./format.js\";\nimport { schemaCompressedEncode } from \"./schemaBasedEncode.js\";\nimport { uncompressedEncode } from \"./uncompressedEncode.js\";\n\n/**\n * Reference ID for a chunk that is incrementally encoded.\n */\nexport type ChunkReferenceId = Brand<number, \"forest.ChunkReferenceId\">;\nconst ChunkReferenceId = brandedNumberType<ChunkReferenceId>({ multipleOf: 1, minimum: 0 });\n\n/**\n * Properties for incremental encoding.\n * Fields that support incremental encoding will encode their chunks separately by calling `encodeIncrementalField`.\n * @remarks\n * This supports features like incremental summarization where the summary from these fields can be re-used if\n * unchanged between summaries.\n * Note that each of these chunks that are incrementally encoded is fully self-describing (contain its own shapes\n * list and identifier table) and does not rely on context from its parent.\n */\nexport interface IncrementalEncoder {\n\t/**\n\t * Returns whether a field should be incrementally encoded.\n\t * @param nodeIdentifier - The identifier of the node containing the field.\n\t * @param fieldKey - The key of the field to check.\n\t */\n\tshouldEncodeFieldIncrementally(\n\t\tnodeIdentifier: TreeNodeSchemaIdentifier,\n\t\tfieldKey: FieldKey,\n\t): boolean;\n\t/**\n\t * Called to encode an incremental field at the cursor.\n\t * The chunks for this field are encoded separately from the main buffer.\n\t * @param cursor - The cursor pointing to the field to encode.\n\t * @param chunkEncoder - A function that encodes the contents of the passed chunk in the field.\n\t * @returns The reference IDs of the encoded chunks in the field.\n\t * This is used to retrieve the encoded chunks later.\n\t */\n\tencodeIncrementalField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tchunkEncoder: (chunk: TreeChunk) => EncodedFieldBatch,\n\t): ChunkReferenceId[];\n}\n\n/**\n * Properties for incremental decoding.\n *\n * Fields that had their chunks incrementally encoded will retrieve them by calling `getEncodedIncrementalChunk`.\n * @remarks\n * See {@link IncrementalEncoder} for more details.\n */\nexport interface IncrementalDecoder {\n\t/**\n\t * Called to get the encoded contents of an chunk in an incremental field with the given reference ID.\n\t * @param referenceId - The reference ID of the chunk to retrieve.\n\t * @returns The encoded contents of the chunk.\n\t */\n\tgetEncodedIncrementalChunk: (referenceId: ChunkReferenceId) => EncodedFieldBatch;\n}\n/**\n * Combines the properties of {@link IncrementalEncoder} and {@link IncrementalDecoder}.\n */\nexport interface IncrementalEncoderDecoder extends IncrementalEncoder, IncrementalDecoder {}\n\nexport interface FieldBatchEncodingContext {\n\treadonly encodeType: TreeCompressionStrategyPrivate;\n\treadonly idCompressor: IIdCompressor;\n\treadonly originatorId: SessionId;\n\treadonly schema?: SchemaAndPolicy;\n\t/**\n\t * An encoder / decoder for encoding and decoding of incremental fields.\n\t * This will be defined if incremental encoding is supported and enabled.\n\t */\n\treadonly incrementalEncoderDecoder?: IncrementalEncoderDecoder;\n}\n/**\n * @remarks\n * Fields in this batch currently don't have field schema for the root, which limits optimizations.\n */\nexport type FieldBatchCodec = IJsonCodec<\n\tFieldBatch,\n\tEncodedFieldBatch,\n\tJsonCompatibleReadOnly,\n\tFieldBatchEncodingContext\n>;\n\n/**\n * Get the write version for {@link makeFieldBatchCodec} based on the `oldestCompatibleClient` version.\n * @privateRemarks\n * TODO: makeFieldBatchCodec (and makeVersionDispatchingCodec transitively) should bake in this versionToFormat logic and the resulting codec can then support use with FluidClientVersion directly.\n */\nexport function fluidVersionToFieldBatchCodecWriteVersion(\n\toldestCompatibleClient: FluidClientVersion,\n): number {\n\t// There is currently on only 1 version.\n\treturn 1;\n}\n\nexport function makeFieldBatchCodec(\n\toptions: ICodecOptions,\n\twriteVersion: number,\n): FieldBatchCodec {\n\t// Note: it's important that the decode function is schema-agnostic for this strategy/layering to work, since\n\t// the schema that an op was encoded in doesn't necessarily match the current schema for the document (e.g. if\n\t// decode is being run on a client that just submitted a schema change, but the op is from another client who has\n\t// yet to receive that change).\n\tassert(\n\t\tvalidVersions.has(writeVersion),\n\t\t0x935 /* Invalid write version for FieldBatch codec */,\n\t);\n\n\t// TODO: use makeVersionDispatchingCodec to support adding more versions in the future.\n\treturn makeVersionedValidatedCodec(options, validVersions, EncodedFieldBatch, {\n\t\tencode: (data: FieldBatch, context: FieldBatchEncodingContext): EncodedFieldBatch => {\n\t\t\tfor (const cursor of data) {\n\t\t\t\tassert(\n\t\t\t\t\tcursor.mode === CursorLocationType.Fields,\n\t\t\t\t\t0x8a3 /* FieldBatch expects fields cursors */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tlet encoded: EncodedFieldBatch;\n\t\t\tswitch (context.encodeType) {\n\t\t\t\tcase TreeCompressionStrategy.Uncompressed:\n\t\t\t\t\tencoded = uncompressedEncode(data);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TreeCompressionStrategyExtended.CompressedIncremental:\n\t\t\t\tcase TreeCompressionStrategy.Compressed:\n\t\t\t\t\t// eslint-disable-next-line unicorn/prefer-ternary\n\t\t\t\t\tif (context.schema !== undefined) {\n\t\t\t\t\t\tencoded = schemaCompressedEncode(\n\t\t\t\t\t\t\tcontext.schema.schema,\n\t\t\t\t\t\t\tcontext.schema.policy,\n\t\t\t\t\t\t\tdata,\n\t\t\t\t\t\t\tcontext.idCompressor,\n\t\t\t\t\t\t\t// Incremental encoding is only supported for CompressedIncremental.\n\t\t\t\t\t\t\tcontext.encodeType === TreeCompressionStrategyExtended.CompressedIncremental\n\t\t\t\t\t\t\t\t? context.incrementalEncoderDecoder\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// TODO: consider enabling a somewhat compressed but not schema accelerated encode.\n\t\t\t\t\t\tencoded = uncompressedEncode(data);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tunreachableCase(context.encodeType);\n\t\t\t}\n\n\t\t\t// TODO: consider checking input data was in schema.\n\t\t\treturn encoded;\n\t\t},\n\t\tdecode: (data: EncodedFieldBatch, context: FieldBatchEncodingContext): FieldBatch => {\n\t\t\t// TODO: consider checking data is in schema.\n\t\t\treturn decode(\n\t\t\t\tdata,\n\t\t\t\t{\n\t\t\t\t\tidCompressor: context.idCompressor,\n\t\t\t\t\toriginatorId: context.originatorId,\n\t\t\t\t},\n\t\t\t\tcontext.incrementalEncoderDecoder,\n\t\t\t).map((chunk) => chunk.cursor());\n\t\t},\n\t});\n}\n"]}
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import type { IIdCompressor } from "@fluidframework/id-compressor";
|
|
6
|
-
import { type FieldKey, type FieldKindIdentifier, type ITreeCursorSynchronous, type TreeFieldStoredSchema, type TreeNodeSchemaIdentifier, type Value } from "../../../core/index.js";
|
|
6
|
+
import { type FieldKey, type FieldKindIdentifier, type ITreeCursorSynchronous, type TreeChunk, type TreeFieldStoredSchema, type TreeNodeSchemaIdentifier, type Value } from "../../../core/index.js";
|
|
7
7
|
import type { FlexFieldKind } from "../../modular-schema/index.js";
|
|
8
8
|
import type { Counter, DeduplicationTable } from "./chunkCodecUtilities.js";
|
|
9
9
|
import { type BufferFormat as BufferFormatGeneric, Shape as ShapeGeneric } from "./chunkEncodingGeneric.js";
|
|
10
10
|
import type { FieldBatch } from "./fieldBatch.js";
|
|
11
11
|
import { type EncodedChunkShape, type EncodedFieldBatch, type EncodedValueShape } from "./format.js";
|
|
12
|
+
import type { ChunkReferenceId, IncrementalEncoder } from "./codecs.js";
|
|
12
13
|
/**
|
|
13
|
-
* Encode data from `FieldBatch` into an `
|
|
14
|
+
* Encode data from `FieldBatch` into an `EncodedFieldBatch`.
|
|
14
15
|
*
|
|
15
16
|
* Optimized for encoded size and encoding performance.
|
|
16
17
|
*
|
|
@@ -114,20 +115,50 @@ export declare class InlineArrayEncoder extends ShapeGeneric<EncodedChunkShape>
|
|
|
114
115
|
countReferencedShapesAndIdentifiers(identifiers: Counter<string>, shapeDiscovered: (shape: Shape) => void): void;
|
|
115
116
|
get shape(): this;
|
|
116
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Encodes the shape for a nested array as {@link EncodedNestedArray} shape.
|
|
120
|
+
*/
|
|
121
|
+
export declare class NestedArrayShape extends ShapeGeneric<EncodedChunkShape> {
|
|
122
|
+
readonly innerShape: Shape;
|
|
123
|
+
/**
|
|
124
|
+
* @param innerShape - The shape of each item in this nested array.
|
|
125
|
+
*/
|
|
126
|
+
constructor(innerShape: Shape);
|
|
127
|
+
encodeShape(identifiers: DeduplicationTable<string>, shapes: DeduplicationTable<Shape>): EncodedChunkShape;
|
|
128
|
+
countReferencedShapesAndIdentifiers(identifiers: Counter<string>, shapeDiscovered: (shape: Shape) => void): void;
|
|
129
|
+
}
|
|
117
130
|
/**
|
|
118
131
|
* Encodes a field as a nested array with the {@link EncodedNestedArrayShape} shape.
|
|
119
132
|
* @remarks
|
|
120
|
-
* The fact this is also a Shape is an implementation detail
|
|
133
|
+
* The fact this is also exposes a Shape is an implementation detail: it allows the shape it uses to be itself
|
|
121
134
|
* which is an easy way to keep all the related code together without extra objects.
|
|
122
135
|
*/
|
|
123
|
-
export declare class NestedArrayEncoder
|
|
124
|
-
readonly
|
|
125
|
-
readonly shape:
|
|
126
|
-
constructor(
|
|
136
|
+
export declare class NestedArrayEncoder implements FieldEncoder {
|
|
137
|
+
readonly innerEncoder: NodeEncoder;
|
|
138
|
+
readonly shape: NestedArrayShape;
|
|
139
|
+
constructor(innerEncoder: NodeEncoder, shape?: NestedArrayShape);
|
|
127
140
|
encodeField(cursor: ITreeCursorSynchronous, context: EncoderContext, outputBuffer: BufferFormat): void;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Encodes a chunk with the {@link EncodedIncrementalChunkShape} shape.
|
|
144
|
+
* This chunks will be encoded separately, i.e., the contents of the chunk will not be part of the main buffer.
|
|
145
|
+
* A reference to the chunk will be stored in the main buffer as an {@link ChunkReferenceId}.
|
|
146
|
+
*/
|
|
147
|
+
export declare class IncrementalChunkShape extends ShapeGeneric<EncodedChunkShape> {
|
|
148
|
+
/**
|
|
149
|
+
* Encodes all the nodes in the chunk at the cursor position using `InlineArrayShape`.
|
|
150
|
+
*/
|
|
151
|
+
static encodeChunk(chunk: TreeChunk, context: EncoderContext): BufferFormat;
|
|
128
152
|
encodeShape(identifiers: DeduplicationTable<string>, shapes: DeduplicationTable<Shape>): EncodedChunkShape;
|
|
129
153
|
countReferencedShapesAndIdentifiers(identifiers: Counter<string>, shapeDiscovered: (shape: Shape) => void): void;
|
|
154
|
+
get shape(): this;
|
|
130
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Encodes an incremental field whose chunks are encoded separately and referenced by their {@link ChunkReferenceId}.
|
|
158
|
+
* The shape of the content of this field is {@link NestedShape} where the items in the array are
|
|
159
|
+
* the {@link ChunkReferenceId}s of the encoded chunks.
|
|
160
|
+
*/
|
|
161
|
+
export declare const incrementalFieldEncoder: FieldEncoder;
|
|
131
162
|
/**
|
|
132
163
|
* Encode `value` with `shape` into `outputBuffer`.
|
|
133
164
|
*
|
|
@@ -137,6 +168,7 @@ export declare function encodeValue(value: Value, shape: EncodedValueShape, outp
|
|
|
137
168
|
/**
|
|
138
169
|
* Provides common contextual information during encoding, like schema and policy settings.
|
|
139
170
|
* Also, provides a cache to avoid duplicating equivalent shapes during a batch of encode operations.
|
|
171
|
+
* @remarks
|
|
140
172
|
* To avoid Shape duplication, any Shapes used in the encoding should either be:
|
|
141
173
|
* - Singletons defined in a static scope.
|
|
142
174
|
* - Cached in this object for future reuse such that all equivalent Shapes are deduplicated.
|
|
@@ -146,12 +178,18 @@ export declare class EncoderContext implements NodeEncodeBuilder, FieldEncodeBui
|
|
|
146
178
|
private readonly fieldEncoderFromPolicy;
|
|
147
179
|
readonly fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>;
|
|
148
180
|
readonly idCompressor: IIdCompressor;
|
|
181
|
+
private readonly incrementalEncoder;
|
|
149
182
|
private readonly nodeEncodersFromSchema;
|
|
150
183
|
private readonly nestedArrayEncoders;
|
|
151
|
-
constructor(nodeEncoderFromPolicy: NodeEncoderPolicy, fieldEncoderFromPolicy: FieldEncoderPolicy, fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>, idCompressor: IIdCompressor);
|
|
184
|
+
constructor(nodeEncoderFromPolicy: NodeEncoderPolicy, fieldEncoderFromPolicy: FieldEncoderPolicy, fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>, idCompressor: IIdCompressor, incrementalEncoder: IncrementalEncoder | undefined);
|
|
152
185
|
nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder;
|
|
153
186
|
fieldEncoderFromSchema(fieldSchema: TreeFieldStoredSchema): FieldEncoder;
|
|
154
187
|
nestedArrayEncoder(inner: NodeEncoder): NestedArrayEncoder;
|
|
188
|
+
get shouldEncodeIncrementally(): boolean;
|
|
189
|
+
/**
|
|
190
|
+
* {@link IncrementalEncoder.encodeIncrementalField}
|
|
191
|
+
*/
|
|
192
|
+
encodeIncrementalField(cursor: ITreeCursorSynchronous, encoder: (chunk: TreeChunk) => BufferFormat): ChunkReferenceId[];
|
|
155
193
|
}
|
|
156
194
|
export interface NodeEncodeBuilder {
|
|
157
195
|
nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compressedEncode.d.ts","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/compressedEncode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAEN,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,KAAK,EAEV,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EACN,KAAK,YAAY,IAAI,mBAAmB,EACxC,KAAK,IAAI,YAAY,EAErB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAEN,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEtB,KAAK,iBAAiB,EAGtB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"compressedEncode.d.ts","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/compressedEncode.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import { getOrCreate } from "../../../util/index.js";
|
|
|
8
8
|
import { Shape as ShapeGeneric, updateShapesAndIdentifiersEncoding, } from "./chunkEncodingGeneric.js";
|
|
9
9
|
import { SpecialField, version, } from "./format.js";
|
|
10
10
|
/**
|
|
11
|
-
* Encode data from `FieldBatch` into an `
|
|
11
|
+
* Encode data from `FieldBatch` into an `EncodedFieldBatch`.
|
|
12
12
|
*
|
|
13
13
|
* Optimized for encoded size and encoding performance.
|
|
14
14
|
*
|
|
@@ -163,17 +163,38 @@ InlineArrayEncoder.empty = new InlineArrayEncoder(0, {
|
|
|
163
163
|
fail(0xb4d /* Empty array should not encode any nodes */);
|
|
164
164
|
},
|
|
165
165
|
});
|
|
166
|
+
/**
|
|
167
|
+
* Encodes the shape for a nested array as {@link EncodedNestedArray} shape.
|
|
168
|
+
*/
|
|
169
|
+
export class NestedArrayShape extends ShapeGeneric {
|
|
170
|
+
/**
|
|
171
|
+
* @param innerShape - The shape of each item in this nested array.
|
|
172
|
+
*/
|
|
173
|
+
constructor(innerShape) {
|
|
174
|
+
super();
|
|
175
|
+
this.innerShape = innerShape;
|
|
176
|
+
}
|
|
177
|
+
encodeShape(identifiers, shapes) {
|
|
178
|
+
const shape = shapes.valueToIndex.get(this.innerShape) ??
|
|
179
|
+
fail(0xb4f /* index for shape not found in table */);
|
|
180
|
+
return {
|
|
181
|
+
a: shape,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
countReferencedShapesAndIdentifiers(identifiers, shapeDiscovered) {
|
|
185
|
+
shapeDiscovered(this.innerShape);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
166
188
|
/**
|
|
167
189
|
* Encodes a field as a nested array with the {@link EncodedNestedArrayShape} shape.
|
|
168
190
|
* @remarks
|
|
169
|
-
* The fact this is also a Shape is an implementation detail
|
|
191
|
+
* The fact this is also exposes a Shape is an implementation detail: it allows the shape it uses to be itself
|
|
170
192
|
* which is an easy way to keep all the related code together without extra objects.
|
|
171
193
|
*/
|
|
172
|
-
export class NestedArrayEncoder
|
|
173
|
-
constructor(
|
|
174
|
-
|
|
175
|
-
this.
|
|
176
|
-
this.shape = this;
|
|
194
|
+
export class NestedArrayEncoder {
|
|
195
|
+
constructor(innerEncoder, shape = new NestedArrayShape(innerEncoder.shape)) {
|
|
196
|
+
this.innerEncoder = innerEncoder;
|
|
197
|
+
this.shape = shape;
|
|
177
198
|
}
|
|
178
199
|
encodeField(cursor, context, outputBuffer) {
|
|
179
200
|
const buffer = [];
|
|
@@ -181,7 +202,7 @@ export class NestedArrayEncoder extends ShapeGeneric {
|
|
|
181
202
|
const length = cursor.getFieldLength();
|
|
182
203
|
forEachNode(cursor, () => {
|
|
183
204
|
const before = buffer.length;
|
|
184
|
-
this.
|
|
205
|
+
this.innerEncoder.encodeNode(cursor, context, buffer);
|
|
185
206
|
allNonZeroSize &&= buffer.length - before !== 0;
|
|
186
207
|
});
|
|
187
208
|
if (buffer.length === 0) {
|
|
@@ -194,17 +215,51 @@ export class NestedArrayEncoder extends ShapeGeneric {
|
|
|
194
215
|
outputBuffer.push(buffer);
|
|
195
216
|
}
|
|
196
217
|
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Encodes a chunk with the {@link EncodedIncrementalChunkShape} shape.
|
|
221
|
+
* This chunks will be encoded separately, i.e., the contents of the chunk will not be part of the main buffer.
|
|
222
|
+
* A reference to the chunk will be stored in the main buffer as an {@link ChunkReferenceId}.
|
|
223
|
+
*/
|
|
224
|
+
export class IncrementalChunkShape extends ShapeGeneric {
|
|
225
|
+
/**
|
|
226
|
+
* Encodes all the nodes in the chunk at the cursor position using `InlineArrayShape`.
|
|
227
|
+
*/
|
|
228
|
+
static encodeChunk(chunk, context) {
|
|
229
|
+
const chunkOutputBuffer = [];
|
|
230
|
+
const nodesEncoder = asNodesEncoder(anyNodeEncoder);
|
|
231
|
+
const chunkCursor = chunk.cursor();
|
|
232
|
+
chunkCursor.firstNode();
|
|
233
|
+
const chunkLength = chunkCursor.chunkLength;
|
|
234
|
+
for (let index = 0; index < chunkLength; index++) {
|
|
235
|
+
nodesEncoder.encodeNodes(chunkCursor, context, chunkOutputBuffer);
|
|
236
|
+
}
|
|
237
|
+
assert(chunkCursor.mode === 1 /* CursorLocationType.Fields */, 0xc29 /* should return to fields mode when finished encoding */);
|
|
238
|
+
return chunkOutputBuffer;
|
|
239
|
+
}
|
|
197
240
|
encodeShape(identifiers, shapes) {
|
|
198
|
-
const shape = shapes.valueToIndex.get(this.inner.shape) ??
|
|
199
|
-
fail(0xb4f /* index for shape not found in table */);
|
|
200
241
|
return {
|
|
201
|
-
|
|
242
|
+
e: 0 /* EncodedIncrementalChunkShape */,
|
|
202
243
|
};
|
|
203
244
|
}
|
|
204
|
-
countReferencedShapesAndIdentifiers(identifiers, shapeDiscovered) {
|
|
205
|
-
|
|
245
|
+
countReferencedShapesAndIdentifiers(identifiers, shapeDiscovered) { }
|
|
246
|
+
get shape() {
|
|
247
|
+
return this;
|
|
206
248
|
}
|
|
207
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* Encodes an incremental field whose chunks are encoded separately and referenced by their {@link ChunkReferenceId}.
|
|
252
|
+
* The shape of the content of this field is {@link NestedShape} where the items in the array are
|
|
253
|
+
* the {@link ChunkReferenceId}s of the encoded chunks.
|
|
254
|
+
*/
|
|
255
|
+
export const incrementalFieldEncoder = {
|
|
256
|
+
encodeField(cursor, context, outputBuffer) {
|
|
257
|
+
assert(context.shouldEncodeIncrementally, 0xc2a /* incremental encoding must be enabled to use IncrementalFieldShape */);
|
|
258
|
+
const chunkReferenceIds = context.encodeIncrementalField(cursor, (chunk) => IncrementalChunkShape.encodeChunk(chunk, context));
|
|
259
|
+
outputBuffer.push(chunkReferenceIds);
|
|
260
|
+
},
|
|
261
|
+
shape: new NestedArrayShape(new IncrementalChunkShape() /* innerShape */),
|
|
262
|
+
};
|
|
208
263
|
/**
|
|
209
264
|
* Encode `value` with `shape` into `outputBuffer`.
|
|
210
265
|
*
|
|
@@ -244,16 +299,18 @@ export function encodeValue(value, shape, outputBuffer) {
|
|
|
244
299
|
/**
|
|
245
300
|
* Provides common contextual information during encoding, like schema and policy settings.
|
|
246
301
|
* Also, provides a cache to avoid duplicating equivalent shapes during a batch of encode operations.
|
|
302
|
+
* @remarks
|
|
247
303
|
* To avoid Shape duplication, any Shapes used in the encoding should either be:
|
|
248
304
|
* - Singletons defined in a static scope.
|
|
249
305
|
* - Cached in this object for future reuse such that all equivalent Shapes are deduplicated.
|
|
250
306
|
*/
|
|
251
307
|
export class EncoderContext {
|
|
252
|
-
constructor(nodeEncoderFromPolicy, fieldEncoderFromPolicy, fieldShapes, idCompressor) {
|
|
308
|
+
constructor(nodeEncoderFromPolicy, fieldEncoderFromPolicy, fieldShapes, idCompressor, incrementalEncoder) {
|
|
253
309
|
this.nodeEncoderFromPolicy = nodeEncoderFromPolicy;
|
|
254
310
|
this.fieldEncoderFromPolicy = fieldEncoderFromPolicy;
|
|
255
311
|
this.fieldShapes = fieldShapes;
|
|
256
312
|
this.idCompressor = idCompressor;
|
|
313
|
+
this.incrementalEncoder = incrementalEncoder;
|
|
257
314
|
this.nodeEncodersFromSchema = new Map();
|
|
258
315
|
this.nestedArrayEncoders = new Map();
|
|
259
316
|
}
|
|
@@ -266,6 +323,22 @@ export class EncoderContext {
|
|
|
266
323
|
nestedArrayEncoder(inner) {
|
|
267
324
|
return getOrCreate(this.nestedArrayEncoders, inner, () => new NestedArrayEncoder(inner));
|
|
268
325
|
}
|
|
326
|
+
get shouldEncodeIncrementally() {
|
|
327
|
+
return this.incrementalEncoder !== undefined;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* {@link IncrementalEncoder.encodeIncrementalField}
|
|
331
|
+
*/
|
|
332
|
+
encodeIncrementalField(cursor, encoder) {
|
|
333
|
+
assert(this.incrementalEncoder !== undefined, 0xc2b /* incremental encoding must be enabled */);
|
|
334
|
+
// Encoder for the chunk that encodes its data using the provided encoder function and
|
|
335
|
+
// updates the encoded data for shapes and identifiers.
|
|
336
|
+
const chunkEncoder = (chunk) => {
|
|
337
|
+
const chunkOutputBuffer = encoder(chunk);
|
|
338
|
+
return updateShapesAndIdentifiersEncoding(version, [chunkOutputBuffer]);
|
|
339
|
+
};
|
|
340
|
+
return this.incrementalEncoder.encodeIncrementalField(cursor, chunkEncoder);
|
|
341
|
+
}
|
|
269
342
|
}
|
|
270
343
|
class LazyFieldEncoder {
|
|
271
344
|
constructor(nodeBuilder, fieldSchema, fieldEncoderFromPolicy) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compressedEncode.js","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/compressedEncode.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase, fail } from \"@fluidframework/core-utils/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nimport {\n\tCursorLocationType,\n\ttype FieldKey,\n\ttype FieldKindIdentifier,\n\ttype ITreeCursorSynchronous,\n\ttype TreeFieldStoredSchema,\n\ttype TreeNodeSchemaIdentifier,\n\ttype Value,\n\tforEachNode,\n} from \"../../../core/index.js\";\nimport { getOrCreate } from \"../../../util/index.js\";\nimport type { FlexFieldKind } from \"../../modular-schema/index.js\";\n\nimport type { Counter, DeduplicationTable } from \"./chunkCodecUtilities.js\";\nimport {\n\ttype BufferFormat as BufferFormatGeneric,\n\tShape as ShapeGeneric,\n\tupdateShapesAndIdentifiersEncoding,\n} from \"./chunkEncodingGeneric.js\";\nimport type { FieldBatch } from \"./fieldBatch.js\";\nimport {\n\ttype EncodedAnyShape,\n\ttype EncodedChunkShape,\n\ttype EncodedFieldBatch,\n\ttype EncodedNestedArrayShape,\n\ttype EncodedValueShape,\n\tSpecialField,\n\tversion,\n} from \"./format.js\";\n\n/**\n * Encode data from `FieldBatch` into an `EncodedChunk`.\n *\n * Optimized for encoded size and encoding performance.\n *\n * Most of the compression strategy comes from the policy provided via `context`.\n */\nexport function compressedEncode(\n\tfieldBatch: FieldBatch,\n\tcontext: EncoderContext,\n): EncodedFieldBatch {\n\tconst batchBuffer: BufferFormat[] = [];\n\n\t// Populate buffer, including shape and identifier references\n\tfor (const cursor of fieldBatch) {\n\t\tconst buffer: BufferFormat = [];\n\t\tanyFieldEncoder.encodeField(cursor, context, buffer);\n\t\tbatchBuffer.push(buffer);\n\t}\n\treturn updateShapesAndIdentifiersEncoding(version, batchBuffer);\n}\n\nexport type BufferFormat = BufferFormatGeneric<EncodedChunkShape>;\nexport type Shape = ShapeGeneric<EncodedChunkShape>;\n\n/**\n * Like {@link FieldEncoder}, except data will be prefixed with the key.\n */\nexport interface KeyedFieldEncoder {\n\treadonly key: FieldKey;\n\treadonly encoder: FieldEncoder;\n}\n\n/**\n * An encoder with an associated shape.\n */\nexport interface Encoder {\n\t/**\n\t * The shape which describes how the encoded data is laid out.\n\t * Used by decoders to interpret the output of `encodeNode`.\n\t */\n\treadonly shape: Shape;\n}\n\n/**\n * An encoder for a specific shape of node.\n *\n * Can only be used with compatible nodes.\n */\nexport interface NodeEncoder extends Encoder {\n\t/**\n\t * @param cursor - in Nodes mode. Does not move cursor.\n\t */\n\tencodeNode(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void;\n}\n\n/**\n * Like {@link NodeEncoder}, except encodes a run of nodes.\n */\nexport interface NodesEncoder extends Encoder {\n\t/**\n\t * @param cursor - in Nodes mode. Moves cursor however many nodes it encodes.\n\t */\n\tencodeNodes(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void;\n}\n\n/**\n * Like {@link NodeEncoder}, except encodes a field.\n */\nexport interface FieldEncoder extends Encoder {\n\t/**\n\t * @param cursor - in Fields mode. Encodes entire field.\n\t */\n\tencodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void;\n}\n\n/**\n * Makes a {@link FieldEncoder} which runs `encoder` on every node in the field.\n * This does not encode the number nodes: the user of this may need to encode that elsewhere.\n */\nexport function asFieldEncoder(encoder: NodeEncoder): FieldEncoder {\n\treturn {\n\t\tencodeField(\n\t\t\tcursor: ITreeCursorSynchronous,\n\t\t\tcontext: EncoderContext,\n\t\t\toutputBuffer: BufferFormat,\n\t\t): void {\n\t\t\tforEachNode(cursor, () => encoder.encodeNode(cursor, context, outputBuffer));\n\t\t},\n\t\tshape: encoder.shape,\n\t};\n}\n\n/**\n * Adapt a {@link NodeEncoder} to a {@link NodesEncoder} which invokes `encoder` once.\n */\nexport function asNodesEncoder(encoder: NodeEncoder): NodesEncoder {\n\treturn {\n\t\tencodeNodes(\n\t\t\tcursor: ITreeCursorSynchronous,\n\t\t\tcontext: EncoderContext,\n\t\t\toutputBuffer: BufferFormat,\n\t\t): void {\n\t\t\tencoder.encodeNode(cursor, context, outputBuffer);\n\t\t\tcursor.nextNode();\n\t\t},\n\t\tshape: encoder.shape,\n\t};\n}\n\n/**\n * Encodes a chunk with {@link EncodedAnyShape} by prefixing the data with its shape.\n */\nexport class AnyShape extends ShapeGeneric<EncodedChunkShape> {\n\tprivate constructor() {\n\t\tsuper();\n\t}\n\tpublic static readonly instance = new AnyShape();\n\n\tpublic encodeShape(\n\t\tidentifiers: DeduplicationTable<string>,\n\t\tshapes: DeduplicationTable<Shape>,\n\t): EncodedChunkShape {\n\t\tconst encodedAnyShape: EncodedAnyShape = 0;\n\t\treturn { d: encodedAnyShape };\n\t}\n\n\tpublic countReferencedShapesAndIdentifiers(\n\t\tidentifiers: Counter<string>,\n\t\tshapeDiscovered: (shape: Shape) => void,\n\t): void {}\n\n\tpublic static encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t\tencoder: FieldEncoder,\n\t): void {\n\t\toutputBuffer.push(encoder.shape);\n\t\tencoder.encodeField(cursor, context, outputBuffer);\n\t}\n\n\tpublic static encodeNode(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t\tencoder: NodeEncoder,\n\t): void {\n\t\toutputBuffer.push(encoder.shape);\n\t\tencoder.encodeNode(cursor, context, outputBuffer);\n\t}\n\n\tpublic static encodeNodes(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t\tencoder: NodesEncoder,\n\t): void {\n\t\toutputBuffer.push(encoder.shape);\n\t\tencoder.encodeNodes(cursor, context, outputBuffer);\n\t}\n}\n\n/**\n * Encodes a single node polymorphically.\n */\nexport const anyNodeEncoder: NodeEncoder = {\n\tencodeNode(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// TODO: Fast path uniform chunk content.\n\t\tconst shape = context.nodeEncoderFromSchema(cursor.type);\n\t\tAnyShape.encodeNode(cursor, context, outputBuffer, shape);\n\t},\n\n\tshape: AnyShape.instance,\n};\n\n/**\n * Encodes a field polymorphically.\n */\nexport const anyFieldEncoder: FieldEncoder = {\n\tencodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// TODO: Fast path uniform chunks.\n\n\t\tif (cursor.getFieldLength() === 0) {\n\t\t\tconst shape = InlineArrayEncoder.empty;\n\t\t\tAnyShape.encodeField(cursor, context, outputBuffer, shape);\n\t\t} else if (cursor.getFieldLength() === 1) {\n\t\t\t// Fast path chunk of size one size one at least: skip nested array.\n\t\t\tcursor.enterNode(0);\n\t\t\tanyNodeEncoder.encodeNode(cursor, context, outputBuffer);\n\t\t\tcursor.exitNode();\n\t\t} else {\n\t\t\t// TODO: more efficient encoding for common cases.\n\t\t\t// Could try to find more specific shape compatible with all children than `anyNodeEncoder`.\n\n\t\t\tconst shape = context.nestedArrayEncoder(anyNodeEncoder);\n\t\t\tAnyShape.encodeField(cursor, context, outputBuffer, shape);\n\t\t}\n\t},\n\n\tshape: AnyShape.instance,\n};\n\n/**\n * Encodes a chunk using {@link EncodedInlineArrayShape}.\n * @remarks\n * The fact this is also a Shape is an implementation detail of the encoder: that allows the shape it uses to be itself,\n * which is an easy way to keep all the related code together without extra objects.\n */\nexport class InlineArrayEncoder\n\textends ShapeGeneric<EncodedChunkShape>\n\timplements NodesEncoder, FieldEncoder\n{\n\tpublic static readonly empty: InlineArrayEncoder = new InlineArrayEncoder(0, {\n\t\tget shape() {\n\t\t\t// Not actually used, makes count work without adding an additional shape.\n\t\t\treturn InlineArrayEncoder.empty;\n\t\t},\n\t\tencodeNodes(\n\t\t\tcursor: ITreeCursorSynchronous,\n\t\t\tcontext: EncoderContext,\n\t\t\toutputBuffer: BufferFormat,\n\t\t): void {\n\t\t\tfail(0xb4d /* Empty array should not encode any nodes */);\n\t\t},\n\t});\n\n\t/**\n\t * @param length - number of invocations of `inner`.\n\t */\n\tpublic constructor(\n\t\tpublic readonly length: number,\n\t\tpublic readonly inner: NodesEncoder,\n\t) {\n\t\tsuper();\n\t}\n\n\tpublic encodeNodes(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// Linter is wrong about this loop being for-of compatible.\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-for-of\n\t\tfor (let index = 0; index < this.length; index++) {\n\t\t\tthis.inner.encodeNodes(cursor, context, outputBuffer);\n\t\t}\n\t}\n\n\tpublic encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// Its possible individual items from this array encode multiple nodes, so don't assume === here.\n\t\tassert(\n\t\t\tcursor.getFieldLength() >= this.length,\n\t\t\t0x73c /* unexpected length for fixed length array */,\n\t\t);\n\t\tcursor.firstNode();\n\t\tthis.encodeNodes(cursor, context, outputBuffer);\n\t\tassert(\n\t\t\tcursor.mode === CursorLocationType.Fields,\n\t\t\t0x73d /* should return to fields mode when finished encoding */,\n\t\t);\n\t}\n\n\tpublic encodeShape(\n\t\tidentifiers: DeduplicationTable<string>,\n\t\tshapes: DeduplicationTable<Shape>,\n\t): EncodedChunkShape {\n\t\treturn {\n\t\t\tb: {\n\t\t\t\tlength: this.length,\n\t\t\t\tshape: shapes.valueToIndex.get(this.inner.shape) ?? fail(0xb4e /* missing shape */),\n\t\t\t},\n\t\t};\n\t}\n\n\tpublic countReferencedShapesAndIdentifiers(\n\t\tidentifiers: Counter<string>,\n\t\tshapeDiscovered: (shape: Shape) => void,\n\t): void {\n\t\tshapeDiscovered(this.inner.shape);\n\t}\n\n\tpublic get shape(): this {\n\t\treturn this;\n\t}\n}\n\n/**\n * Encodes a field as a nested array with the {@link EncodedNestedArrayShape} shape.\n * @remarks\n * The fact this is also a Shape is an implementation detail of the encoder: that allows the shape it uses to be itself,\n * which is an easy way to keep all the related code together without extra objects.\n */\nexport class NestedArrayEncoder\n\textends ShapeGeneric<EncodedChunkShape>\n\timplements FieldEncoder\n{\n\tpublic readonly shape: Shape;\n\n\tpublic constructor(public readonly inner: NodeEncoder) {\n\t\tsuper();\n\t\tthis.shape = this;\n\t}\n\n\tpublic encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\tconst buffer: BufferFormat = [];\n\t\tlet allNonZeroSize = true;\n\t\tconst length = cursor.getFieldLength();\n\t\tforEachNode(cursor, () => {\n\t\t\tconst before = buffer.length;\n\t\t\tthis.inner.encodeNode(cursor, context, buffer);\n\t\t\tallNonZeroSize &&= buffer.length - before !== 0;\n\t\t});\n\t\tif (buffer.length === 0) {\n\t\t\t// This relies on the number of inner chunks being the same as the number of nodes.\n\t\t\t// If making inner a `NodesEncoder`, this code will have to be adjusted accordingly.\n\t\t\toutputBuffer.push(length);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tallNonZeroSize,\n\t\t\t\t0x73e /* either all or none of the members of a nested array must be 0 sized, or there is no way the decoder could process the content correctly. */,\n\t\t\t);\n\t\t\toutputBuffer.push(buffer);\n\t\t}\n\t}\n\n\tpublic encodeShape(\n\t\tidentifiers: DeduplicationTable<string>,\n\t\tshapes: DeduplicationTable<Shape>,\n\t): EncodedChunkShape {\n\t\tconst shape: EncodedNestedArrayShape =\n\t\t\tshapes.valueToIndex.get(this.inner.shape) ??\n\t\t\tfail(0xb4f /* index for shape not found in table */);\n\t\treturn {\n\t\t\ta: shape,\n\t\t};\n\t}\n\n\tpublic countReferencedShapesAndIdentifiers(\n\t\tidentifiers: Counter<string>,\n\t\tshapeDiscovered: (shape: Shape) => void,\n\t): void {\n\t\tshapeDiscovered(this.inner.shape);\n\t}\n}\n\n/**\n * Encode `value` with `shape` into `outputBuffer`.\n *\n * Requires that `value` is compatible with `shape`.\n */\nexport function encodeValue(\n\tvalue: Value,\n\tshape: EncodedValueShape,\n\toutputBuffer: BufferFormat,\n): void {\n\tif (shape === undefined) {\n\t\tif (value !== undefined) {\n\t\t\toutputBuffer.push(true, value);\n\t\t} else {\n\t\t\toutputBuffer.push(false);\n\t\t}\n\t} else {\n\t\tif (shape === true) {\n\t\t\tassert(value !== undefined, 0x78d /* required value must not be missing */);\n\t\t\toutputBuffer.push(value);\n\t\t} else if (shape === false) {\n\t\t\tassert(value === undefined, 0x73f /* incompatible value shape: expected no value */);\n\t\t} else if (Array.isArray(shape)) {\n\t\t\tassert(shape.length === 1, 0x740 /* expected a single constant for value */);\n\t\t} else if (shape === SpecialField.Identifier) {\n\t\t\t// This case is a special case handling the encoding of identifier fields.\n\t\t\tassert(value !== undefined, 0x998 /* required value must not be missing */);\n\t\t\toutputBuffer.push(value);\n\t\t} else {\n\t\t\t// EncodedCounter case:\n\t\t\tunreachableCase(shape, \"Encoding values as deltas is not yet supported\");\n\t\t}\n\t}\n}\n\n/**\n * Provides common contextual information during encoding, like schema and policy settings.\n * Also, provides a cache to avoid duplicating equivalent shapes during a batch of encode operations.\n * To avoid Shape duplication, any Shapes used in the encoding should either be:\n * - Singletons defined in a static scope.\n * - Cached in this object for future reuse such that all equivalent Shapes are deduplicated.\n */\nexport class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {\n\tprivate readonly nodeEncodersFromSchema: Map<TreeNodeSchemaIdentifier, NodeEncoder> =\n\t\tnew Map();\n\tprivate readonly nestedArrayEncoders: Map<NodeEncoder, NestedArrayEncoder> = new Map();\n\tpublic constructor(\n\t\tprivate readonly nodeEncoderFromPolicy: NodeEncoderPolicy,\n\t\tprivate readonly fieldEncoderFromPolicy: FieldEncoderPolicy,\n\t\tpublic readonly fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,\n\t\tpublic readonly idCompressor: IIdCompressor,\n\t) {}\n\n\tpublic nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder {\n\t\treturn getOrCreate(this.nodeEncodersFromSchema, schemaName, () =>\n\t\t\tthis.nodeEncoderFromPolicy(this, schemaName),\n\t\t);\n\t}\n\n\tpublic fieldEncoderFromSchema(fieldSchema: TreeFieldStoredSchema): FieldEncoder {\n\t\treturn new LazyFieldEncoder(this, fieldSchema, this.fieldEncoderFromPolicy);\n\t}\n\n\tpublic nestedArrayEncoder(inner: NodeEncoder): NestedArrayEncoder {\n\t\treturn getOrCreate(this.nestedArrayEncoders, inner, () => new NestedArrayEncoder(inner));\n\t}\n}\n\nexport interface NodeEncodeBuilder {\n\tnodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder;\n}\n\nexport interface FieldEncodeBuilder {\n\tfieldEncoderFromSchema(schema: TreeFieldStoredSchema): FieldEncoder;\n}\n\n/**\n * The policy for building a {@link FieldEncoder} for a field.\n */\nexport type FieldEncoderPolicy = (\n\tnodeBuilder: NodeEncodeBuilder,\n\tschema: TreeFieldStoredSchema,\n) => FieldEncoder;\n\n/**\n * The policy for building a {@link NodeEncoder} for a node.\n */\nexport type NodeEncoderPolicy = (\n\tfieldBuilder: FieldEncodeBuilder,\n\tschemaName: TreeNodeSchemaIdentifier,\n) => NodeEncoder;\n\nclass LazyFieldEncoder implements FieldEncoder {\n\tprivate encoderLazy: FieldEncoder | undefined;\n\n\tpublic constructor(\n\t\tpublic readonly nodeBuilder: NodeEncodeBuilder,\n\t\tpublic readonly fieldSchema: TreeFieldStoredSchema,\n\t\tprivate readonly fieldEncoderFromPolicy: FieldEncoderPolicy,\n\t) {}\n\tpublic encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\tthis.encoder.encodeField(cursor, context, outputBuffer);\n\t}\n\n\tprivate get encoder(): FieldEncoder {\n\t\tif (this.encoderLazy === undefined) {\n\t\t\tthis.encoderLazy = this.fieldEncoderFromPolicy(this.nodeBuilder, this.fieldSchema);\n\t\t}\n\t\treturn this.encoderLazy;\n\t}\n\n\tpublic get shape(): Shape {\n\t\treturn this.encoder.shape;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"compressedEncode.js","sourceRoot":"","sources":["../../../../src/feature-libraries/chunked-forest/codec/compressedEncode.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase, fail } from \"@fluidframework/core-utils/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\n\nimport {\n\tCursorLocationType,\n\ttype FieldKey,\n\ttype FieldKindIdentifier,\n\ttype ITreeCursorSynchronous,\n\ttype TreeChunk,\n\ttype TreeFieldStoredSchema,\n\ttype TreeNodeSchemaIdentifier,\n\ttype Value,\n\tforEachNode,\n} from \"../../../core/index.js\";\nimport { getOrCreate } from \"../../../util/index.js\";\nimport type { FlexFieldKind } from \"../../modular-schema/index.js\";\n\nimport type { Counter, DeduplicationTable } from \"./chunkCodecUtilities.js\";\nimport {\n\ttype BufferFormat as BufferFormatGeneric,\n\tShape as ShapeGeneric,\n\tupdateShapesAndIdentifiersEncoding,\n} from \"./chunkEncodingGeneric.js\";\nimport type { FieldBatch } from \"./fieldBatch.js\";\nimport {\n\ttype EncodedAnyShape,\n\ttype EncodedChunkShape,\n\ttype EncodedFieldBatch,\n\ttype EncodedNestedArrayShape,\n\ttype EncodedValueShape,\n\tSpecialField,\n\tversion,\n} from \"./format.js\";\nimport type { ChunkReferenceId, IncrementalEncoder } from \"./codecs.js\";\n\n/**\n * Encode data from `FieldBatch` into an `EncodedFieldBatch`.\n *\n * Optimized for encoded size and encoding performance.\n *\n * Most of the compression strategy comes from the policy provided via `context`.\n */\nexport function compressedEncode(\n\tfieldBatch: FieldBatch,\n\tcontext: EncoderContext,\n): EncodedFieldBatch {\n\tconst batchBuffer: BufferFormat[] = [];\n\n\t// Populate buffer, including shape and identifier references\n\tfor (const cursor of fieldBatch) {\n\t\tconst buffer: BufferFormat = [];\n\t\tanyFieldEncoder.encodeField(cursor, context, buffer);\n\t\tbatchBuffer.push(buffer);\n\t}\n\treturn updateShapesAndIdentifiersEncoding(version, batchBuffer);\n}\n\nexport type BufferFormat = BufferFormatGeneric<EncodedChunkShape>;\nexport type Shape = ShapeGeneric<EncodedChunkShape>;\n\n/**\n * Like {@link FieldEncoder}, except data will be prefixed with the key.\n */\nexport interface KeyedFieldEncoder {\n\treadonly key: FieldKey;\n\treadonly encoder: FieldEncoder;\n}\n\n/**\n * An encoder with an associated shape.\n */\nexport interface Encoder {\n\t/**\n\t * The shape which describes how the encoded data is laid out.\n\t * Used by decoders to interpret the output of `encodeNode`.\n\t */\n\treadonly shape: Shape;\n}\n\n/**\n * An encoder for a specific shape of node.\n *\n * Can only be used with compatible nodes.\n */\nexport interface NodeEncoder extends Encoder {\n\t/**\n\t * @param cursor - in Nodes mode. Does not move cursor.\n\t */\n\tencodeNode(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void;\n}\n\n/**\n * Like {@link NodeEncoder}, except encodes a run of nodes.\n */\nexport interface NodesEncoder extends Encoder {\n\t/**\n\t * @param cursor - in Nodes mode. Moves cursor however many nodes it encodes.\n\t */\n\tencodeNodes(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void;\n}\n\n/**\n * Like {@link NodeEncoder}, except encodes a field.\n */\nexport interface FieldEncoder extends Encoder {\n\t/**\n\t * @param cursor - in Fields mode. Encodes entire field.\n\t */\n\tencodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void;\n}\n\n/**\n * Makes a {@link FieldEncoder} which runs `encoder` on every node in the field.\n * This does not encode the number nodes: the user of this may need to encode that elsewhere.\n */\nexport function asFieldEncoder(encoder: NodeEncoder): FieldEncoder {\n\treturn {\n\t\tencodeField(\n\t\t\tcursor: ITreeCursorSynchronous,\n\t\t\tcontext: EncoderContext,\n\t\t\toutputBuffer: BufferFormat,\n\t\t): void {\n\t\t\tforEachNode(cursor, () => encoder.encodeNode(cursor, context, outputBuffer));\n\t\t},\n\t\tshape: encoder.shape,\n\t};\n}\n\n/**\n * Adapt a {@link NodeEncoder} to a {@link NodesEncoder} which invokes `encoder` once.\n */\nexport function asNodesEncoder(encoder: NodeEncoder): NodesEncoder {\n\treturn {\n\t\tencodeNodes(\n\t\t\tcursor: ITreeCursorSynchronous,\n\t\t\tcontext: EncoderContext,\n\t\t\toutputBuffer: BufferFormat,\n\t\t): void {\n\t\t\tencoder.encodeNode(cursor, context, outputBuffer);\n\t\t\tcursor.nextNode();\n\t\t},\n\t\tshape: encoder.shape,\n\t};\n}\n\n/**\n * Encodes a chunk with {@link EncodedAnyShape} by prefixing the data with its shape.\n */\nexport class AnyShape extends ShapeGeneric<EncodedChunkShape> {\n\tprivate constructor() {\n\t\tsuper();\n\t}\n\tpublic static readonly instance = new AnyShape();\n\n\tpublic encodeShape(\n\t\tidentifiers: DeduplicationTable<string>,\n\t\tshapes: DeduplicationTable<Shape>,\n\t): EncodedChunkShape {\n\t\tconst encodedAnyShape: EncodedAnyShape = 0;\n\t\treturn { d: encodedAnyShape };\n\t}\n\n\tpublic countReferencedShapesAndIdentifiers(\n\t\tidentifiers: Counter<string>,\n\t\tshapeDiscovered: (shape: Shape) => void,\n\t): void {}\n\n\tpublic static encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t\tencoder: FieldEncoder,\n\t): void {\n\t\toutputBuffer.push(encoder.shape);\n\t\tencoder.encodeField(cursor, context, outputBuffer);\n\t}\n\n\tpublic static encodeNode(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t\tencoder: NodeEncoder,\n\t): void {\n\t\toutputBuffer.push(encoder.shape);\n\t\tencoder.encodeNode(cursor, context, outputBuffer);\n\t}\n\n\tpublic static encodeNodes(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t\tencoder: NodesEncoder,\n\t): void {\n\t\toutputBuffer.push(encoder.shape);\n\t\tencoder.encodeNodes(cursor, context, outputBuffer);\n\t}\n}\n\n/**\n * Encodes a single node polymorphically.\n */\nexport const anyNodeEncoder: NodeEncoder = {\n\tencodeNode(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// TODO: Fast path uniform chunk content.\n\t\tconst shape = context.nodeEncoderFromSchema(cursor.type);\n\t\tAnyShape.encodeNode(cursor, context, outputBuffer, shape);\n\t},\n\n\tshape: AnyShape.instance,\n};\n\n/**\n * Encodes a field polymorphically.\n */\nexport const anyFieldEncoder: FieldEncoder = {\n\tencodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// TODO: Fast path uniform chunks.\n\n\t\tif (cursor.getFieldLength() === 0) {\n\t\t\tconst shape = InlineArrayEncoder.empty;\n\t\t\tAnyShape.encodeField(cursor, context, outputBuffer, shape);\n\t\t} else if (cursor.getFieldLength() === 1) {\n\t\t\t// Fast path chunk of size one size one at least: skip nested array.\n\t\t\tcursor.enterNode(0);\n\t\t\tanyNodeEncoder.encodeNode(cursor, context, outputBuffer);\n\t\t\tcursor.exitNode();\n\t\t} else {\n\t\t\t// TODO: more efficient encoding for common cases.\n\t\t\t// Could try to find more specific shape compatible with all children than `anyNodeEncoder`.\n\n\t\t\tconst shape = context.nestedArrayEncoder(anyNodeEncoder);\n\t\t\tAnyShape.encodeField(cursor, context, outputBuffer, shape);\n\t\t}\n\t},\n\n\tshape: AnyShape.instance,\n};\n\n/**\n * Encodes a chunk using {@link EncodedInlineArrayShape}.\n * @remarks\n * The fact this is also a Shape is an implementation detail of the encoder: that allows the shape it uses to be itself,\n * which is an easy way to keep all the related code together without extra objects.\n */\nexport class InlineArrayEncoder\n\textends ShapeGeneric<EncodedChunkShape>\n\timplements NodesEncoder, FieldEncoder\n{\n\tpublic static readonly empty: InlineArrayEncoder = new InlineArrayEncoder(0, {\n\t\tget shape() {\n\t\t\t// Not actually used, makes count work without adding an additional shape.\n\t\t\treturn InlineArrayEncoder.empty;\n\t\t},\n\t\tencodeNodes(\n\t\t\tcursor: ITreeCursorSynchronous,\n\t\t\tcontext: EncoderContext,\n\t\t\toutputBuffer: BufferFormat,\n\t\t): void {\n\t\t\tfail(0xb4d /* Empty array should not encode any nodes */);\n\t\t},\n\t});\n\n\t/**\n\t * @param length - number of invocations of `inner`.\n\t */\n\tpublic constructor(\n\t\tpublic readonly length: number,\n\t\tpublic readonly inner: NodesEncoder,\n\t) {\n\t\tsuper();\n\t}\n\n\tpublic encodeNodes(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// Linter is wrong about this loop being for-of compatible.\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-for-of\n\t\tfor (let index = 0; index < this.length; index++) {\n\t\t\tthis.inner.encodeNodes(cursor, context, outputBuffer);\n\t\t}\n\t}\n\n\tpublic encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\t// Its possible individual items from this array encode multiple nodes, so don't assume === here.\n\t\tassert(\n\t\t\tcursor.getFieldLength() >= this.length,\n\t\t\t0x73c /* unexpected length for fixed length array */,\n\t\t);\n\t\tcursor.firstNode();\n\t\tthis.encodeNodes(cursor, context, outputBuffer);\n\t\tassert(\n\t\t\tcursor.mode === CursorLocationType.Fields,\n\t\t\t0x73d /* should return to fields mode when finished encoding */,\n\t\t);\n\t}\n\n\tpublic encodeShape(\n\t\tidentifiers: DeduplicationTable<string>,\n\t\tshapes: DeduplicationTable<Shape>,\n\t): EncodedChunkShape {\n\t\treturn {\n\t\t\tb: {\n\t\t\t\tlength: this.length,\n\t\t\t\tshape: shapes.valueToIndex.get(this.inner.shape) ?? fail(0xb4e /* missing shape */),\n\t\t\t},\n\t\t};\n\t}\n\n\tpublic countReferencedShapesAndIdentifiers(\n\t\tidentifiers: Counter<string>,\n\t\tshapeDiscovered: (shape: Shape) => void,\n\t): void {\n\t\tshapeDiscovered(this.inner.shape);\n\t}\n\n\tpublic get shape(): this {\n\t\treturn this;\n\t}\n}\n\n/**\n * Encodes the shape for a nested array as {@link EncodedNestedArray} shape.\n */\nexport class NestedArrayShape extends ShapeGeneric<EncodedChunkShape> {\n\t/**\n\t * @param innerShape - The shape of each item in this nested array.\n\t */\n\tpublic constructor(public readonly innerShape: Shape) {\n\t\tsuper();\n\t}\n\n\tpublic encodeShape(\n\t\tidentifiers: DeduplicationTable<string>,\n\t\tshapes: DeduplicationTable<Shape>,\n\t): EncodedChunkShape {\n\t\tconst shape: EncodedNestedArrayShape =\n\t\t\tshapes.valueToIndex.get(this.innerShape) ??\n\t\t\tfail(0xb4f /* index for shape not found in table */);\n\t\treturn {\n\t\t\ta: shape,\n\t\t};\n\t}\n\n\tpublic countReferencedShapesAndIdentifiers(\n\t\tidentifiers: Counter<string>,\n\t\tshapeDiscovered: (shape: Shape) => void,\n\t): void {\n\t\tshapeDiscovered(this.innerShape);\n\t}\n}\n\n/**\n * Encodes a field as a nested array with the {@link EncodedNestedArrayShape} shape.\n * @remarks\n * The fact this is also exposes a Shape is an implementation detail: it allows the shape it uses to be itself\n * which is an easy way to keep all the related code together without extra objects.\n */\nexport class NestedArrayEncoder implements FieldEncoder {\n\tpublic constructor(\n\t\tpublic readonly innerEncoder: NodeEncoder,\n\t\tpublic readonly shape: NestedArrayShape = new NestedArrayShape(innerEncoder.shape),\n\t) {}\n\n\tpublic encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\tconst buffer: BufferFormat = [];\n\t\tlet allNonZeroSize = true;\n\t\tconst length = cursor.getFieldLength();\n\t\tforEachNode(cursor, () => {\n\t\t\tconst before = buffer.length;\n\t\t\tthis.innerEncoder.encodeNode(cursor, context, buffer);\n\t\t\tallNonZeroSize &&= buffer.length - before !== 0;\n\t\t});\n\t\tif (buffer.length === 0) {\n\t\t\t// This relies on the number of inner chunks being the same as the number of nodes.\n\t\t\t// If making inner a `NodesEncoder`, this code will have to be adjusted accordingly.\n\t\t\toutputBuffer.push(length);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tallNonZeroSize,\n\t\t\t\t0x73e /* either all or none of the members of a nested array must be 0 sized, or there is no way the decoder could process the content correctly. */,\n\t\t\t);\n\t\t\toutputBuffer.push(buffer);\n\t\t}\n\t}\n}\n\n/**\n * Encodes a chunk with the {@link EncodedIncrementalChunkShape} shape.\n * This chunks will be encoded separately, i.e., the contents of the chunk will not be part of the main buffer.\n * A reference to the chunk will be stored in the main buffer as an {@link ChunkReferenceId}.\n */\nexport class IncrementalChunkShape extends ShapeGeneric<EncodedChunkShape> {\n\t/**\n\t * Encodes all the nodes in the chunk at the cursor position using `InlineArrayShape`.\n\t */\n\tpublic static encodeChunk(chunk: TreeChunk, context: EncoderContext): BufferFormat {\n\t\tconst chunkOutputBuffer: BufferFormat = [];\n\t\tconst nodesEncoder = asNodesEncoder(anyNodeEncoder);\n\t\tconst chunkCursor = chunk.cursor();\n\t\tchunkCursor.firstNode();\n\t\tconst chunkLength = chunkCursor.chunkLength;\n\t\tfor (let index = 0; index < chunkLength; index++) {\n\t\t\tnodesEncoder.encodeNodes(chunkCursor, context, chunkOutputBuffer);\n\t\t}\n\t\tassert(\n\t\t\tchunkCursor.mode === CursorLocationType.Fields,\n\t\t\t0xc29 /* should return to fields mode when finished encoding */,\n\t\t);\n\t\treturn chunkOutputBuffer;\n\t}\n\n\tpublic encodeShape(\n\t\tidentifiers: DeduplicationTable<string>,\n\t\tshapes: DeduplicationTable<Shape>,\n\t): EncodedChunkShape {\n\t\treturn {\n\t\t\te: 0 /* EncodedIncrementalChunkShape */,\n\t\t};\n\t}\n\n\tpublic countReferencedShapesAndIdentifiers(\n\t\tidentifiers: Counter<string>,\n\t\tshapeDiscovered: (shape: Shape) => void,\n\t): void {}\n\n\tpublic get shape(): this {\n\t\treturn this;\n\t}\n}\n\n/**\n * Encodes an incremental field whose chunks are encoded separately and referenced by their {@link ChunkReferenceId}.\n * The shape of the content of this field is {@link NestedShape} where the items in the array are\n * the {@link ChunkReferenceId}s of the encoded chunks.\n */\nexport const incrementalFieldEncoder: FieldEncoder = {\n\tencodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\tassert(\n\t\t\tcontext.shouldEncodeIncrementally,\n\t\t\t0xc2a /* incremental encoding must be enabled to use IncrementalFieldShape */,\n\t\t);\n\n\t\tconst chunkReferenceIds = context.encodeIncrementalField(cursor, (chunk: TreeChunk) =>\n\t\t\tIncrementalChunkShape.encodeChunk(chunk, context),\n\t\t);\n\t\toutputBuffer.push(chunkReferenceIds);\n\t},\n\n\tshape: new NestedArrayShape(new IncrementalChunkShape() /* innerShape */),\n};\n\n/**\n * Encode `value` with `shape` into `outputBuffer`.\n *\n * Requires that `value` is compatible with `shape`.\n */\nexport function encodeValue(\n\tvalue: Value,\n\tshape: EncodedValueShape,\n\toutputBuffer: BufferFormat,\n): void {\n\tif (shape === undefined) {\n\t\tif (value !== undefined) {\n\t\t\toutputBuffer.push(true, value);\n\t\t} else {\n\t\t\toutputBuffer.push(false);\n\t\t}\n\t} else {\n\t\tif (shape === true) {\n\t\t\tassert(value !== undefined, 0x78d /* required value must not be missing */);\n\t\t\toutputBuffer.push(value);\n\t\t} else if (shape === false) {\n\t\t\tassert(value === undefined, 0x73f /* incompatible value shape: expected no value */);\n\t\t} else if (Array.isArray(shape)) {\n\t\t\tassert(shape.length === 1, 0x740 /* expected a single constant for value */);\n\t\t} else if (shape === SpecialField.Identifier) {\n\t\t\t// This case is a special case handling the encoding of identifier fields.\n\t\t\tassert(value !== undefined, 0x998 /* required value must not be missing */);\n\t\t\toutputBuffer.push(value);\n\t\t} else {\n\t\t\t// EncodedCounter case:\n\t\t\tunreachableCase(shape, \"Encoding values as deltas is not yet supported\");\n\t\t}\n\t}\n}\n\n/**\n * Provides common contextual information during encoding, like schema and policy settings.\n * Also, provides a cache to avoid duplicating equivalent shapes during a batch of encode operations.\n * @remarks\n * To avoid Shape duplication, any Shapes used in the encoding should either be:\n * - Singletons defined in a static scope.\n * - Cached in this object for future reuse such that all equivalent Shapes are deduplicated.\n */\nexport class EncoderContext implements NodeEncodeBuilder, FieldEncodeBuilder {\n\tprivate readonly nodeEncodersFromSchema: Map<TreeNodeSchemaIdentifier, NodeEncoder> =\n\t\tnew Map();\n\tprivate readonly nestedArrayEncoders: Map<NodeEncoder, NestedArrayEncoder> = new Map();\n\tpublic constructor(\n\t\tprivate readonly nodeEncoderFromPolicy: NodeEncoderPolicy,\n\t\tprivate readonly fieldEncoderFromPolicy: FieldEncoderPolicy,\n\t\tpublic readonly fieldShapes: ReadonlyMap<FieldKindIdentifier, FlexFieldKind>,\n\t\tpublic readonly idCompressor: IIdCompressor,\n\t\tprivate readonly incrementalEncoder: IncrementalEncoder | undefined,\n\t) {}\n\n\tpublic nodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder {\n\t\treturn getOrCreate(this.nodeEncodersFromSchema, schemaName, () =>\n\t\t\tthis.nodeEncoderFromPolicy(this, schemaName),\n\t\t);\n\t}\n\n\tpublic fieldEncoderFromSchema(fieldSchema: TreeFieldStoredSchema): FieldEncoder {\n\t\treturn new LazyFieldEncoder(this, fieldSchema, this.fieldEncoderFromPolicy);\n\t}\n\n\tpublic nestedArrayEncoder(inner: NodeEncoder): NestedArrayEncoder {\n\t\treturn getOrCreate(this.nestedArrayEncoders, inner, () => new NestedArrayEncoder(inner));\n\t}\n\n\tpublic get shouldEncodeIncrementally(): boolean {\n\t\treturn this.incrementalEncoder !== undefined;\n\t}\n\n\t/**\n\t * {@link IncrementalEncoder.encodeIncrementalField}\n\t */\n\tpublic encodeIncrementalField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tencoder: (chunk: TreeChunk) => BufferFormat,\n\t): ChunkReferenceId[] {\n\t\tassert(\n\t\t\tthis.incrementalEncoder !== undefined,\n\t\t\t0xc2b /* incremental encoding must be enabled */,\n\t\t);\n\t\t// Encoder for the chunk that encodes its data using the provided encoder function and\n\t\t// updates the encoded data for shapes and identifiers.\n\t\tconst chunkEncoder = (chunk: TreeChunk): EncodedFieldBatch => {\n\t\t\tconst chunkOutputBuffer = encoder(chunk);\n\t\t\treturn updateShapesAndIdentifiersEncoding(version, [chunkOutputBuffer]);\n\t\t};\n\t\treturn this.incrementalEncoder.encodeIncrementalField(cursor, chunkEncoder);\n\t}\n}\n\nexport interface NodeEncodeBuilder {\n\tnodeEncoderFromSchema(schemaName: TreeNodeSchemaIdentifier): NodeEncoder;\n}\n\nexport interface FieldEncodeBuilder {\n\tfieldEncoderFromSchema(schema: TreeFieldStoredSchema): FieldEncoder;\n}\n\n/**\n * The policy for building a {@link FieldEncoder} for a field.\n */\nexport type FieldEncoderPolicy = (\n\tnodeBuilder: NodeEncodeBuilder,\n\tschema: TreeFieldStoredSchema,\n) => FieldEncoder;\n\n/**\n * The policy for building a {@link NodeEncoder} for a node.\n */\nexport type NodeEncoderPolicy = (\n\tfieldBuilder: FieldEncodeBuilder,\n\tschemaName: TreeNodeSchemaIdentifier,\n) => NodeEncoder;\n\nclass LazyFieldEncoder implements FieldEncoder {\n\tprivate encoderLazy: FieldEncoder | undefined;\n\n\tpublic constructor(\n\t\tpublic readonly nodeBuilder: NodeEncodeBuilder,\n\t\tpublic readonly fieldSchema: TreeFieldStoredSchema,\n\t\tprivate readonly fieldEncoderFromPolicy: FieldEncoderPolicy,\n\t) {}\n\tpublic encodeField(\n\t\tcursor: ITreeCursorSynchronous,\n\t\tcontext: EncoderContext,\n\t\toutputBuffer: BufferFormat,\n\t): void {\n\t\tthis.encoder.encodeField(cursor, context, outputBuffer);\n\t}\n\n\tprivate get encoder(): FieldEncoder {\n\t\tif (this.encoderLazy === undefined) {\n\t\t\tthis.encoderLazy = this.fieldEncoderFromPolicy(this.nodeBuilder, this.fieldSchema);\n\t\t}\n\t\treturn this.encoderLazy;\n\t}\n\n\tpublic get shape(): Shape {\n\t\treturn this.encoder.shape;\n\t}\n}\n"]}
|