@fluidframework/tree 2.101.1 → 2.103.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/CHANGELOG.md +8 -0
- package/api-report/tree.alpha.api.md +19 -0
- package/dist/codec/codec.d.ts +22 -53
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +7 -44
- 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 +2 -2
- package/dist/codec/index.js.map +1 -1
- package/dist/codec/versioned/codec.d.ts +56 -28
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js +29 -12
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/codec/versioned/format.d.ts +5 -4
- package/dist/codec/versioned/format.d.ts.map +1 -1
- package/dist/codec/versioned/format.js +26 -3
- package/dist/codec/versioned/format.js.map +1 -1
- package/dist/codec/versioned/index.d.ts +1 -1
- package/dist/codec/versioned/index.d.ts.map +1 -1
- package/dist/codec/versioned/index.js +2 -2
- package/dist/codec/versioned/index.js.map +1 -1
- package/dist/core/rebase/types.d.ts +4 -3
- package/dist/core/rebase/types.d.ts.map +1 -1
- package/dist/core/rebase/types.js +27 -4
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/schema-stored/formatV1.d.ts +16 -15
- package/dist/core/schema-stored/formatV1.d.ts.map +1 -1
- package/dist/core/schema-stored/formatV1.js +31 -8
- package/dist/core/schema-stored/formatV1.js.map +1 -1
- package/dist/core/schema-stored/formatV2.d.ts +29 -28
- package/dist/core/schema-stored/formatV2.d.ts.map +1 -1
- package/dist/core/schema-stored/formatV2.js +33 -10
- package/dist/core/schema-stored/formatV2.js.map +1 -1
- package/dist/core/tree/deltaUtil.d.ts +2 -2
- package/dist/core/tree/deltaUtil.js +2 -2
- package/dist/core/tree/deltaUtil.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV1.js +3 -2
- package/dist/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecV2.js +4 -2
- package/dist/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.d.ts +3 -3
- package/dist/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.js +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatCommon.d.ts +11 -10
- package/dist/core/tree/detachedFieldIndexFormatCommon.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatCommon.js +33 -10
- package/dist/core/tree/detachedFieldIndexFormatCommon.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatV2.d.ts +7 -6
- package/dist/core/tree/detachedFieldIndexFormatV2.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatV2.js +25 -2
- package/dist/core/tree/detachedFieldIndexFormatV2.js.map +1 -1
- package/dist/core/tree/persistedTreeTextFormat.d.ts +19 -18
- package/dist/core/tree/persistedTreeTextFormat.d.ts.map +1 -1
- package/dist/core/tree/persistedTreeTextFormat.js +33 -10
- package/dist/core/tree/persistedTreeTextFormat.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.d.ts +38 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +63 -5
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +18 -4
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +34 -2
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js +106 -3
- package/dist/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +5 -5
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +2 -2
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +7 -7
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +13 -12
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js +36 -13
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.d.ts +36 -35
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js +41 -18
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.d.ts +35 -14
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js +35 -6
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.d.ts +106 -0
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.d.ts.map +1 -0
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js +67 -0
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js.map +1 -0
- package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts +2 -1
- package/dist/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/index.js +5 -1
- package/dist/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts +38 -4
- package/dist/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/versions.js +7 -1
- package/dist/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts +7 -7
- package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.js +1 -2
- package/dist/feature-libraries/chunked-forest/codec/nodeEncoder.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts +66 -14
- package/dist/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js +101 -36
- package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js +36 -14
- package/dist/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.d.ts +5 -4
- package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.js +2 -2
- package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.d.ts +6 -5
- package/dist/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.js +26 -3
- package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.d.ts +4 -3
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js +26 -3
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +45 -44
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js +48 -25
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +23 -22
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +29 -6
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts +9 -8
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js +31 -8
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts +14 -13
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js +34 -11
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js.map +1 -1
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.d.ts +5 -4
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.d.ts.map +1 -1
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.js +25 -2
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.js.map +1 -1
- package/dist/feature-libraries/schema-index/codec.d.ts +2 -2
- package/dist/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/codec.js +1 -1
- package/dist/feature-libraries/schema-index/codec.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV1.d.ts +15 -14
- package/dist/feature-libraries/schema-index/formatV1.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/formatV1.js +27 -4
- package/dist/feature-libraries/schema-index/formatV1.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV2.d.ts +20 -19
- package/dist/feature-libraries/schema-index/formatV2.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/formatV2.js +27 -4
- package/dist/feature-libraries/schema-index/formatV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +1 -3
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV1.d.ts +283 -282
- package/dist/feature-libraries/sequence-field/formatV1.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV1.js +63 -40
- package/dist/feature-libraries/sequence-field/formatV1.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV2.d.ts +180 -179
- package/dist/feature-libraries/sequence-field/formatV2.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV2.js +55 -32
- package/dist/feature-libraries/sequence-field/formatV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV3.d.ts +126 -125
- package/dist/feature-libraries/sequence-field/formatV3.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV3.js +27 -4
- package/dist/feature-libraries/sequence-field/formatV3.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.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/isAuditableFromOutcome.d.ts +20 -0
- package/dist/shared-tree/isAuditableFromOutcome.d.ts.map +1 -0
- package/dist/shared-tree/isAuditableFromOutcome.js +36 -0
- package/dist/shared-tree/isAuditableFromOutcome.js.map +1 -0
- package/dist/shared-tree/sharedTree.d.ts +2 -2
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFormat.d.ts +8 -7
- package/dist/shared-tree/sharedTreeChangeFormat.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFormat.js +28 -5
- package/dist/shared-tree/sharedTreeChangeFormat.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +5 -3
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +37 -8
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/editManager.d.ts +2 -2
- package/dist/shared-tree-core/editManager.d.ts.map +1 -1
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.d.ts +3 -3
- package/dist/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecs.js +2 -2
- package/dist/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts +35 -34
- package/dist/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.js +39 -16
- package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts +15 -15
- package/dist/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.js +33 -10
- package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts +40 -40
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js +27 -4
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.js +25 -2
- package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/messageCodecs.d.ts +3 -3
- package/dist/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecs.js +2 -2
- package/dist/shared-tree-core/messageCodecs.js.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts +5 -5
- package/dist/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js +31 -8
- package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts +7 -7
- package/dist/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -1
- package/dist/shared-tree-core/messageFormatVSharedBranches.js +29 -6
- package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts +5 -0
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +62 -24
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.d.ts +121 -120
- package/dist/simple-tree/simpleSchemaFormatV1.d.ts.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.js +54 -31
- package/dist/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/dist/text/codePointUtils.d.ts +48 -0
- package/dist/text/codePointUtils.d.ts.map +1 -0
- package/dist/text/codePointUtils.js +80 -0
- package/dist/text/codePointUtils.js.map +1 -0
- package/dist/text/index.d.ts +1 -0
- package/dist/text/index.d.ts.map +1 -1
- package/dist/text/index.js +4 -1
- package/dist/text/index.js.map +1 -1
- package/dist/text/textDomain.d.ts +93 -1
- package/dist/text/textDomain.d.ts.map +1 -1
- package/dist/text/textDomain.js +65 -8
- package/dist/text/textDomain.js.map +1 -1
- package/dist/text/textDomainFormatted.d.ts +24 -6
- package/dist/text/textDomainFormatted.d.ts.map +1 -1
- package/dist/text/textDomainFormatted.js +29 -1
- package/dist/text/textDomainFormatted.js.map +1 -1
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +9 -7
- package/dist/treeFactory.js.map +1 -1
- package/dist/util/breakable.d.ts +7 -1
- package/dist/util/breakable.d.ts.map +1 -1
- package/dist/util/breakable.js +18 -4
- package/dist/util/breakable.js.map +1 -1
- package/dist/util/typeboxBrand.d.ts +1 -1
- package/dist/util/typeboxBrand.d.ts.map +1 -1
- package/dist/util/typeboxBrand.js +26 -3
- package/dist/util/typeboxBrand.js.map +1 -1
- package/dist/util/utils.d.ts +2 -2
- package/dist/util/utils.d.ts.map +1 -1
- package/dist/util/utils.js +25 -2
- package/dist/util/utils.js.map +1 -1
- package/eslint.config.mts +44 -0
- package/lib/codec/codec.d.ts +22 -53
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +7 -44
- 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/codec/versioned/codec.d.ts +56 -28
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js +27 -10
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/codec/versioned/format.d.ts +5 -4
- package/lib/codec/versioned/format.d.ts.map +1 -1
- package/lib/codec/versioned/format.js +1 -1
- package/lib/codec/versioned/format.js.map +1 -1
- package/lib/codec/versioned/index.d.ts +1 -1
- package/lib/codec/versioned/index.d.ts.map +1 -1
- package/lib/codec/versioned/index.js +1 -1
- package/lib/codec/versioned/index.js.map +1 -1
- package/lib/core/rebase/types.d.ts +4 -3
- package/lib/core/rebase/types.d.ts.map +1 -1
- package/lib/core/rebase/types.js +1 -1
- package/lib/core/rebase/types.js.map +1 -1
- package/lib/core/schema-stored/formatV1.d.ts +16 -15
- package/lib/core/schema-stored/formatV1.d.ts.map +1 -1
- package/lib/core/schema-stored/formatV1.js +1 -1
- package/lib/core/schema-stored/formatV1.js.map +1 -1
- package/lib/core/schema-stored/formatV2.d.ts +29 -28
- package/lib/core/schema-stored/formatV2.d.ts.map +1 -1
- package/lib/core/schema-stored/formatV2.js +1 -1
- package/lib/core/schema-stored/formatV2.js.map +1 -1
- package/lib/core/tree/deltaUtil.d.ts +2 -2
- package/lib/core/tree/deltaUtil.js +2 -2
- package/lib/core/tree/deltaUtil.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV1.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV1.js +3 -2
- package/lib/core/tree/detachedFieldIndexCodecV1.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV2.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecV2.js +5 -3
- package/lib/core/tree/detachedFieldIndexCodecV2.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.d.ts +3 -3
- package/lib/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.js +2 -2
- package/lib/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormatCommon.d.ts +11 -10
- package/lib/core/tree/detachedFieldIndexFormatCommon.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormatCommon.js +1 -1
- package/lib/core/tree/detachedFieldIndexFormatCommon.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormatV2.d.ts +7 -6
- package/lib/core/tree/detachedFieldIndexFormatV2.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexFormatV2.js +1 -1
- package/lib/core/tree/detachedFieldIndexFormatV2.js.map +1 -1
- package/lib/core/tree/persistedTreeTextFormat.d.ts +19 -18
- package/lib/core/tree/persistedTreeTextFormat.d.ts.map +1 -1
- package/lib/core/tree/persistedTreeTextFormat.js +1 -1
- package/lib/core/tree/persistedTreeTextFormat.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.d.ts +38 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +62 -5
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +20 -6
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts +34 -2
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js +102 -2
- package/lib/feature-libraries/chunked-forest/codec/chunkDecoding.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +5 -5
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +3 -3
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts +7 -7
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/compressedEncode.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts +13 -12
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatV1.d.ts +36 -35
- package/lib/feature-libraries/chunked-forest/codec/format/formatV1.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatV1.js +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatV1.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatV2.d.ts +35 -14
- package/lib/feature-libraries/chunked-forest/codec/format/formatV2.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatV2.js +9 -3
- package/lib/feature-libraries/chunked-forest/codec/format/formatV2.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/formatVText.d.ts +106 -0
- package/lib/feature-libraries/chunked-forest/codec/format/formatVText.d.ts.map +1 -0
- package/lib/feature-libraries/chunked-forest/codec/format/formatVText.js +41 -0
- package/lib/feature-libraries/chunked-forest/codec/format/formatVText.js.map +1 -0
- package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts +2 -1
- package/lib/feature-libraries/chunked-forest/codec/format/index.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/index.js +2 -1
- package/lib/feature-libraries/chunked-forest/codec/format/index.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts +38 -4
- package/lib/feature-libraries/chunked-forest/codec/format/versions.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/format/versions.js +6 -0
- package/lib/feature-libraries/chunked-forest/codec/format/versions.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts +7 -7
- package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.js +2 -3
- package/lib/feature-libraries/chunked-forest/codec/nodeEncoder.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts +66 -14
- package/lib/feature-libraries/chunked-forest/uniformChunk.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js +101 -36
- package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js +36 -14
- package/lib/feature-libraries/default-schema/defaultEditBuilder.js.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.d.ts +5 -4
- package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.js +3 -3
- package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
- package/lib/feature-libraries/forest-summary/formatCommon.d.ts +6 -5
- package/lib/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/formatCommon.js +1 -1
- package/lib/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.d.ts +4 -3
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.js +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +45 -44
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +23 -22
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts +9 -8
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV1.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV1.js +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV1.js.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts +14 -13
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV2.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV2.js +1 -1
- package/lib/feature-libraries/optional-field/optionalFieldChangeFormatV2.js.map +1 -1
- package/lib/feature-libraries/schema-edits/schemaChangeFormat.d.ts +5 -4
- package/lib/feature-libraries/schema-edits/schemaChangeFormat.d.ts.map +1 -1
- package/lib/feature-libraries/schema-edits/schemaChangeFormat.js +1 -1
- package/lib/feature-libraries/schema-edits/schemaChangeFormat.js.map +1 -1
- package/lib/feature-libraries/schema-index/codec.d.ts +2 -2
- package/lib/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/codec.js +2 -2
- package/lib/feature-libraries/schema-index/codec.js.map +1 -1
- package/lib/feature-libraries/schema-index/formatV1.d.ts +15 -14
- package/lib/feature-libraries/schema-index/formatV1.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/formatV1.js +1 -1
- package/lib/feature-libraries/schema-index/formatV1.js.map +1 -1
- package/lib/feature-libraries/schema-index/formatV2.d.ts +20 -19
- package/lib/feature-libraries/schema-index/formatV2.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/formatV2.js +1 -1
- package/lib/feature-libraries/schema-index/formatV2.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +1 -3
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV1.d.ts +283 -282
- package/lib/feature-libraries/sequence-field/formatV1.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV1.js +1 -1
- package/lib/feature-libraries/sequence-field/formatV1.js.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV2.d.ts +180 -179
- package/lib/feature-libraries/sequence-field/formatV2.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV2.js +1 -1
- package/lib/feature-libraries/sequence-field/formatV2.js.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV3.d.ts +126 -125
- package/lib/feature-libraries/sequence-field/formatV3.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/formatV3.js +1 -1
- package/lib/feature-libraries/sequence-field/formatV3.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.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/isAuditableFromOutcome.d.ts +20 -0
- package/lib/shared-tree/isAuditableFromOutcome.d.ts.map +1 -0
- package/lib/shared-tree/isAuditableFromOutcome.js +32 -0
- package/lib/shared-tree/isAuditableFromOutcome.js.map +1 -0
- package/lib/shared-tree/sharedTree.d.ts +2 -2
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +1 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFormat.d.ts +8 -7
- package/lib/shared-tree/sharedTreeChangeFormat.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFormat.js +1 -1
- package/lib/shared-tree/sharedTreeChangeFormat.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +5 -3
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +38 -9
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/editManager.d.ts +2 -2
- package/lib/shared-tree-core/editManager.d.ts.map +1 -1
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.d.ts +3 -3
- package/lib/shared-tree-core/editManagerCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecs.js +3 -3
- package/lib/shared-tree-core/editManagerCodecs.js.map +1 -1
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts +35 -34
- package/lib/shared-tree-core/editManagerFormatCommons.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatCommons.js +1 -1
- package/lib/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts +15 -15
- package/lib/shared-tree-core/editManagerFormatV1toV4.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.js +1 -1
- package/lib/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts +40 -40
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.js +1 -1
- package/lib/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.js +1 -1
- package/lib/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/lib/shared-tree-core/messageCodecs.d.ts +3 -3
- package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecs.js +3 -3
- package/lib/shared-tree-core/messageCodecs.js.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts +5 -5
- package/lib/shared-tree-core/messageFormatV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js +1 -1
- package/lib/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts +7 -7
- package/lib/shared-tree-core/messageFormatVSharedBranches.d.ts.map +1 -1
- package/lib/shared-tree-core/messageFormatVSharedBranches.js +1 -1
- package/lib/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts +5 -0
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +60 -23
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.d.ts +121 -120
- package/lib/simple-tree/simpleSchemaFormatV1.d.ts.map +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.js +1 -1
- package/lib/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/lib/text/codePointUtils.d.ts +48 -0
- package/lib/text/codePointUtils.d.ts.map +1 -0
- package/lib/text/codePointUtils.js +75 -0
- package/lib/text/codePointUtils.js.map +1 -0
- package/lib/text/index.d.ts +1 -0
- package/lib/text/index.d.ts.map +1 -1
- package/lib/text/index.js +1 -0
- package/lib/text/index.js.map +1 -1
- package/lib/text/textDomain.d.ts +93 -1
- package/lib/text/textDomain.d.ts.map +1 -1
- package/lib/text/textDomain.js +56 -0
- package/lib/text/textDomain.js.map +1 -1
- package/lib/text/textDomainFormatted.d.ts +24 -6
- package/lib/text/textDomainFormatted.d.ts.map +1 -1
- package/lib/text/textDomainFormatted.js +30 -2
- package/lib/text/textDomainFormatted.js.map +1 -1
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +2 -0
- package/lib/treeFactory.js.map +1 -1
- package/lib/util/breakable.d.ts +7 -1
- package/lib/util/breakable.d.ts.map +1 -1
- package/lib/util/breakable.js +18 -4
- package/lib/util/breakable.js.map +1 -1
- package/lib/util/typeboxBrand.d.ts +1 -1
- package/lib/util/typeboxBrand.d.ts.map +1 -1
- package/lib/util/typeboxBrand.js +1 -1
- package/lib/util/typeboxBrand.js.map +1 -1
- package/lib/util/utils.d.ts +2 -2
- package/lib/util/utils.d.ts.map +1 -1
- package/lib/util/utils.js +1 -1
- package/lib/util/utils.js.map +1 -1
- package/package.json +24 -24
- package/src/codec/codec.ts +82 -73
- package/src/codec/index.ts +2 -1
- package/src/codec/versioned/codec.ts +173 -73
- package/src/codec/versioned/format.ts +2 -1
- package/src/codec/versioned/index.ts +2 -1
- package/src/core/rebase/types.ts +1 -1
- package/src/core/schema-stored/formatV1.ts +2 -1
- package/src/core/schema-stored/formatV2.ts +2 -1
- package/src/core/tree/deltaUtil.ts +2 -2
- package/src/core/tree/detachedFieldIndexCodecV1.ts +3 -2
- package/src/core/tree/detachedFieldIndexCodecV2.ts +5 -3
- package/src/core/tree/detachedFieldIndexCodecs.ts +2 -2
- package/src/core/tree/detachedFieldIndexFormatCommon.ts +2 -1
- package/src/core/tree/detachedFieldIndexFormatV2.ts +2 -1
- package/src/core/tree/persistedTreeTextFormat.ts +2 -1
- package/src/feature-libraries/chunked-forest/chunkTree.ts +88 -3
- package/src/feature-libraries/chunked-forest/chunkedForest.ts +27 -7
- package/src/feature-libraries/chunked-forest/codec/chunkDecoding.ts +143 -7
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +30 -28
- package/src/feature-libraries/chunked-forest/codec/compressedEncode.ts +7 -7
- package/src/feature-libraries/chunked-forest/codec/format/formatGeneric.ts +2 -1
- package/src/feature-libraries/chunked-forest/codec/format/formatV1.ts +2 -1
- package/src/feature-libraries/chunked-forest/codec/format/formatV2.ts +13 -8
- package/src/feature-libraries/chunked-forest/codec/format/formatVText.ts +84 -0
- package/src/feature-libraries/chunked-forest/codec/format/index.ts +6 -1
- package/src/feature-libraries/chunked-forest/codec/format/versions.ts +25 -4
- package/src/feature-libraries/chunked-forest/codec/nodeEncoder.ts +14 -18
- package/src/feature-libraries/chunked-forest/uniformChunk.ts +131 -44
- package/src/feature-libraries/default-schema/defaultEditBuilder.ts +36 -14
- package/src/feature-libraries/forest-summary/codec.ts +9 -4
- package/src/feature-libraries/forest-summary/formatCommon.ts +2 -1
- package/src/feature-libraries/modular-schema/genericFieldKindFormat.ts +2 -1
- package/src/feature-libraries/modular-schema/modularChangeFormatV1.ts +2 -1
- package/src/feature-libraries/modular-schema/modularChangeFormatV2.ts +2 -1
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +1 -1
- package/src/feature-libraries/optional-field/optionalFieldChangeFormatV1.ts +2 -1
- package/src/feature-libraries/optional-field/optionalFieldChangeFormatV2.ts +2 -1
- package/src/feature-libraries/schema-edits/schemaChangeFormat.ts +2 -1
- package/src/feature-libraries/schema-index/codec.ts +2 -5
- package/src/feature-libraries/schema-index/formatV1.ts +2 -1
- package/src/feature-libraries/schema-index/formatV2.ts +2 -1
- package/src/feature-libraries/sequence-field/compose.ts +1 -4
- package/src/feature-libraries/sequence-field/formatV1.ts +2 -1
- package/src/feature-libraries/sequence-field/formatV2.ts +2 -1
- package/src/feature-libraries/sequence-field/formatV3.ts +2 -1
- package/src/index.ts +6 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/isAuditableFromOutcome.ts +34 -0
- package/src/shared-tree/sharedTree.ts +2 -5
- package/src/shared-tree/sharedTreeChangeFormat.ts +2 -1
- package/src/shared-tree/treeCheckout.ts +55 -15
- package/src/shared-tree-core/editManager.ts +2 -2
- package/src/shared-tree-core/editManagerCodecs.ts +4 -6
- package/src/shared-tree-core/editManagerFormatCommons.ts +2 -1
- package/src/shared-tree-core/editManagerFormatV1toV4.ts +2 -1
- package/src/shared-tree-core/editManagerFormatVSharedBranches.ts +2 -1
- package/src/shared-tree-core/messageCodecVSharedBranches.ts +2 -1
- package/src/shared-tree-core/messageCodecs.ts +4 -4
- package/src/shared-tree-core/messageFormatV1ToV4.ts +2 -1
- package/src/shared-tree-core/messageFormatVSharedBranches.ts +2 -1
- package/src/simple-tree/core/treeNodeKernel.ts +66 -28
- package/src/simple-tree/simpleSchemaFormatV1.ts +2 -1
- package/src/text/codePointUtils.ts +81 -0
- package/src/text/index.ts +1 -0
- package/src/text/textDomain.ts +155 -2
- package/src/text/textDomainFormatted.ts +73 -2
- package/src/treeFactory.ts +5 -0
- package/src/util/breakable.ts +27 -6
- package/src/util/typeboxBrand.ts +2 -1
- package/src/util/utils.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textDomain.js","sourceRoot":"","sources":["../../src/text/textDomain.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 { compareArrays, debugAssert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tbuildFunc,\n\texposeMethodsSymbol,\n\ttype ExposedMethods,\n\ttype IExposedMethods,\n\t// eslint-disable-next-line import-x/no-internal-modules\n} from \"@fluidframework/type-factory/alpha\";\nimport { typeFactory as tf } from \"@fluidframework/type-factory/internal\";\n\nimport { EmptyKey, mapCursorField, type ITreeCursorSynchronous } from \"../core/index.js\";\nimport {\n\teraseSchemaDetails,\n\tgetInnerNode,\n\tSchemaFactory,\n\tSchemaFactoryAlpha,\n\tTreeArrayNode,\n} from \"../simple-tree/index.js\";\n// eslint-disable-next-line import-x/no-duplicates\nimport type { TreeNode, WithType } from \"../simple-tree/index.js\";\n// Add some unused imports which show up in the generated d.ts file.\n// This prevents them from getting inline imports generated, cleaning up the d.ts file and API reports.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports, import-x/no-duplicates\nimport type { NodeKind, TreeNodeSchema } from \"../simple-tree/index.js\";\n\nconst sf = new SchemaFactoryAlpha(\"com.fluidframework.text\");\n\nclass TextNode\n\textends sf.object(\"Text\", {\n\t\tcontent: SchemaFactory.required([() => StringArray], { key: EmptyKey }),\n\t})\n\timplements TextAsTree.Members, IExposedMethods\n{\n\tpublic static [exposeMethodsSymbol](methods: ExposedMethods): void {\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"insertAt\",\n\t\t\tbuildFunc(\n\t\t\t\t{\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Insert characters into the text at the given character index (Unicode code points).\",\n\t\t\t\t\treturns: tf.void(),\n\t\t\t\t},\n\t\t\t\t[\"index\", tf.number()],\n\t\t\t\t[\"additionalCharacters\", tf.string()],\n\t\t\t),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"removeRange\",\n\t\t\tbuildFunc(\n\t\t\t\t{\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Remove a range of characters from the text by character index (Unicode code points). startIndex defaults to 0 and endIndex defaults to the length of the text.\",\n\t\t\t\t\treturns: tf.void(),\n\t\t\t\t},\n\t\t\t\t[\"startIndex\", tf.union([tf.number(), tf.undefined()])],\n\t\t\t\t[\"endIndex\", tf.union([tf.number(), tf.undefined()])],\n\t\t\t),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"fullString\",\n\t\t\tbuildFunc({\n\t\t\t\tdescription: \"Return a copy of this text node's content as a string.\",\n\t\t\t\treturns: tf.string(),\n\t\t\t}),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"characterCount\",\n\t\t\tbuildFunc({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Gets the number of characters (Unicode code points) currently in the text. Joined emojis and other grapheme clusters count as multiple characters.\",\n\t\t\t\treturns: tf.number(),\n\t\t\t}),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"charactersCopy\",\n\t\t\tbuildFunc({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Returns all characters in the text as an array, where each element is a single Unicode code point. Joined emojis and other grapheme clusters are split into separate elements.\",\n\t\t\t\treturns: tf.array(tf.string()),\n\t\t\t}),\n\t\t);\n\t}\n\n\tpublic [exposeMethodsSymbol](methods: ExposedMethods): void {\n\t\tTextNode[exposeMethodsSymbol](methods);\n\t}\n\n\tpublic insertAt(index: number, additionalCharacters: string): void {\n\t\tthis.content.insertAt(\n\t\t\tindex,\n\t\t\tTreeArrayNode.spread(charactersFromString(additionalCharacters)),\n\t\t);\n\t}\n\tpublic removeRange(index: number | undefined, end: number | undefined): void {\n\t\tthis.content.removeRange(index, end);\n\t}\n\tpublic characters(): Iterable<string> {\n\t\treturn this.content[Symbol.iterator]();\n\t}\n\n\tpublic characterCount(): number {\n\t\treturn this.content.length;\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\tconst result = this.content.charactersCopy();\n\t\tdebugAssert(\n\t\t\t() =>\n\t\t\t\tcompareArrays(result, this.charactersCopy_reference()) ||\n\t\t\t\t\"invalid charactersCopy optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\tpublic fullString(): string {\n\t\tconst result = this.content.fullString();\n\t\tdebugAssert(\n\t\t\t() => result === this.fullString_reference() || \"invalid fullString optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\t/**\n\t * Unoptimized trivially correct implementation of fullString.\n\t */\n\tpublic fullString_reference(): string {\n\t\treturn this.content.join(\"\");\n\t}\n\n\t/**\n\t * Unoptimized trivially correct implementation of charactersCopy.\n\t */\n\tpublic charactersCopy_reference(): string[] {\n\t\treturn [...this.content];\n\t}\n\n\tpublic static fromString(value: string): TextNode {\n\t\t// Constructing an ArrayNode from an iterator is supported, so creating an array from the iterable of characters seems like its not necessary here,\n\t\t// but to reduce the risk of incorrect data interpretation, we actually ban this in the special case where the iterable is a string directly, which is the case here.\n\t\t// Thus the array construction here is necessary to avoid a runtime error.\n\t\treturn new TextNode({ content: [...charactersFromString(value)] });\n\t}\n}\n\n/**\n * Interpret a string as an iterable of characters.\n * @remarks\n * This mostly exists to clearly document where the code is interpreting a string as characters,\n * and provide a centralized place where validation could be added in the future if desired.\n * Additionally using this function consistently will make any refactors to support alternative character boundaries easier.\n */\nexport function charactersFromString(value: string): Iterable<string> {\n\t// Uses the string as an iterable of characters, so utf-16 surrogate pairs get grouped together correctly.\n\t// Might be nice to call isWellFormed or toWellFormed here (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toWellFormed)\n\t// But those are not widely supported yet.\n\treturn value;\n}\n\nclass StringArray extends sf.array(\"StringArray\", SchemaFactory.string) {\n\tpublic withBorrowedSequenceCursor<T>(f: (cursor: ITreeCursorSynchronous) => T): T {\n\t\tconst cursor = getInnerNode(this).borrowCursor();\n\t\tcursor.enterField(EmptyKey);\n\t\tconst result = f(cursor);\n\t\tcursor.exitField();\n\t\treturn result;\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\treturn this.withBorrowedSequenceCursor((cursor) =>\n\t\t\tmapCursorField(cursor, () => cursor.value as string),\n\t\t);\n\t}\n\n\tpublic fullString(): string {\n\t\treturn this.charactersCopy().join(\"\");\n\t}\n}\n\n/**\n * A collection of text related types, schema and utilities for working with text beyond the basic {@link SchemaStatics.string}.\n * @privateRemarks\n * Currently this API only supports a really minimal feature set, and has no support for more advanced features like:\n * - Alternative character boundaries (e.g. grapheme clusters, paragraphs, tokens, etc.).\n * We may want to provide either ways to create strings with application controlled character boundaries since there is not a clear single answer on how to break a string into atomic units.\n * - Character attributes (e.g. bold, italic, etc):\n * Properties that can be set on any character independently with optimizations for runs of characters with the same attributes.\n * - Inline objects (e.g. images, embedded components, etc):\n * These would be logically part of the text, generalizing characters to allow inline objects in character ranges.\n * How character attributes apply to inline objects is an open question\n * (there could be a kind of object which gets them, and one that doesn't for example).\n * - Annotations (e.g. comments, suggestions, etc).\n * Objects which can be associated with a range of characters but are not logically part of the text.\n * These would need to have the logical range they apply to updated by edits.\n * How edits which overlap annotation boundaries are handled may require hints from the application for optimal behavior (mainly inserts at the boundaries).\n * These get a lifetime tied to the text node, not any of the characters the annotation covers,\n * however it might be desirable to have a way for a range edit to (optionally) also remove any annotations which are fully covered by the edit.\n * Annotations over an empty range should also be supported and behave well (for example not end up with characters inside the range after edits unless specifically structured so that makes sense).\n * - Anchors (e.g. positions in the text which survive edits).\n * These would be useful for ephemeral state like cursor positions, but should match the behaviors with respect to edits exhibited by the ends of Annotations.\n *\n * How these features will be represented in the schema and API should be determined before any of this is stabilized so the simple more limited version can neatly fit into the larger design.\n *\n * There are various optimizations that should be implemented to make this performant for large texts and common usage patterns.\n * These include:\n * - Optimized persisted format.\n * - Optimized in memory representation (via chunked forest).\n * - Optimized edit persisted format (e.g. combining adjacent inserts/removes into single operations as well as support for efficient attribute editing of ranges).\n * - Optimized edit application (e.g. applying the above noted optimizable edit cases efficiently).\n * This applies to the revision manager, the forest, and any flex or simple-tree nodes and user events.\n *\n * There are also additional features required for ensuring the invariants of collaborative text editing are maintained through concurrent edits.\n * The main challenges here are related to annotations, but some policies for what to do in the case of corrupt/invalid text should also be included.\n * There are quite a few ways invariants could break, including:\n * - concurrent edits without proper constraints.\n * - collaboration with clients using compatible schema with different constraints.\n * - opening documents which contain invalid content (e.g. from older versions of the software, manual edits to the persisted format, or simply an existing corrupt case which was saved).\n * - a user inserting/constructing/importing invalid content.\n *\n * These cases could break constraints causing issues like invalided characters (empty, a utf-16 surrogate pair alone, etc) or\n * annotations which reference out of bounds character ranges.\n * Addressing these issues mainly falls into these categories:\n * - Handling of invalid content on import/construction of unhydrated nodes and/or insertion into the document (hydration).\n * - Handling of invalid content which is already part of the document (live). This should ideally include both detection and repair.\n * - Constraints on edits to prevent invalid content from being created by merges.\n * - Optimization of the constraints to reduce cases in which edits are rejected due to conflicts.\n *\n * Note that these cases of invariant violations are the same cases any component should handle, so ideally there would be a general framework or pattern for documenting and enforcing such constraints.\n *\n * Another area for future work is improved APIs for import, export and non-schema-aware use. This includes a variety of cases, including but not limited to:\n * - Insertable content format (taken by the constructor and import APIs).\n * - Customizable export formats (like a way to make exportVerbose and exportConcise flatten the text nodes to strings automatically).\n * - Customizable toJson behavior (e.g. flattening to strings, possibly via tools or patterns for custom tree stringifier).\n * - Ensure JS object APIs (like iteration, own vs inherited properties, etc) provide a good and consistent experience with respect to other nodes.\n * - Support in generateSchemaFromSimpleSchema for recognizing text nodes and generating the appropriate schema.\n * - Ensure above features work well enough to support important scenarios like AI assisted editing and document indexing for search.\n *\n * Part of that work will be establishing and documenting those patterns so other components with complex encodings can follow them,\n * in addition to implementing them for text.\n * @alpha\n */\nexport namespace TextAsTree {\n\t/**\n\t * Statics for text nodes.\n\t * @alpha\n\t */\n\texport interface Statics {\n\t\t/**\n\t\t * Construct a {@link TextAsTree.(Tree:type)} from a string, where each character (as defined by iterating over the string) becomes a single character in the text node.\n\t\t * This combines pairs of utf-16 surrogate code units into single characters as appropriate.\n\t\t */\n\t\tfromString(value: string): Tree;\n\t}\n\n\t/**\n\t * Interface for a text node.\n\t * @remarks\n\t * The string is broken up into substrings which are referred to as 'characters'.\n\t * Unlike with JavaScript strings, all indexes are by character, not UTF-16 code unit.\n\t * This avoids the problem JavaScript where it can split UTF-16 surrogate pairs producing invalid strings,\n\t * and avoids the issue where indexing a string and iterating it segment the string differently.\n\t * This does NOT mean the characters correspond to user perceived characters (like grapheme clusters try to do):\n\t * applications will likely want to include higher level segmentation logic\n\t * which might differ between operations like delete\n\t * (which often operates on something in between unicode code points and grapheme clusters)\n\t * and navigation/selection (which typically uses grapheme clusters).\n\t *\n\t * @see {@link TextAsTree.Statics.fromString} for construction.\n\t * @see {@link TextAsTree.(Tree:type)} for schema.\n\t * @alpha\n\t */\n\texport interface Members {\n\t\t/**\n\t\t * Gets an iterable over the characters currently in the text.\n\t\t * @remarks\n\t\t * This iterator matches the behavior of {@link (TreeArrayNode:interface)} with respect to edits during iteration.\n\t\t */\n\t\tcharacters(): Iterable<string>;\n\n\t\t/**\n\t\t * Optimized way to get a copy of the {@link TextAsTree.Members.characters} in an array.\n\t\t */\n\t\tcharactersCopy(): string[];\n\n\t\t/**\n\t\t * Gets the number of characters currently in the text.\n\t\t * @remarks\n\t\t * The length of {@link TextAsTree.Members.characters}.\n\t\t * This is not the length of the string returned by {@link TextAsTree.Members.fullString},\n\t\t * as that string may contain characters which are made up of multiple UTF-16 code units.\n\t\t */\n\t\tcharacterCount(): number;\n\n\t\t/**\n\t\t * Copy the content of this node into a string.\n\t\t */\n\t\tfullString(): string;\n\n\t\t/**\n\t\t * Insert a range of characters into the string based on character index.\n\t\t * @remarks\n\t\t * See {@link (TreeArrayNode:interface).insertAt} for more details on the behavior.\n\t\t * See {@link TextAsTree.Statics.fromString} for how the `additionalCharacters` string is broken into characters.\n\t\t * @privateRemarks\n\t\t * If we provide ways to customize character boundaries, that could be handled here by taking in an Iterable<string> instead of a string.\n\t\t * Doing this currently would enable insertion of text with different character boundaries than the existing text,\n\t\t * which would violate the currently documented character boundary invariants.\n\t\t *\n\t\t * Another option would be to take an approach like Table,\n\t\t * where the user of the API uses a factory function to generate the schema, and can inject custom logic, like a string character iterator.\n\t\t */\n\t\tinsertAt(index: number, additionalCharacters: string): void;\n\n\t\t/**\n\t\t * Remove a range from a string based on character index.\n\t\t * See {@link (TreeArrayNode:interface).removeRange} for more details on the behavior.\n\t\t */\n\t\tremoveRange(startIndex: number | undefined, endIndex: number | undefined): void;\n\t}\n\n\t/**\n\t * Schema for a {@link TextAsTree.(Tree:variable)} node.\n\t * @remarks\n\t * See {@link TextAsTree.Statics} for static APIs on this schema, including construction.\n\t * @alpha\n\t */\n\texport const Tree = eraseSchemaDetails<Members, Statics>()(TextNode);\n\n\t/**\n\t * Node for the {@link TextAsTree.(Tree:type)} schema exposing the {@link TextAsTree.Members} API.\n\t * @remarks\n\t * Create using {@link TextAsTree.Statics.fromString}.\n\t * @alpha\n\t */\n\texport type Tree = Members & TreeNode & WithType<\"com.fluidframework.text.Text\">;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"textDomain.js","sourceRoot":"","sources":["../../src/text/textDomain.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAiF;AACjF,8DAM4C;AAC5C,oEAA0E;AAE1E,+CAAyF;AACzF,sDAAoD;AACpD,sDAMiC;AAajC,MAAM,EAAE,GAAG,IAAI,6BAAkB,CAAC,yBAAyB,CAAC,CAAC;AAE7D,MAAM,QACL,SAAQ,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE;IACzB,OAAO,EAAE,wBAAa,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,mBAAQ,EAAE,CAAC;CACvE,CAAC;IAGK,MAAM,CAAC,CAAC,2BAAmB,CAAC,CAAC,OAAuB;QAC1D,OAAO,CAAC,YAAY,CACnB,QAAQ,EACR,UAAU,EACV,IAAA,iBAAS,EACR;YACC,WAAW,EACV,qFAAqF;YACtF,OAAO,EAAE,sBAAE,CAAC,IAAI,EAAE;SAClB,EACD,CAAC,OAAO,EAAE,sBAAE,CAAC,MAAM,EAAE,CAAC,EACtB,CAAC,sBAAsB,EAAE,sBAAE,CAAC,MAAM,EAAE,CAAC,CACrC,CACD,CAAC;QACF,OAAO,CAAC,YAAY,CACnB,QAAQ,EACR,aAAa,EACb,IAAA,iBAAS,EACR;YACC,WAAW,EACV,gKAAgK;YACjK,OAAO,EAAE,sBAAE,CAAC,IAAI,EAAE;SAClB,EACD,CAAC,YAAY,EAAE,sBAAE,CAAC,KAAK,CAAC,CAAC,sBAAE,CAAC,MAAM,EAAE,EAAE,sBAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EACvD,CAAC,UAAU,EAAE,sBAAE,CAAC,KAAK,CAAC,CAAC,sBAAE,CAAC,MAAM,EAAE,EAAE,sBAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CACrD,CACD,CAAC;QACF,OAAO,CAAC,YAAY,CACnB,QAAQ,EACR,YAAY,EACZ,IAAA,iBAAS,EAAC;YACT,WAAW,EAAE,wDAAwD;YACrE,OAAO,EAAE,sBAAE,CAAC,MAAM,EAAE;SACpB,CAAC,CACF,CAAC;QACF,OAAO,CAAC,YAAY,CACnB,QAAQ,EACR,gBAAgB,EAChB,IAAA,iBAAS,EAAC;YACT,WAAW,EACV,oJAAoJ;YACrJ,OAAO,EAAE,sBAAE,CAAC,MAAM,EAAE;SACpB,CAAC,CACF,CAAC;QACF,OAAO,CAAC,YAAY,CACnB,QAAQ,EACR,gBAAgB,EAChB,IAAA,iBAAS,EAAC;YACT,WAAW,EACV,gLAAgL;YACjL,OAAO,EAAE,sBAAE,CAAC,KAAK,CAAC,sBAAE,CAAC,MAAM,EAAE,CAAC;SAC9B,CAAC,CACF,CAAC;IACH,CAAC;IAEM,CAAC,2BAAmB,CAAC,CAAC,OAAuB;QACnD,QAAQ,CAAC,2BAAmB,CAAC,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAEM,QAAQ,CAAC,KAAa,EAAE,oBAA4B;QAC1D,IAAI,CAAC,OAAO,CAAC,QAAQ,CACpB,KAAK,EACL,wBAAa,CAAC,MAAM,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,CAAC,CAChE,CAAC;IACH,CAAC;IACM,WAAW,CAAC,KAAyB,EAAE,GAAuB;QACpE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IACM,UAAU;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxC,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5B,CAAC;IAEM,cAAc;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC7C,IAAA,sBAAW,EACV,GAAG,EAAE,CACJ,IAAA,wBAAa,EAAC,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACtD,sCAAsC,CACvC,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,UAAU;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACzC,IAAA,sBAAW,EACV,GAAG,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,oBAAoB,EAAE,IAAI,kCAAkC,CAClF,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;OAEG;IACI,oBAAoB;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,wBAAwB;QAC9B,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAEM,mBAAmB,CACzB,QAAiE;QAEjE,OAAO,oBAAS,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAC9D,6BAA6B,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CACtE,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,KAAa;QACrC,mJAAmJ;QACnJ,qKAAqK;QACrK,0EAA0E;QAC1E,OAAO,IAAI,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;CACD;AAED;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAC,KAAa;IACjD,0GAA0G;IAC1G,iKAAiK;IACjK,0CAA0C;IAC1C,OAAO,KAAK,CAAC;AACd,CAAC;AALD,oDAKC;AAED,MAAM,WAAY,SAAQ,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,wBAAa,CAAC,MAAM,CAAC;IAC/D,0BAA0B,CAAI,CAAwC;QAC5E,MAAM,MAAM,GAAG,IAAA,uBAAY,EAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;QACjD,MAAM,CAAC,UAAU,CAAC,mBAAQ,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,0BAA0B,CAAC,CAAC,MAAM,EAAE,EAAE,CACjD,IAAA,yBAAc,EAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAe,CAAC,CACpD,CAAC;IACH,CAAC;IAEM,UAAU;QAChB,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;CACD;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,6BAA6B,CAC5C,KAA8E,EAC9E,YAAmD,EACnD,QAAiE;IAEjE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpB,OAAO;IACR,CAAC;IACD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,4EAA4E;YAC5E,GAAG,CAAC,IAAI,CACP,gBAAgB,IAAI,EAAE;gBACrB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,CAAC,cAAc,KAAK,IAAI,EAAE;gBACpF,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CACtC,CAAC;YACF,YAAY,IAAI,EAAE,CAAC,KAAK,CAAC;QAC1B,CAAC;aAAM,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACjC,mFAAmF;YACnF,6EAA6E;YAC7E,MAAM,UAAU,GAAa,EAAE,CAAC;YAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBACnC,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC7C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;oBAC7B,kEAAkE;oBAClE,QAAQ,CAAC,SAAS,CAAC,CAAC;oBACpB,OAAO;gBACR,CAAC;gBACD,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC3B,YAAY,EAAE,CAAC;YAChB,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACP,+EAA+E;YAC/E,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC;IACD,QAAQ,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAzCD,sEAyCC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,IAAiB,UAAU,CAgL1B;AAhLD,WAAiB,UAAU;IAiK1B;;;;;OAKG;IACU,eAAI,GAAG,IAAA,6BAAkB,GAAoB,CAAC,QAAQ,CAAC,CAAC;AAStE,CAAC,EAhLgB,UAAU,0BAAV,UAAU,QAgL1B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { compareArrays, debugAssert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tbuildFunc,\n\texposeMethodsSymbol,\n\ttype ExposedMethods,\n\ttype IExposedMethods,\n\t// eslint-disable-next-line import-x/no-internal-modules\n} from \"@fluidframework/type-factory/alpha\";\nimport { typeFactory as tf } from \"@fluidframework/type-factory/internal\";\n\nimport { EmptyKey, mapCursorField, type ITreeCursorSynchronous } from \"../core/index.js\";\nimport { TreeAlpha } from \"../shared-tree/index.js\";\nimport {\n\teraseSchemaDetails,\n\tgetInnerNode,\n\tSchemaFactory,\n\tSchemaFactoryAlpha,\n\tTreeArrayNode,\n} from \"../simple-tree/index.js\";\nimport type {\n\tArrayNodeDeltaOp,\n\tArrayNodeTreeChangedDeltaOp,\n\tTreeNode,\n\tWithType,\n\t// eslint-disable-next-line import-x/no-duplicates\n} from \"../simple-tree/index.js\";\n// Add some unused imports which show up in the generated d.ts file.\n// This prevents them from getting inline imports generated, cleaning up the d.ts file and API reports.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports, import-x/no-duplicates\nimport type { NodeKind, TreeNodeSchema } from \"../simple-tree/index.js\";\n\nconst sf = new SchemaFactoryAlpha(\"com.fluidframework.text\");\n\nclass TextNode\n\textends sf.object(\"Text\", {\n\t\tcontent: SchemaFactory.required([() => StringArray], { key: EmptyKey }),\n\t})\n\timplements TextAsTree.Members, IExposedMethods\n{\n\tpublic static [exposeMethodsSymbol](methods: ExposedMethods): void {\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"insertAt\",\n\t\t\tbuildFunc(\n\t\t\t\t{\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Insert characters into the text at the given character index (Unicode code points).\",\n\t\t\t\t\treturns: tf.void(),\n\t\t\t\t},\n\t\t\t\t[\"index\", tf.number()],\n\t\t\t\t[\"additionalCharacters\", tf.string()],\n\t\t\t),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"removeRange\",\n\t\t\tbuildFunc(\n\t\t\t\t{\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Remove a range of characters from the text by character index (Unicode code points). startIndex defaults to 0 and endIndex defaults to the length of the text.\",\n\t\t\t\t\treturns: tf.void(),\n\t\t\t\t},\n\t\t\t\t[\"startIndex\", tf.union([tf.number(), tf.undefined()])],\n\t\t\t\t[\"endIndex\", tf.union([tf.number(), tf.undefined()])],\n\t\t\t),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"fullString\",\n\t\t\tbuildFunc({\n\t\t\t\tdescription: \"Return a copy of this text node's content as a string.\",\n\t\t\t\treturns: tf.string(),\n\t\t\t}),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"characterCount\",\n\t\t\tbuildFunc({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Gets the number of characters (Unicode code points) currently in the text. Joined emojis and other grapheme clusters count as multiple characters.\",\n\t\t\t\treturns: tf.number(),\n\t\t\t}),\n\t\t);\n\t\tmethods.exposeMethod(\n\t\t\tTextNode,\n\t\t\t\"charactersCopy\",\n\t\t\tbuildFunc({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Returns all characters in the text as an array, where each element is a single Unicode code point. Joined emojis and other grapheme clusters are split into separate elements.\",\n\t\t\t\treturns: tf.array(tf.string()),\n\t\t\t}),\n\t\t);\n\t}\n\n\tpublic [exposeMethodsSymbol](methods: ExposedMethods): void {\n\t\tTextNode[exposeMethodsSymbol](methods);\n\t}\n\n\tpublic insertAt(index: number, additionalCharacters: string): void {\n\t\tthis.content.insertAt(\n\t\t\tindex,\n\t\t\tTreeArrayNode.spread(charactersFromString(additionalCharacters)),\n\t\t);\n\t}\n\tpublic removeRange(index: number | undefined, end: number | undefined): void {\n\t\tthis.content.removeRange(index, end);\n\t}\n\tpublic characters(): Iterable<string> {\n\t\treturn this.content[Symbol.iterator]();\n\t}\n\n\tpublic characterCount(): number {\n\t\treturn this.content.length;\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\tconst result = this.content.charactersCopy();\n\t\tdebugAssert(\n\t\t\t() =>\n\t\t\t\tcompareArrays(result, this.charactersCopy_reference()) ||\n\t\t\t\t\"invalid charactersCopy optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\tpublic fullString(): string {\n\t\tconst result = this.content.fullString();\n\t\tdebugAssert(\n\t\t\t() => result === this.fullString_reference() || \"invalid fullString optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\t/**\n\t * Unoptimized trivially correct implementation of fullString.\n\t */\n\tpublic fullString_reference(): string {\n\t\treturn this.content.join(\"\");\n\t}\n\n\t/**\n\t * Unoptimized trivially correct implementation of charactersCopy.\n\t */\n\tpublic charactersCopy_reference(): string[] {\n\t\treturn [...this.content];\n\t}\n\n\tpublic onCharactersChanged(\n\t\tcallback: (ops: readonly TextAsTree.TextOp[] | undefined) => void,\n\t): () => void {\n\t\treturn TreeAlpha.on(this.content, \"nodeChanged\", ({ delta }) =>\n\t\t\tprocessCharactersChangedDelta(delta, (i) => this.content[i], callback),\n\t\t);\n\t}\n\n\tpublic static fromString(value: string): TextNode {\n\t\t// Constructing an ArrayNode from an iterator is supported, so creating an array from the iterable of characters seems like its not necessary here,\n\t\t// but to reduce the risk of incorrect data interpretation, we actually ban this in the special case where the iterable is a string directly, which is the case here.\n\t\t// Thus the array construction here is necessary to avoid a runtime error.\n\t\treturn new TextNode({ content: [...charactersFromString(value)] });\n\t}\n}\n\n/**\n * Interpret a string as an iterable of characters.\n * @remarks\n * This mostly exists to clearly document where the code is interpreting a string as characters,\n * and provide a centralized place where validation could be added in the future if desired.\n * Additionally using this function consistently will make any refactors to support alternative character boundaries easier.\n */\nexport function charactersFromString(value: string): Iterable<string> {\n\t// Uses the string as an iterable of characters, so utf-16 surrogate pairs get grouped together correctly.\n\t// Might be nice to call isWellFormed or toWellFormed here (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toWellFormed)\n\t// But those are not widely supported yet.\n\treturn value;\n}\n\nclass StringArray extends sf.array(\"StringArray\", SchemaFactory.string) {\n\tpublic withBorrowedSequenceCursor<T>(f: (cursor: ITreeCursorSynchronous) => T): T {\n\t\tconst cursor = getInnerNode(this).borrowCursor();\n\t\tcursor.enterField(EmptyKey);\n\t\tconst result = f(cursor);\n\t\tcursor.exitField();\n\t\treturn result;\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\treturn this.withBorrowedSequenceCursor((cursor) =>\n\t\t\tmapCursorField(cursor, () => cursor.value as string),\n\t\t);\n\t}\n\n\tpublic fullString(): string {\n\t\treturn this.charactersCopy().join(\"\");\n\t}\n}\n\n/**\n * Processes an array-node delta into a {@link TextAsTree.TextOp}[] and calls `callback`.\n * @remarks\n * Shared by both the plain `onCharactersChanged` (from `nodeChanged`) and formatted `onContentChanged`\n * (from `treeChanged`) implementations.\n * @param delta - The raw array-node delta, or `undefined` when no delta is available.\n * When retain ops carry `subtreeChanged` (i.e. delta comes from a `treeChanged` event), the emitted\n * retain ops include an explicit `formattingChanged: boolean`. Otherwise `formattingChanged` is omitted.\n * @param getCharacter - Returns the character string at the given array index in the **post-edit** tree.\n * Only invoked for insert ops, where it must read the inserted character at the given index of the tree\n * after the edit has been applied. Passing an accessor that reads pre-edit content will silently produce wrong text.\n * Return `undefined` if the tree is out of sync with the delta; this triggers a full-reread fallback.\n * @param callback - The user-supplied callback to invoke with the translated ops.\n */\nexport function processCharactersChangedDelta(\n\tdelta: readonly (ArrayNodeDeltaOp | ArrayNodeTreeChangedDeltaOp)[] | undefined,\n\tgetCharacter: (index: number) => string | undefined,\n\tcallback: (ops: readonly TextAsTree.TextOp[] | undefined) => void,\n): void {\n\tif (delta === undefined) {\n\t\tcallback(undefined);\n\t\treturn;\n\t}\n\tlet readPosition = 0;\n\tconst ops: TextAsTree.TextOp[] = [];\n\tfor (const op of delta) {\n\t\tif (op.type === \"retain\") {\n\t\t\t// `subtreeChanged` is only present on retain ops from `treeChanged` deltas.\n\t\t\tops.push(\n\t\t\t\t\"subtreeChanged\" in op\n\t\t\t\t\t? { type: \"retain\", count: op.count, formattingChanged: op.subtreeChanged === true }\n\t\t\t\t\t: { type: \"retain\", count: op.count },\n\t\t\t);\n\t\t\treadPosition += op.count;\n\t\t} else if (op.type === \"insert\") {\n\t\t\t// Accumulate into an array and join at the end to keep this O(n) for large inserts\n\t\t\t// (paste of long text) instead of O(n^2) from repeated string concatenation.\n\t\t\tconst characters: string[] = [];\n\t\t\tfor (let i = 0; i < op.count; i++) {\n\t\t\t\tconst character = getCharacter(readPosition);\n\t\t\t\tif (character === undefined) {\n\t\t\t\t\t// Tree is out of sync with the delta — fall back to full re-read.\n\t\t\t\t\tcallback(undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcharacters.push(character);\n\t\t\t\treadPosition++;\n\t\t\t}\n\t\t\tops.push({ type: \"insert\", text: characters.join(\"\") });\n\t\t} else {\n\t\t\t// Construct explicit remove op so internal fields on the source op don't leak.\n\t\t\tops.push({ type: \"remove\", count: op.count });\n\t\t}\n\t}\n\tcallback(ops);\n}\n\n/**\n * A collection of text related types, schema and utilities for working with text beyond the basic {@link SchemaStatics.string}.\n * @privateRemarks\n * Currently this API only supports a really minimal feature set, and has no support for more advanced features like:\n * - Alternative character boundaries (e.g. grapheme clusters, paragraphs, tokens, etc.).\n * We may want to provide either ways to create strings with application controlled character boundaries since there is not a clear single answer on how to break a string into atomic units.\n * - Character attributes (e.g. bold, italic, etc):\n * Properties that can be set on any character independently with optimizations for runs of characters with the same attributes.\n * - Inline objects (e.g. images, embedded components, etc):\n * These would be logically part of the text, generalizing characters to allow inline objects in character ranges.\n * How character attributes apply to inline objects is an open question\n * (there could be a kind of object which gets them, and one that doesn't for example).\n * - Annotations (e.g. comments, suggestions, etc).\n * Objects which can be associated with a range of characters but are not logically part of the text.\n * These would need to have the logical range they apply to updated by edits.\n * How edits which overlap annotation boundaries are handled may require hints from the application for optimal behavior (mainly inserts at the boundaries).\n * These get a lifetime tied to the text node, not any of the characters the annotation covers,\n * however it might be desirable to have a way for a range edit to (optionally) also remove any annotations which are fully covered by the edit.\n * Annotations over an empty range should also be supported and behave well (for example not end up with characters inside the range after edits unless specifically structured so that makes sense).\n * - Anchors (e.g. positions in the text which survive edits).\n * These would be useful for ephemeral state like cursor positions, but should match the behaviors with respect to edits exhibited by the ends of Annotations.\n *\n * How these features will be represented in the schema and API should be determined before any of this is stabilized so the simple more limited version can neatly fit into the larger design.\n *\n * There are various optimizations that should be implemented to make this performant for large texts and common usage patterns.\n * These include:\n * - Optimized persisted format.\n * - Optimized in memory representation (via chunked forest).\n * - Optimized edit persisted format (e.g. combining adjacent inserts/removes into single operations as well as support for efficient attribute editing of ranges).\n * - Optimized edit application (e.g. applying the above noted optimizable edit cases efficiently).\n * This applies to the revision manager, the forest, and any flex or simple-tree nodes and user events.\n *\n * There are also additional features required for ensuring the invariants of collaborative text editing are maintained through concurrent edits.\n * The main challenges here are related to annotations, but some policies for what to do in the case of corrupt/invalid text should also be included.\n * There are quite a few ways invariants could break, including:\n * - concurrent edits without proper constraints.\n * - collaboration with clients using compatible schema with different constraints.\n * - opening documents which contain invalid content (e.g. from older versions of the software, manual edits to the persisted format, or simply an existing corrupt case which was saved).\n * - a user inserting/constructing/importing invalid content.\n *\n * These cases could break constraints causing issues like invalided characters (empty, a utf-16 surrogate pair alone, etc) or\n * annotations which reference out of bounds character ranges.\n * Addressing these issues mainly falls into these categories:\n * - Handling of invalid content on import/construction of unhydrated nodes and/or insertion into the document (hydration).\n * - Handling of invalid content which is already part of the document (live). This should ideally include both detection and repair.\n * - Constraints on edits to prevent invalid content from being created by merges.\n * - Optimization of the constraints to reduce cases in which edits are rejected due to conflicts.\n *\n * Note that these cases of invariant violations are the same cases any component should handle, so ideally there would be a general framework or pattern for documenting and enforcing such constraints.\n *\n * Another area for future work is improved APIs for import, export and non-schema-aware use. This includes a variety of cases, including but not limited to:\n * - Insertable content format (taken by the constructor and import APIs).\n * - Customizable export formats (like a way to make exportVerbose and exportConcise flatten the text nodes to strings automatically).\n * - Customizable toJson behavior (e.g. flattening to strings, possibly via tools or patterns for custom tree stringifier).\n * - Ensure JS object APIs (like iteration, own vs inherited properties, etc) provide a good and consistent experience with respect to other nodes.\n * - Support in generateSchemaFromSimpleSchema for recognizing text nodes and generating the appropriate schema.\n * - Ensure above features work well enough to support important scenarios like AI assisted editing and document indexing for search.\n *\n * Part of that work will be establishing and documenting those patterns so other components with complex encodings can follow them,\n * in addition to implementing them for text.\n * @alpha\n */\nexport namespace TextAsTree {\n\t/**\n\t * A retain op in a character-level delta — a span of unchanged characters that the consumer should skip over.\n\t * @sealed\n\t * @alpha\n\t */\n\texport interface TextRetainOp {\n\t\t/**\n\t\t * Discriminator identifying this op as a retain.\n\t\t */\n\t\treadonly type: \"retain\";\n\t\t/**\n\t\t * The number of Unicode code points to retain.\n\t\t */\n\t\treadonly count: number;\n\t\t/**\n\t\t * Whether at least one character in the retained range had a deep change.\n\t\t * @remarks\n\t\t * Present only on retain ops delivered by {@link @fluidframework/tree#FormattedTextAsTree.Members.onContentChanged};\n\t\t * always absent on retain ops delivered by {@link TextAsTree.Members.onCharactersChanged}.\n\t\t * When present, `true` indicates the retained range contained a formatting property update\n\t\t * or an atom content edit; `false` indicates no deep change.\n\t\t */\n\t\treadonly formattingChanged?: boolean;\n\t}\n\n\t/**\n\t * An insert op in a character-level delta — characters newly added to the text.\n\t * @remarks\n\t * Carries the inserted text as a single string, which is more convenient for consumers than individual characters.\n\t * @sealed\n\t * @alpha\n\t */\n\texport interface TextInsertOp {\n\t\t/**\n\t\t * Discriminator identifying this op as an insert.\n\t\t */\n\t\treadonly type: \"insert\";\n\t\t/**\n\t\t * The newly inserted characters, concatenated into a single string.\n\t\t */\n\t\treadonly text: string;\n\t}\n\n\t/**\n\t * A remove op in a character-level delta — a span of characters that has been deleted from the text.\n\t * @sealed\n\t * @alpha\n\t */\n\texport interface TextRemoveOp {\n\t\t/**\n\t\t * Discriminator identifying this op as a remove.\n\t\t */\n\t\treadonly type: \"remove\";\n\t\t/**\n\t\t * The number of Unicode code points removed.\n\t\t */\n\t\treadonly count: number;\n\t}\n\n\t/**\n\t * A single operation in a character-level delta describing an insert, remove, or retain of text.\n\t * @alpha\n\t */\n\texport type TextOp = TextRetainOp | TextInsertOp | TextRemoveOp;\n\n\t/**\n\t * Statics for text nodes.\n\t * @alpha\n\t */\n\texport interface Statics {\n\t\t/**\n\t\t * Construct a {@link TextAsTree.(Tree:type)} from a string, where each character (as defined by iterating over the string) becomes a single character in the text node.\n\t\t * This combines pairs of utf-16 surrogate code units into single characters as appropriate.\n\t\t */\n\t\tfromString(value: string): Tree;\n\t}\n\n\t/**\n\t * Interface for a text node.\n\t * @remarks\n\t * The string is broken up into substrings which are referred to as 'characters'.\n\t * Unlike with JavaScript strings, all indexes are by character, not UTF-16 code unit.\n\t * This avoids the problem JavaScript where it can split UTF-16 surrogate pairs producing invalid strings,\n\t * and avoids the issue where indexing a string and iterating it segment the string differently.\n\t * This does NOT mean the characters correspond to user perceived characters (like grapheme clusters try to do):\n\t * applications will likely want to include higher level segmentation logic\n\t * which might differ between operations like delete\n\t * (which often operates on something in between unicode code points and grapheme clusters)\n\t * and navigation/selection (which typically uses grapheme clusters).\n\t *\n\t * @see {@link TextAsTree.Statics.fromString} for construction.\n\t * @see {@link TextAsTree.(Tree:type)} for schema.\n\t * @sealed\n\t * @alpha\n\t */\n\texport interface Members {\n\t\t/**\n\t\t * Gets an iterable over the characters currently in the text.\n\t\t * @remarks\n\t\t * This iterator matches the behavior of {@link (TreeArrayNode:interface)} with respect to edits during iteration.\n\t\t */\n\t\tcharacters(): Iterable<string>;\n\n\t\t/**\n\t\t * Optimized way to get a copy of the {@link TextAsTree.Members.characters} in an array.\n\t\t */\n\t\tcharactersCopy(): string[];\n\n\t\t/**\n\t\t * Gets the number of characters currently in the text.\n\t\t * @remarks\n\t\t * The length of {@link TextAsTree.Members.characters}.\n\t\t * This is not the length of the string returned by {@link TextAsTree.Members.fullString},\n\t\t * as that string may contain characters which are made up of multiple UTF-16 code units.\n\t\t */\n\t\tcharacterCount(): number;\n\n\t\t/**\n\t\t * Copy the content of this node into a string.\n\t\t */\n\t\tfullString(): string;\n\n\t\t/**\n\t\t * Insert a range of characters into the string based on character index.\n\t\t * @remarks\n\t\t * See {@link (TreeArrayNode:interface).insertAt} for more details on the behavior.\n\t\t * See {@link TextAsTree.Statics.fromString} for how the `additionalCharacters` string is broken into characters.\n\t\t * @privateRemarks\n\t\t * If we provide ways to customize character boundaries, that could be handled here by taking in an Iterable<string> instead of a string.\n\t\t * Doing this currently would enable insertion of text with different character boundaries than the existing text,\n\t\t * which would violate the currently documented character boundary invariants.\n\t\t *\n\t\t * Another option would be to take an approach like Table,\n\t\t * where the user of the API uses a factory function to generate the schema, and can inject custom logic, like a string character iterator.\n\t\t */\n\t\tinsertAt(index: number, additionalCharacters: string): void;\n\n\t\t/**\n\t\t * Remove a range from a string based on character index.\n\t\t * See {@link (TreeArrayNode:interface).removeRange} for more details on the behavior.\n\t\t */\n\t\tremoveRange(startIndex: number | undefined, endIndex: number | undefined): void;\n\n\t\t/**\n\t\t * Subscribe to shallow character-level changes on this text node — inserts and removes only.\n\t\t * @param callback - Called after each change with a sequence of {@link TextAsTree.TextOp}s describing what changed,\n\t\t * or `undefined` when a delta could not be computed (e.g. during a schema upgrade).\n\t\t * @returns A cleanup function that unsubscribes the callback when called.\n\t\t * @remarks\n\t\t * Only fires on shallow changes — inserts and removes.\n\t\t * It does not fire on deep changes such as formatting property updates on existing characters.\n\t\t * For formatted text, use {@link @fluidframework/tree#FormattedTextAsTree.Members.onContentChanged} to also receive deep changes.\n\t\t *\n\t\t * All counts in the delivered ops are in Unicode code points, not UTF-16 code units.\n\t\t * For characters outside the Basic Multilingual Plane (e.g. emoji), one code point\n\t\t * corresponds to two UTF-16 code units — convert before using the counts as string indices.\n\t\t */\n\t\tonCharactersChanged(callback: (ops: readonly TextOp[] | undefined) => void): () => void;\n\t}\n\n\t/**\n\t * Schema for a {@link TextAsTree.(Tree:variable)} node.\n\t * @remarks\n\t * See {@link TextAsTree.Statics} for static APIs on this schema, including construction.\n\t * @alpha\n\t */\n\texport const Tree = eraseSchemaDetails<Members, Statics>()(TextNode);\n\n\t/**\n\t * Node for the {@link TextAsTree.(Tree:type)} schema exposing the {@link TextAsTree.Members} API.\n\t * @remarks\n\t * Create using {@link TextAsTree.Statics.fromString}.\n\t * @alpha\n\t */\n\texport type Tree = Members & TreeNode & WithType<\"com.fluidframework.text.Text\">;\n}\n"]}
|
|
@@ -31,7 +31,7 @@ export declare namespace FormattedTextAsTree {
|
|
|
31
31
|
/**
|
|
32
32
|
* The underlying text content of this atom.
|
|
33
33
|
* @remarks
|
|
34
|
-
* This is typically a single
|
|
34
|
+
* This is typically a single Unicode code point, and thus may contain multiple UTF-16 surrogate pair code units.
|
|
35
35
|
* Using longer strings is still valid. For example, so users might store whole grapheme clusters here, or even longer sections of text.
|
|
36
36
|
* Anything combined into a single atom will be treated atomically, and can not be partially selected or formatted.
|
|
37
37
|
* Using larger atoms and splitting them as needed is NOT a recommended approach, since this will result in poor merge behavior for concurrent edits.
|
|
@@ -46,7 +46,7 @@ export declare namespace FormattedTextAsTree {
|
|
|
46
46
|
/**
|
|
47
47
|
* The underlying text content of this atom.
|
|
48
48
|
* @remarks
|
|
49
|
-
* This is typically a single
|
|
49
|
+
* This is typically a single Unicode code point, and thus may contain multiple UTF-16 surrogate pair code units.
|
|
50
50
|
* Using longer strings is still valid. For example, so users might store whole grapheme clusters here, or even longer sections of text.
|
|
51
51
|
* Anything combined into a single atom will be treated atomically, and can not be partially selected or formatted.
|
|
52
52
|
* Using larger atoms and splitting them as needed is NOT a recommended approach, since this will result in poor merge behavior for concurrent edits.
|
|
@@ -84,8 +84,8 @@ export declare namespace FormattedTextAsTree {
|
|
|
84
84
|
h4: import("../simple-tree/index.js").TreeNodeSchemaClass<"com.fluidframework.text.formatted.lineTag.h4" | "com.h4", import("../simple-tree/index.js").NodeKind.Object, TreeNode & {
|
|
85
85
|
readonly value: "h4";
|
|
86
86
|
}, Record<string, never>, true, Record<string, never>, undefined>;
|
|
87
|
-
|
|
88
|
-
readonly value: "
|
|
87
|
+
checked: import("../simple-tree/index.js").TreeNodeSchemaClass<"com.fluidframework.text.formatted.lineTag.checked" | "com.checked", import("../simple-tree/index.js").NodeKind.Object, TreeNode & {
|
|
88
|
+
readonly value: "checked";
|
|
89
89
|
}, Record<string, never>, true, Record<string, never>, undefined>;
|
|
90
90
|
h5: import("../simple-tree/index.js").TreeNodeSchemaClass<"com.fluidframework.text.formatted.lineTag.h5" | "com.h5", import("../simple-tree/index.js").NodeKind.Object, TreeNode & {
|
|
91
91
|
readonly value: "h5";
|
|
@@ -93,8 +93,8 @@ export declare namespace FormattedTextAsTree {
|
|
|
93
93
|
li: import("../simple-tree/index.js").TreeNodeSchemaClass<"com.fluidframework.text.formatted.lineTag.li" | "com.li", import("../simple-tree/index.js").NodeKind.Object, TreeNode & {
|
|
94
94
|
readonly value: "li";
|
|
95
95
|
}, Record<string, never>, true, Record<string, never>, undefined>;
|
|
96
|
-
|
|
97
|
-
readonly value: "
|
|
96
|
+
ol: import("../simple-tree/index.js").TreeNodeSchemaClass<"com.fluidframework.text.formatted.lineTag.ol" | "com.ol", import("../simple-tree/index.js").NodeKind.Object, TreeNode & {
|
|
97
|
+
readonly value: "ol";
|
|
98
98
|
}, Record<string, never>, true, Record<string, never>, undefined>;
|
|
99
99
|
unchecked: import("../simple-tree/index.js").TreeNodeSchemaClass<"com.fluidframework.text.formatted.lineTag.unchecked" | "com.unchecked", import("../simple-tree/index.js").NodeKind.Object, TreeNode & {
|
|
100
100
|
readonly value: "unchecked";
|
|
@@ -871,6 +871,24 @@ export declare namespace FormattedTextAsTree {
|
|
|
871
871
|
* @param endIndex - Optional ending index (exclusive). Defaults to the end of the text.
|
|
872
872
|
*/
|
|
873
873
|
getString(startIndex: number, endIndex?: number): string;
|
|
874
|
+
/**
|
|
875
|
+
* Subscribe to all content changes on this text node, including both shallow
|
|
876
|
+
* changes (inserts/removes) and deep changes (formatting updates on existing characters).
|
|
877
|
+
* @param callback - Called after each change with a sequence of {@link TextAsTree.TextOp}s describing what changed,
|
|
878
|
+
* or `undefined` when a delta could not be computed (e.g. during a schema upgrade).
|
|
879
|
+
* @returns A cleanup function that unsubscribes the callback when called.
|
|
880
|
+
* @remarks
|
|
881
|
+
* Unlike {@link TextAsTree.Members.onCharactersChanged} which only fires on
|
|
882
|
+
* shallow changes (inserts and removes), this method also fires on deep changes —
|
|
883
|
+
* formatting property updates on existing characters.
|
|
884
|
+
* The {@link TextAsTree.TextRetainOp.formattingChanged} flag on retain ops
|
|
885
|
+
* indicates which character ranges had formatting updates.
|
|
886
|
+
*
|
|
887
|
+
* All counts in the delivered ops are in Unicode code points, not UTF-16 code units.
|
|
888
|
+
* For characters outside the Basic Multilingual Plane (e.g. emoji), one code point
|
|
889
|
+
* corresponds to two UTF-16 code units — convert before using the counts as string indices.
|
|
890
|
+
*/
|
|
891
|
+
onContentChanged(callback: (ops: readonly TextAsTree.TextOp[] | undefined) => void): () => void;
|
|
874
892
|
}
|
|
875
893
|
/**
|
|
876
894
|
* Schema for a text node.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textDomainFormatted.d.ts","sourceRoot":"","sources":["../../src/text/textDomainFormatted.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsBH,OAAO,KAAK,EACX,mBAAmB,EACnB,QAAQ,EACR,gCAAgC,EAChC,QAAQ,EACR,MAAM,yBAAyB,CAAC;AAGjC,OAAO,
|
|
1
|
+
{"version":3,"file":"textDomainFormatted.d.ts","sourceRoot":"","sources":["../../src/text/textDomainFormatted.ts"],"names":[],"mappings":"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"}
|
|
@@ -101,6 +101,15 @@ class TextNode extends sf.object("Text", {
|
|
|
101
101
|
// If this node does not have a corresponding branch, then it is unhydrated.
|
|
102
102
|
// I.e., it is not part of a collaborative session yet.
|
|
103
103
|
// Therefore, we don't need to run the edits as a transaction.
|
|
104
|
+
// Note: for unhydrated nodes each atom edit fires a separate `treeChanged` event,
|
|
105
|
+
// so formatting N atoms will produce N callbacks on `onContentChanged` subscribers
|
|
106
|
+
// instead of the single callback that hydrated (transacted) edits produce.
|
|
107
|
+
// `withBufferedTreeEvents` is not a viable mitigation here: when more than one atom's
|
|
108
|
+
// `format` field changes within the same buffered scope, the kernel's per-field
|
|
109
|
+
// dedup logic discards the delta (see `treeNodeKernel.ts` `#fieldMarksBuffer`),
|
|
110
|
+
// which is worse for incremental consumers than N well-formed callbacks.
|
|
111
|
+
// Use `runTransaction` on a hydrated node (i.e. after inserting into the document)
|
|
112
|
+
// if batched events matter.
|
|
104
113
|
applyFormatting();
|
|
105
114
|
}
|
|
106
115
|
else {
|
|
@@ -110,6 +119,25 @@ class TextNode extends sf.object("Text", {
|
|
|
110
119
|
});
|
|
111
120
|
}
|
|
112
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Returns the character string at the given atom index, or `undefined` if out of bounds.
|
|
124
|
+
* @remarks
|
|
125
|
+
* Line atoms expand to `"\n"`; text atoms return their underlying code point(s).
|
|
126
|
+
*/
|
|
127
|
+
getAtomCharacterAt(index) {
|
|
128
|
+
const atom = this.content[index];
|
|
129
|
+
if (atom === undefined)
|
|
130
|
+
return undefined;
|
|
131
|
+
return atom.content instanceof FormattedTextAsTree.StringLineAtom
|
|
132
|
+
? "\n"
|
|
133
|
+
: atom.content.content;
|
|
134
|
+
}
|
|
135
|
+
onCharactersChanged(callback) {
|
|
136
|
+
return index_js_3.TreeAlpha.on(this.content, "nodeChanged", ({ delta }) => (0, textDomain_js_1.processCharactersChangedDelta)(delta, (index) => this.getAtomCharacterAt(index), callback));
|
|
137
|
+
}
|
|
138
|
+
onContentChanged(callback) {
|
|
139
|
+
return index_js_3.TreeAlpha.on(this.content, "treeChanged", ({ delta }) => (0, textDomain_js_1.processCharactersChangedDelta)(delta, (index) => this.getAtomCharacterAt(index), callback));
|
|
140
|
+
}
|
|
113
141
|
getUniformRun(startIndex, endIndex) {
|
|
114
142
|
return this.content.getUniformRun(startIndex, endIndex);
|
|
115
143
|
}
|
|
@@ -269,7 +297,7 @@ var FormattedTextAsTree;
|
|
|
269
297
|
/**
|
|
270
298
|
* The underlying text content of this atom.
|
|
271
299
|
* @remarks
|
|
272
|
-
* This is typically a single
|
|
300
|
+
* This is typically a single Unicode code point, and thus may contain multiple UTF-16 surrogate pair code units.
|
|
273
301
|
* Using longer strings is still valid. For example, so users might store whole grapheme clusters here, or even longer sections of text.
|
|
274
302
|
* Anything combined into a single atom will be treated atomically, and can not be partially selected or formatted.
|
|
275
303
|
* Using larger atoms and splitting them as needed is NOT a recommended approach, since this will result in poor merge behavior for concurrent edits.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textDomainFormatted.js","sourceRoot":"","sources":["../../src/text/textDomainFormatted.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, compareArrays, debugAssert, fail } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tEmptyKey,\n\tforEachNodeSubsequence,\n\ttype FieldKey,\n\ttype ITreeCursorSynchronous,\n} from \"../core/index.js\";\nimport { currentObserver, buildNodeComparator } from \"../feature-libraries/index.js\";\nimport { TreeAlpha } from \"../shared-tree/index.js\";\nimport {\n\tenumFromStrings,\n\teraseSchemaDetails,\n\tgetInnerNode,\n\tSchemaFactory,\n\tSchemaFactoryAlpha,\n\tTreeArrayNode,\n\tTreeBeta,\n} from \"../simple-tree/index.js\";\nimport type {\n\tInsertableTypedNode,\n\tTreeNode,\n\tTreeNodeFromImplicitAllowedTypes,\n\tWithType,\n} from \"../simple-tree/index.js\";\nimport { brand, mapIterable, validateIndex, validateIndexRange } from \"../util/index.js\";\n\nimport { charactersFromString, type TextAsTree } from \"./textDomain.js\";\n\nconst sf = new SchemaFactoryAlpha(\"com.fluidframework.text.formatted\");\n\nclass TextNode\n\textends sf.object(\"Text\", {\n\t\tcontent: SchemaFactory.required([() => StringArray], { key: EmptyKey }),\n\t})\n\timplements FormattedTextAsTree.Members\n{\n\tpublic defaultFormat: FormattedTextAsTree.CharacterFormat =\n\t\tnew FormattedTextAsTree.CharacterFormat(defaultFormat);\n\n\tpublic insertAt(index: number, additionalCharacters: string): void {\n\t\tthis.content.insertAt(\n\t\t\tindex,\n\t\t\tTreeArrayNode.spread(textAtomsFromString(additionalCharacters, this.defaultFormat)),\n\t\t);\n\t}\n\n\tpublic removeRange(index: number | undefined, end: number | undefined): void {\n\t\tthis.content.removeRange(index, end);\n\t}\n\n\tpublic characters(): Iterable<string> {\n\t\treturn mapIterable(this.content, (atom) => atom.content.content);\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\tconst result = this.content.charactersCopy();\n\t\tdebugAssert(\n\t\t\t() =>\n\t\t\t\tcompareArrays(result, this.charactersCopy_reference()) ||\n\t\t\t\t\"invalid charactersCopy optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\tpublic characterCount(): number {\n\t\treturn this.content.length;\n\t}\n\n\tpublic fullString(): string {\n\t\tconst result = this.content.fullString();\n\t\tdebugAssert(\n\t\t\t() => result === this.fullString_reference() || \"invalid fullString optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\t/**\n\t * A non-optimized reference implementation of fullString.\n\t */\n\tpublic fullString_reference(): string {\n\t\treturn [...this.characters()].join(\"\");\n\t}\n\n\t/**\n\t * Unoptimized trivially correct implementation of charactersCopy.\n\t */\n\tpublic charactersCopy_reference(): string[] {\n\t\treturn [...this.characters()];\n\t}\n\n\tpublic static fromString(\n\t\tvalue: string,\n\t\tformat?: FormattedTextAsTree.CharacterFormat,\n\t): TextNode {\n\t\t// Constructing an ArrayNode from an iterator is supported, so creating an array from the iterable of characters seems like it's not necessary here,\n\t\t// but to reduce the risk of incorrect data interpretation, we actually ban this in the special case where the iterable is a string directly, which is the case here.\n\t\t// Thus the array construction here is necessary to avoid a runtime error.\n\t\treturn new TextNode({\n\t\t\tcontent: [\n\t\t\t\t...textAtomsFromString(\n\t\t\t\t\tvalue,\n\t\t\t\t\tformat ?? new FormattedTextAsTree.CharacterFormat(defaultFormat),\n\t\t\t\t),\n\t\t\t],\n\t\t});\n\t}\n\n\tpublic charactersWithFormatting(): readonly FormattedTextAsTree.StringAtom[] {\n\t\treturn this.content;\n\t}\n\tpublic insertWithFormattingAt(\n\t\tindex: number,\n\t\tadditionalCharacters: Iterable<InsertableTypedNode<typeof FormattedTextAsTree.StringAtom>>,\n\t): void {\n\t\tthis.content.insertAt(index, TreeArrayNode.spread(additionalCharacters));\n\t}\n\tpublic formatRange(\n\t\tstart: number | undefined,\n\t\tend: number | undefined,\n\t\tformat: Partial<FormattedTextAsTree.CharacterFormat>,\n\t): void {\n\t\tconst formatStart = start ?? 0;\n\t\tvalidateIndex(formatStart, this.content, \"FormattedTextAsTree.formatRange\", true);\n\n\t\tconst formatEnd = Math.min(this.content.length, end ?? this.content.length);\n\t\tvalidateIndexRange(\n\t\t\tformatStart,\n\t\t\tformatEnd,\n\t\t\tthis.content,\n\t\t\t\"FormattedTextAsTree.formatRange\",\n\t\t);\n\n\t\tconst branch = TreeAlpha.branch(this);\n\n\t\tconst applyFormatting = (): void => {\n\t\t\tfor (let i = formatStart; i < formatEnd; i++) {\n\t\t\t\tconst atom = this.content[i];\n\t\t\t\tif (atom === undefined) {\n\t\t\t\t\tthrow new UsageError(\"Index out of bounds while formatting text range.\");\n\t\t\t\t}\n\t\t\t\tfor (const [key, value] of Object.entries(format) as [\n\t\t\t\t\tkeyof FormattedTextAsTree.CharacterFormat,\n\t\t\t\t\tunknown,\n\t\t\t\t][]) {\n\t\t\t\t\t// Object.entries should only return string keyed enumerable own properties.\n\t\t\t\t\t// The TypeScript typing does not account for this, and thus this assertion is necessary for this code to compile.\n\t\t\t\t\tassert(\n\t\t\t\t\t\ttypeof key === \"string\",\n\t\t\t\t\t\t0xcc8 /* Object.entries returned a non-string key. */,\n\t\t\t\t\t);\n\t\t\t\t\tconst f = FormattedTextAsTree.CharacterFormat.fields.get(key);\n\t\t\t\t\tif (f === undefined) {\n\t\t\t\t\t\tthrow new UsageError(`Unknown format key: ${key}`);\n\t\t\t\t\t}\n\t\t\t\t\t// Ensures that if the input is a node, it is cloned before being inserted into the tree.\n\t\t\t\t\tatom.format[key] = TreeBeta.clone(TreeBeta.create(f, value as never)) as never;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tif (branch === undefined) {\n\t\t\t// If this node does not have a corresponding branch, then it is unhydrated.\n\t\t\t// I.e., it is not part of a collaborative session yet.\n\t\t\t// Therefore, we don't need to run the edits as a transaction.\n\t\t\tapplyFormatting();\n\t\t} else {\n\t\t\t// Wrap all formatting operations in a single transaction for atomicity.\n\t\t\tbranch.runTransaction(() => {\n\t\t\t\tapplyFormatting();\n\t\t\t});\n\t\t}\n\t}\n\tpublic getUniformRun(startIndex: number, endIndex?: number): number {\n\t\treturn this.content.getUniformRun(startIndex, endIndex);\n\t}\n\tpublic getString(startIndex: number, endIndex?: number): string {\n\t\treturn this.content.getString(startIndex, endIndex);\n\t}\n}\n\nconst defaultFormat = {\n\tbold: false,\n\titalic: false,\n\tunderline: false,\n\tsize: 12,\n\tfont: \"Arial\",\n} as const;\n\nconst formatKey: FieldKey = brand(\"format\");\n\nfunction textAtomsFromString(\n\tvalue: string,\n\tformat: FormattedTextAsTree.CharacterFormat,\n): Iterable<FormattedTextAsTree.StringAtom> {\n\tconst result = mapIterable(\n\t\tcharactersFromString(value),\n\t\t(char) =>\n\t\t\tnew FormattedTextAsTree.StringAtom({\n\t\t\t\tcontent: { content: char },\n\t\t\t\tformat: TreeBeta.clone<typeof FormattedTextAsTree.CharacterFormat>(format),\n\t\t\t}),\n\t);\n\treturn result;\n}\n\nclass StringArray extends sf.array(\"StringArray\", [() => FormattedTextAsTree.StringAtom]) {\n\tpublic withBorrowedSequenceCursor<T>(f: (cursor: ITreeCursorSynchronous) => T): T {\n\t\tconst innerNode = getInnerNode(this);\n\t\t// Since the cursor will be used to read content from the tree and won't track observations,\n\t\t// treat it as if it observed the whole subtree.\n\t\tcurrentObserver?.observeNodeDeep(innerNode);\n\t\tconst cursor = innerNode.borrowCursor();\n\t\tcursor.enterField(EmptyKey);\n\t\tconst result = f(cursor);\n\t\tcursor.exitField();\n\t\treturn result;\n\t}\n\n\tprivate getCharactersSubarray(startIndex: number, endIndex: number): string[] {\n\t\treturn this.withBorrowedSequenceCursor((cursor) => {\n\t\t\tconst result: string[] = [];\n\t\t\tforEachNodeSubsequence(cursor, startIndex, endIndex, () => {\n\t\t\t\tdebugAssert(\n\t\t\t\t\t() =>\n\t\t\t\t\t\tcursor.type === FormattedTextAsTree.StringAtom.identifier ||\n\t\t\t\t\t\t\"invalid fullString type optimizations\",\n\t\t\t\t);\n\t\t\t\tcursor.enterField(EmptyKey);\n\t\t\t\tcursor.enterNode(0);\n\t\t\t\tlet content: string;\n\t\t\t\tswitch (cursor.type) {\n\t\t\t\t\tcase FormattedTextAsTree.StringTextAtom.identifier: {\n\t\t\t\t\t\tcursor.enterField(EmptyKey);\n\t\t\t\t\t\tcursor.enterNode(0);\n\t\t\t\t\t\tcontent = cursor.value as string;\n\t\t\t\t\t\tdebugAssert(\n\t\t\t\t\t\t\t() => typeof content === \"string\" || \"invalid fullString type optimizations\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcursor.exitNode();\n\t\t\t\t\t\tcursor.exitField();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase FormattedTextAsTree.StringLineAtom.identifier: {\n\t\t\t\t\t\tcontent = \"\\n\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tfail(0xcde /* Unsupported node type in text array */, () => `${cursor.type}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcursor.exitNode();\n\t\t\t\tcursor.exitField();\n\t\t\t\tresult.push(content);\n\t\t\t});\n\t\t\treturn result;\n\t\t});\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\treturn this.getCharactersSubarray(0, this.length);\n\t}\n\n\tpublic fullString(): string {\n\t\treturn this.charactersCopy().join(\"\");\n\t}\n\n\tpublic getString(startIndex: number, endIndex: number = this.length): string {\n\t\tvalidateIndexRange(startIndex, endIndex, this, \"FormattedTextAsTree.getString\");\n\t\treturn this.getCharactersSubarray(startIndex, endIndex).join(\"\");\n\t}\n\n\tpublic getUniformRun(startIndex: number, endIndex: number = this.length): number {\n\t\tvalidateIndexRange(startIndex, endIndex, this, \"FormattedTextAsTree.getUniformRun\");\n\t\tif (endIndex === startIndex) {\n\t\t\tthrow new UsageError(\"endIndex must be greater than startIndex for getUniformRun.\");\n\t\t}\n\t\tconst arrayLength = this.length;\n\t\treturn this.withBorrowedSequenceCursor((cursor) => {\n\t\t\tcursor.enterNode(startIndex);\n\n\t\t\t// Capture the content type of the first atom\n\t\t\tcursor.enterField(EmptyKey);\n\t\t\tcursor.enterNode(0);\n\t\t\tconst contentType = cursor.type;\n\t\t\tcursor.exitNode();\n\t\t\tcursor.exitField();\n\n\t\t\t// Build a comparator from the format subtree of the first atom\n\t\t\t// This compares by field key\n\t\t\tcursor.enterField(formatKey);\n\t\t\tcursor.enterNode(0);\n\t\t\tconst formatComparator = buildNodeComparator(cursor);\n\t\t\tcursor.exitNode();\n\t\t\tcursor.exitField();\n\n\t\t\tlet runLength = 1;\n\t\t\tconst limit = Math.min(endIndex, arrayLength) - startIndex;\n\n\t\t\twhile (runLength < limit && cursor.nextNode()) {\n\t\t\t\t// Compare atom type\n\t\t\t\tcursor.enterField(EmptyKey);\n\t\t\t\tcursor.enterNode(0);\n\t\t\t\tconst typeMatches = cursor.type === contentType;\n\t\t\t\tcursor.exitNode();\n\t\t\t\tcursor.exitField();\n\t\t\t\tif (!typeMatches) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Compare format subtree using the compiled comparator\n\t\t\t\tcursor.enterField(formatKey);\n\t\t\t\tcursor.enterNode(0);\n\t\t\t\tconst formatMatches = formatComparator(cursor);\n\t\t\t\tcursor.exitNode();\n\t\t\t\tcursor.exitField();\n\n\t\t\t\tif (formatMatches !== true) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\trunLength++;\n\t\t\t}\n\t\t\tcursor.exitNode();\n\t\t\treturn runLength;\n\t\t});\n\t}\n}\n\n/**\n * A collection of text related types, schema and utilities for working with text beyond the basic {@link SchemaStatics.string}.\n * @privateRemarks\n * This has hard-coded assumptions about what kind of embedded content and what kind of formatting is supported.\n * We will want to generalize this with a more generic schema factory function like with table.\n * Then either that and/or the output from it can be package exported.\n * This version is just an initial prototype.\n * @internal\n */\nexport namespace FormattedTextAsTree {\n\t/**\n\t * Formatting options for characters.\n\t * @internal\n\t */\n\texport class CharacterFormat extends sf.objectAlpha(\"CharacterFormat\", {\n\t\tbold: SchemaFactory.boolean,\n\t\titalic: SchemaFactory.boolean,\n\t\tunderline: SchemaFactory.boolean,\n\t\tsize: SchemaFactory.number,\n\t\tfont: SchemaFactory.string,\n\t}) {}\n\n\t/**\n\t * Unit in the string representing a single character.\n\t * @internal\n\t */\n\texport class StringTextAtom extends sf.object(\"StringTextAtom\", {\n\t\t/**\n\t\t * The underlying text content of this atom.\n\t\t * @remarks\n\t\t * This is typically a single unicode codepoint, and thus may contain multiple utf-16 surrogate pair code units.\n\t\t * Using longer strings is still valid. For example, so users might store whole grapheme clusters here, or even longer sections of text.\n\t\t * Anything combined into a single atom will be treated atomically, and can not be partially selected or formatted.\n\t\t * Using larger atoms and splitting them as needed is NOT a recommended approach, since this will result in poor merge behavior for concurrent edits.\n\t\t * Instead atoms should always be the smallest unit of text which will be independently selected, moved or formatted.\n\t\t * @privateRemarks\n\t\t * This content logically represents the whole atom's content, so using {@link EmptyKey} makes sense to help indicate that.\n\t\t */\n\t\tcontent: SchemaFactory.required([SchemaFactory.string], { key: EmptyKey }),\n\t}) {}\n\n\t/**\n\t * Tag with which a line in text can be formatted from HTML.\n\t * @internal\n\t */\n\texport const LineTag = enumFromStrings(sf.scopedFactory(\"lineTag\"), [\n\t\t\"h1\",\n\t\t\"h2\",\n\t\t\"h3\",\n\t\t\"h4\",\n\t\t\"h5\",\n\t\t\"li\",\n\t\t\"ol\",\n\t\t\"checked\",\n\t\t\"unchecked\",\n\t\t\"blockquote\",\n\t\t\"codeBlock\",\n\t]);\n\t/**\n\t * {@inheritdoc FormattedTextAsTree.(LineTag:variable)}\n\t * @internal\n\t */\n\texport type LineTag = TreeNodeFromImplicitAllowedTypes<typeof LineTag.schema>;\n\n\t/**\n\t * Unit in the string representing a new line character with line formatting.\n\t * @remarks\n\t * This aligns with how Quill represents line formatting.\n\t * Quill formats line attributes (headers, list, blockquote, etc... ) on the newline character\n\t * and only lines using this atom can have line-specific formatting.\n\t * The optional indent level mirrors Quill's indent attribute,\n\t * which is applies to the line before the line break.\n\t * Any tagged line can be indented independently.\n\t * @internal\n\t */\n\texport class StringLineAtom extends sf.object(\"StringLineAtom\", {\n\t\ttag: LineTag.schema,\n\t\tindent: SchemaFactory.number,\n\t}) {\n\t\tpublic readonly content = \"\\n\";\n\t}\n\n\t/**\n\t * Types of \"atoms\" that make up the text.\n\t * @internal\n\t */\n\texport const StringAtomContent = [StringTextAtom, StringLineAtom] as const;\n\t/**\n\t * {@inheritdoc FormattedTextAsTree.(StringAtomContent:variable)}\n\t * @internal\n\t */\n\texport type StringAtomContent = TreeNodeFromImplicitAllowedTypes<typeof StringAtomContent>;\n\n\t/**\n\t * A unit of the text, with formatting.\n\t * @internal\n\t */\n\texport class StringAtom extends sf.object(\"StringAtom\", {\n\t\tcontent: SchemaFactory.required(StringAtomContent, { key: EmptyKey }),\n\t\tformat: CharacterFormat,\n\t}) {}\n\n\t/**\n\t * Statics for text nodes.\n\t * @internal\n\t */\n\texport interface Statics {\n\t\t/**\n\t\t * Construct a {@link FormattedTextAsTree.(Tree:type)} from a string, where each character (as defined by iterating over the string) becomes a single character in the text node.\n\t\t * @remarks This combines pairs of utf-16 surrogate code units into single characters as appropriate.\n\t\t */\n\t\tfromString(value: string): Tree;\n\t}\n\n\t/**\n\t * Interface for a text node.\n\t * @remarks\n\t * The string is broken up into substrings which are referred to as 'characters'.\n\t * Unlike with JavaScript strings, all indexes are by character, not UTF-16 code unit.\n\t * This avoids the problem JavaScript where it can split UTF-16 surrogate pairs producing invalid strings,\n\t * and avoids the issue where indexing a string and iterating it segment the string differently.\n\t * This does NOT mean the characters correspond to user perceived characters (like grapheme clusters try to do):\n\t * applications will likely want to include higher level segmentation logic\n\t * which might differ between operations like delete\n\t * (which often operates on something in between unicode code points and grapheme clusters)\n\t * and navigation/selection (which typically uses grapheme clusters).\n\t *\n\t * @see {@link FormattedTextAsTree.Statics.fromString} for construction.\n\t * @see {@link FormattedTextAsTree.(Tree:type)} for schema.\n\t * @internal\n\t */\n\texport interface Members extends TextAsTree.Members {\n\t\t/**\n\t\t * Format to use by default for text inserted with non-formatted APIs.\n\t\t * @remarks\n\t\t * This is not persisted in the tree, and observation of it is not tracked by the tree observation tracking.\n\t\t * @privateRemarks\n\t\t * Opt this into observation tracking.\n\t\t */\n\t\tdefaultFormat: CharacterFormat;\n\n\t\t/**\n\t\t * Gets an array type view of the characters currently in the text.\n\t\t * @remarks\n\t\t * This iterator matches the behavior of {@link (TreeArrayNode:interface)} with respect to edits during iteration.\n\t\t * @privateRemarks\n\t\t * Currently this is implemented by a node and changes with the text over time.\n\t\t * We might not want to leak a node like this in the API.\n\t\t * Providing a way to index and iterate separately might be better.\n\t\t */\n\t\tcharactersWithFormatting(): readonly StringAtom[];\n\n\t\t/**\n\t\t * Insert a range of characters into the string based on character index.\n\t\t * @remarks\n\t\t * See {@link (TreeArrayNode:interface).insertAt} for more details on the behavior.\n\t\t * See {@link FormattedTextAsTree.Statics.fromString} for how the `additionalCharacters` string is broken into characters.\n\t\t * @privateRemarks\n\t\t * If we provide ways to customize character boundaries, that could be handled here by taking in an Iterable<string> instead of a string.\n\t\t * Doing this currently would enable insertion of text with different character boundaries than the existing text,\n\t\t * which would violate the currently documented character boundary invariants.\n\t\t *\n\t\t * Another option would be to take an approach like Table,\n\t\t * where the user of the API uses a factory function to generate the schema, and can inject custom logic, like a string character iterator.\n\t\t */\n\t\tinsertWithFormattingAt(\n\t\t\tindex: number,\n\t\t\tadditionalCharacters: Iterable<InsertableTypedNode<typeof StringAtom>>,\n\t\t): void;\n\n\t\t/**\n\t\t * Apply formatting to a range of characters based on character index.\n\t\t * @param startIndex - The starting index (inclusive) of the range to format.\n\t\t * @param endIndex - The ending index (exclusive) of the range to format.\n\t\t * @param format - The formatting to apply to the specified range.\n\t\t * @remarks\n\t\t * The start and end behave the same as in {@link (TreeArrayNode:interface).removeRange}.\n\t\t */\n\t\tformatRange(\n\t\t\tstartIndex: number | undefined,\n\t\t\tendIndex: number | undefined,\n\t\t\tformat: Partial<CharacterFormat>,\n\t\t): void;\n\n\t\t/**\n\t\t * Returns the length of the run of characters starting at `startIndex` which have the same formatting and atom type, up to `endIndex`.\n\t\t * @param startIndex - The starting index of the run.\n\t\t * @param endIndex - The ending index (exclusive) of the run. Defaults to the end of the text.\n\t\t */\n\t\tgetUniformRun(startIndex: number, endIndex?: number): number;\n\t\t/**\n\t\t * Returns a substring of the text from `startIndex` to `endIndex`\n\t\t * @param startIndex - starting index (inclusive)\n\t\t * @param endIndex - Optional ending index (exclusive). Defaults to the end of the text.\n\t\t */\n\t\tgetString(startIndex: number, endIndex?: number): string;\n\t}\n\n\t/**\n\t * Schema for a text node.\n\t * @remarks\n\t * See {@link FormattedTextAsTree.Members} for the API.\n\t * See {@link FormattedTextAsTree.Statics} for static APIs on this Schema, including construction.\n\t * @internal\n\t */\n\texport const Tree = eraseSchemaDetails<Members, Statics>()(TextNode);\n\texport type Tree = Members & TreeNode & WithType<\"com.fluidframework.text.formatted.Text\">;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"textDomainFormatted.js","sourceRoot":"","sources":["../../src/text/textDomainFormatted.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, compareArrays, debugAssert, fail } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tEmptyKey,\n\tforEachNodeSubsequence,\n\ttype FieldKey,\n\ttype ITreeCursorSynchronous,\n} from \"../core/index.js\";\nimport { currentObserver, buildNodeComparator } from \"../feature-libraries/index.js\";\nimport { TreeAlpha } from \"../shared-tree/index.js\";\nimport {\n\tenumFromStrings,\n\teraseSchemaDetails,\n\tgetInnerNode,\n\tSchemaFactory,\n\tSchemaFactoryAlpha,\n\tTreeArrayNode,\n\tTreeBeta,\n} from \"../simple-tree/index.js\";\nimport type {\n\tInsertableTypedNode,\n\tTreeNode,\n\tTreeNodeFromImplicitAllowedTypes,\n\tWithType,\n} from \"../simple-tree/index.js\";\nimport { brand, mapIterable, validateIndex, validateIndexRange } from \"../util/index.js\";\n\nimport {\n\tcharactersFromString,\n\tprocessCharactersChangedDelta,\n\ttype TextAsTree,\n} from \"./textDomain.js\";\n\nconst sf = new SchemaFactoryAlpha(\"com.fluidframework.text.formatted\");\n\nclass TextNode\n\textends sf.object(\"Text\", {\n\t\tcontent: SchemaFactory.required([() => StringArray], { key: EmptyKey }),\n\t})\n\timplements FormattedTextAsTree.Members\n{\n\tpublic defaultFormat: FormattedTextAsTree.CharacterFormat =\n\t\tnew FormattedTextAsTree.CharacterFormat(defaultFormat);\n\n\tpublic insertAt(index: number, additionalCharacters: string): void {\n\t\tthis.content.insertAt(\n\t\t\tindex,\n\t\t\tTreeArrayNode.spread(textAtomsFromString(additionalCharacters, this.defaultFormat)),\n\t\t);\n\t}\n\n\tpublic removeRange(index: number | undefined, end: number | undefined): void {\n\t\tthis.content.removeRange(index, end);\n\t}\n\n\tpublic characters(): Iterable<string> {\n\t\treturn mapIterable(this.content, (atom) => atom.content.content);\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\tconst result = this.content.charactersCopy();\n\t\tdebugAssert(\n\t\t\t() =>\n\t\t\t\tcompareArrays(result, this.charactersCopy_reference()) ||\n\t\t\t\t\"invalid charactersCopy optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\tpublic characterCount(): number {\n\t\treturn this.content.length;\n\t}\n\n\tpublic fullString(): string {\n\t\tconst result = this.content.fullString();\n\t\tdebugAssert(\n\t\t\t() => result === this.fullString_reference() || \"invalid fullString optimizations\",\n\t\t);\n\t\treturn result;\n\t}\n\n\t/**\n\t * A non-optimized reference implementation of fullString.\n\t */\n\tpublic fullString_reference(): string {\n\t\treturn [...this.characters()].join(\"\");\n\t}\n\n\t/**\n\t * Unoptimized trivially correct implementation of charactersCopy.\n\t */\n\tpublic charactersCopy_reference(): string[] {\n\t\treturn [...this.characters()];\n\t}\n\n\tpublic static fromString(\n\t\tvalue: string,\n\t\tformat?: FormattedTextAsTree.CharacterFormat,\n\t): TextNode {\n\t\t// Constructing an ArrayNode from an iterator is supported, so creating an array from the iterable of characters seems like it's not necessary here,\n\t\t// but to reduce the risk of incorrect data interpretation, we actually ban this in the special case where the iterable is a string directly, which is the case here.\n\t\t// Thus the array construction here is necessary to avoid a runtime error.\n\t\treturn new TextNode({\n\t\t\tcontent: [\n\t\t\t\t...textAtomsFromString(\n\t\t\t\t\tvalue,\n\t\t\t\t\tformat ?? new FormattedTextAsTree.CharacterFormat(defaultFormat),\n\t\t\t\t),\n\t\t\t],\n\t\t});\n\t}\n\n\tpublic charactersWithFormatting(): readonly FormattedTextAsTree.StringAtom[] {\n\t\treturn this.content;\n\t}\n\tpublic insertWithFormattingAt(\n\t\tindex: number,\n\t\tadditionalCharacters: Iterable<InsertableTypedNode<typeof FormattedTextAsTree.StringAtom>>,\n\t): void {\n\t\tthis.content.insertAt(index, TreeArrayNode.spread(additionalCharacters));\n\t}\n\tpublic formatRange(\n\t\tstart: number | undefined,\n\t\tend: number | undefined,\n\t\tformat: Partial<FormattedTextAsTree.CharacterFormat>,\n\t): void {\n\t\tconst formatStart = start ?? 0;\n\t\tvalidateIndex(formatStart, this.content, \"FormattedTextAsTree.formatRange\", true);\n\n\t\tconst formatEnd = Math.min(this.content.length, end ?? this.content.length);\n\t\tvalidateIndexRange(\n\t\t\tformatStart,\n\t\t\tformatEnd,\n\t\t\tthis.content,\n\t\t\t\"FormattedTextAsTree.formatRange\",\n\t\t);\n\n\t\tconst branch = TreeAlpha.branch(this);\n\n\t\tconst applyFormatting = (): void => {\n\t\t\tfor (let i = formatStart; i < formatEnd; i++) {\n\t\t\t\tconst atom = this.content[i];\n\t\t\t\tif (atom === undefined) {\n\t\t\t\t\tthrow new UsageError(\"Index out of bounds while formatting text range.\");\n\t\t\t\t}\n\t\t\t\tfor (const [key, value] of Object.entries(format) as [\n\t\t\t\t\tkeyof FormattedTextAsTree.CharacterFormat,\n\t\t\t\t\tunknown,\n\t\t\t\t][]) {\n\t\t\t\t\t// Object.entries should only return string keyed enumerable own properties.\n\t\t\t\t\t// The TypeScript typing does not account for this, and thus this assertion is necessary for this code to compile.\n\t\t\t\t\tassert(\n\t\t\t\t\t\ttypeof key === \"string\",\n\t\t\t\t\t\t0xcc8 /* Object.entries returned a non-string key. */,\n\t\t\t\t\t);\n\t\t\t\t\tconst f = FormattedTextAsTree.CharacterFormat.fields.get(key);\n\t\t\t\t\tif (f === undefined) {\n\t\t\t\t\t\tthrow new UsageError(`Unknown format key: ${key}`);\n\t\t\t\t\t}\n\t\t\t\t\t// Ensures that if the input is a node, it is cloned before being inserted into the tree.\n\t\t\t\t\tatom.format[key] = TreeBeta.clone(TreeBeta.create(f, value as never)) as never;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tif (branch === undefined) {\n\t\t\t// If this node does not have a corresponding branch, then it is unhydrated.\n\t\t\t// I.e., it is not part of a collaborative session yet.\n\t\t\t// Therefore, we don't need to run the edits as a transaction.\n\t\t\t// Note: for unhydrated nodes each atom edit fires a separate `treeChanged` event,\n\t\t\t// so formatting N atoms will produce N callbacks on `onContentChanged` subscribers\n\t\t\t// instead of the single callback that hydrated (transacted) edits produce.\n\t\t\t// `withBufferedTreeEvents` is not a viable mitigation here: when more than one atom's\n\t\t\t// `format` field changes within the same buffered scope, the kernel's per-field\n\t\t\t// dedup logic discards the delta (see `treeNodeKernel.ts` `#fieldMarksBuffer`),\n\t\t\t// which is worse for incremental consumers than N well-formed callbacks.\n\t\t\t// Use `runTransaction` on a hydrated node (i.e. after inserting into the document)\n\t\t\t// if batched events matter.\n\t\t\tapplyFormatting();\n\t\t} else {\n\t\t\t// Wrap all formatting operations in a single transaction for atomicity.\n\t\t\tbranch.runTransaction(() => {\n\t\t\t\tapplyFormatting();\n\t\t\t});\n\t\t}\n\t}\n\t/**\n\t * Returns the character string at the given atom index, or `undefined` if out of bounds.\n\t * @remarks\n\t * Line atoms expand to `\"\\n\"`; text atoms return their underlying code point(s).\n\t */\n\tprivate getAtomCharacterAt(index: number): string | undefined {\n\t\tconst atom = this.content[index];\n\t\tif (atom === undefined) return undefined;\n\t\treturn atom.content instanceof FormattedTextAsTree.StringLineAtom\n\t\t\t? \"\\n\"\n\t\t\t: atom.content.content;\n\t}\n\n\tpublic onCharactersChanged(\n\t\tcallback: (ops: readonly TextAsTree.TextOp[] | undefined) => void,\n\t): () => void {\n\t\treturn TreeAlpha.on(this.content, \"nodeChanged\", ({ delta }) =>\n\t\t\tprocessCharactersChangedDelta(\n\t\t\t\tdelta,\n\t\t\t\t(index) => this.getAtomCharacterAt(index),\n\t\t\t\tcallback,\n\t\t\t),\n\t\t);\n\t}\n\n\tpublic onContentChanged(\n\t\tcallback: (ops: readonly TextAsTree.TextOp[] | undefined) => void,\n\t): () => void {\n\t\treturn TreeAlpha.on(this.content, \"treeChanged\", ({ delta }) =>\n\t\t\tprocessCharactersChangedDelta(\n\t\t\t\tdelta,\n\t\t\t\t(index) => this.getAtomCharacterAt(index),\n\t\t\t\tcallback,\n\t\t\t),\n\t\t);\n\t}\n\n\tpublic getUniformRun(startIndex: number, endIndex?: number): number {\n\t\treturn this.content.getUniformRun(startIndex, endIndex);\n\t}\n\tpublic getString(startIndex: number, endIndex?: number): string {\n\t\treturn this.content.getString(startIndex, endIndex);\n\t}\n}\n\nconst defaultFormat = {\n\tbold: false,\n\titalic: false,\n\tunderline: false,\n\tsize: 12,\n\tfont: \"Arial\",\n} as const;\n\nconst formatKey: FieldKey = brand(\"format\");\n\nfunction textAtomsFromString(\n\tvalue: string,\n\tformat: FormattedTextAsTree.CharacterFormat,\n): Iterable<FormattedTextAsTree.StringAtom> {\n\tconst result = mapIterable(\n\t\tcharactersFromString(value),\n\t\t(char) =>\n\t\t\tnew FormattedTextAsTree.StringAtom({\n\t\t\t\tcontent: { content: char },\n\t\t\t\tformat: TreeBeta.clone<typeof FormattedTextAsTree.CharacterFormat>(format),\n\t\t\t}),\n\t);\n\treturn result;\n}\n\nclass StringArray extends sf.array(\"StringArray\", [() => FormattedTextAsTree.StringAtom]) {\n\tpublic withBorrowedSequenceCursor<T>(f: (cursor: ITreeCursorSynchronous) => T): T {\n\t\tconst innerNode = getInnerNode(this);\n\t\t// Since the cursor will be used to read content from the tree and won't track observations,\n\t\t// treat it as if it observed the whole subtree.\n\t\tcurrentObserver?.observeNodeDeep(innerNode);\n\t\tconst cursor = innerNode.borrowCursor();\n\t\tcursor.enterField(EmptyKey);\n\t\tconst result = f(cursor);\n\t\tcursor.exitField();\n\t\treturn result;\n\t}\n\n\tprivate getCharactersSubarray(startIndex: number, endIndex: number): string[] {\n\t\treturn this.withBorrowedSequenceCursor((cursor) => {\n\t\t\tconst result: string[] = [];\n\t\t\tforEachNodeSubsequence(cursor, startIndex, endIndex, () => {\n\t\t\t\tdebugAssert(\n\t\t\t\t\t() =>\n\t\t\t\t\t\tcursor.type === FormattedTextAsTree.StringAtom.identifier ||\n\t\t\t\t\t\t\"invalid fullString type optimizations\",\n\t\t\t\t);\n\t\t\t\tcursor.enterField(EmptyKey);\n\t\t\t\tcursor.enterNode(0);\n\t\t\t\tlet content: string;\n\t\t\t\tswitch (cursor.type) {\n\t\t\t\t\tcase FormattedTextAsTree.StringTextAtom.identifier: {\n\t\t\t\t\t\tcursor.enterField(EmptyKey);\n\t\t\t\t\t\tcursor.enterNode(0);\n\t\t\t\t\t\tcontent = cursor.value as string;\n\t\t\t\t\t\tdebugAssert(\n\t\t\t\t\t\t\t() => typeof content === \"string\" || \"invalid fullString type optimizations\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcursor.exitNode();\n\t\t\t\t\t\tcursor.exitField();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase FormattedTextAsTree.StringLineAtom.identifier: {\n\t\t\t\t\t\tcontent = \"\\n\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tfail(0xcde /* Unsupported node type in text array */, () => `${cursor.type}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcursor.exitNode();\n\t\t\t\tcursor.exitField();\n\t\t\t\tresult.push(content);\n\t\t\t});\n\t\t\treturn result;\n\t\t});\n\t}\n\n\tpublic charactersCopy(): string[] {\n\t\treturn this.getCharactersSubarray(0, this.length);\n\t}\n\n\tpublic fullString(): string {\n\t\treturn this.charactersCopy().join(\"\");\n\t}\n\n\tpublic getString(startIndex: number, endIndex: number = this.length): string {\n\t\tvalidateIndexRange(startIndex, endIndex, this, \"FormattedTextAsTree.getString\");\n\t\treturn this.getCharactersSubarray(startIndex, endIndex).join(\"\");\n\t}\n\n\tpublic getUniformRun(startIndex: number, endIndex: number = this.length): number {\n\t\tvalidateIndexRange(startIndex, endIndex, this, \"FormattedTextAsTree.getUniformRun\");\n\t\tif (endIndex === startIndex) {\n\t\t\tthrow new UsageError(\"endIndex must be greater than startIndex for getUniformRun.\");\n\t\t}\n\t\tconst arrayLength = this.length;\n\t\treturn this.withBorrowedSequenceCursor((cursor) => {\n\t\t\tcursor.enterNode(startIndex);\n\n\t\t\t// Capture the content type of the first atom\n\t\t\tcursor.enterField(EmptyKey);\n\t\t\tcursor.enterNode(0);\n\t\t\tconst contentType = cursor.type;\n\t\t\tcursor.exitNode();\n\t\t\tcursor.exitField();\n\n\t\t\t// Build a comparator from the format subtree of the first atom\n\t\t\t// This compares by field key\n\t\t\tcursor.enterField(formatKey);\n\t\t\tcursor.enterNode(0);\n\t\t\tconst formatComparator = buildNodeComparator(cursor);\n\t\t\tcursor.exitNode();\n\t\t\tcursor.exitField();\n\n\t\t\tlet runLength = 1;\n\t\t\tconst limit = Math.min(endIndex, arrayLength) - startIndex;\n\n\t\t\twhile (runLength < limit && cursor.nextNode()) {\n\t\t\t\t// Compare atom type\n\t\t\t\tcursor.enterField(EmptyKey);\n\t\t\t\tcursor.enterNode(0);\n\t\t\t\tconst typeMatches = cursor.type === contentType;\n\t\t\t\tcursor.exitNode();\n\t\t\t\tcursor.exitField();\n\t\t\t\tif (!typeMatches) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Compare format subtree using the compiled comparator\n\t\t\t\tcursor.enterField(formatKey);\n\t\t\t\tcursor.enterNode(0);\n\t\t\t\tconst formatMatches = formatComparator(cursor);\n\t\t\t\tcursor.exitNode();\n\t\t\t\tcursor.exitField();\n\n\t\t\t\tif (formatMatches !== true) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\trunLength++;\n\t\t\t}\n\t\t\tcursor.exitNode();\n\t\t\treturn runLength;\n\t\t});\n\t}\n}\n\n/**\n * A collection of text related types, schema and utilities for working with text beyond the basic {@link SchemaStatics.string}.\n * @privateRemarks\n * This has hard-coded assumptions about what kind of embedded content and what kind of formatting is supported.\n * We will want to generalize this with a more generic schema factory function like with table.\n * Then either that and/or the output from it can be package exported.\n * This version is just an initial prototype.\n * @internal\n */\nexport namespace FormattedTextAsTree {\n\t/**\n\t * Formatting options for characters.\n\t * @internal\n\t */\n\texport class CharacterFormat extends sf.objectAlpha(\"CharacterFormat\", {\n\t\tbold: SchemaFactory.boolean,\n\t\titalic: SchemaFactory.boolean,\n\t\tunderline: SchemaFactory.boolean,\n\t\tsize: SchemaFactory.number,\n\t\tfont: SchemaFactory.string,\n\t}) {}\n\n\t/**\n\t * Unit in the string representing a single character.\n\t * @internal\n\t */\n\texport class StringTextAtom extends sf.object(\"StringTextAtom\", {\n\t\t/**\n\t\t * The underlying text content of this atom.\n\t\t * @remarks\n\t\t * This is typically a single Unicode code point, and thus may contain multiple UTF-16 surrogate pair code units.\n\t\t * Using longer strings is still valid. For example, so users might store whole grapheme clusters here, or even longer sections of text.\n\t\t * Anything combined into a single atom will be treated atomically, and can not be partially selected or formatted.\n\t\t * Using larger atoms and splitting them as needed is NOT a recommended approach, since this will result in poor merge behavior for concurrent edits.\n\t\t * Instead atoms should always be the smallest unit of text which will be independently selected, moved or formatted.\n\t\t * @privateRemarks\n\t\t * This content logically represents the whole atom's content, so using {@link EmptyKey} makes sense to help indicate that.\n\t\t */\n\t\tcontent: SchemaFactory.required([SchemaFactory.string], { key: EmptyKey }),\n\t}) {}\n\n\t/**\n\t * Tag with which a line in text can be formatted from HTML.\n\t * @internal\n\t */\n\texport const LineTag = enumFromStrings(sf.scopedFactory(\"lineTag\"), [\n\t\t\"h1\",\n\t\t\"h2\",\n\t\t\"h3\",\n\t\t\"h4\",\n\t\t\"h5\",\n\t\t\"li\",\n\t\t\"ol\",\n\t\t\"checked\",\n\t\t\"unchecked\",\n\t\t\"blockquote\",\n\t\t\"codeBlock\",\n\t]);\n\t/**\n\t * {@inheritdoc FormattedTextAsTree.(LineTag:variable)}\n\t * @internal\n\t */\n\texport type LineTag = TreeNodeFromImplicitAllowedTypes<typeof LineTag.schema>;\n\n\t/**\n\t * Unit in the string representing a new line character with line formatting.\n\t * @remarks\n\t * This aligns with how Quill represents line formatting.\n\t * Quill formats line attributes (headers, list, blockquote, etc... ) on the newline character\n\t * and only lines using this atom can have line-specific formatting.\n\t * The optional indent level mirrors Quill's indent attribute,\n\t * which is applies to the line before the line break.\n\t * Any tagged line can be indented independently.\n\t * @internal\n\t */\n\texport class StringLineAtom extends sf.object(\"StringLineAtom\", {\n\t\ttag: LineTag.schema,\n\t\tindent: SchemaFactory.number,\n\t}) {\n\t\tpublic readonly content = \"\\n\";\n\t}\n\n\t/**\n\t * Types of \"atoms\" that make up the text.\n\t * @internal\n\t */\n\texport const StringAtomContent = [StringTextAtom, StringLineAtom] as const;\n\t/**\n\t * {@inheritdoc FormattedTextAsTree.(StringAtomContent:variable)}\n\t * @internal\n\t */\n\texport type StringAtomContent = TreeNodeFromImplicitAllowedTypes<typeof StringAtomContent>;\n\n\t/**\n\t * A unit of the text, with formatting.\n\t * @internal\n\t */\n\texport class StringAtom extends sf.object(\"StringAtom\", {\n\t\tcontent: SchemaFactory.required(StringAtomContent, { key: EmptyKey }),\n\t\tformat: CharacterFormat,\n\t}) {}\n\n\t/**\n\t * Statics for text nodes.\n\t * @internal\n\t */\n\texport interface Statics {\n\t\t/**\n\t\t * Construct a {@link FormattedTextAsTree.(Tree:type)} from a string, where each character (as defined by iterating over the string) becomes a single character in the text node.\n\t\t * @remarks This combines pairs of utf-16 surrogate code units into single characters as appropriate.\n\t\t */\n\t\tfromString(value: string): Tree;\n\t}\n\n\t/**\n\t * Interface for a text node.\n\t * @remarks\n\t * The string is broken up into substrings which are referred to as 'characters'.\n\t * Unlike with JavaScript strings, all indexes are by character, not UTF-16 code unit.\n\t * This avoids the problem JavaScript where it can split UTF-16 surrogate pairs producing invalid strings,\n\t * and avoids the issue where indexing a string and iterating it segment the string differently.\n\t * This does NOT mean the characters correspond to user perceived characters (like grapheme clusters try to do):\n\t * applications will likely want to include higher level segmentation logic\n\t * which might differ between operations like delete\n\t * (which often operates on something in between unicode code points and grapheme clusters)\n\t * and navigation/selection (which typically uses grapheme clusters).\n\t *\n\t * @see {@link FormattedTextAsTree.Statics.fromString} for construction.\n\t * @see {@link FormattedTextAsTree.(Tree:type)} for schema.\n\t * @internal\n\t */\n\texport interface Members extends TextAsTree.Members {\n\t\t/**\n\t\t * Format to use by default for text inserted with non-formatted APIs.\n\t\t * @remarks\n\t\t * This is not persisted in the tree, and observation of it is not tracked by the tree observation tracking.\n\t\t * @privateRemarks\n\t\t * Opt this into observation tracking.\n\t\t */\n\t\tdefaultFormat: CharacterFormat;\n\n\t\t/**\n\t\t * Gets an array type view of the characters currently in the text.\n\t\t * @remarks\n\t\t * This iterator matches the behavior of {@link (TreeArrayNode:interface)} with respect to edits during iteration.\n\t\t * @privateRemarks\n\t\t * Currently this is implemented by a node and changes with the text over time.\n\t\t * We might not want to leak a node like this in the API.\n\t\t * Providing a way to index and iterate separately might be better.\n\t\t */\n\t\tcharactersWithFormatting(): readonly StringAtom[];\n\n\t\t/**\n\t\t * Insert a range of characters into the string based on character index.\n\t\t * @remarks\n\t\t * See {@link (TreeArrayNode:interface).insertAt} for more details on the behavior.\n\t\t * See {@link FormattedTextAsTree.Statics.fromString} for how the `additionalCharacters` string is broken into characters.\n\t\t * @privateRemarks\n\t\t * If we provide ways to customize character boundaries, that could be handled here by taking in an Iterable<string> instead of a string.\n\t\t * Doing this currently would enable insertion of text with different character boundaries than the existing text,\n\t\t * which would violate the currently documented character boundary invariants.\n\t\t *\n\t\t * Another option would be to take an approach like Table,\n\t\t * where the user of the API uses a factory function to generate the schema, and can inject custom logic, like a string character iterator.\n\t\t */\n\t\tinsertWithFormattingAt(\n\t\t\tindex: number,\n\t\t\tadditionalCharacters: Iterable<InsertableTypedNode<typeof StringAtom>>,\n\t\t): void;\n\n\t\t/**\n\t\t * Apply formatting to a range of characters based on character index.\n\t\t * @param startIndex - The starting index (inclusive) of the range to format.\n\t\t * @param endIndex - The ending index (exclusive) of the range to format.\n\t\t * @param format - The formatting to apply to the specified range.\n\t\t * @remarks\n\t\t * The start and end behave the same as in {@link (TreeArrayNode:interface).removeRange}.\n\t\t */\n\t\tformatRange(\n\t\t\tstartIndex: number | undefined,\n\t\t\tendIndex: number | undefined,\n\t\t\tformat: Partial<CharacterFormat>,\n\t\t): void;\n\n\t\t/**\n\t\t * Returns the length of the run of characters starting at `startIndex` which have the same formatting and atom type, up to `endIndex`.\n\t\t * @param startIndex - The starting index of the run.\n\t\t * @param endIndex - The ending index (exclusive) of the run. Defaults to the end of the text.\n\t\t */\n\t\tgetUniformRun(startIndex: number, endIndex?: number): number;\n\t\t/**\n\t\t * Returns a substring of the text from `startIndex` to `endIndex`\n\t\t * @param startIndex - starting index (inclusive)\n\t\t * @param endIndex - Optional ending index (exclusive). Defaults to the end of the text.\n\t\t */\n\t\tgetString(startIndex: number, endIndex?: number): string;\n\n\t\t/**\n\t\t * Subscribe to all content changes on this text node, including both shallow\n\t\t * changes (inserts/removes) and deep changes (formatting updates on existing characters).\n\t\t * @param callback - Called after each change with a sequence of {@link TextAsTree.TextOp}s describing what changed,\n\t\t * or `undefined` when a delta could not be computed (e.g. during a schema upgrade).\n\t\t * @returns A cleanup function that unsubscribes the callback when called.\n\t\t * @remarks\n\t\t * Unlike {@link TextAsTree.Members.onCharactersChanged} which only fires on\n\t\t * shallow changes (inserts and removes), this method also fires on deep changes —\n\t\t * formatting property updates on existing characters.\n\t\t * The {@link TextAsTree.TextRetainOp.formattingChanged} flag on retain ops\n\t\t * indicates which character ranges had formatting updates.\n\t\t *\n\t\t * All counts in the delivered ops are in Unicode code points, not UTF-16 code units.\n\t\t * For characters outside the Basic Multilingual Plane (e.g. emoji), one code point\n\t\t * corresponds to two UTF-16 code units — convert before using the counts as string indices.\n\t\t */\n\t\tonContentChanged(\n\t\t\tcallback: (ops: readonly TextAsTree.TextOp[] | undefined) => void,\n\t\t): () => void;\n\t}\n\n\t/**\n\t * Schema for a text node.\n\t * @remarks\n\t * See {@link FormattedTextAsTree.Members} for the API.\n\t * See {@link FormattedTextAsTree.Statics} for static APIs on this Schema, including construction.\n\t * @internal\n\t */\n\texport const Tree = eraseSchemaDetails<Members, Statics>()(TextNode);\n\texport type Tree = Members & TreeNode & WithType<\"com.fluidframework.text.formatted.Text\">;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeFactory.d.ts","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAMtB,MAAM,6CAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"treeFactory.d.ts","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAMtB,MAAM,6CAA6C,CAAC;AAQrD,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAE9B,MAAM,wBAAwB,CAAC;AAQhC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAGpD;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,aAAa,EAAE,YAAY;CAAG;AA8DnE;;;;GAIG;AACH,eAAO,MAAM,UAAU,oDAA2B,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,qBAAqB,GAC5B,gBAAgB,CAAC,KAAK,CAAC,CAEzB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,qBAAqB,GAC5B,iBAAiB,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAEpD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,iBAAiB,GACxB,gBAAgB,CAAC,KAAK,CAAC,CAEzB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,iBAAiB,GACxB,iBAAiB,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAGpD;AAED,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,yBAAyB,GAChC,iBAAiB,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CASpD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,iBAAiB,GAAG,yBAAyB,CAQpF"}
|
package/dist/treeFactory.js
CHANGED
|
@@ -8,10 +8,11 @@ exports.resolveOptions = exports.configuredSharedTreeInternal = exports.configur
|
|
|
8
8
|
const internal_1 = require("@fluidframework/shared-object-base/internal");
|
|
9
9
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
10
10
|
const index_js_1 = require("./codec/index.js");
|
|
11
|
-
const index_js_2 = require("./
|
|
12
|
-
const index_js_3 = require("./shared-tree
|
|
11
|
+
const index_js_2 = require("./core/index.js");
|
|
12
|
+
const index_js_3 = require("./shared-tree/index.js");
|
|
13
|
+
const index_js_4 = require("./shared-tree-core/index.js");
|
|
13
14
|
const sharedTreeAttributes_js_1 = require("./sharedTreeAttributes.js");
|
|
14
|
-
const
|
|
15
|
+
const index_js_5 = require("./util/index.js");
|
|
15
16
|
/**
|
|
16
17
|
* Creates a factory for shared tree kernels with the given options.
|
|
17
18
|
* @remarks
|
|
@@ -36,7 +37,7 @@ function treeKernelFactory(options) {
|
|
|
36
37
|
// C. If neither specifies it, we fall back to a default value default of 2.0 since that is the oldest version that supports SharedTree.
|
|
37
38
|
minVersionForCollab: minVersionForCollab ?? args.minVersionForCollab ?? index_js_1.FluidClientVersion.v2_0,
|
|
38
39
|
};
|
|
39
|
-
return new
|
|
40
|
+
return new index_js_3.SharedTreeKernel(new index_js_5.Breakable("SharedTree"), args.sharedObject, args.serializer, args.submitLocalMessage, args.lastSequenceNumber, args.initialSequenceNumber, args.logger, args.idCompressor, adjustedOptions);
|
|
40
41
|
}
|
|
41
42
|
return {
|
|
42
43
|
create: (args) => {
|
|
@@ -144,7 +145,7 @@ function resolveOptions(options) {
|
|
|
144
145
|
...resolveFormatOptions(options),
|
|
145
146
|
};
|
|
146
147
|
for (const optionName of Object.keys(options)) {
|
|
147
|
-
(0,
|
|
148
|
+
(0, index_js_5.copyProperty)(options, optionName, internal);
|
|
148
149
|
}
|
|
149
150
|
return internal;
|
|
150
151
|
}
|
|
@@ -158,8 +159,9 @@ function resolveFormatOptions(options) {
|
|
|
158
159
|
}
|
|
159
160
|
const sharedBranchesOptions = {
|
|
160
161
|
writeVersionOverrides: new Map([
|
|
161
|
-
[
|
|
162
|
-
[
|
|
162
|
+
[index_js_4.editManagerCodecName, index_js_4.EditManagerFormatVersion.vSharedBranches],
|
|
163
|
+
[index_js_4.messageCodecName, index_js_4.MessageFormatVersion.vSharedBranches],
|
|
164
|
+
[index_js_2.detachedFieldIndexCodecBuilder.name, index_js_2.DetachedFieldIndexFormatVersion.v2],
|
|
163
165
|
]),
|
|
164
166
|
allowPossiblyIncompatibleWriteVersionOverrides: true,
|
|
165
167
|
};
|
package/dist/treeFactory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeFactory.js","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IChannelStorageService } from \"@fluidframework/datastore-definitions/internal\";\nimport type { SharedObjectKind } from \"@fluidframework/shared-object-base\";\nimport {\n\ttype ISharedObject,\n\ttype ISharedObjectKind,\n\tmakeSharedObjectKind,\n\ttype KernelArgs,\n\ttype SharedKernelFactory,\n\ttype SharedObjectOptions,\n\ttype FactoryOut,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { FluidClientVersion, type FormatVersion } from \"./codec/index.js\";\nimport {\n\tSharedTreeKernel,\n\ttype ITreePrivate,\n\ttype SharedTreeOptions,\n\ttype SharedTreeOptionsBeta,\n\ttype SharedTreeOptionsInternal,\n\ttype SharedTreeKernelView,\n} from \"./shared-tree/index.js\";\nimport {\n\teditManagerCodecName,\n\tEditManagerFormatVersion,\n\tmessageCodecName,\n\tMessageFormatVersion,\n} from \"./shared-tree-core/index.js\";\nimport { SharedTreeFactoryType, SharedTreeAttributes } from \"./sharedTreeAttributes.js\";\nimport type { ITree } from \"./simple-tree/index.js\";\nimport { Breakable, copyProperty } from \"./util/index.js\";\n\n/**\n * {@link ITreePrivate} extended with ISharedObject.\n * @remarks\n * This is used when integration testing this package with the Fluid runtime as it exposes the APIs the runtime consumes to manipulate the tree.\n */\nexport interface ISharedTree extends ISharedObject, ITreePrivate {}\n\n/**\n * Creates a factory for shared tree kernels with the given options.\n * @remarks\n * Exposes {@link ITreePrivate} to allow access to internals in tests without a cast.\n * Code exposing this beyond this package will need to update to a more public type.\n */\nfunction treeKernelFactory(\n\toptions: SharedTreeOptionsInternal,\n): SharedKernelFactory<SharedTreeKernelView> {\n\tfunction treeFromKernelArgs(args: KernelArgs): SharedTreeKernel {\n\t\tif (args.idCompressor === undefined) {\n\t\t\tthrow new UsageError(\"IdCompressor must be enabled to use SharedTree\");\n\t\t}\n\n\t\tconst { minVersionForCollab, ...otherOptions } = options;\n\n\t\tconst adjustedOptions = {\n\t\t\t...otherOptions,\n\t\t\t// Cases:\n\t\t\t// A. If options specifies minVersionForCollab, it takes precedence over args.minVersionForCollab.\n\t\t\t// This value is set when:\n\t\t\t// - A customer using the declarative SharedTree API specifies the setting at the Shared Tree level.\n\t\t\t// There is currently no way to set it via the declarative API, but it could be added in the future.\n\t\t\t// - treeKernelFactory is invoked in a fuzz test with a specific minVersionForCollab\n\t\t\t// B. Otherwise, we use args.minVersionForCollab, which is propagated from the ContainerRuntime.\n\t\t\t// C. If neither specifies it, we fall back to a default value default of 2.0 since that is the oldest version that supports SharedTree.\n\t\t\tminVersionForCollab:\n\t\t\t\tminVersionForCollab ?? args.minVersionForCollab ?? FluidClientVersion.v2_0,\n\t\t};\n\n\t\treturn new SharedTreeKernel(\n\t\t\tnew Breakable(\"SharedTree\"),\n\t\t\targs.sharedObject,\n\t\t\targs.serializer,\n\t\t\targs.submitLocalMessage,\n\t\t\targs.lastSequenceNumber,\n\t\t\targs.initialSequenceNumber,\n\t\t\targs.logger,\n\t\t\targs.idCompressor,\n\t\t\tadjustedOptions,\n\t\t);\n\t}\n\n\treturn {\n\t\tcreate: (args: KernelArgs): FactoryOut<SharedTreeKernelView> => {\n\t\t\tconst k = treeFromKernelArgs(args);\n\t\t\treturn { kernel: k, view: k.view };\n\t\t},\n\n\t\tasync loadCore(\n\t\t\targs: KernelArgs,\n\t\t\tstorage: IChannelStorageService,\n\t\t): Promise<FactoryOut<SharedTreeKernelView>> {\n\t\t\tconst k = treeFromKernelArgs(args);\n\t\t\tawait k.loadCore(storage);\n\t\t\treturn { kernel: k, view: k.view };\n\t\t},\n\t};\n}\n\n/**\n * SharedTree is a hierarchical data structure for collaboratively editing strongly typed JSON-like trees\n * of objects, arrays, and other data types.\n * @legacy @beta\n */\nexport const SharedTree = configuredSharedTree({});\n\n/**\n * {@link SharedTree} but allowing a non-default configuration.\n * @remarks\n * This is useful for debugging and testing.\n * For example it can be used to opt into extra validation or see if opting out of some optimizations fixes an issue.\n *\n * With great care, and knowledge of the support and stability of the options exposed here,\n * this can also be used to opt into some features early or for performance tuning.\n *\n * @example\n * ```typescript\n * import {\n * \tconfiguredSharedTreeBeta,\n * \tForestTypeReference,\n * } from \"fluid-framework/beta\";\n * const SharedTree = configuredSharedTree({\n * \tforest: ForestTypeReference,\n * });\n * ```\n * @privateRemarks\n * The Legacy `ISharedObjectKind<ITree>` type is omitted here for simplicity.\n * @beta\n */\nexport function configuredSharedTreeBeta(\n\toptions: SharedTreeOptionsBeta,\n): SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBeta} including the legacy `ISharedObjectKind` type.\n * @privateRemarks\n * This is given a different export name (with legacy appended) to avoid the need to do the special reexport with different types from the fluid-framework package.\n * @legacy @beta\n */\nexport function configuredSharedTreeBetaLegacy(\n\toptions: SharedTreeOptionsBeta,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBeta} but including the alpha {@link SharedTreeOptions}.\n * @alpha\n */\nexport function configuredSharedTreeAlpha(\n\toptions: SharedTreeOptions,\n): SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBetaLegacy} but including `@alpha` options.\n *\n * @example\n * ```typescript\n * import {\n * \tTreeCompressionStrategy,\n * \tconfiguredSharedTree,\n * \tFormatValidatorBasic,\n * \tForestTypeReference,\n * } from \"@fluidframework/tree/internal\";\n * const SharedTree = configuredSharedTree({\n * \tforest: ForestTypeReference,\n * \tjsonValidator: FormatValidatorBasic,\n * \ttreeEncodeType: TreeCompressionStrategy.Uncompressed,\n * });\n * ```\n * @privateRemarks\n * This should be legacy, but has to be internal due to no alpha+legacy being setup yet.\n *\n * This should be renamed to `configuredSharedTreeAlpha` to avoid colliding with the eventual public version which will have less options.\n * @internal\n */\nexport function configuredSharedTree(\n\toptions: SharedTreeOptions,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\tconst internalOptions = resolveOptions(options);\n\treturn configuredSharedTreeInternal(internalOptions);\n}\n\nexport function configuredSharedTreeInternal(\n\toptions: SharedTreeOptionsInternal,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\tconst sharedObjectOptions: SharedObjectOptions<ITree> = {\n\t\ttype: SharedTreeFactoryType,\n\t\tattributes: SharedTreeAttributes,\n\t\ttelemetryContextPrefix: \"fluid_sharedTree_\",\n\t\tfactory: treeKernelFactory(options),\n\t};\n\n\treturn makeSharedObjectKind<ITree>(sharedObjectOptions);\n}\n\nexport function resolveOptions(options: SharedTreeOptions): SharedTreeOptionsInternal {\n\tconst internal: SharedTreeOptionsInternal = {\n\t\t...resolveFormatOptions(options),\n\t};\n\tfor (const optionName of Object.keys(options)) {\n\t\tcopyProperty(options, optionName, internal);\n\t}\n\treturn internal;\n}\n\nfunction resolveFormatOptions(options: SharedTreeOptions): SharedTreeOptionsInternal {\n\tconst enableSharedBranches = options.enableSharedBranches ?? false;\n\n\tif (enableSharedBranches) {\n\t\treturn sharedBranchesOptions;\n\t}\n\n\treturn {};\n}\n\nconst sharedBranchesOptions: SharedTreeOptionsInternal = {\n\twriteVersionOverrides: new Map<string, FormatVersion>([\n\t\t[editManagerCodecName, EditManagerFormatVersion.vSharedBranches],\n\t\t[messageCodecName, MessageFormatVersion.vSharedBranches],\n\t]),\n\tallowPossiblyIncompatibleWriteVersionOverrides: true,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"treeFactory.js","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IChannelStorageService } from \"@fluidframework/datastore-definitions/internal\";\nimport type { SharedObjectKind } from \"@fluidframework/shared-object-base\";\nimport {\n\ttype ISharedObject,\n\ttype ISharedObjectKind,\n\tmakeSharedObjectKind,\n\ttype KernelArgs,\n\ttype SharedKernelFactory,\n\ttype SharedObjectOptions,\n\ttype FactoryOut,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { FluidClientVersion, type FormatVersion } from \"./codec/index.js\";\nimport {\n\tdetachedFieldIndexCodecBuilder,\n\tDetachedFieldIndexFormatVersion,\n} from \"./core/index.js\";\nimport {\n\tSharedTreeKernel,\n\ttype ITreePrivate,\n\ttype SharedTreeOptions,\n\ttype SharedTreeOptionsBeta,\n\ttype SharedTreeOptionsInternal,\n\ttype SharedTreeKernelView,\n} from \"./shared-tree/index.js\";\nimport {\n\teditManagerCodecName,\n\tEditManagerFormatVersion,\n\tmessageCodecName,\n\tMessageFormatVersion,\n} from \"./shared-tree-core/index.js\";\nimport { SharedTreeFactoryType, SharedTreeAttributes } from \"./sharedTreeAttributes.js\";\nimport type { ITree } from \"./simple-tree/index.js\";\nimport { Breakable, copyProperty } from \"./util/index.js\";\n\n/**\n * {@link ITreePrivate} extended with ISharedObject.\n * @remarks\n * This is used when integration testing this package with the Fluid runtime as it exposes the APIs the runtime consumes to manipulate the tree.\n */\nexport interface ISharedTree extends ISharedObject, ITreePrivate {}\n\n/**\n * Creates a factory for shared tree kernels with the given options.\n * @remarks\n * Exposes {@link ITreePrivate} to allow access to internals in tests without a cast.\n * Code exposing this beyond this package will need to update to a more public type.\n */\nfunction treeKernelFactory(\n\toptions: SharedTreeOptionsInternal,\n): SharedKernelFactory<SharedTreeKernelView> {\n\tfunction treeFromKernelArgs(args: KernelArgs): SharedTreeKernel {\n\t\tif (args.idCompressor === undefined) {\n\t\t\tthrow new UsageError(\"IdCompressor must be enabled to use SharedTree\");\n\t\t}\n\n\t\tconst { minVersionForCollab, ...otherOptions } = options;\n\n\t\tconst adjustedOptions = {\n\t\t\t...otherOptions,\n\t\t\t// Cases:\n\t\t\t// A. If options specifies minVersionForCollab, it takes precedence over args.minVersionForCollab.\n\t\t\t// This value is set when:\n\t\t\t// - A customer using the declarative SharedTree API specifies the setting at the Shared Tree level.\n\t\t\t// There is currently no way to set it via the declarative API, but it could be added in the future.\n\t\t\t// - treeKernelFactory is invoked in a fuzz test with a specific minVersionForCollab\n\t\t\t// B. Otherwise, we use args.minVersionForCollab, which is propagated from the ContainerRuntime.\n\t\t\t// C. If neither specifies it, we fall back to a default value default of 2.0 since that is the oldest version that supports SharedTree.\n\t\t\tminVersionForCollab:\n\t\t\t\tminVersionForCollab ?? args.minVersionForCollab ?? FluidClientVersion.v2_0,\n\t\t};\n\n\t\treturn new SharedTreeKernel(\n\t\t\tnew Breakable(\"SharedTree\"),\n\t\t\targs.sharedObject,\n\t\t\targs.serializer,\n\t\t\targs.submitLocalMessage,\n\t\t\targs.lastSequenceNumber,\n\t\t\targs.initialSequenceNumber,\n\t\t\targs.logger,\n\t\t\targs.idCompressor,\n\t\t\tadjustedOptions,\n\t\t);\n\t}\n\n\treturn {\n\t\tcreate: (args: KernelArgs): FactoryOut<SharedTreeKernelView> => {\n\t\t\tconst k = treeFromKernelArgs(args);\n\t\t\treturn { kernel: k, view: k.view };\n\t\t},\n\n\t\tasync loadCore(\n\t\t\targs: KernelArgs,\n\t\t\tstorage: IChannelStorageService,\n\t\t): Promise<FactoryOut<SharedTreeKernelView>> {\n\t\t\tconst k = treeFromKernelArgs(args);\n\t\t\tawait k.loadCore(storage);\n\t\t\treturn { kernel: k, view: k.view };\n\t\t},\n\t};\n}\n\n/**\n * SharedTree is a hierarchical data structure for collaboratively editing strongly typed JSON-like trees\n * of objects, arrays, and other data types.\n * @legacy @beta\n */\nexport const SharedTree = configuredSharedTree({});\n\n/**\n * {@link SharedTree} but allowing a non-default configuration.\n * @remarks\n * This is useful for debugging and testing.\n * For example it can be used to opt into extra validation or see if opting out of some optimizations fixes an issue.\n *\n * With great care, and knowledge of the support and stability of the options exposed here,\n * this can also be used to opt into some features early or for performance tuning.\n *\n * @example\n * ```typescript\n * import {\n * \tconfiguredSharedTreeBeta,\n * \tForestTypeReference,\n * } from \"fluid-framework/beta\";\n * const SharedTree = configuredSharedTree({\n * \tforest: ForestTypeReference,\n * });\n * ```\n * @privateRemarks\n * The Legacy `ISharedObjectKind<ITree>` type is omitted here for simplicity.\n * @beta\n */\nexport function configuredSharedTreeBeta(\n\toptions: SharedTreeOptionsBeta,\n): SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBeta} including the legacy `ISharedObjectKind` type.\n * @privateRemarks\n * This is given a different export name (with legacy appended) to avoid the need to do the special reexport with different types from the fluid-framework package.\n * @legacy @beta\n */\nexport function configuredSharedTreeBetaLegacy(\n\toptions: SharedTreeOptionsBeta,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBeta} but including the alpha {@link SharedTreeOptions}.\n * @alpha\n */\nexport function configuredSharedTreeAlpha(\n\toptions: SharedTreeOptions,\n): SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBetaLegacy} but including `@alpha` options.\n *\n * @example\n * ```typescript\n * import {\n * \tTreeCompressionStrategy,\n * \tconfiguredSharedTree,\n * \tFormatValidatorBasic,\n * \tForestTypeReference,\n * } from \"@fluidframework/tree/internal\";\n * const SharedTree = configuredSharedTree({\n * \tforest: ForestTypeReference,\n * \tjsonValidator: FormatValidatorBasic,\n * \ttreeEncodeType: TreeCompressionStrategy.Uncompressed,\n * });\n * ```\n * @privateRemarks\n * This should be legacy, but has to be internal due to no alpha+legacy being setup yet.\n *\n * This should be renamed to `configuredSharedTreeAlpha` to avoid colliding with the eventual public version which will have less options.\n * @internal\n */\nexport function configuredSharedTree(\n\toptions: SharedTreeOptions,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\tconst internalOptions = resolveOptions(options);\n\treturn configuredSharedTreeInternal(internalOptions);\n}\n\nexport function configuredSharedTreeInternal(\n\toptions: SharedTreeOptionsInternal,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\tconst sharedObjectOptions: SharedObjectOptions<ITree> = {\n\t\ttype: SharedTreeFactoryType,\n\t\tattributes: SharedTreeAttributes,\n\t\ttelemetryContextPrefix: \"fluid_sharedTree_\",\n\t\tfactory: treeKernelFactory(options),\n\t};\n\n\treturn makeSharedObjectKind<ITree>(sharedObjectOptions);\n}\n\nexport function resolveOptions(options: SharedTreeOptions): SharedTreeOptionsInternal {\n\tconst internal: SharedTreeOptionsInternal = {\n\t\t...resolveFormatOptions(options),\n\t};\n\tfor (const optionName of Object.keys(options)) {\n\t\tcopyProperty(options, optionName, internal);\n\t}\n\treturn internal;\n}\n\nfunction resolveFormatOptions(options: SharedTreeOptions): SharedTreeOptionsInternal {\n\tconst enableSharedBranches = options.enableSharedBranches ?? false;\n\n\tif (enableSharedBranches) {\n\t\treturn sharedBranchesOptions;\n\t}\n\n\treturn {};\n}\n\nconst sharedBranchesOptions: SharedTreeOptionsInternal = {\n\twriteVersionOverrides: new Map<string, FormatVersion>([\n\t\t[editManagerCodecName, EditManagerFormatVersion.vSharedBranches],\n\t\t[messageCodecName, MessageFormatVersion.vSharedBranches],\n\t\t[detachedFieldIndexCodecBuilder.name, DetachedFieldIndexFormatVersion.v2],\n\t]),\n\tallowPossiblyIncompatibleWriteVersionOverrides: true,\n};\n"]}
|
package/dist/util/breakable.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare class Breakable {
|
|
|
28
28
|
* @remarks
|
|
29
29
|
* Can use {@link throwIfBroken} to apply this to a method.
|
|
30
30
|
*/
|
|
31
|
-
use(): void;
|
|
31
|
+
use(message?: (brokenBy: Error) => string): void;
|
|
32
32
|
/**
|
|
33
33
|
* Puts this object into the broken state, and throws an error.
|
|
34
34
|
*
|
|
@@ -47,6 +47,12 @@ export declare class Breakable {
|
|
|
47
47
|
* Like {@link Breakable.use}, this also throws if already broken.
|
|
48
48
|
* Any exceptions this catches are re-thrown.
|
|
49
49
|
* Can use {@link breakingMethod} to apply this to a method.
|
|
50
|
+
*
|
|
51
|
+
* If `breaker` returns a Promise, the breakable is also broken if that Promise rejects, and the broken state is rechecked when it resolves:
|
|
52
|
+
* if the breakable was put into a broken state during the async operation (by some other code path), the resolved value is discarded and the returned Promise rejects with a {@link UsageError}.
|
|
53
|
+
*
|
|
54
|
+
* This does not serialize concurrent runs: a synchronous run invoked while an async run is in flight will execute immediately, and is only blocked if the breakable is already broken.
|
|
55
|
+
* Detection of an async result uses `instanceof Promise`, so custom Promise-like objects and Promises from other realms will be treated as synchronous results.
|
|
50
56
|
*/
|
|
51
57
|
run<TResult>(breaker: () => TResult): TResult;
|
|
52
58
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breakable.d.ts","sourceRoot":"","sources":["../../src/util/breakable.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;GAKG;AACH,qBAAa,SAAS;IAIpB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI;IARtB,OAAO,CAAC,QAAQ,CAAC,CAAQ;;IAGxB;;;;OAIG;IACc,IAAI,EAAE,MAAM;IAG9B;;;;OAIG;IACI,GAAG,
|
|
1
|
+
{"version":3,"file":"breakable.d.ts","sourceRoot":"","sources":["../../src/util/breakable.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;GAKG;AACH,qBAAa,SAAS;IAIpB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI;IARtB,OAAO,CAAC,QAAQ,CAAC,CAAQ;;IAGxB;;;;OAIG;IACc,IAAI,EAAE,MAAM;IAG9B;;;;OAIG;IACI,GAAG,CACT,OAAO,GAAE,CAAC,QAAQ,EAAE,KAAK,KAAK,MACuF,GACnH,IAAI;IAcP;;;;OAIG;IACI,KAAK,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK;IAUpC;;;;OAIG;IACH,OAAO,CAAC,aAAa;IASrB;;;;;;;;;;;;OAYG;IACI,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,GAAG,OAAO;IAuBpD;;;;;OAKG;IACI,UAAU,IAAI,IAAI;CAIzB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC7B,MAAM,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,EACtF,IAAI,SAAS,aAAa,EAC1B,IAAI,SAAS,KAAK,EAAE,EACpB,MAAM,EACL,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,MAAM,CAe7E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC5B,MAAM,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,EACtF,IAAI,SAAS,aAAa,EAC1B,IAAI,SAAS,KAAK,EAAE,EACpB,MAAM,EACL,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,MAAM,CAQ5E;AAyBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,aAAa,EAC1F,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,CAAC,MAAM,CAAC,GACpC,MAAM,CAiCR"}
|
package/dist/util/breakable.js
CHANGED
|
@@ -28,10 +28,10 @@ class Breakable {
|
|
|
28
28
|
* @remarks
|
|
29
29
|
* Can use {@link throwIfBroken} to apply this to a method.
|
|
30
30
|
*/
|
|
31
|
-
use() {
|
|
31
|
+
use(message = (brokenBy) => `Invalid use of ${this.name} after it was put into an invalid state by another error.\nOriginal Error:\n${brokenBy}`) {
|
|
32
32
|
if (this.brokenBy !== undefined) {
|
|
33
|
-
const error = new internal_2.UsageError(
|
|
34
|
-
// This "cause" field is added in ES2022, but using
|
|
33
|
+
const error = new internal_2.UsageError(message(this.brokenBy));
|
|
34
|
+
// This "cause" field is added in ES2022, but using it even without that built in support, it is still helpful.
|
|
35
35
|
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
|
|
36
36
|
// TODO: remove this cast when targeting ES2022 lib or later.
|
|
37
37
|
error.cause =
|
|
@@ -70,11 +70,25 @@ class Breakable {
|
|
|
70
70
|
* Like {@link Breakable.use}, this also throws if already broken.
|
|
71
71
|
* Any exceptions this catches are re-thrown.
|
|
72
72
|
* Can use {@link breakingMethod} to apply this to a method.
|
|
73
|
+
*
|
|
74
|
+
* If `breaker` returns a Promise, the breakable is also broken if that Promise rejects, and the broken state is rechecked when it resolves:
|
|
75
|
+
* if the breakable was put into a broken state during the async operation (by some other code path), the resolved value is discarded and the returned Promise rejects with a {@link UsageError}.
|
|
76
|
+
*
|
|
77
|
+
* This does not serialize concurrent runs: a synchronous run invoked while an async run is in flight will execute immediately, and is only blocked if the breakable is already broken.
|
|
78
|
+
* Detection of an async result uses `instanceof Promise`, so custom Promise-like objects and Promises from other realms will be treated as synchronous results.
|
|
73
79
|
*/
|
|
74
80
|
run(breaker) {
|
|
75
81
|
this.use();
|
|
76
82
|
try {
|
|
77
|
-
|
|
83
|
+
const result = breaker();
|
|
84
|
+
if (result instanceof Promise) {
|
|
85
|
+
return result.then((value) => {
|
|
86
|
+
// If broken while process was running: this will throw instead of returning the value.
|
|
87
|
+
this.use((brokenBy) => `${this.name} was put into a broken state during an async operation.\nOriginal Error:\n${brokenBy}`);
|
|
88
|
+
return value;
|
|
89
|
+
}, (error) => this.rethrowCaught(error));
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
78
92
|
}
|
|
79
93
|
catch (error) {
|
|
80
94
|
this.rethrowCaught(error);
|