@fluidframework/tree 2.81.1 → 2.83.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 +168 -0
- package/README.md +33 -5
- package/api-report/tree.alpha.api.md +75 -39
- package/api-report/tree.beta.api.md +164 -3
- package/api-report/tree.legacy.beta.api.md +164 -3
- package/api-report/tree.legacy.public.api.md +2 -1
- package/api-report/tree.public.api.md +2 -1
- package/dist/alpha.d.ts +10 -4
- package/dist/beta.d.ts +4 -0
- package/dist/codec/codec.d.ts +18 -45
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +12 -50
- 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 +20 -7
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js +56 -30
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/rebase/changeRebaser.d.ts +3 -2
- package/dist/core/rebase/changeRebaser.d.ts.map +1 -1
- package/dist/core/rebase/changeRebaser.js.map +1 -1
- package/dist/core/rebase/index.d.ts +1 -1
- package/dist/core/rebase/index.d.ts.map +1 -1
- package/dist/core/rebase/index.js +4 -2
- package/dist/core/rebase/index.js.map +1 -1
- package/dist/core/rebase/types.d.ts +23 -3
- package/dist/core/rebase/types.d.ts.map +1 -1
- package/dist/core/rebase/types.js +30 -16
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/schema-stored/formatV1.d.ts +2 -2
- package/dist/core/schema-stored/formatV1.d.ts.map +1 -1
- package/dist/core/schema-stored/formatV1.js +0 -5
- package/dist/core/schema-stored/formatV1.js.map +1 -1
- package/dist/core/schema-stored/formatV2.d.ts +11 -10
- package/dist/core/schema-stored/formatV2.d.ts.map +1 -1
- package/dist/core/schema-stored/formatV2.js +1 -6
- package/dist/core/schema-stored/formatV2.js.map +1 -1
- package/dist/core/schema-stored/index.d.ts.map +1 -1
- package/dist/core/schema-stored/index.js.map +1 -1
- package/dist/core/schema-stored/schema.d.ts.map +1 -1
- package/dist/core/schema-stored/schema.js.map +1 -1
- package/dist/core/tree/anchorSet.d.ts.map +1 -1
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/core/tree/delta.d.ts +9 -7
- package/dist/core/tree/delta.d.ts.map +1 -1
- package/dist/core/tree/delta.js.map +1 -1
- package/dist/core/tree/deltaUtil.js +1 -1
- package/dist/core/tree/deltaUtil.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.js +6 -4
- package/dist/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/dist/core/tree/visitDelta.js +2 -2
- package/dist/core/tree/visitDelta.js.map +1 -1
- package/dist/extensibleUnionNode.d.ts +97 -0
- package/dist/extensibleUnionNode.d.ts.map +1 -0
- package/dist/extensibleUnionNode.js +89 -0
- package/dist/extensibleUnionNode.js.map +1 -0
- package/dist/feature-libraries/changeAtomIdBTree.d.ts +4 -2
- package/dist/feature-libraries/changeAtomIdBTree.d.ts.map +1 -1
- package/dist/feature-libraries/changeAtomIdBTree.js +9 -1
- package/dist/feature-libraries/changeAtomIdBTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +4 -4
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -3
- package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +20 -21
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/default-schema/index.d.ts +1 -1
- package/dist/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/default-schema/index.js.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.d.ts +2 -1
- package/dist/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/codec.js +7 -1
- package/dist/feature-libraries/forest-summary/codec.js.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/forestSummarizer.js +5 -2
- package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.d.ts +4 -42
- package/dist/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.js +1 -2
- package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatV1.d.ts +2 -41
- package/dist/feature-libraries/forest-summary/formatV1.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/formatV1.js +1 -2
- package/dist/feature-libraries/forest-summary/formatV1.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatV2.d.ts +2 -41
- package/dist/feature-libraries/forest-summary/formatV2.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/formatV2.js +1 -2
- package/dist/feature-libraries/forest-summary/formatV2.js.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js +1 -1
- package/dist/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/dist/feature-libraries/index.d.ts +3 -3
- package/dist/feature-libraries/index.d.ts.map +1 -1
- package/dist/feature-libraries/index.js +4 -3
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +2 -2
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js +42 -22
- package/dist/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
- package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/index.js +2 -1
- package/dist/feature-libraries/modular-schema/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +3 -3
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +13 -9
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +11 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +30 -7
- package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +38 -27
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +10 -127
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -4
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +3 -79
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js +1 -1
- package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/dist/feature-libraries/optional-field/requiredField.d.ts.map +1 -1
- package/dist/feature-libraries/optional-field/requiredField.js.map +1 -1
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.d.ts +2 -2
- package/dist/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/codec.js +6 -4
- package/dist/feature-libraries/schema-index/codec.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV2.d.ts +4 -4
- package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/sequence-field/invert.js +2 -2
- package/dist/feature-libraries/sequence-field/invert.js.map +1 -1
- package/dist/feature-libraries/sequence-field/replaceRevisions.js +16 -16
- package/dist/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js +1 -1
- package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +4 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/independentView.d.ts +36 -13
- package/dist/shared-tree/independentView.d.ts.map +1 -1
- package/dist/shared-tree/independentView.js +1 -0
- package/dist/shared-tree/independentView.js.map +1 -1
- package/dist/shared-tree/index.d.ts +1 -1
- package/dist/shared-tree/index.d.ts.map +1 -1
- package/dist/shared-tree/index.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +10 -0
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +25 -9
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +3 -3
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +8 -32
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts +11 -3
- package/dist/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js +39 -5
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFormat.d.ts +4 -4
- package/dist/shared-tree/tree.d.ts +1 -1
- package/dist/shared-tree/tree.js +1 -1
- package/dist/shared-tree/tree.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts +1 -1
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +20 -0
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +41 -7
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsCommons.d.ts +3 -3
- package/dist/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsCommons.js +2 -2
- package/dist/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts +2 -2
- package/dist/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsV1toV4.js +1 -1
- package/dist/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +2 -2
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js +1 -1
- package/dist/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js +1 -1
- package/dist/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/dist/shared-tree-core/messageCodecV1ToV4.js +2 -2
- package/dist/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- 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/transaction.d.ts +14 -3
- package/dist/shared-tree-core/transaction.d.ts.map +1 -1
- package/dist/shared-tree-core/transaction.js +59 -16
- package/dist/shared-tree-core/transaction.js.map +1 -1
- package/dist/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
- package/dist/shared-tree-core/versionedSummarizer.js +1 -1
- package/dist/shared-tree-core/versionedSummarizer.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +2 -2
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +4 -3
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.d.ts +9 -0
- package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.js +16 -1
- package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/dist/simple-tree/api/simpleTreeIndex.js.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts +148 -29
- package/dist/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js +180 -99
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/dist/simple-tree/api/transactionTypes.d.ts +10 -0
- package/dist/simple-tree/api/transactionTypes.d.ts.map +1 -1
- package/dist/simple-tree/api/transactionTypes.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +82 -7
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/api/treeBeta.d.ts +1 -1
- package/dist/simple-tree/api/treeBeta.js.map +1 -1
- package/dist/simple-tree/core/allowedTypes.d.ts +1 -1
- package/dist/simple-tree/core/allowedTypes.js.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts +1 -0
- package/dist/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +29 -0
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/index.d.ts +2 -2
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +5 -3
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/dist/simple-tree/leafNodeSchema.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts +63 -0
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +47 -14
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/index.d.ts +1 -1
- package/dist/simple-tree/node-kinds/array/index.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/index.js +2 -1
- package/dist/simple-tree/node-kinds/array/index.js.map +1 -1
- package/dist/simple-tree/node-kinds/index.d.ts +1 -1
- package/dist/simple-tree/node-kinds/index.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/index.js +2 -1
- package/dist/simple-tree/node-kinds/index.js.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js +33 -7
- package/dist/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/dist/tableSchema.d.ts +71 -48
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +200 -98
- package/dist/tableSchema.js.map +1 -1
- package/dist/text/textDomainFormatted.d.ts +3 -3
- package/dist/text/textDomainFormatted.d.ts.map +1 -1
- package/dist/text/textDomainFormatted.js +48 -32
- package/dist/text/textDomainFormatted.js.map +1 -1
- package/dist/util/bTreeUtils.d.ts +30 -4
- package/dist/util/bTreeUtils.d.ts.map +1 -1
- package/dist/util/bTreeUtils.js +35 -23
- package/dist/util/bTreeUtils.js.map +1 -1
- package/dist/util/brand.d.ts.map +1 -1
- package/dist/util/brand.js.map +1 -1
- package/dist/util/brandedMap.d.ts.map +1 -1
- package/dist/util/brandedMap.js.map +1 -1
- package/dist/util/breakable.d.ts.map +1 -1
- package/dist/util/breakable.js +2 -1
- package/dist/util/breakable.js.map +1 -1
- package/dist/util/index.d.ts +2 -2
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +6 -3
- package/dist/util/index.js.map +1 -1
- package/dist/util/opaque.d.ts.map +1 -1
- package/dist/util/opaque.js.map +1 -1
- package/dist/util/rangeMap.d.ts +3 -2
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +12 -7
- package/dist/util/rangeMap.js.map +1 -1
- package/dist/util/readSnapshotBlob.d.ts +1 -1
- package/dist/util/readSnapshotBlob.d.ts.map +1 -1
- package/dist/util/readSnapshotBlob.js.map +1 -1
- package/dist/util/typeCheck.d.ts.map +1 -1
- package/dist/util/typeCheck.js.map +1 -1
- package/dist/util/utils.d.ts +20 -16
- package/dist/util/utils.d.ts.map +1 -1
- package/dist/util/utils.js +49 -17
- package/dist/util/utils.js.map +1 -1
- package/eslint.config.mts +0 -9
- package/lib/alpha.d.ts +10 -4
- package/lib/beta.d.ts +4 -0
- package/lib/codec/codec.d.ts +18 -45
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +10 -47
- 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 +20 -7
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js +59 -33
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/core/index.d.ts +1 -1
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +1 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/rebase/changeRebaser.d.ts +3 -2
- package/lib/core/rebase/changeRebaser.d.ts.map +1 -1
- package/lib/core/rebase/changeRebaser.js.map +1 -1
- package/lib/core/rebase/index.d.ts +1 -1
- package/lib/core/rebase/index.d.ts.map +1 -1
- package/lib/core/rebase/index.js +1 -1
- package/lib/core/rebase/index.js.map +1 -1
- package/lib/core/rebase/types.d.ts +23 -3
- package/lib/core/rebase/types.d.ts.map +1 -1
- package/lib/core/rebase/types.js +27 -15
- package/lib/core/rebase/types.js.map +1 -1
- package/lib/core/schema-stored/formatV1.d.ts +2 -2
- package/lib/core/schema-stored/formatV1.d.ts.map +1 -1
- package/lib/core/schema-stored/formatV1.js +0 -5
- package/lib/core/schema-stored/formatV1.js.map +1 -1
- package/lib/core/schema-stored/formatV2.d.ts +11 -10
- package/lib/core/schema-stored/formatV2.d.ts.map +1 -1
- package/lib/core/schema-stored/formatV2.js +1 -6
- package/lib/core/schema-stored/formatV2.js.map +1 -1
- package/lib/core/schema-stored/index.d.ts.map +1 -1
- package/lib/core/schema-stored/index.js +2 -0
- package/lib/core/schema-stored/index.js.map +1 -1
- package/lib/core/schema-stored/schema.d.ts.map +1 -1
- package/lib/core/schema-stored/schema.js.map +1 -1
- package/lib/core/tree/anchorSet.d.ts.map +1 -1
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/core/tree/delta.d.ts +9 -7
- package/lib/core/tree/delta.d.ts.map +1 -1
- package/lib/core/tree/delta.js.map +1 -1
- package/lib/core/tree/deltaUtil.js +1 -1
- package/lib/core/tree/deltaUtil.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.d.ts.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.js +6 -4
- package/lib/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/lib/core/tree/visitDelta.js +2 -2
- package/lib/core/tree/visitDelta.js.map +1 -1
- package/lib/extensibleUnionNode.d.ts +97 -0
- package/lib/extensibleUnionNode.d.ts.map +1 -0
- package/lib/extensibleUnionNode.js +86 -0
- package/lib/extensibleUnionNode.js.map +1 -0
- package/lib/feature-libraries/changeAtomIdBTree.d.ts +4 -2
- package/lib/feature-libraries/changeAtomIdBTree.d.ts.map +1 -1
- package/lib/feature-libraries/changeAtomIdBTree.js +7 -0
- package/lib/feature-libraries/changeAtomIdBTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +5 -5
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts +1 -3
- package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +4 -5
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/default-schema/index.d.ts +1 -1
- package/lib/feature-libraries/default-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/default-schema/index.js.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.d.ts +2 -1
- package/lib/feature-libraries/forest-summary/codec.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/codec.js +8 -2
- package/lib/feature-libraries/forest-summary/codec.js.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/forestSummarizer.js +6 -3
- package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
- package/lib/feature-libraries/forest-summary/formatCommon.d.ts +4 -42
- package/lib/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/formatCommon.js +2 -3
- package/lib/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/lib/feature-libraries/forest-summary/formatV1.d.ts +2 -41
- package/lib/feature-libraries/forest-summary/formatV1.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/formatV1.js +1 -2
- package/lib/feature-libraries/forest-summary/formatV1.js.map +1 -1
- package/lib/feature-libraries/forest-summary/formatV2.d.ts +2 -41
- package/lib/feature-libraries/forest-summary/formatV2.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/formatV2.js +1 -2
- package/lib/feature-libraries/forest-summary/formatV2.js.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js +1 -1
- package/lib/feature-libraries/forest-summary/incrementalSummaryBuilder.js.map +1 -1
- package/lib/feature-libraries/index.d.ts +3 -3
- package/lib/feature-libraries/index.d.ts.map +1 -1
- package/lib/feature-libraries/index.js +3 -3
- package/lib/feature-libraries/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts +2 -2
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js +41 -21
- package/lib/feature-libraries/modular-schema/defaultRevisionReplacer.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
- package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/index.js +1 -1
- package/lib/feature-libraries/modular-schema/index.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts +3 -3
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +14 -10
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +11 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +29 -6
- package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +41 -30
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts +10 -127
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -4
- package/lib/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts +3 -79
- package/lib/feature-libraries/modular-schema/modularChangeFormatV2.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js +1 -1
- package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
- package/lib/feature-libraries/optional-field/requiredField.d.ts.map +1 -1
- package/lib/feature-libraries/optional-field/requiredField.js.map +1 -1
- package/lib/feature-libraries/schema-edits/schemaChangeFormat.d.ts +2 -2
- package/lib/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/codec.js +6 -4
- package/lib/feature-libraries/schema-index/codec.js.map +1 -1
- package/lib/feature-libraries/schema-index/formatV2.d.ts +4 -4
- package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/sequence-field/invert.js +2 -2
- package/lib/feature-libraries/sequence-field/invert.js.map +1 -1
- package/lib/feature-libraries/sequence-field/replaceRevisions.js +16 -16
- package/lib/feature-libraries/sequence-field/replaceRevisions.js.map +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js +1 -1
- package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
- package/lib/index.d.ts +5 -5
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -3
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +4 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/independentView.d.ts +36 -13
- package/lib/shared-tree/independentView.d.ts.map +1 -1
- package/lib/shared-tree/independentView.js +1 -0
- package/lib/shared-tree/independentView.js.map +1 -1
- package/lib/shared-tree/index.d.ts +1 -1
- package/lib/shared-tree/index.d.ts.map +1 -1
- package/lib/shared-tree/index.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts +10 -0
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +25 -9
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +3 -3
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +10 -34
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts +11 -3
- package/lib/shared-tree/sharedTreeChangeCodecs.d.ts.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js +40 -6
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeFormat.d.ts +4 -4
- package/lib/shared-tree/tree.d.ts +1 -1
- package/lib/shared-tree/tree.js +1 -1
- package/lib/shared-tree/tree.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts +1 -1
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +20 -0
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +41 -7
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsCommons.d.ts +3 -3
- package/lib/shared-tree-core/editManagerCodecsCommons.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsCommons.js +2 -2
- package/lib/shared-tree-core/editManagerCodecsCommons.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts +2 -2
- package/lib/shared-tree-core/editManagerCodecsV1toV4.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsV1toV4.js +2 -2
- package/lib/shared-tree-core/editManagerCodecsV1toV4.js.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts +2 -2
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.d.ts.map +1 -1
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js +2 -2
- package/lib/shared-tree-core/editManagerCodecsVSharedBranches.js.map +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js +1 -1
- package/lib/shared-tree-core/editManagerSummarizer.js.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecV1ToV4.js +2 -2
- package/lib/shared-tree-core/messageCodecV1ToV4.js.map +1 -1
- package/lib/shared-tree-core/messageCodecs.d.ts.map +1 -1
- package/lib/shared-tree-core/messageCodecs.js +2 -2
- package/lib/shared-tree-core/messageCodecs.js.map +1 -1
- package/lib/shared-tree-core/transaction.d.ts +14 -3
- package/lib/shared-tree-core/transaction.d.ts.map +1 -1
- package/lib/shared-tree-core/transaction.js +61 -18
- package/lib/shared-tree-core/transaction.js.map +1 -1
- package/lib/shared-tree-core/versionedSummarizer.d.ts.map +1 -1
- package/lib/shared-tree-core/versionedSummarizer.js +1 -1
- package/lib/shared-tree-core/versionedSummarizer.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +2 -2
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +2 -2
- package/lib/simple-tree/api/index.js.map +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.d.ts +9 -0
- package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.js +14 -0
- package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/lib/simple-tree/api/simpleTreeIndex.js.map +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts +148 -29
- package/lib/simple-tree/api/snapshotCompatibilityChecker.d.ts.map +1 -1
- package/lib/simple-tree/api/snapshotCompatibilityChecker.js +179 -98
- package/lib/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/lib/simple-tree/api/transactionTypes.d.ts +10 -0
- package/lib/simple-tree/api/transactionTypes.d.ts.map +1 -1
- package/lib/simple-tree/api/transactionTypes.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +82 -7
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/api/treeBeta.d.ts +1 -1
- package/lib/simple-tree/api/treeBeta.js.map +1 -1
- package/lib/simple-tree/core/allowedTypes.d.ts +1 -1
- package/lib/simple-tree/core/allowedTypes.js.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts +1 -0
- package/lib/simple-tree/core/unhydratedFlexTree.d.ts.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +29 -0
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/index.d.ts +2 -2
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +2 -2
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.d.ts.map +1 -1
- package/lib/simple-tree/leafNodeSchema.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts +63 -0
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +46 -14
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/index.d.ts +1 -1
- package/lib/simple-tree/node-kinds/array/index.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/index.js +1 -1
- package/lib/simple-tree/node-kinds/array/index.js.map +1 -1
- package/lib/simple-tree/node-kinds/index.d.ts +1 -1
- package/lib/simple-tree/node-kinds/index.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/index.js +1 -1
- package/lib/simple-tree/node-kinds/index.js.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/object/objectNode.js.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.d.ts.map +1 -1
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js +34 -8
- package/lib/simple-tree/unhydratedFlexTreeFromInsertable.js.map +1 -1
- package/lib/tableSchema.d.ts +71 -48
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +201 -99
- package/lib/tableSchema.js.map +1 -1
- package/lib/text/textDomainFormatted.d.ts +3 -3
- package/lib/text/textDomainFormatted.d.ts.map +1 -1
- package/lib/text/textDomainFormatted.js +30 -14
- package/lib/text/textDomainFormatted.js.map +1 -1
- package/lib/util/bTreeUtils.d.ts +30 -4
- package/lib/util/bTreeUtils.d.ts.map +1 -1
- package/lib/util/bTreeUtils.js +33 -22
- package/lib/util/bTreeUtils.js.map +1 -1
- package/lib/util/brand.d.ts.map +1 -1
- package/lib/util/brand.js.map +1 -1
- package/lib/util/brandedMap.d.ts.map +1 -1
- package/lib/util/brandedMap.js.map +1 -1
- package/lib/util/breakable.d.ts.map +1 -1
- package/lib/util/breakable.js +2 -1
- package/lib/util/breakable.js.map +1 -1
- package/lib/util/index.d.ts +2 -2
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +2 -2
- package/lib/util/index.js.map +1 -1
- package/lib/util/opaque.d.ts.map +1 -1
- package/lib/util/opaque.js.map +1 -1
- package/lib/util/rangeMap.d.ts +3 -2
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +12 -7
- package/lib/util/rangeMap.js.map +1 -1
- package/lib/util/readSnapshotBlob.d.ts +1 -1
- package/lib/util/readSnapshotBlob.d.ts.map +1 -1
- package/lib/util/readSnapshotBlob.js.map +1 -1
- package/lib/util/typeCheck.d.ts.map +1 -1
- package/lib/util/typeCheck.js.map +1 -1
- package/lib/util/utils.d.ts +20 -16
- package/lib/util/utils.d.ts.map +1 -1
- package/lib/util/utils.js +44 -15
- package/lib/util/utils.js.map +1 -1
- package/package.json +24 -24
- package/src/codec/codec.ts +33 -116
- package/src/codec/index.ts +2 -3
- package/src/codec/versioned/codec.ts +127 -95
- package/src/core/index.ts +3 -1
- package/src/core/rebase/changeRebaser.ts +3 -2
- package/src/core/rebase/index.ts +3 -1
- package/src/core/rebase/types.ts +51 -13
- package/src/core/schema-stored/formatV1.ts +2 -4
- package/src/core/schema-stored/formatV2.ts +9 -7
- package/src/core/schema-stored/index.ts +2 -0
- package/src/core/schema-stored/schema.ts +4 -1
- package/src/core/tree/anchorSet.ts +1 -3
- package/src/core/tree/delta.ts +9 -7
- package/src/core/tree/deltaUtil.ts +1 -1
- package/src/core/tree/detachedFieldIndexCodecs.ts +6 -4
- package/src/core/tree/visitDelta.ts +2 -2
- package/src/extensibleUnionNode.ts +177 -0
- package/src/feature-libraries/changeAtomIdBTree.ts +17 -2
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +5 -11
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +5 -6
- package/src/feature-libraries/default-schema/index.ts +0 -1
- package/src/feature-libraries/forest-summary/codec.ts +15 -9
- package/src/feature-libraries/forest-summary/forestSummarizer.ts +15 -3
- package/src/feature-libraries/forest-summary/formatCommon.ts +7 -6
- package/src/feature-libraries/forest-summary/formatV1.ts +1 -3
- package/src/feature-libraries/forest-summary/formatV2.ts +1 -3
- package/src/feature-libraries/forest-summary/incrementalSummaryBuilder.ts +4 -5
- package/src/feature-libraries/index.ts +3 -2
- package/src/feature-libraries/modular-schema/defaultRevisionReplacer.ts +57 -31
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +1 -1
- package/src/feature-libraries/modular-schema/index.ts +4 -1
- package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +12 -12
- package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +32 -7
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +54 -33
- package/src/feature-libraries/modular-schema/modularChangeFormatV1.ts +2 -4
- package/src/feature-libraries/optional-field/optionalField.ts +1 -1
- package/src/feature-libraries/optional-field/requiredField.ts +2 -4
- package/src/feature-libraries/schema-index/codec.ts +7 -5
- package/src/feature-libraries/schema-index/schemaSummarizer.ts +1 -1
- package/src/feature-libraries/sequence-field/invert.ts +2 -2
- package/src/feature-libraries/sequence-field/replaceRevisions.ts +17 -10
- package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +1 -1
- package/src/index.ts +14 -9
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/independentView.ts +42 -6
- package/src/shared-tree/index.ts +2 -0
- package/src/shared-tree/schematizingTreeView.ts +63 -18
- package/src/shared-tree/sharedTree.ts +19 -37
- package/src/shared-tree/sharedTreeChangeCodecs.ts +45 -11
- package/src/shared-tree/tree.ts +2 -2
- package/src/shared-tree/treeAlpha.ts +1 -1
- package/src/shared-tree/treeCheckout.ts +52 -7
- package/src/shared-tree-core/editManagerCodecsCommons.ts +7 -7
- package/src/shared-tree-core/editManagerCodecsV1toV4.ts +3 -10
- package/src/shared-tree-core/editManagerCodecsVSharedBranches.ts +3 -10
- package/src/shared-tree-core/editManagerSummarizer.ts +1 -1
- package/src/shared-tree-core/messageCodecV1ToV4.ts +4 -3
- package/src/shared-tree-core/messageCodecs.ts +2 -6
- package/src/shared-tree-core/transaction.ts +125 -23
- package/src/shared-tree-core/versionedSummarizer.ts +3 -2
- package/src/simple-tree/api/index.ts +3 -2
- package/src/simple-tree/api/schemaCreationUtilities.ts +35 -5
- package/src/simple-tree/api/simpleTreeIndex.ts +1 -1
- package/src/simple-tree/api/snapshotCompatibilityChecker.ts +344 -142
- package/src/simple-tree/api/transactionTypes.ts +10 -0
- package/src/simple-tree/api/tree.ts +89 -7
- package/src/simple-tree/api/treeBeta.ts +1 -1
- package/src/simple-tree/core/allowedTypes.ts +1 -1
- package/src/simple-tree/core/treeNodeSchema.ts +5 -8
- package/src/simple-tree/core/unhydratedFlexTree.ts +43 -1
- package/src/simple-tree/index.ts +5 -2
- package/src/simple-tree/leafNodeSchema.ts +3 -2
- package/src/simple-tree/node-kinds/array/arrayNode.ts +99 -19
- package/src/simple-tree/node-kinds/array/index.ts +2 -0
- package/src/simple-tree/node-kinds/index.ts +2 -0
- package/src/simple-tree/node-kinds/object/objectNode.ts +19 -18
- package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +51 -10
- package/src/tableSchema.ts +280 -140
- package/src/text/textDomainFormatted.ts +37 -17
- package/src/util/bTreeUtils.ts +55 -32
- package/src/util/brand.ts +4 -12
- package/src/util/brandedMap.ts +2 -6
- package/src/util/breakable.ts +3 -2
- package/src/util/index.ts +9 -3
- package/src/util/opaque.ts +2 -6
- package/src/util/rangeMap.ts +20 -11
- package/src/util/readSnapshotBlob.ts +3 -3
- package/src/util/typeCheck.ts +11 -9
- package/src/util/utils.ts +57 -28
- package/api-extractor-lint.json +0 -4
- package/biome.jsonc +0 -4
|
@@ -8,25 +8,26 @@ exports.FormattedTextAsTree = void 0;
|
|
|
8
8
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
9
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
10
10
|
const index_js_1 = require("../core/index.js");
|
|
11
|
-
const index_js_2 = require("../
|
|
12
|
-
const index_js_3 = require("../
|
|
11
|
+
const index_js_2 = require("../shared-tree/index.js");
|
|
12
|
+
const index_js_3 = require("../simple-tree/index.js");
|
|
13
|
+
const index_js_4 = require("../util/index.js");
|
|
13
14
|
const textDomain_js_1 = require("./textDomain.js");
|
|
14
|
-
const sf = new
|
|
15
|
+
const sf = new index_js_3.SchemaFactoryAlpha("com.fluidframework.text.formatted");
|
|
15
16
|
class TextNode extends sf.object("Text", {
|
|
16
|
-
content:
|
|
17
|
+
content: index_js_3.SchemaFactory.required([() => StringArray], { key: index_js_1.EmptyKey }),
|
|
17
18
|
}) {
|
|
18
19
|
constructor() {
|
|
19
20
|
super(...arguments);
|
|
20
21
|
this.defaultFormat = new FormattedTextAsTree.CharacterFormat(defaultFormat);
|
|
21
22
|
}
|
|
22
23
|
insertAt(index, additionalCharacters) {
|
|
23
|
-
this.content.insertAt(index,
|
|
24
|
+
this.content.insertAt(index, index_js_3.TreeArrayNode.spread(textAtomsFromString(additionalCharacters, this.defaultFormat)));
|
|
24
25
|
}
|
|
25
26
|
removeRange(index, length) {
|
|
26
27
|
this.content.removeRange(index, length);
|
|
27
28
|
}
|
|
28
29
|
characters() {
|
|
29
|
-
return (0,
|
|
30
|
+
return (0, index_js_4.mapIterable)(this.content, (atom) => atom.content.content);
|
|
30
31
|
}
|
|
31
32
|
fullString() {
|
|
32
33
|
return [...this.characters()].join("");
|
|
@@ -45,25 +46,40 @@ class TextNode extends sf.object("Text", {
|
|
|
45
46
|
return this.content;
|
|
46
47
|
}
|
|
47
48
|
insertWithFormattingAt(index, additionalCharacters) {
|
|
48
|
-
this.content.insertAt(index,
|
|
49
|
+
this.content.insertAt(index, index_js_3.TreeArrayNode.spread(additionalCharacters));
|
|
49
50
|
}
|
|
50
51
|
formatRange(startIndex, length, format) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
const branch = index_js_2.TreeAlpha.branch(this);
|
|
53
|
+
const applyFormatting = () => {
|
|
54
|
+
for (let i = startIndex; i < startIndex + length; i++) {
|
|
55
|
+
const atom = this.content[i];
|
|
56
|
+
if (atom === undefined) {
|
|
57
|
+
throw new internal_2.UsageError("Index out of bounds while formatting text range.");
|
|
58
|
+
}
|
|
59
|
+
for (const [key, value] of Object.entries(format)) {
|
|
60
|
+
// Object.entries should only return string keyed enumerable own properties.
|
|
61
|
+
// The TypeScript typing does not account for this, and thus this assertion is necessary for this code to compile.
|
|
62
|
+
(0, internal_1.assert)(typeof key === "string", 0xcc8 /* Object.entries returned a non-string key. */);
|
|
63
|
+
const f = FormattedTextAsTree.CharacterFormat.fields.get(key);
|
|
64
|
+
if (f === undefined) {
|
|
65
|
+
throw new internal_2.UsageError(`Unknown format key: ${key}`);
|
|
66
|
+
}
|
|
67
|
+
// Ensures that if the input is a node, it is cloned before being inserted into the tree.
|
|
68
|
+
atom.format[key] = index_js_3.TreeBeta.clone(index_js_3.TreeBeta.create(f, value));
|
|
63
69
|
}
|
|
64
|
-
// Ensures that if the input is a node, it is cloned before being inserted into the tree.
|
|
65
|
-
atom.format[key] = index_js_2.TreeBeta.clone(index_js_2.TreeBeta.create(f, value));
|
|
66
70
|
}
|
|
71
|
+
};
|
|
72
|
+
if (branch === undefined) {
|
|
73
|
+
// If this node does not have a corresponding branch, then it is unhydrated.
|
|
74
|
+
// I.e., it is not part of a collaborative session yet.
|
|
75
|
+
// Therefore, we don't need to run the edits as a transaction.
|
|
76
|
+
applyFormatting();
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Wrap all formatting operations in a single transaction for atomicity.
|
|
80
|
+
branch.runTransaction(() => {
|
|
81
|
+
applyFormatting();
|
|
82
|
+
});
|
|
67
83
|
}
|
|
68
84
|
}
|
|
69
85
|
}
|
|
@@ -75,9 +91,9 @@ const defaultFormat = {
|
|
|
75
91
|
font: "Arial",
|
|
76
92
|
};
|
|
77
93
|
function textAtomsFromString(value, format) {
|
|
78
|
-
const result = (0,
|
|
94
|
+
const result = (0, index_js_4.mapIterable)((0, textDomain_js_1.charactersFromString)(value), (char) => new FormattedTextAsTree.StringAtom({
|
|
79
95
|
content: { content: char },
|
|
80
|
-
format:
|
|
96
|
+
format: index_js_3.TreeBeta.clone(format),
|
|
81
97
|
}));
|
|
82
98
|
return result;
|
|
83
99
|
}
|
|
@@ -99,11 +115,11 @@ var FormattedTextAsTree;
|
|
|
99
115
|
* @internal
|
|
100
116
|
*/
|
|
101
117
|
class CharacterFormat extends sf.objectAlpha("CharacterFormat", {
|
|
102
|
-
bold:
|
|
103
|
-
italic:
|
|
104
|
-
underline:
|
|
105
|
-
size:
|
|
106
|
-
font:
|
|
118
|
+
bold: index_js_3.SchemaFactory.boolean,
|
|
119
|
+
italic: index_js_3.SchemaFactory.boolean,
|
|
120
|
+
underline: index_js_3.SchemaFactory.boolean,
|
|
121
|
+
size: index_js_3.SchemaFactory.number,
|
|
122
|
+
font: index_js_3.SchemaFactory.string,
|
|
107
123
|
}) {
|
|
108
124
|
}
|
|
109
125
|
FormattedTextAsTree.CharacterFormat = CharacterFormat;
|
|
@@ -123,7 +139,7 @@ var FormattedTextAsTree;
|
|
|
123
139
|
* @privateRemarks
|
|
124
140
|
* This content logically represents the whole atom's content, so using {@link EmptyKey} makes sense to help indicate that.
|
|
125
141
|
*/
|
|
126
|
-
content:
|
|
142
|
+
content: index_js_3.SchemaFactory.required([index_js_3.SchemaFactory.string], { key: index_js_1.EmptyKey }),
|
|
127
143
|
}) {
|
|
128
144
|
}
|
|
129
145
|
FormattedTextAsTree.StringTextAtom = StringTextAtom;
|
|
@@ -131,7 +147,7 @@ var FormattedTextAsTree;
|
|
|
131
147
|
* Tag with which a line in text can be formatted from HTML.
|
|
132
148
|
* @internal
|
|
133
149
|
*/
|
|
134
|
-
FormattedTextAsTree.LineTag = (0,
|
|
150
|
+
FormattedTextAsTree.LineTag = (0, index_js_3.enumFromStrings)(sf.scopedFactory("lineTag"), [
|
|
135
151
|
"h1",
|
|
136
152
|
"h2",
|
|
137
153
|
"h3",
|
|
@@ -166,7 +182,7 @@ var FormattedTextAsTree;
|
|
|
166
182
|
* @internal
|
|
167
183
|
*/
|
|
168
184
|
class StringAtom extends sf.object("StringAtom", {
|
|
169
|
-
content:
|
|
185
|
+
content: index_js_3.SchemaFactory.required(FormattedTextAsTree.StringAtomContent, { key: index_js_1.EmptyKey }),
|
|
170
186
|
format: CharacterFormat,
|
|
171
187
|
}) {
|
|
172
188
|
}
|
|
@@ -178,6 +194,6 @@ var FormattedTextAsTree;
|
|
|
178
194
|
* See {@link FormattedTextAsTree.Statics} for static APIs on this Schema, including construction.
|
|
179
195
|
* @internal
|
|
180
196
|
*/
|
|
181
|
-
FormattedTextAsTree.Tree = (0,
|
|
197
|
+
FormattedTextAsTree.Tree = (0, index_js_3.eraseSchemaDetails)()(TextNode);
|
|
182
198
|
})(FormattedTextAsTree || (exports.FormattedTextAsTree = FormattedTextAsTree = {}));
|
|
183
199
|
//# sourceMappingURL=textDomainFormatted.js.map
|
|
@@ -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 } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { EmptyKey } from \"../core/index.js\";\nimport {\n\tenumFromStrings,\n\teraseSchemaDetails,\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 { mapIterable } 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\tpublic removeRange(index: number, length: number): void {\n\t\tthis.content.removeRange(index, length);\n\t}\n\tpublic characters(): Iterable<string> {\n\t\treturn mapIterable(this.content, (atom) => atom.content.content);\n\t}\n\tpublic fullString(): string {\n\t\treturn [...this.characters()].join(\"\");\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(): Iterable<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\tstartIndex: number,\n\t\tlength: number,\n\t\tformat: Partial<FormattedTextAsTree.CharacterFormat>,\n\t): void {\n\t\tfor (let i = startIndex; i < startIndex + length; i++) {\n\t\t\tconst atom = this.content[i];\n\t\t\tif (atom === undefined) {\n\t\t\t\tthrow new UsageError(\"Index out of bounds while formatting text range.\");\n\t\t\t}\n\t\t\tfor (const [key, value] of Object.entries(format) as [\n\t\t\t\tkeyof FormattedTextAsTree.CharacterFormat,\n\t\t\t\tunknown,\n\t\t\t][]) {\n\t\t\t\t// Object.entries should only return string keyed enumerable own properties.\n\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\tassert(typeof key === \"string\", \"Object.entries returned a non-string key.\");\n\t\t\t\tconst f = FormattedTextAsTree.CharacterFormat.fields.get(key);\n\t\t\t\tif (f === undefined) {\n\t\t\t\t\tthrow new UsageError(`Unknown format key: ${key}`);\n\t\t\t\t}\n\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\tatom.format[key] = TreeBeta.clone(TreeBeta.create(f, value as never)) as never;\n\t\t\t}\n\t\t}\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\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\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]);\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 * Note that not all new lines will use this,\n\t * but only ones using this can have line specific formatting.\n\t * @internal\n\t */\n\texport class StringLineAtom extends sf.object(\"StringLineAtom\", {\n\t\ttag: LineTag.schema,\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 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\tcharactersWithFormatting(): Iterable<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 of the range to format.\n\t\t * @param length - The number of characters to format.\n\t\t * @param format - The formatting to apply to the specified range.\n\t\t */\n\t\tformatRange(startIndex: number, length: number, format: Partial<CharacterFormat>): 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
|
+
{"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 } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { EmptyKey } from \"../core/index.js\";\nimport { TreeAlpha } from \"../shared-tree/index.js\";\nimport {\n\tenumFromStrings,\n\teraseSchemaDetails,\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 { mapIterable } 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\tpublic removeRange(index: number, length: number): void {\n\t\tthis.content.removeRange(index, length);\n\t}\n\tpublic characters(): Iterable<string> {\n\t\treturn mapIterable(this.content, (atom) => atom.content.content);\n\t}\n\tpublic fullString(): string {\n\t\treturn [...this.characters()].join(\"\");\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(): Iterable<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\tstartIndex: number,\n\t\tlength: number,\n\t\tformat: Partial<FormattedTextAsTree.CharacterFormat>,\n\t): void {\n\t\tconst branch = TreeAlpha.branch(this);\n\n\t\tconst applyFormatting = (): void => {\n\t\t\tfor (let i = startIndex; i < startIndex + length; 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}\n\nconst defaultFormat = {\n\tbold: false,\n\titalic: false,\n\tunderline: false,\n\tsize: 12,\n\tfont: \"Arial\",\n} as const;\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\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]);\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 * Note that not all new lines will use this,\n\t * but only ones using this can have line specific formatting.\n\t * @internal\n\t */\n\texport class StringLineAtom extends sf.object(\"StringLineAtom\", {\n\t\ttag: LineTag.schema,\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 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\tcharactersWithFormatting(): Iterable<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 of the range to format.\n\t\t * @param length - The number of characters to format.\n\t\t * @param format - The formatting to apply to the specified range.\n\t\t */\n\t\tformatRange(startIndex: number, length: number, format: Partial<CharacterFormat>): 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"]}
|
|
@@ -6,13 +6,39 @@ import { BTree, type DefaultComparable } from "@tylerbu/sorted-btree-es6";
|
|
|
6
6
|
import { type Brand } from "./brand.js";
|
|
7
7
|
/**
|
|
8
8
|
* A BTree which uses tuples (arrays) as the key.
|
|
9
|
-
* @remarks
|
|
10
|
-
* All keys must be the same length.
|
|
9
|
+
* @remarks All keys must be the same length.
|
|
11
10
|
*/
|
|
12
11
|
export type TupleBTree<K extends readonly DefaultComparable[], V> = Brand<BTree<K, V>, "TupleBTree">;
|
|
13
12
|
/**
|
|
14
13
|
* Create a new {@link TupleBTree}.
|
|
14
|
+
* @param comparator - Either a single {@link TupleComparator | comparator} for all pairs of elements in the tuple or a {@link TupleComparators | tuple of comparators} that compares each pair of corresponding elements individually.
|
|
15
|
+
* @param entries - Optional initial entries for the btree.
|
|
15
16
|
*/
|
|
16
|
-
export declare function newTupleBTree<const K extends readonly DefaultComparable[], V>(entries?: [K, V][]): TupleBTree<K, V>;
|
|
17
|
-
|
|
17
|
+
export declare function newTupleBTree<const K extends readonly DefaultComparable[], V>(comparator: (a: K, b: K) => number, entries?: [K, V][]): TupleBTree<K, V>;
|
|
18
|
+
/** A comparator which can compare any pair of corresponding elements in the key of a {@link TupleBTree} */
|
|
19
|
+
type TupleComparator<T extends DefaultComparable> = (a: T, b: T) => number;
|
|
20
|
+
/**
|
|
21
|
+
* A list of comparators for a {@link TupleBTree}.
|
|
22
|
+
* @remarks For each comparator _C_ at index _i_, C compares the pair of corresponding elements at index _i_ in the key of the btree.
|
|
23
|
+
*/
|
|
24
|
+
type TupleComparators<T extends readonly DefaultComparable[]> = {
|
|
25
|
+
[P in keyof T]: TupleComparator<T[P]>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Compares two tuples (arrays) element by element.
|
|
29
|
+
* @param a - The first tuple to compare.
|
|
30
|
+
* @param b - The second tuple to compare.
|
|
31
|
+
* @returns The comparison of the first pair of elements at the same index that differ, or 0 if all elements are equal.
|
|
32
|
+
* @remarks The tuples must be the same length and have the same type of elements in the same order.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createTupleComparator<const K extends readonly DefaultComparable[]>(compare?: TupleComparator<K[number]> | TupleComparators<K>): (a: K, b: K) => number;
|
|
35
|
+
/**
|
|
36
|
+
* Merge the entries of two {@link TupleBTree}s.
|
|
37
|
+
* @param tree1 - The first btree.
|
|
38
|
+
* @param tree2 - The second btree.
|
|
39
|
+
* This always returns a new btree and does not modify either input.
|
|
40
|
+
* @param preferLeft - If true, colliding keys will use the value from `tree1`, otherwise the value from `tree2` is used.
|
|
41
|
+
*/
|
|
42
|
+
export declare function mergeTupleBTrees<const K extends readonly DefaultComparable[], V>(tree1: TupleBTree<K, V>, tree2: TupleBTree<K, V> | undefined, preferLeft?: boolean): TupleBTree<K, V>;
|
|
43
|
+
export {};
|
|
18
44
|
//# sourceMappingURL=bTreeUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bTreeUtils.d.ts","sourceRoot":"","sources":["../../src/util/bTreeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,EAAqB,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"bTreeUtils.d.ts","sourceRoot":"","sources":["../../src/util/bTreeUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,EAAqB,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAI7F,OAAO,EAAS,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,EAAE,CAAC,IAAI,KAAK,CACxE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EACX,YAAY,CACZ,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,EAAE,CAAC,EAC5E,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,EAClC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAChB,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAElB;AAED,2GAA2G;AAC3G,KAAK,eAAe,CAAC,CAAC,SAAS,iBAAiB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;AAE3E;;;GAGG;AACH,KAAK,gBAAgB,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,IAAI;KAC9D,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACrC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,EACjF,OAAO,GAAE,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAqB,GAC3E,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAexB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,EAAE,CAAC,EAC/E,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,EACnC,UAAU,UAAO,GACf,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAalB"}
|
package/dist/util/bTreeUtils.js
CHANGED
|
@@ -4,45 +4,57 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.mergeTupleBTrees = exports.newTupleBTree = void 0;
|
|
7
|
+
exports.mergeTupleBTrees = exports.createTupleComparator = exports.newTupleBTree = void 0;
|
|
8
8
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
9
|
const sorted_btree_es6_1 = require("@tylerbu/sorted-btree-es6");
|
|
10
|
+
// eslint-disable-next-line import-x/no-internal-modules
|
|
11
|
+
const union_1 = require("@tylerbu/sorted-btree-es6/extended/union");
|
|
10
12
|
const brand_js_1 = require("./brand.js");
|
|
11
13
|
/**
|
|
12
14
|
* Create a new {@link TupleBTree}.
|
|
15
|
+
* @param comparator - Either a single {@link TupleComparator | comparator} for all pairs of elements in the tuple or a {@link TupleComparators | tuple of comparators} that compares each pair of corresponding elements individually.
|
|
16
|
+
* @param entries - Optional initial entries for the btree.
|
|
13
17
|
*/
|
|
14
|
-
function newTupleBTree(entries) {
|
|
15
|
-
return (0, brand_js_1.brand)(new sorted_btree_es6_1.BTree(entries,
|
|
18
|
+
function newTupleBTree(comparator, entries) {
|
|
19
|
+
return (0, brand_js_1.brand)(new sorted_btree_es6_1.BTree(entries, comparator));
|
|
16
20
|
}
|
|
17
21
|
exports.newTupleBTree = newTupleBTree;
|
|
18
22
|
/**
|
|
19
23
|
* Compares two tuples (arrays) element by element.
|
|
20
|
-
* @param
|
|
21
|
-
* @param
|
|
22
|
-
* @returns
|
|
24
|
+
* @param a - The first tuple to compare.
|
|
25
|
+
* @param b - The second tuple to compare.
|
|
26
|
+
* @returns The comparison of the first pair of elements at the same index that differ, or 0 if all elements are equal.
|
|
27
|
+
* @remarks The tuples must be the same length and have the same type of elements in the same order.
|
|
23
28
|
*/
|
|
24
|
-
function
|
|
25
|
-
(
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
function createTupleComparator(compare = sorted_btree_es6_1.defaultComparator) {
|
|
30
|
+
return (a, b) => {
|
|
31
|
+
(0, internal_1.debugAssert)(() => a.length === b.length || "compareTuples requires arrays of the same length");
|
|
32
|
+
const comparators = typeof compare === "function" ? undefined : compare;
|
|
33
|
+
for (let i = 0; i < a.length; i++) {
|
|
34
|
+
const comparator = comparators?.[i] ?? compare;
|
|
35
|
+
const result = comparator(a[i], b[i]);
|
|
36
|
+
if (result !== 0) {
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
30
39
|
}
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
return 0;
|
|
41
|
+
};
|
|
33
42
|
}
|
|
43
|
+
exports.createTupleComparator = createTupleComparator;
|
|
44
|
+
/**
|
|
45
|
+
* Merge the entries of two {@link TupleBTree}s.
|
|
46
|
+
* @param tree1 - The first btree.
|
|
47
|
+
* @param tree2 - The second btree.
|
|
48
|
+
* This always returns a new btree and does not modify either input.
|
|
49
|
+
* @param preferLeft - If true, colliding keys will use the value from `tree1`, otherwise the value from `tree2` is used.
|
|
50
|
+
*/
|
|
34
51
|
function mergeTupleBTrees(tree1, tree2, preferLeft = true) {
|
|
35
|
-
if (tree1 === undefined) {
|
|
36
|
-
return tree2 === undefined ? newTupleBTree() : (0, brand_js_1.brand)(tree2.clone());
|
|
37
|
-
}
|
|
38
|
-
const result = (0, brand_js_1.brand)(tree1.clone());
|
|
39
52
|
if (tree2 === undefined) {
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
for (const [key, value] of tree2.entries()) {
|
|
43
|
-
result.set(key, value, !preferLeft);
|
|
53
|
+
return (0, brand_js_1.brand)(tree1.clone());
|
|
44
54
|
}
|
|
45
|
-
|
|
55
|
+
// Use efficient union operation from sorted-btree 2.x
|
|
56
|
+
const result = (0, union_1.union)(tree1, tree2, (_key, val1, val2) => (preferLeft ? val1 : val2));
|
|
57
|
+
return (0, brand_js_1.brand)(result);
|
|
46
58
|
}
|
|
47
59
|
exports.mergeTupleBTrees = mergeTupleBTrees;
|
|
48
60
|
//# sourceMappingURL=bTreeUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bTreeUtils.js","sourceRoot":"","sources":["../../src/util/bTreeUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAkE;AAClE,gEAA6F;
|
|
1
|
+
{"version":3,"file":"bTreeUtils.js","sourceRoot":"","sources":["../../src/util/bTreeUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAkE;AAClE,gEAA6F;AAC7F,wDAAwD;AACxD,oEAAiE;AAEjE,yCAA+C;AAW/C;;;;GAIG;AACH,SAAgB,aAAa,CAC5B,UAAkC,EAClC,OAAkB;IAElB,OAAO,IAAA,gBAAK,EAAC,IAAI,wBAAK,CAAO,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;AACpD,CAAC;AALD,sCAKC;AAaD;;;;;;GAMG;AACH,SAAgB,qBAAqB,CACpC,UAA4D,oCAAiB;IAE7E,OAAO,CAAC,CAAI,EAAE,CAAI,EAAU,EAAE;QAC7B,IAAA,sBAAW,EACV,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,kDAAkD,CACjF,CAAC;QACF,MAAM,WAAW,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC,IAAK,OAAsC,CAAC;YAC/E,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClB,OAAO,MAAM,CAAC;YACf,CAAC;QACF,CAAC;QACD,OAAO,CAAC,CAAC;IACV,CAAC,CAAC;AACH,CAAC;AAjBD,sDAiBC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAC/B,KAAuB,EACvB,KAAmC,EACnC,UAAU,GAAG,IAAI;IAEjB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,IAAA,gBAAK,EAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,sDAAsD;IACtD,MAAM,MAAM,GAAG,IAAA,aAAK,EACnB,KAAoB,EACpB,KAAoB,EACpB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAChD,CAAC;IAEF,OAAO,IAAA,gBAAK,EAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAjBD,4CAiBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { debugAssert } from \"@fluidframework/core-utils/internal\";\nimport { BTree, defaultComparator, type DefaultComparable } from \"@tylerbu/sorted-btree-es6\";\n// eslint-disable-next-line import-x/no-internal-modules\nimport { union } from \"@tylerbu/sorted-btree-es6/extended/union\";\n\nimport { brand, type Brand } from \"./brand.js\";\n\n/**\n * A BTree which uses tuples (arrays) as the key.\n * @remarks All keys must be the same length.\n */\nexport type TupleBTree<K extends readonly DefaultComparable[], V> = Brand<\n\tBTree<K, V>,\n\t\"TupleBTree\"\n>;\n\n/**\n * Create a new {@link TupleBTree}.\n * @param comparator - Either a single {@link TupleComparator | comparator} for all pairs of elements in the tuple or a {@link TupleComparators | tuple of comparators} that compares each pair of corresponding elements individually.\n * @param entries - Optional initial entries for the btree.\n */\nexport function newTupleBTree<const K extends readonly DefaultComparable[], V>(\n\tcomparator: (a: K, b: K) => number,\n\tentries?: [K, V][],\n): TupleBTree<K, V> {\n\treturn brand(new BTree<K, V>(entries, comparator));\n}\n\n/** A comparator which can compare any pair of corresponding elements in the key of a {@link TupleBTree} */\ntype TupleComparator<T extends DefaultComparable> = (a: T, b: T) => number;\n\n/**\n * A list of comparators for a {@link TupleBTree}.\n * @remarks For each comparator _C_ at index _i_, C compares the pair of corresponding elements at index _i_ in the key of the btree.\n */\ntype TupleComparators<T extends readonly DefaultComparable[]> = {\n\t[P in keyof T]: TupleComparator<T[P]>;\n};\n\n/**\n * Compares two tuples (arrays) element by element.\n * @param a - The first tuple to compare.\n * @param b - The second tuple to compare.\n * @returns The comparison of the first pair of elements at the same index that differ, or 0 if all elements are equal.\n * @remarks The tuples must be the same length and have the same type of elements in the same order.\n */\nexport function createTupleComparator<const K extends readonly DefaultComparable[]>(\n\tcompare: TupleComparator<K[number]> | TupleComparators<K> = defaultComparator,\n): (a: K, b: K) => number {\n\treturn (a: K, b: K): number => {\n\t\tdebugAssert(\n\t\t\t() => a.length === b.length || \"compareTuples requires arrays of the same length\",\n\t\t);\n\t\tconst comparators = typeof compare === \"function\" ? undefined : compare;\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tconst comparator = comparators?.[i] ?? (compare as TupleComparator<K[number]>);\n\t\t\tconst result = comparator(a[i], b[i]);\n\t\t\tif (result !== 0) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t};\n}\n\n/**\n * Merge the entries of two {@link TupleBTree}s.\n * @param tree1 - The first btree.\n * @param tree2 - The second btree.\n * This always returns a new btree and does not modify either input.\n * @param preferLeft - If true, colliding keys will use the value from `tree1`, otherwise the value from `tree2` is used.\n */\nexport function mergeTupleBTrees<const K extends readonly DefaultComparable[], V>(\n\ttree1: TupleBTree<K, V>,\n\ttree2: TupleBTree<K, V> | undefined,\n\tpreferLeft = true,\n): TupleBTree<K, V> {\n\tif (tree2 === undefined) {\n\t\treturn brand(tree1.clone());\n\t}\n\n\t// Use efficient union operation from sorted-btree 2.x\n\tconst result = union<BTree<K, V>, K, V>(\n\t\ttree1 as BTree<K, V>,\n\t\ttree2 as BTree<K, V>,\n\t\t(_key, val1, val2) => (preferLeft ? val1 : val2),\n\t);\n\n\treturn brand(result);\n}\n"]}
|
package/dist/util/brand.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brand.d.ts","sourceRoot":"","sources":["../../src/util/brand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,KAAK,CAAC,SAAS,EAAE,IAAI,IAAI,SAAS,GAAG,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,8BAAsB,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI;IACpD,SAAS,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C;;;;;;;;OAQG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAE5C;;OAEG;IACH,OAAO;IAEP;;;;OAIG;WACW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,KAAK;CAKhE;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"brand.d.ts","sourceRoot":"","sources":["../../src/util/brand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,KAAK,CAAC,SAAS,EAAE,IAAI,IAAI,SAAS,GAAG,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,8BAAsB,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI;IACpD,SAAS,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C;;;;;;;;OAQG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAE5C;;OAEG;IACH,OAAO;IAEP;;;;OAIG;WACW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,IAAI,KAAK;CAKhE;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,IACnE,CAAC,SAAS,WAAW,CAAC,MAAM,SAAS,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,KAAK,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,IAClE,CAAC,SAAS,WAAW,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EACtB,KAAK,EAAE,CAAC,SAAS,WAAW,CAAC,MAAM,SAAS,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,KAAK,GACxE,CAAC,CAEH;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,CAAC,EACjC,KAAK,EAAE,CAAC,GACN,CAAC,EAAE,SAAS,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,EAC3C,GAAG,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,WAAW,CAAC,MAAM,SAAS,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,KAAK,CAAC,GACvF,EAAE,GACF,CAAC,KAAK,CAAC,KACN,EAAE,GAAG,CAAC,CAEV;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,EACpE,KAAK,EAAE,CAAC,GACN,gBAAgB,CAAC,CAAC,CAAC,CAErB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,EAC/C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,GACR;IAAE,QAAQ,EAAE,QAAQ,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAAE,CAIhE;AAED;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC"}
|
package/dist/util/brand.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brand.js","sourceRoot":"","sources":["../../src/util/brand.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,uEAAsE;AAwBtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAsB,WAAW;IAahC;;OAEG;IACH,gBAAuB,CAAC;IAExB;;;;OAIG;IACI,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAY;QAC9C,MAAM,IAAI,qBAAU,CACnB,0GAA0G,CAC1G,CAAC;IACH,CAAC;CACD;AA5BD,kCA4BC;
|
|
1
|
+
{"version":3,"file":"brand.js","sourceRoot":"","sources":["../../src/util/brand.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,uEAAsE;AAwBtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAsB,WAAW;IAahC;;OAEG;IACH,gBAAuB,CAAC;IAExB;;;;OAIG;IACI,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAY;QAC9C,MAAM,IAAI,qBAAU,CACnB,0GAA0G,CAC1G,CAAC;IACH,CAAC;CACD;AA5BD,kCA4BC;AAgBD;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,KAAK,CACpB,KAA0E;IAE1E,OAAO,KAAU,CAAC;AACnB,CAAC;AAJD,sBAIC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,UAAU,CACzB,KAAQ;IAMR,OAAO,GAAO,EAAE,CAAC,KAAe,CAAC;AAClC,CAAC;AARD,gCAQC;AAED;;;;;GAKG;AACH,SAAgB,OAAO,CACtB,KAAQ;IAER,OAAO,KAAc,CAAC;AACvB,CAAC;AAJD,0BAIC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,SAAgB,UAAU,CACzB,IAAY,EACZ,OAAU;IAEV,OAAO,OAEN,CAAC;AACH,CAAC;AAPD,gCAOC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { Covariant } from \"./typeCheck.js\";\n\n/**\n * Constructs a \"Branded\" type, adding a type-checking only field to `ValueType`.\n * @remarks\n * Two usages of `Brand` should never use the same `Name`.\n * If they do, the resulting types will be assignable which defeats the point of this type.\n *\n * This type is constructed such that the first line of type errors when assigning\n * mismatched branded types will be:\n * `Type 'Name1' is not assignable to type 'Name2'.`\n *\n * These branded types are not opaque: A `Brand<A, B>` can still be used as a `A`.\n *\n * @example Simple usage:\n * ```typescript\n * export type StrongId = Brand<string, \"tree.StrongId\">;\n * const x: StrongId = brand(\"myId\");\n * ```\n */\nexport type Brand<ValueType, Name> = ValueType & BrandedType<ValueType, Name>;\n\n/**\n * Implementation detail for {@link Brand}.\n *\n * See `MakeNominal` for some more details.\n *\n * Do not use this class with `instanceof`: this will always be false at runtime,\n * but the compiler may think it's true in some cases.\n *\n * @remarks\n * This is covariant over ValueType.\n * This is suitable for when ValueType is immutable (like string or number),\n * which is the common use-case for branding.\n *\n * @privateRemarks\n * This is split out into its own type as that's the only way to:\n *\n * - make the member protected (so you can't accidentally try and access it).\n * - get nominal typing (so types produced without using this class can never be assignable to it).\n *\n * @sealed\n */\nexport abstract class BrandedType<out ValueType, Name> {\n\tprotected _typeCheck?: Covariant<ValueType>;\n\t/**\n\t * Compile time only marker to make type checking more strict.\n\t * This method will not exist at runtime and accessing it is invalid.\n\t * See {@link Brand} for details.\n\t *\n\t * @privateRemarks\n\t * `Name` is used as the return type of a method rather than a a simple readonly member as this allows types with two brands to be intersected without getting `never`.\n\t * The method takes in never to help emphasize that its not callable.\n\t */\n\tprotected abstract brand(dummy: never): Name;\n\n\t/**\n\t * This class should never exist at runtime, so make it un-constructable.\n\t */\n\tprivate constructor() {}\n\n\t/**\n\t * Since this class is a compile time only type brand, `instanceof` will never work with it.\n\t * This `Symbol.hasInstance` implementation ensures that `instanceof` will error if used,\n\t * and in TypeScript 5.3 and newer will produce a compile time error if used.\n\t */\n\tpublic static [Symbol.hasInstance](value: never): value is never {\n\t\tthrow new UsageError(\n\t\t\t\"BrandedType is a compile time type brand not a real class that can be used with `instanceof` at runtime.\",\n\t\t);\n\t}\n}\n\n/**\n * Implementation detail of type branding. Should not be used directly outside this file,\n * but shows up as part of branded types so API-Extractor requires it to be exported.\n */\nexport type ValueFromBranded<T extends BrandedType<unknown, unknown>> =\n\tT extends BrandedType<infer ValueType, unknown> ? ValueType : never;\n\n/**\n * Implementation detail of type branding. Should not be used directly outside this file,\n * but shows up as part of branded types so API-Extractor requires it to be exported.\n */\nexport type NameFromBranded<T extends BrandedType<unknown, unknown>> =\n\tT extends BrandedType<unknown, infer Name> ? Name : never;\n\n/**\n * Adds a type {@link Brand} to a value.\n *\n * Only do this when specifically allowed by the requirements of the type being converted to.\n * @remarks\n * This infers the branded type from context so it can very easily be used to a semantically invalid conversion.\n * Treat this like \"as\" casts: they are an indicator that the user/reader must ensure the conversion is valid.\n *\n * If branding a constant, and wanting to preserve the exact typing of the constant, use {@link brandConst} instead.\n * @privateRemarks\n * Leaving `T` unconstrained here allows for better type inference when branding unions.\n * For example when assigning `brand(number)` a number to an optional branded number field,\n * constraining T to `BrandedType<unknown, string>` causes the inference to fail and requires explicitly providing the type parameter.\n * For example leaving T unconstrained instead allows the union of `BrandedType | undefined` to distribute over the conditional allowing the branding only the the union members which should be branded.\n * This does not permit branding an optional value into an optional field since non branded union members are still excluded from input to this function:\n * this is an intended restriction as it causes compile errors for misuse of this function (like using brand when the relevant type is not a branded type).\n */\nexport function brand<T>(\n\tvalue: T extends BrandedType<infer ValueType, unknown> ? ValueType : never,\n): T {\n\treturn value as T;\n}\n\n/**\n * Adds a type {@link Brand} to a value, while preserving the exact type of the value being branded.\n * @remarks\n * This takes in the type to brand to as a required type parameter, unlike {@link brand} which infers it from context.\n * This also preserves the exact type of the value being branded.\n * TypeScript has no way to take an explicit type parameter and infer another in a single generic context.\n * To work around this, two generic contexts are used, first a function to infer the parameter type,\n * and a second function (returned) to take the explicit type parameter.\n *\n * This is intended for use when branding constants.\n * @example\n * ```typescript\n * const requiredIdentifier = brandConst(\"Value\")<FieldKindIdentifier>();\n * ```\n * @privateRemarks\n * The dummy parameter is used to produce a compile error in the event where the value being branded is incompatible with the branded type.\n */\nexport function brandConst<const T>(\n\tvalue: T,\n): <T2 extends BrandedType<unknown, unknown>>(\n\t...dummy: T extends (T2 extends BrandedType<infer ValueType, unknown> ? ValueType : never)\n\t\t? []\n\t\t: [never]\n) => T2 & T {\n\treturn <T2>() => value as T2 & T;\n}\n\n/**\n * Removes a type brand from a branded value.\n * @remarks\n * This is useful when trying to do an exhaustive switch over a union of branded types,\n * which for some reason fails if the brand is not removed from the \"case\" entries.\n */\nexport function unbrand<const T extends BrandedType<unknown, unknown>>(\n\tvalue: T,\n): ValueFromBranded<T> {\n\treturn value as never;\n}\n\n/**\n * Make an enum like object using {@link Brand} to brand the values.\n * @remarks\n * This has stricter typing than TypeScript built in enums since it does not allow implicit assignment of `number` to enums with a numeric value.\n * It also blocks implicit conversions of individual constants to the enum type:\n * such cases must use {@link brand} or get the branded value from the enum instead.\n *\n * One limitation is that narrowing does not work in switch statements:\n * the values in each case can use {@link unbrand} to work around this.\n *\n * This object does not provide {@link https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings | reverse mappings}.\n *\n * @example\n * ```typescript\n * const TestA = strictEnum(\"TestA\", {\n * \ta: 1,\n * \tb: 2,\n * });\n * type TestA = Values<typeof TestA>;\n *\n * function switchUnbrand(x: TestA) {\n * \tswitch (x) {\n * \t\tcase unbrand(TestA.a):\n * \t\t\treturn \"a\";\n * \t\tcase unbrand(TestA.b):\n * \t\t\treturn \"b\";\n * \t\tdefault:\n * \t\t\tunreachableCase(x);\n * \t}\n * }\n * ```\n */\nexport function strictEnum<const T, const TBrand>(\n\tname: TBrand,\n\tentries: T,\n): { readonly [Property in keyof T]: Brand<T[Property], TBrand> } {\n\treturn entries as {\n\t\treadonly [Property in keyof T]: Brand<T[Property], TBrand>;\n\t};\n}\n\n/**\n * Extracts the values of an object type as a union.\n * @remarks\n * Like `keyof`\texcept for values.\n * This is useful for extracting the value types of enums created with {@link strictEnum}.\n */\nexport type Values<T> = T[keyof T];\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brandedMap.d.ts","sourceRoot":"","sources":["../../src/util/brandedMap.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,CAAC,IAAI,EAAE,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAG1F,MAAM,MAAM,iBAAiB,CAAC,IAAI,SAAS,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"brandedMap.d.ts","sourceRoot":"","sources":["../../src/util/brandedMap.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,CAAC,IAAI,EAAE,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAG1F,MAAM,MAAM,iBAAiB,CAAC,IAAI,SAAS,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,IAClE,IAAI,SAAS,UAAU,CAAC,OAAO,EAAE,MAAM,QAAQ,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErE;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC;IACnE,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,iBAAiB,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;IAC9D,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAC/D,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,CAAC,EAC1C,GAAG,EAAE,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAChD,GAAG,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,YAAY,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GACjD,CAAC,CAEH;AASD;;GAEG;AACH,wBAAgB,WAAW,CAG1B,KAAK,SAAS,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,KACjE,KAAK,CAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brandedMap.js","sourceRoot":"","sources":["../../src/util/brandedMap.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAKH,yCAAyC;
|
|
1
|
+
{"version":3,"file":"brandedMap.js","sourceRoot":"","sources":["../../src/util/brandedMap.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAKH,yCAAyC;AAsCzC;;;;GAIG;AACH,SAAgB,sBAAsB,CACrC,GAAgD,EAChD,GAAqB,EACrB,YAAmD;IAEnD,OAAO,IAAA,sBAAW,EAAsB,GAAG,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;AACjE,CAAC;AAND,wDAMC;AAED;;;;GAIG;AACH,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB;;GAEG;AACH,SAAgB,WAAW;IAK1B,OAAO,WAAW,EAAW,CAAC;AAC/B,CAAC;AAND,kCAMC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { Brand } from \"./brand.js\";\nimport type { Opaque } from \"./opaque.js\";\nimport type { Invariant } from \"./typeCheck.js\";\nimport { getOrCreate } from \"./utils.js\";\n\n/**\n * Key in a {@link BrandedMapSubset}.\n * @remarks\n * `TContent` is used as part of the brand to strongly associate the key type with the type of the values it looks up.\n *\n * Due to the `TContent` type parameter being invariant (which it has to be since keys are used to both read and write data),\n * generic collections end up needing to constrain their key's `TContent` to `any`.\n */\nexport type BrandedKey<TKey, TContent> = Brand<TKey, [\"BrandedKey\", Invariant<TContent>]>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type BrandedKeyContent<TKey extends BrandedKey<unknown, any>> =\n\tTKey extends BrandedKey<unknown, infer TContent> ? TContent : never;\n\n/**\n * A Map where the keys carry the types of values which they correspond to.\n *\n * Example usage:\n * ```typescript\n * type FooSlot<TContent> = BrandedKey<Opaque<Brand<number, \"FooSlot\">>, TContent>;\n * const counterSlot = brandedSlot<FooSlot<number>>();\n * const slots: BrandedMapSubset<FooSlot<any>> = new Map();\n * slots.set(counterSlot, slots.get(counterSlot) ?? 0 + 1);\n * ```\n *\n * @remarks\n * These APIs are designed so that a Map can be used to implement this type.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface BrandedMapSubset<K extends BrandedKey<unknown, any>> {\n\tget<K2 extends K>(key: K2): BrandedKeyContent<K2> | undefined;\n\thas(key: K): boolean;\n\tset<K2 extends K>(key: K2, value: BrandedKeyContent<K2>): this;\n\tdelete(key: K): boolean;\n}\n\n/**\n * Version of {@link getOrCreate} with better typing for {@link BrandedMapSubset}.\n * @privateRemarks\n * Only infers type from key to avoid inferring `any` from map's key.\n */\nexport function getOrCreateSlotContent<K, V>(\n\tmap: NoInfer<BrandedMapSubset<BrandedKey<K, V>>>,\n\tkey: BrandedKey<K, V>,\n\tdefaultValue: NoInfer<(key: BrandedKey<K, V>) => V>,\n): V {\n\treturn getOrCreate<BrandedKey<K, V>, V>(map, key, defaultValue);\n}\n\n/**\n * A counter used to allocate unique numbers (See {@link brandedSlot}) to use as {@link BrandedKey}s.\n * This allows the keys to be small integers, which are efficient to use as keys in maps.\n * See {@link BrandedMapSubset}.\n */\nlet slotCounter = 0;\n\n/**\n * Define a strongly typed slot in which data can be stored in a {@link BrandedMapSubset}.\n */\nexport function brandedSlot<\n\t// See note on BrandedKey.\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tTSlot extends BrandedKey<number | Opaque<Brand<number, string>>, any>,\n>(): TSlot {\n\treturn slotCounter++ as TSlot;\n}\n"]}
|
|
@@ -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,IAAI,IAAI;IAgBlB;;;;OAIG;IACI,KAAK,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK;IAUpC;;;;OAIG;IACH,OAAO,CAAC,aAAa;IASrB;;;;;;OAMG;IACI,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,GAAG,OAAO;IASpD;;;;;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,
|
|
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,IAAI,IAAI;IAgBlB;;;;OAIG;IACI,KAAK,CAAC,QAAQ,EAAE,KAAK,GAAG,KAAK;IAUpC;;;;OAIG;IACH,OAAO,CAAC,aAAa;IASrB;;;;;;OAMG;IACI,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,GAAG,OAAO;IASpD;;;;;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
|
@@ -180,7 +180,8 @@ function breakingClass(target, context) {
|
|
|
180
180
|
typeof descriptor.value === "function" &&
|
|
181
181
|
!isBreaker(descriptor.value)) {
|
|
182
182
|
// This does not affect the original class, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor
|
|
183
|
-
|
|
183
|
+
const method = descriptor.value;
|
|
184
|
+
descriptor.value = breakingMethod(method);
|
|
184
185
|
Object.defineProperty(DecoratedBreakable.prototype, key, descriptor);
|
|
185
186
|
}
|
|
186
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breakable.js","sourceRoot":"","sources":["../../src/util/breakable.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * An object which can enter a \"broken\" state where trying to use it is a UsageError.\n * @remarks\n * Use {@link WithBreakable} to apply this to another object.\n * @sealed\n */\nexport class Breakable {\n\tprivate brokenBy?: Error;\n\n\tpublic constructor(\n\t\t/**\n\t\t * A name for a given breakable scope.\n\t\t * @remarks\n\t\t * This is useful for documenting the semantics of a given Breakable and when inspecting things in the debugger, but is currently otherwise unused.\n\t\t */\n\t\tprivate readonly name: string,\n\t) {}\n\n\t/**\n\t * Throws if this object is in the broken state.\n\t * @remarks\n\t * Can use {@link throwIfBroken} to apply this to a method.\n\t */\n\tpublic use(): void {\n\t\tif (this.brokenBy !== undefined) {\n\t\t\tconst error = new UsageError(\n\t\t\t\t`Invalid use of ${this.name} after it was put into an invalid state by another error.\\nOriginal Error:\\n${this.brokenBy}`,\n\t\t\t);\n\n\t\t\t// This \"cause\" field is added in ES2022, but using if even without that built in support, it is still helpful.\n\t\t\t// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause\n\t\t\t// TODO: remove this cast when targeting ES2022 lib or later.\n\t\t\t(error as { cause?: unknown }).cause =\n\t\t\t\t(this.brokenBy as { cause?: unknown }).cause ?? this.brokenBy;\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Puts this object into the broken state, and throws an error.\n\t *\n\t * @throws If already broken by a different error, throws a UsageError, otherwise throws `brokenBy`.\n\t */\n\tpublic break(brokenBy: Error): never {\n\t\t// If already broken by this error, let it bubble up without rethrowing a modified version.\n\t\t// This prevents internal errors like asserts getting rethrown as different errors when wrapped with multiple call to `{@link Breakable.run}` or `{@link breakingMethod}`.\n\t\tif (this.brokenBy !== brokenBy) {\n\t\t\tthis.use();\n\t\t\tthis.brokenBy = brokenBy;\n\t\t}\n\t\tthrow brokenBy;\n\t}\n\n\t/**\n\t * {@link Breakable.break}, except tolerates `unknown` to be more easily used by catch blocks.\n\t * @privateRemarks\n\t * If there is a use-case, this should be made public.\n\t */\n\tprivate rethrowCaught(brokenBy: unknown): never {\n\t\tif (brokenBy instanceof Error) {\n\t\t\tthis.break(brokenBy);\n\t\t}\n\t\tthis.break(\n\t\t\tnew Error(`Non-error thrown breaking ${this.name}. Thrown value: \"${brokenBy}\"`),\n\t\t);\n\t}\n\n\t/**\n\t * Runs code which should break the object if it throws.\n\t * @remarks\n\t * Like {@link Breakable.use}, this also throws if already broken.\n\t * Any exceptions this catches are re-thrown.\n\t * Can use {@link breakingMethod} to apply this to a method.\n\t */\n\tpublic run<TResult>(breaker: () => TResult): TResult {\n\t\tthis.use();\n\t\ttry {\n\t\t\treturn breaker();\n\t\t} catch (error: unknown) {\n\t\t\tthis.rethrowCaught(error);\n\t\t}\n\t}\n\n\t/**\n\t * Clears the existing broken state.\n\t * @remarks\n\t * This is rarely safe to to: it is only ok when all objects using this breaker are known to not have been left in an invalid state.\n\t * This is pretty much only safe in tests which just were checking a specific error was thrown, and which know that error closepath is actually exception safe.\n\t */\n\tpublic clearError(): void {\n\t\tassert(this.brokenBy !== undefined, 0x9b6 /* No error to clear */);\n\t\tthis.brokenBy = undefined;\n\t}\n}\n\n/**\n * Marks an object as being able to be in a broken state (unknown/unspecified/broken state due to unhandled exception).\n * @remarks\n * See decorators {@link breakingMethod} and {@link throwIfBroken} for ease of use.\n */\nexport interface WithBreakable {\n\t/**\n\t * The breaker for this object.\n\t * @remarks\n\t * If this `breaker` is in the broken state, the `WithBreakable` should be considered in a broken state.\n\t */\n\treadonly breaker: Breakable;\n}\n\n/**\n * Decorator for methods which should break the object when they throw.\n * @remarks\n * This also throws if already broken like {@link throwIfBroken}.\n * See {@link Breakable.run} for details.\n *\n * This should be used on methods which modify data that could result in an unsupported/broken state if an exception is thrown while modifying.\n * It is ok for breakingMethods to call each-other.\n * @privateRemarks\n * Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.\n */\nexport function breakingMethod<\n\tTarget extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return),\n\tThis extends WithBreakable,\n\tArgs extends never[],\n\tReturn,\n>(target: Target, context?: ClassMethodDecoratorContext<This, Target>): Target {\n\tfunction replacementMethod(this: This, ...args: Args): Return {\n\t\tif (this.breaker === undefined) {\n\t\t\t// This case is necessary for when wrapping methods which are invoked inside the constructor of the base class before `breaker` is set.\n\t\t\t// Since the constructor throwing does not return an object, failing to put it into a broken state is not too bad.\n\t\t\t// However when more than just the constructed object should be broken, this can result in missing a break.\n\t\t\treturn target.call(this, ...args);\n\t\t}\n\t\treturn this.breaker.run(() => {\n\t\t\treturn target.call(this, ...args);\n\t\t});\n\t}\n\tmarkBreaker(replacementMethod);\n\tnameFunctionFrom(replacementMethod, target);\n\treturn replacementMethod as Target;\n}\n\n/**\n * Decorator for methods which should throw if the object is in a broken state.\n * @remarks\n * This should be used on methods which read data that could be invalid when the object is broken.\n * @privateRemarks\n * Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.\n */\nexport function throwIfBroken<\n\tTarget extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return),\n\tThis extends WithBreakable,\n\tArgs extends never[],\n\tReturn,\n>(target: Target, context: ClassMethodDecoratorContext<This, Target>): Target {\n\tfunction replacementMethod(this: This, ...args: Args): Return {\n\t\tthis.breaker.use();\n\t\treturn target.call(this, ...args);\n\t}\n\tmarkBreaker(replacementMethod);\n\tnameFunctionFrom(replacementMethod, target);\n\treturn replacementMethod as Target;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype PossiblyNamedFunction = Function & { displayName?: undefined | string };\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction nameFunctionFrom(toName: Function, nameFrom: Function): void {\n\t(toName as PossiblyNamedFunction).displayName =\n\t\t(nameFrom as PossiblyNamedFunction).displayName ?? nameFrom.name;\n}\n\nconst isBreakerSymbol: unique symbol = Symbol(\"isBreaker\");\n\n// Accepting any function like value is desired and safe here as this does not call the provided function.\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction markBreaker(f: Function): void {\n\t(f as unknown as Record<typeof isBreakerSymbol, true>)[isBreakerSymbol] = true;\n}\n\n// Accepting any function like value is desired and safe here as this does not call the provided function.\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction isBreaker(f: Function): boolean {\n\treturn isBreakerSymbol in (f as unknown as Record<typeof isBreakerSymbol, true>);\n}\n\n/**\n * Decorator for classes which should break when their methods throw.\n * @remarks\n * Applies {@link breakingMethod} to all methods declared directly by class or its base classes.\n * Does not include those on derived classes.\n * Does not include getters or setters, or value properties.\n * Methods already marked as {@link breakingMethod} or {@link throwIfBroken} are unaffected.\n */\nexport function breakingClass<Target extends abstract new (...args: any[]) => WithBreakable>(\n\ttarget: Target,\n\tcontext: ClassDecoratorContext<Target>,\n): Target {\n\t// This could extend target, but doing so adds an extra step in the prototype chain and makes the instances just show up as \"DecoratedBreakable\" in the debugger.\n\tconst DecoratedBreakable = target;\n\n\t// Keep track of what keys we have seen (and already wrapped if needed).\n\t// Used to avoid rewrapping already wrapped properties.\n\t// Preloaded with \"constructor\" to avoid wrapping the constructor as there is no need to set the broken flag when the constructor throws and does not return an object.\n\t// Avoiding wrapping the constructor also avoids messing up the displayed name in the debugger.\n\tconst doNotWrap: Set<string | symbol> = new Set([\"constructor\"]);\n\n\tlet prototype: object | null = target.prototype;\n\twhile (prototype !== null) {\n\t\tfor (const key of Reflect.ownKeys(prototype)) {\n\t\t\tif (!doNotWrap.has(key)) {\n\t\t\t\tdoNotWrap.add(key);\n\t\t\t\tconst descriptor = Reflect.getOwnPropertyDescriptor(prototype, key);\n\t\t\t\t// Method\n\t\t\t\tif (\n\t\t\t\t\tdescriptor !== undefined &&\n\t\t\t\t\ttypeof descriptor.value === \"function\" &&\n\t\t\t\t\t!isBreaker(descriptor.value)\n\t\t\t\t) {\n\t\t\t\t\t// This does not affect the original class, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor\n\t\t\t\t\tdescriptor.value = breakingMethod(descriptor.value);\n\t\t\t\t\tObject.defineProperty(DecoratedBreakable.prototype, key, descriptor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tprototype = Reflect.getPrototypeOf(prototype);\n\t}\n\n\treturn DecoratedBreakable;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"breakable.js","sourceRoot":"","sources":["../../src/util/breakable.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * An object which can enter a \"broken\" state where trying to use it is a UsageError.\n * @remarks\n * Use {@link WithBreakable} to apply this to another object.\n * @sealed\n */\nexport class Breakable {\n\tprivate brokenBy?: Error;\n\n\tpublic constructor(\n\t\t/**\n\t\t * A name for a given breakable scope.\n\t\t * @remarks\n\t\t * This is useful for documenting the semantics of a given Breakable and when inspecting things in the debugger, but is currently otherwise unused.\n\t\t */\n\t\tprivate readonly name: string,\n\t) {}\n\n\t/**\n\t * Throws if this object is in the broken state.\n\t * @remarks\n\t * Can use {@link throwIfBroken} to apply this to a method.\n\t */\n\tpublic use(): void {\n\t\tif (this.brokenBy !== undefined) {\n\t\t\tconst error = new UsageError(\n\t\t\t\t`Invalid use of ${this.name} after it was put into an invalid state by another error.\\nOriginal Error:\\n${this.brokenBy}`,\n\t\t\t);\n\n\t\t\t// This \"cause\" field is added in ES2022, but using if even without that built in support, it is still helpful.\n\t\t\t// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause\n\t\t\t// TODO: remove this cast when targeting ES2022 lib or later.\n\t\t\t(error as { cause?: unknown }).cause =\n\t\t\t\t(this.brokenBy as { cause?: unknown }).cause ?? this.brokenBy;\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Puts this object into the broken state, and throws an error.\n\t *\n\t * @throws If already broken by a different error, throws a UsageError, otherwise throws `brokenBy`.\n\t */\n\tpublic break(brokenBy: Error): never {\n\t\t// If already broken by this error, let it bubble up without rethrowing a modified version.\n\t\t// This prevents internal errors like asserts getting rethrown as different errors when wrapped with multiple call to `{@link Breakable.run}` or `{@link breakingMethod}`.\n\t\tif (this.brokenBy !== brokenBy) {\n\t\t\tthis.use();\n\t\t\tthis.brokenBy = brokenBy;\n\t\t}\n\t\tthrow brokenBy;\n\t}\n\n\t/**\n\t * {@link Breakable.break}, except tolerates `unknown` to be more easily used by catch blocks.\n\t * @privateRemarks\n\t * If there is a use-case, this should be made public.\n\t */\n\tprivate rethrowCaught(brokenBy: unknown): never {\n\t\tif (brokenBy instanceof Error) {\n\t\t\tthis.break(brokenBy);\n\t\t}\n\t\tthis.break(\n\t\t\tnew Error(`Non-error thrown breaking ${this.name}. Thrown value: \"${brokenBy}\"`),\n\t\t);\n\t}\n\n\t/**\n\t * Runs code which should break the object if it throws.\n\t * @remarks\n\t * Like {@link Breakable.use}, this also throws if already broken.\n\t * Any exceptions this catches are re-thrown.\n\t * Can use {@link breakingMethod} to apply this to a method.\n\t */\n\tpublic run<TResult>(breaker: () => TResult): TResult {\n\t\tthis.use();\n\t\ttry {\n\t\t\treturn breaker();\n\t\t} catch (error: unknown) {\n\t\t\tthis.rethrowCaught(error);\n\t\t}\n\t}\n\n\t/**\n\t * Clears the existing broken state.\n\t * @remarks\n\t * This is rarely safe to to: it is only ok when all objects using this breaker are known to not have been left in an invalid state.\n\t * This is pretty much only safe in tests which just were checking a specific error was thrown, and which know that error closepath is actually exception safe.\n\t */\n\tpublic clearError(): void {\n\t\tassert(this.brokenBy !== undefined, 0x9b6 /* No error to clear */);\n\t\tthis.brokenBy = undefined;\n\t}\n}\n\n/**\n * Marks an object as being able to be in a broken state (unknown/unspecified/broken state due to unhandled exception).\n * @remarks\n * See decorators {@link breakingMethod} and {@link throwIfBroken} for ease of use.\n */\nexport interface WithBreakable {\n\t/**\n\t * The breaker for this object.\n\t * @remarks\n\t * If this `breaker` is in the broken state, the `WithBreakable` should be considered in a broken state.\n\t */\n\treadonly breaker: Breakable;\n}\n\n/**\n * Decorator for methods which should break the object when they throw.\n * @remarks\n * This also throws if already broken like {@link throwIfBroken}.\n * See {@link Breakable.run} for details.\n *\n * This should be used on methods which modify data that could result in an unsupported/broken state if an exception is thrown while modifying.\n * It is ok for breakingMethods to call each-other.\n * @privateRemarks\n * Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.\n */\nexport function breakingMethod<\n\tTarget extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return),\n\tThis extends WithBreakable,\n\tArgs extends never[],\n\tReturn,\n>(target: Target, context?: ClassMethodDecoratorContext<This, Target>): Target {\n\tfunction replacementMethod(this: This, ...args: Args): Return {\n\t\tif (this.breaker === undefined) {\n\t\t\t// This case is necessary for when wrapping methods which are invoked inside the constructor of the base class before `breaker` is set.\n\t\t\t// Since the constructor throwing does not return an object, failing to put it into a broken state is not too bad.\n\t\t\t// However when more than just the constructed object should be broken, this can result in missing a break.\n\t\t\treturn target.call(this, ...args);\n\t\t}\n\t\treturn this.breaker.run(() => {\n\t\t\treturn target.call(this, ...args);\n\t\t});\n\t}\n\tmarkBreaker(replacementMethod);\n\tnameFunctionFrom(replacementMethod, target);\n\treturn replacementMethod as Target;\n}\n\n/**\n * Decorator for methods which should throw if the object is in a broken state.\n * @remarks\n * This should be used on methods which read data that could be invalid when the object is broken.\n * @privateRemarks\n * Explicitly capturing the full `Target` type is necessary to make this work with generic methods with unknown numbers of type parameters.\n */\nexport function throwIfBroken<\n\tTarget extends ((...args: any[]) => unknown) & ((this: This, ...args: Args) => Return),\n\tThis extends WithBreakable,\n\tArgs extends never[],\n\tReturn,\n>(target: Target, context: ClassMethodDecoratorContext<This, Target>): Target {\n\tfunction replacementMethod(this: This, ...args: Args): Return {\n\t\tthis.breaker.use();\n\t\treturn target.call(this, ...args);\n\t}\n\tmarkBreaker(replacementMethod);\n\tnameFunctionFrom(replacementMethod, target);\n\treturn replacementMethod as Target;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype PossiblyNamedFunction = Function & { displayName?: undefined | string };\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction nameFunctionFrom(toName: Function, nameFrom: Function): void {\n\t(toName as PossiblyNamedFunction).displayName =\n\t\t(nameFrom as PossiblyNamedFunction).displayName ?? nameFrom.name;\n}\n\nconst isBreakerSymbol: unique symbol = Symbol(\"isBreaker\");\n\n// Accepting any function like value is desired and safe here as this does not call the provided function.\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction markBreaker(f: Function): void {\n\t(f as unknown as Record<typeof isBreakerSymbol, true>)[isBreakerSymbol] = true;\n}\n\n// Accepting any function like value is desired and safe here as this does not call the provided function.\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nfunction isBreaker(f: Function): boolean {\n\treturn isBreakerSymbol in (f as unknown as Record<typeof isBreakerSymbol, true>);\n}\n\n/**\n * Decorator for classes which should break when their methods throw.\n * @remarks\n * Applies {@link breakingMethod} to all methods declared directly by class or its base classes.\n * Does not include those on derived classes.\n * Does not include getters or setters, or value properties.\n * Methods already marked as {@link breakingMethod} or {@link throwIfBroken} are unaffected.\n */\nexport function breakingClass<Target extends abstract new (...args: any[]) => WithBreakable>(\n\ttarget: Target,\n\tcontext: ClassDecoratorContext<Target>,\n): Target {\n\t// This could extend target, but doing so adds an extra step in the prototype chain and makes the instances just show up as \"DecoratedBreakable\" in the debugger.\n\tconst DecoratedBreakable = target;\n\n\t// Keep track of what keys we have seen (and already wrapped if needed).\n\t// Used to avoid rewrapping already wrapped properties.\n\t// Preloaded with \"constructor\" to avoid wrapping the constructor as there is no need to set the broken flag when the constructor throws and does not return an object.\n\t// Avoiding wrapping the constructor also avoids messing up the displayed name in the debugger.\n\tconst doNotWrap: Set<string | symbol> = new Set([\"constructor\"]);\n\n\tlet prototype: object | null = target.prototype as object;\n\twhile (prototype !== null) {\n\t\tfor (const key of Reflect.ownKeys(prototype)) {\n\t\t\tif (!doNotWrap.has(key)) {\n\t\t\t\tdoNotWrap.add(key);\n\t\t\t\tconst descriptor = Reflect.getOwnPropertyDescriptor(prototype, key);\n\t\t\t\t// Method\n\t\t\t\tif (\n\t\t\t\t\tdescriptor !== undefined &&\n\t\t\t\t\ttypeof descriptor.value === \"function\" &&\n\t\t\t\t\t!isBreaker(descriptor.value)\n\t\t\t\t) {\n\t\t\t\t\t// This does not affect the original class, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor\n\t\t\t\t\tconst method = descriptor.value as (...args: unknown[]) => unknown;\n\t\t\t\t\tdescriptor.value = breakingMethod(method);\n\t\t\t\t\tObject.defineProperty(DecoratedBreakable.prototype, key, descriptor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tprototype = Reflect.getPrototypeOf(prototype);\n\t}\n\n\treturn DecoratedBreakable;\n}\n"]}
|