@fluidframework/tree 2.82.0 → 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 +43 -0
- package/README.md +33 -5
- package/api-report/tree.alpha.api.md +25 -21
- package/api-report/tree.beta.api.md +14 -2
- package/api-report/tree.legacy.beta.api.md +14 -2
- package/api-report/tree.legacy.public.api.md +1 -1
- package/api-report/tree.public.api.md +1 -1
- package/dist/alpha.d.ts +3 -3
- package/dist/beta.d.ts +1 -0
- package/dist/codec/codec.d.ts +3 -39
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +5 -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 +1 -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/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/extensibleUnionNode.d.ts +97 -0
- package/dist/extensibleUnionNode.d.ts.map +1 -0
- package/dist/{extensibleSchemaUnion.js → extensibleUnionNode.js} +28 -18
- package/dist/extensibleUnionNode.js.map +1 -0
- 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/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/formatCommon.d.ts +3 -3
- package/dist/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatV1.d.ts +2 -3
- 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 -3
- 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/modular-schema/modularChangeCodecV1.d.ts +2 -2
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js +4 -4
- package/dist/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- 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/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -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/sharedTreeChangeCodecs.js +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/tree.d.ts +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.map +1 -1
- package/dist/shared-tree/treeCheckout.js +2 -4
- 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/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/simple-tree/api/index.d.ts +1 -1
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +2 -2
- package/dist/simple-tree/api/index.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/tree.d.ts +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/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 +1 -1
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +2 -2
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +4 -13
- package/dist/simple-tree/node-kinds/array/arrayNode.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/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.map +1 -1
- package/dist/util/bTreeUtils.js +6 -6
- package/dist/util/bTreeUtils.js.map +1 -1
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +5 -6
- package/dist/util/rangeMap.js.map +1 -1
- package/lib/alpha.d.ts +3 -3
- package/lib/beta.d.ts +1 -0
- package/lib/codec/codec.d.ts +3 -39
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +4 -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/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/extensibleUnionNode.d.ts +97 -0
- package/lib/extensibleUnionNode.d.ts.map +1 -0
- package/lib/{extensibleSchemaUnion.js → extensibleUnionNode.js} +28 -18
- package/lib/extensibleUnionNode.js.map +1 -0
- 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/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/formatCommon.d.ts +3 -3
- package/lib/feature-libraries/forest-summary/formatCommon.d.ts.map +1 -1
- package/lib/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/lib/feature-libraries/forest-summary/formatV1.d.ts +2 -3
- 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 -3
- 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/modular-schema/modularChangeCodecV1.d.ts +2 -2
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js +4 -4
- package/lib/feature-libraries/modular-schema/modularChangeCodecV1.js.map +1 -1
- 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/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -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/sharedTreeChangeCodecs.js +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/tree.d.ts +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.map +1 -1
- package/lib/shared-tree/treeCheckout.js +2 -4
- 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/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/simple-tree/api/index.d.ts +1 -1
- package/lib/simple-tree/api/index.d.ts.map +1 -1
- package/lib/simple-tree/api/index.js +1 -1
- package/lib/simple-tree/api/index.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/tree.d.ts +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/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 +1 -1
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js +1 -1
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +5 -14
- package/lib/simple-tree/node-kinds/array/arrayNode.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/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.map +1 -1
- package/lib/util/bTreeUtils.js +6 -6
- package/lib/util/bTreeUtils.js.map +1 -1
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +5 -6
- package/lib/util/rangeMap.js.map +1 -1
- package/package.json +23 -23
- package/src/codec/codec.ts +10 -112
- package/src/codec/index.ts +0 -3
- package/src/codec/versioned/codec.ts +119 -83
- package/src/core/tree/detachedFieldIndexCodecs.ts +6 -4
- package/src/{extensibleSchemaUnion.ts → extensibleUnionNode.ts} +61 -19
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +5 -11
- package/src/feature-libraries/forest-summary/codec.ts +8 -7
- package/src/feature-libraries/forest-summary/formatCommon.ts +5 -3
- package/src/feature-libraries/forest-summary/formatV1.ts +1 -3
- package/src/feature-libraries/forest-summary/formatV2.ts +1 -3
- package/src/feature-libraries/modular-schema/modularChangeCodecV1.ts +5 -6
- package/src/feature-libraries/schema-index/codec.ts +6 -4
- package/src/index.ts +3 -3
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/sharedTreeChangeCodecs.ts +2 -2
- package/src/shared-tree/tree.ts +1 -1
- package/src/shared-tree/treeAlpha.ts +1 -1
- package/src/shared-tree/treeCheckout.ts +2 -4
- 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/messageCodecs.ts +2 -6
- package/src/simple-tree/api/index.ts +2 -2
- package/src/simple-tree/api/snapshotCompatibilityChecker.ts +344 -142
- package/src/simple-tree/api/tree.ts +1 -1
- package/src/simple-tree/api/treeBeta.ts +1 -1
- package/src/simple-tree/core/allowedTypes.ts +1 -1
- package/src/simple-tree/core/unhydratedFlexTree.ts +43 -1
- package/src/simple-tree/index.ts +2 -2
- package/src/simple-tree/node-kinds/array/arrayNode.ts +13 -19
- package/src/simple-tree/unhydratedFlexTreeFromInsertable.ts +51 -10
- package/src/text/textDomainFormatted.ts +37 -17
- package/src/util/bTreeUtils.ts +10 -6
- package/src/util/rangeMap.ts +9 -6
- package/api-extractor-lint.json +0 -4
- package/dist/extensibleSchemaUnion.d.ts +0 -72
- package/dist/extensibleSchemaUnion.d.ts.map +0 -1
- package/dist/extensibleSchemaUnion.js.map +0 -1
- package/lib/extensibleSchemaUnion.d.ts +0 -72
- package/lib/extensibleSchemaUnion.d.ts.map +0 -1
- package/lib/extensibleSchemaUnion.js.map +0 -1
|
@@ -425,7 +425,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
|
|
|
425
425
|
* @remarks
|
|
426
426
|
* {@link TreeViewEvents.schemaChanged} is fired when the compatibility status changes.
|
|
427
427
|
* See {@link https://fluidframework.com/docs/data-structures/tree/schema-evolution/ | schema-evolution} for more guidance on how to change schema while maintaining compatibility.
|
|
428
|
-
* Use {@link
|
|
428
|
+
* Use {@link snapshotSchemaCompatibility} to write tests to validate that this compatibility behaves as desired across schema changes.
|
|
429
429
|
*/
|
|
430
430
|
readonly compatibility: SchemaCompatibilityStatus;
|
|
431
431
|
|
|
@@ -120,7 +120,7 @@ export interface TreeChangeEventsBeta<TNode extends TreeNode = TreeNode>
|
|
|
120
120
|
* Extensions to {@link (Tree:interface)} which are not yet stable.
|
|
121
121
|
* @remarks
|
|
122
122
|
* Use via the {@link (TreeBeta:variable)} singleton.
|
|
123
|
-
* @
|
|
123
|
+
* @sealed @beta
|
|
124
124
|
*/
|
|
125
125
|
export interface TreeBeta {
|
|
126
126
|
/**
|
|
@@ -650,7 +650,7 @@ export type TreeNodeFromImplicitAllowedTypes<
|
|
|
650
650
|
* This type exists only to be linked from documentation to provide a single linkable place to document some details of
|
|
651
651
|
* "Input" types and how they handle schema.
|
|
652
652
|
*
|
|
653
|
-
* When a schema is used to describe data which is an input into an API, the API is {@link https://en.wikipedia.org/wiki/Type_variance | contravariant}
|
|
653
|
+
* When a schema is used to describe data which is an input into an API, the API is {@link https://en.wikipedia.org/wiki/Type_variance | contravariant} over the schema.
|
|
654
654
|
* (See also {@link https://www.typescriptlang.org/docs/handbook/2/generics.html#variance-annotations | TypeScript Variance Annotations}).
|
|
655
655
|
*
|
|
656
656
|
* Since these schema are expressed using TypeScript types, it is possible for the user of the API to provide non-exact values of these types which has implications that depended on the variance.
|
|
@@ -59,7 +59,22 @@ import type { Context } from "./context.js";
|
|
|
59
59
|
import type { TreeNode } from "./treeNode.js";
|
|
60
60
|
|
|
61
61
|
interface UnhydratedTreeSequenceFieldEditBuilder
|
|
62
|
-
extends SequenceFieldEditBuilder<FlexibleFieldContent, UnhydratedFlexTreeNode[]> {
|
|
62
|
+
extends SequenceFieldEditBuilder<FlexibleFieldContent, UnhydratedFlexTreeNode[]> {
|
|
63
|
+
/**
|
|
64
|
+
* Moves elements from a source position to a destination position.
|
|
65
|
+
* Can move within the same field or from another unhydrated sequence field.
|
|
66
|
+
* @param sourceIndex - The index of the first element to move.
|
|
67
|
+
* @param count - The number of elements to move.
|
|
68
|
+
* @param destIndex - The index at which to insert the moved elements.
|
|
69
|
+
* @param source - The source field to move from (defaults to this field for within-field moves).
|
|
70
|
+
*/
|
|
71
|
+
move(
|
|
72
|
+
sourceIndex: number,
|
|
73
|
+
count: number,
|
|
74
|
+
destIndex: number,
|
|
75
|
+
source?: UnhydratedSequenceField,
|
|
76
|
+
): void;
|
|
77
|
+
}
|
|
63
78
|
|
|
64
79
|
type UnhydratedFlexTreeNodeEvents = Pick<
|
|
65
80
|
AnchorEvents,
|
|
@@ -543,6 +558,33 @@ export class UnhydratedSequenceField
|
|
|
543
558
|
});
|
|
544
559
|
return removed ?? fail(0xb4a /* Expected removed to be set by edit */);
|
|
545
560
|
},
|
|
561
|
+
move: (sourceIndex, count, destIndex, source?): void => {
|
|
562
|
+
const sourceField = source ?? this;
|
|
563
|
+
if (sourceField === this) {
|
|
564
|
+
// Within-field move: do both operations in a single edit to emit only one event
|
|
565
|
+
this.edit((mapTrees) => {
|
|
566
|
+
const removed = mapTrees.splice(sourceIndex, count);
|
|
567
|
+
// Adjust destination index if it comes after the source
|
|
568
|
+
const adjustedDest = destIndex > sourceIndex ? destIndex - count : destIndex;
|
|
569
|
+
if (removed.length < 1000) {
|
|
570
|
+
// For "smallish arrays" (`1000` is not empirically derived), the `splice` function is appropriate...
|
|
571
|
+
mapTrees.splice(adjustedDest, 0, ...removed);
|
|
572
|
+
} else {
|
|
573
|
+
// ...but we avoid using `splice` + spread for very large arrays since there is a limit on how many elements can be spread (too many will overflow the stack).
|
|
574
|
+
return [
|
|
575
|
+
...mapTrees.slice(0, adjustedDest),
|
|
576
|
+
...removed,
|
|
577
|
+
...mapTrees.slice(adjustedDest),
|
|
578
|
+
];
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
} else {
|
|
582
|
+
// Cross-field move: remove from source, insert into destination
|
|
583
|
+
// Each field emits one event (correct behavior for different fields)
|
|
584
|
+
const removed = sourceField.editor.remove(sourceIndex, count);
|
|
585
|
+
this.editor.insert(destIndex, removed);
|
|
586
|
+
}
|
|
587
|
+
},
|
|
546
588
|
} satisfies UnhydratedTreeSequenceFieldEditBuilder;
|
|
547
589
|
|
|
548
590
|
public at(index: number): FlexTreeUnknownUnboxed | undefined {
|
package/src/simple-tree/index.ts
CHANGED
|
@@ -197,9 +197,9 @@ export {
|
|
|
197
197
|
checkCompatibility,
|
|
198
198
|
eraseSchemaDetails,
|
|
199
199
|
eraseSchemaDetailsSubclassable,
|
|
200
|
-
|
|
200
|
+
snapshotSchemaCompatibility,
|
|
201
201
|
type SnapshotFileSystem,
|
|
202
|
-
type
|
|
202
|
+
type SnapshotSchemaCompatibilityOptions,
|
|
203
203
|
createCustomizedFluidFrameworkScopedFactory,
|
|
204
204
|
} from "./api/index.js";
|
|
205
205
|
export type {
|
|
@@ -52,7 +52,6 @@ import {
|
|
|
52
52
|
createTreeNodeSchemaPrivateData,
|
|
53
53
|
type FlexContent,
|
|
54
54
|
type TreeNodeSchemaPrivateData,
|
|
55
|
-
withBufferedTreeEvents,
|
|
56
55
|
AnnotatedAllowedTypesInternal,
|
|
57
56
|
} from "../../core/index.js";
|
|
58
57
|
import {
|
|
@@ -1121,24 +1120,19 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
|
|
|
1121
1120
|
);
|
|
1122
1121
|
}
|
|
1123
1122
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
destinationGap - movedCount,
|
|
1138
|
-
sourceField.editor.remove(sourceStart, movedCount),
|
|
1139
|
-
);
|
|
1140
|
-
}
|
|
1141
|
-
});
|
|
1123
|
+
assert(
|
|
1124
|
+
destinationField instanceof UnhydratedSequenceField,
|
|
1125
|
+
0xcd5 /* destinationField should be unhydrated since we're in the else branch of isHydrated() check */,
|
|
1126
|
+
);
|
|
1127
|
+
|
|
1128
|
+
// Use native move which handles the operation atomically for within-field moves
|
|
1129
|
+
// to ensure only a single event is emitted per affected field.
|
|
1130
|
+
destinationField.editor.move(
|
|
1131
|
+
sourceStart,
|
|
1132
|
+
movedCount,
|
|
1133
|
+
destinationGap,
|
|
1134
|
+
sourceField === destinationField ? undefined : sourceField,
|
|
1135
|
+
);
|
|
1142
1136
|
}
|
|
1143
1137
|
}
|
|
1144
1138
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { IFluidHandle } from "@fluidframework/core-interfaces";
|
|
7
|
-
import { assert, fail } from "@fluidframework/core-utils/internal";
|
|
7
|
+
import { assert, debugAssert, fail } from "@fluidframework/core-utils/internal";
|
|
8
8
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
9
9
|
|
|
10
10
|
import { filterIterable, hasSingle, oneFromIterable } from "../util/index.js";
|
|
@@ -58,7 +58,9 @@ export function unhydratedFlexTreeFromInsertable<TIn extends InsertableContent |
|
|
|
58
58
|
if (data === undefined) {
|
|
59
59
|
// TODO: this code-path should support defaults
|
|
60
60
|
if (normalizedFieldSchema.kind !== FieldKind.Optional) {
|
|
61
|
-
throw new UsageError(
|
|
61
|
+
throw new UsageError(
|
|
62
|
+
`Got undefined for non-optional field expecting one of ${quotedAllowedTypesWithNames(normalizedFieldSchema.allowedTypeSet)}`,
|
|
63
|
+
);
|
|
62
64
|
}
|
|
63
65
|
return undefined as TIn extends undefined ? undefined : UnhydratedFlexTreeNode;
|
|
64
66
|
}
|
|
@@ -71,6 +73,47 @@ export function unhydratedFlexTreeFromInsertable<TIn extends InsertableContent |
|
|
|
71
73
|
return flexTree as TIn extends undefined ? undefined : UnhydratedFlexTreeNode;
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Throw a usage error with a helpful message about `schema` not being in `allowedTypes` for insertable content.
|
|
78
|
+
*/
|
|
79
|
+
function allowedTypesInsertableSchemaError(
|
|
80
|
+
allowedTypes: ReadonlySet<TreeNodeSchema>,
|
|
81
|
+
schema: TreeNodeSchema,
|
|
82
|
+
): never {
|
|
83
|
+
debugAssert(
|
|
84
|
+
() =>
|
|
85
|
+
!allowedTypes.has(schema) ||
|
|
86
|
+
"This function should only be called if the schema is not in the allowed types.",
|
|
87
|
+
);
|
|
88
|
+
const map = new Map([...allowedTypes].map((s) => [s.identifier, s]));
|
|
89
|
+
const expected = map.get(schema.identifier);
|
|
90
|
+
if (expected !== undefined) {
|
|
91
|
+
throw new UsageError(
|
|
92
|
+
`A node with schema ${quotedSchemaIdentifierWithName(schema)} was provided where a node with that identifier is allowed, but the actual schema required (${quotedSchemaIdentifierWithName(expected)}) is not the same schema object.
|
|
93
|
+
TreeNodeSchema have significant object identity and thus the exact same object must be used as the schema when defining what nodes are allowed and when constructing the node to use.`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
throw new UsageError(
|
|
97
|
+
`Expected insertable for one of ${quotedAllowedTypesWithNames(allowedTypes)}. Got node with schema ${quotedSchemaIdentifierWithName(schema)}.
|
|
98
|
+
Nodes are valid insertable objects, but only if their schema are in the allowed list.`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Gets a description of a schema for use in error messages.
|
|
104
|
+
*/
|
|
105
|
+
function quotedSchemaIdentifierWithName(schema: TreeNodeSchema): string {
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
107
|
+
return `${JSON.stringify(schema.identifier)} (name: ${JSON.stringify((schema as Function).name)})`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Gets a description of an allowedTypes for use in error messages.
|
|
112
|
+
*/
|
|
113
|
+
function quotedAllowedTypesWithNames(allowedTypes: Iterable<TreeNodeSchema>): string {
|
|
114
|
+
return `[${[...allowedTypes].map(quotedSchemaIdentifierWithName).join(", ")}]`;
|
|
115
|
+
}
|
|
116
|
+
|
|
74
117
|
/**
|
|
75
118
|
* Copy content from `data` into a UnhydratedFlexTreeNode.
|
|
76
119
|
*/
|
|
@@ -83,10 +126,12 @@ export function unhydratedFlexTreeFromInsertableNode(
|
|
|
83
126
|
const inner = kernel.getInnerNodeIfUnhydrated();
|
|
84
127
|
if (inner === undefined) {
|
|
85
128
|
// The node is already hydrated, meaning that it already got inserted into the tree previously
|
|
86
|
-
throw new UsageError(
|
|
129
|
+
throw new UsageError(
|
|
130
|
+
`A node with schema ${quotedSchemaIdentifierWithName(kernel.schema)} was inserted into the tree more than once. This is not supported.`,
|
|
131
|
+
);
|
|
87
132
|
} else {
|
|
88
133
|
if (!allowedTypes.has(kernel.schema)) {
|
|
89
|
-
|
|
134
|
+
allowedTypesInsertableSchemaError(allowedTypes, kernel.schema);
|
|
90
135
|
}
|
|
91
136
|
return inner;
|
|
92
137
|
}
|
|
@@ -112,17 +157,13 @@ function getType(
|
|
|
112
157
|
const possibleTypes = getPossibleTypes(allowedTypes, data);
|
|
113
158
|
if (possibleTypes.length === 0) {
|
|
114
159
|
throw new UsageError(
|
|
115
|
-
`The provided data is incompatible with all of the types allowed by the schema. The set of allowed types is: ${
|
|
116
|
-
[...allowedTypes].map((schema) => schema.identifier),
|
|
117
|
-
)}.`,
|
|
160
|
+
`The provided data is incompatible with all of the types allowed by the schema. The set of allowed types is: ${quotedAllowedTypesWithNames(allowedTypes)}.`,
|
|
118
161
|
);
|
|
119
162
|
}
|
|
120
163
|
if (!hasSingle(possibleTypes)) {
|
|
121
164
|
throw new UsageError(
|
|
122
165
|
`The provided data is compatible with more than one type allowed by the schema.
|
|
123
|
-
The set of possible types is ${
|
|
124
|
-
...possibleTypes.map((schema) => schema.identifier),
|
|
125
|
-
])}.
|
|
166
|
+
The set of possible types is ${quotedAllowedTypesWithNames(possibleTypes)}.
|
|
126
167
|
Explicitly construct an unhydrated node of the desired type to disambiguate.
|
|
127
168
|
For class-based schema, this can be done by replacing an expression like "{foo: 1}" with "new MySchema({foo: 1})".`,
|
|
128
169
|
);
|
|
@@ -7,6 +7,7 @@ import { assert } from "@fluidframework/core-utils/internal";
|
|
|
7
7
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
8
8
|
|
|
9
9
|
import { EmptyKey } from "../core/index.js";
|
|
10
|
+
import { TreeAlpha } from "../shared-tree/index.js";
|
|
10
11
|
import {
|
|
11
12
|
enumFromStrings,
|
|
12
13
|
eraseSchemaDetails,
|
|
@@ -83,25 +84,44 @@ class TextNode
|
|
|
83
84
|
length: number,
|
|
84
85
|
format: Partial<FormattedTextAsTree.CharacterFormat>,
|
|
85
86
|
): void {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
87
|
+
const branch = TreeAlpha.branch(this);
|
|
88
|
+
|
|
89
|
+
const applyFormatting = (): void => {
|
|
90
|
+
for (let i = startIndex; i < startIndex + length; i++) {
|
|
91
|
+
const atom = this.content[i];
|
|
92
|
+
if (atom === undefined) {
|
|
93
|
+
throw new UsageError("Index out of bounds while formatting text range.");
|
|
94
|
+
}
|
|
95
|
+
for (const [key, value] of Object.entries(format) as [
|
|
96
|
+
keyof FormattedTextAsTree.CharacterFormat,
|
|
97
|
+
unknown,
|
|
98
|
+
][]) {
|
|
99
|
+
// Object.entries should only return string keyed enumerable own properties.
|
|
100
|
+
// The TypeScript typing does not account for this, and thus this assertion is necessary for this code to compile.
|
|
101
|
+
assert(
|
|
102
|
+
typeof key === "string",
|
|
103
|
+
0xcc8 /* Object.entries returned a non-string key. */,
|
|
104
|
+
);
|
|
105
|
+
const f = FormattedTextAsTree.CharacterFormat.fields.get(key);
|
|
106
|
+
if (f === undefined) {
|
|
107
|
+
throw new UsageError(`Unknown format key: ${key}`);
|
|
108
|
+
}
|
|
109
|
+
// Ensures that if the input is a node, it is cloned before being inserted into the tree.
|
|
110
|
+
atom.format[key] = TreeBeta.clone(TreeBeta.create(f, value as never)) as never;
|
|
101
111
|
}
|
|
102
|
-
// Ensures that if the input is a node, it is cloned before being inserted into the tree.
|
|
103
|
-
atom.format[key] = TreeBeta.clone(TreeBeta.create(f, value as never)) as never;
|
|
104
112
|
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (branch === undefined) {
|
|
116
|
+
// If this node does not have a corresponding branch, then it is unhydrated.
|
|
117
|
+
// I.e., it is not part of a collaborative session yet.
|
|
118
|
+
// Therefore, we don't need to run the edits as a transaction.
|
|
119
|
+
applyFormatting();
|
|
120
|
+
} else {
|
|
121
|
+
// Wrap all formatting operations in a single transaction for atomicity.
|
|
122
|
+
branch.runTransaction(() => {
|
|
123
|
+
applyFormatting();
|
|
124
|
+
});
|
|
105
125
|
}
|
|
106
126
|
}
|
|
107
127
|
}
|
package/src/util/bTreeUtils.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { debugAssert } from "@fluidframework/core-utils/internal";
|
|
7
7
|
import { BTree, defaultComparator, type DefaultComparable } from "@tylerbu/sorted-btree-es6";
|
|
8
|
+
// eslint-disable-next-line import-x/no-internal-modules
|
|
9
|
+
import { union } from "@tylerbu/sorted-btree-es6/extended/union";
|
|
8
10
|
|
|
9
11
|
import { brand, type Brand } from "./brand.js";
|
|
10
12
|
|
|
@@ -78,14 +80,16 @@ export function mergeTupleBTrees<const K extends readonly DefaultComparable[], V
|
|
|
78
80
|
tree2: TupleBTree<K, V> | undefined,
|
|
79
81
|
preferLeft = true,
|
|
80
82
|
): TupleBTree<K, V> {
|
|
81
|
-
const result: TupleBTree<K, V> = brand(tree1.clone());
|
|
82
83
|
if (tree2 === undefined) {
|
|
83
|
-
return
|
|
84
|
+
return brand(tree1.clone());
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
// Use efficient union operation from sorted-btree 2.x
|
|
88
|
+
const result = union<BTree<K, V>, K, V>(
|
|
89
|
+
tree1 as BTree<K, V>,
|
|
90
|
+
tree2 as BTree<K, V>,
|
|
91
|
+
(_key, val1, val2) => (preferLeft ? val1 : val2),
|
|
92
|
+
);
|
|
89
93
|
|
|
90
|
-
return result;
|
|
94
|
+
return brand(result);
|
|
91
95
|
}
|
package/src/util/rangeMap.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert, oob } from "@fluidframework/core-utils/internal";
|
|
7
7
|
import { BTree } from "@tylerbu/sorted-btree-es6";
|
|
8
|
+
// eslint-disable-next-line import-x/no-internal-modules
|
|
9
|
+
import { union } from "@tylerbu/sorted-btree-es6/extended/union";
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* RangeMap represents a mapping from keys of type K to values of type V or undefined.
|
|
@@ -224,12 +226,13 @@ export class RangeMap<K, V> {
|
|
|
224
226
|
|
|
225
227
|
const merged = new RangeMap<K, V>(a.offsetKey, a.subtractKeys, a.offsetValue);
|
|
226
228
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
229
|
+
merged.tree = union<BTree<K, RangeEntry<V>>, K, RangeEntry<V>>(
|
|
230
|
+
a.tree,
|
|
231
|
+
b.tree,
|
|
232
|
+
(_key, _val1, val2) => {
|
|
233
|
+
return val2;
|
|
234
|
+
},
|
|
235
|
+
);
|
|
233
236
|
|
|
234
237
|
return merged;
|
|
235
238
|
}
|
package/api-extractor-lint.json
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import type { TreeNodeSchema, TreeNodeFromImplicitAllowedTypes, TreeFieldFromImplicitField, SchemaFactoryBeta } from "./simple-tree/index.js";
|
|
6
|
-
/**
|
|
7
|
-
* Utilities for creating extensible schema unions.
|
|
8
|
-
* @remarks
|
|
9
|
-
* Use {@link ExtensibleSchemaUnion.extensibleSchemaUnion} to create the union schema.
|
|
10
|
-
*
|
|
11
|
-
* Unlike a schema union created using {@link SchemaStaticsBeta.staged | staged} allowed types, this union allows for unknown future types to exist in addition to the known types.
|
|
12
|
-
* This allows for faster roll-outs of new types without waiting for old clients to be updated to be aware of them.
|
|
13
|
-
* This does mean however that old clients may see types they do not know about, which are simply exposed as `undefined` children.
|
|
14
|
-
*
|
|
15
|
-
* `staged` types are lower overhead, and might gain support for `unknown` types in the future, so prefer them when possible.
|
|
16
|
-
* This is simply an alternative for when future compatibility with unknown types is required.
|
|
17
|
-
* It is built on top of the existing {@link ObjectSchemaOptions.allowUnknownOptionalFields | allowUnknownOptionalFields} feature.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* const sf = new SchemaFactoryBeta("extensibleSchemaUnionExample.items");
|
|
22
|
-
* class ItemA extends sf.object("A", { x: sf.string }) {}
|
|
23
|
-
* class ItemB extends sf.object("B", { x: sf.number }) {}
|
|
24
|
-
*
|
|
25
|
-
* class AnyItem extends ExtensibleSchemaUnion.extensibleSchemaUnion(
|
|
26
|
-
* [ItemA, ItemB], // Future versions may add more members here
|
|
27
|
-
* sf,
|
|
28
|
-
* "ExtensibleUnion",
|
|
29
|
-
* ) {}
|
|
30
|
-
* // Instances of the union are created using `create`.
|
|
31
|
-
* const anyItem = AnyItem.create(new ItemA({ x: "hello" }));
|
|
32
|
-
* // Reading the content from the union is done via `child`,
|
|
33
|
-
* // which can be `undefined` to handle the case where a future version of this schema allows a type unknown to the current version.
|
|
34
|
-
* const childNode: ItemA | ItemB | undefined = anyItem.child;
|
|
35
|
-
* // To determine which member of the union was present, its schema can be inspected:
|
|
36
|
-
* const aSchema = Tree.schema(childNode ?? assert.fail("No child"));
|
|
37
|
-
* assert.equal(aSchema, ItemA);
|
|
38
|
-
* ```
|
|
39
|
-
* @alpha
|
|
40
|
-
*/
|
|
41
|
-
export declare namespace ExtensibleSchemaUnion {
|
|
42
|
-
/**
|
|
43
|
-
* Members for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.
|
|
44
|
-
* @alpha
|
|
45
|
-
*/
|
|
46
|
-
interface Members<T> {
|
|
47
|
-
/**
|
|
48
|
-
* The child wrapped by this node, which is has one of the type allowed by the union,
|
|
49
|
-
* or `undefined` if the type is one which was added to the union by a future version of this schema.
|
|
50
|
-
*/
|
|
51
|
-
readonly child: T | undefined;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Statics for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.
|
|
55
|
-
* @alpha
|
|
56
|
-
*/
|
|
57
|
-
interface Statics<T extends readonly TreeNodeSchema[]> {
|
|
58
|
-
/**
|
|
59
|
-
* Create a {@link TreeNode} with `this` schema which wraps the provided child to create the union.
|
|
60
|
-
*/
|
|
61
|
-
create<TThis extends TreeNodeSchema>(this: TThis, child: TreeNodeFromImplicitAllowedTypes<T>): TreeFieldFromImplicitField<TThis>;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Create an extensible schema union which currently supports the types in `types`,
|
|
65
|
-
* but tolerates collaboration with future versions that may include additional types.
|
|
66
|
-
* @remarks
|
|
67
|
-
* See {@link ExtensibleSchemaUnion} for an example use.
|
|
68
|
-
* @alpha
|
|
69
|
-
*/
|
|
70
|
-
function extensibleSchemaUnion<const T extends readonly TreeNodeSchema[], const TScope extends string, const TName extends string>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName): Statics<T> & import("./simple-tree/index.js").TreeNodeSchemaCore<import("./simple-tree/index.js").ScopedSchemaName<`com.fluidframework.extensibleSchemaUnion<${TScope}>`, TName>, import("./simple-tree/index.js").NodeKind, false, unknown, never, unknown> & (new (data: import("./simple-tree/index.js").InternalTreeNode) => Members<TreeNodeFromImplicitAllowedTypes<T>> & import("./simple-tree/index.js").TreeNode & import("./simple-tree/index.js").WithType<import("./simple-tree/index.js").ScopedSchemaName<`com.fluidframework.extensibleSchemaUnion<${TScope}>`, TName>, import("./simple-tree/index.js").NodeKind, unknown>);
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=extensibleSchemaUnion.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extensibleSchemaUnion.d.ts","sourceRoot":"","sources":["../src/extensibleSchemaUnion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,cAAc,EACd,gCAAgC,EAChC,0BAA0B,EAG1B,iBAAiB,EACjB,MAAM,wBAAwB,CAAC;AAShC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,yBAAiB,qBAAqB,CAAC;IACtC;;;OAGG;IACH,UAAiB,OAAO,CAAC,CAAC;QACzB;;;WAGG;QACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;KAC9B;IAED;;;OAGG;IACH,UAAiB,OAAO,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;QAC3D;;WAEG;QACH,MAAM,CAAC,KAAK,SAAS,cAAc,EAClC,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,gCAAgC,CAAC,CAAC,CAAC,GACxC,0BAA0B,CAAC,KAAK,CAAC,CAAC;KACrC;IAED;;;;;;OAMG;IAEH,SAAgB,qBAAqB,CACpC,KAAK,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE,EACzC,KAAK,CAAC,MAAM,SAAS,MAAM,EAC3B,KAAK,CAAC,KAAK,SAAS,MAAM,EACzB,KAAK,EAAE,CAAC,EAAE,kBAAkB,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,+mBAqCrE;CACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extensibleSchemaUnion.js","sourceRoot":"","sources":["../src/extensibleSchemaUnion.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,qDAAyD;AASzD,qDAKgC;AAGhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,IAAiB,qBAAqB,CA6ErC;AA7ED,WAAiB,qBAAqB;IA2BrC;;;;;;OAMG;IACH,4EAA4E;IAC5E,SAAgB,qBAAqB,CAInC,KAAQ,EAAE,kBAA6C,EAAE,IAAW;QACrE,MAAM,MAAM,GAAwC,EAAE,CAAC;QACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,wBAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,aAAa,GAAG,IAAA,sDAA2C,EAChE,kBAAkB,EAClB,uBAAuB,CACvB,CAAC;QACF,MAAM,KACL,SAAQ,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,0BAA0B,EAAE,IAAI,EAAE,CAAC;YAGhF,IAAW,KAAK;gBACf,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,oBAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtD,OAAO,KAA4C,CAAC;gBACrD,CAAC;gBACD,OAAO,SAAS,CAAC;YAClB,CAAC;YAEM,MAAM,CAAC,MAAM,CAEnB,KAA0C;gBAE1C,MAAM,MAAM,GAAG,eAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClC,OAAO,mBAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;oBAC5B,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK;iBAIhC,CAAC,CAAC;YACJ,CAAC;SACD;QACD,OAAO,IAAA,yCAA8B,GAGlC,CAAC,KAAK,CAAC,CAAC;IACZ,CAAC;IAzCe,2CAAqB,wBAyCpC,CAAA;AACF,CAAC,EA7EgB,qBAAqB,qCAArB,qBAAqB,QA6ErC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TreeAlpha, Tree } from \"./shared-tree/index.js\";\nimport type {\n\tTreeNodeSchema,\n\tTreeNodeFromImplicitAllowedTypes,\n\tTreeFieldFromImplicitField,\n\tImplicitFieldSchema,\n\tInsertableTreeFieldFromImplicitField,\n\tSchemaFactoryBeta,\n} from \"./simple-tree/index.js\";\nimport {\n\tcreateCustomizedFluidFrameworkScopedFactory,\n\teraseSchemaDetailsSubclassable,\n\tSchemaFactory,\n\tTreeBeta,\n} from \"./simple-tree/index.js\";\nimport type { UnionToIntersection } from \"./util/index.js\";\n\n/**\n * Utilities for creating extensible schema unions.\n * @remarks\n * Use {@link ExtensibleSchemaUnion.extensibleSchemaUnion} to create the union schema.\n *\n * Unlike a schema union created using {@link SchemaStaticsBeta.staged | staged} allowed types, this union allows for unknown future types to exist in addition to the known types.\n * This allows for faster roll-outs of new types without waiting for old clients to be updated to be aware of them.\n * This does mean however that old clients may see types they do not know about, which are simply exposed as `undefined` children.\n *\n * `staged` types are lower overhead, and might gain support for `unknown` types in the future, so prefer them when possible.\n * This is simply an alternative for when future compatibility with unknown types is required.\n * It is built on top of the existing {@link ObjectSchemaOptions.allowUnknownOptionalFields | allowUnknownOptionalFields} feature.\n *\n * @example\n * ```typescript\n * const sf = new SchemaFactoryBeta(\"extensibleSchemaUnionExample.items\");\n * class ItemA extends sf.object(\"A\", { x: sf.string }) {}\n * class ItemB extends sf.object(\"B\", { x: sf.number }) {}\n *\n * class AnyItem extends ExtensibleSchemaUnion.extensibleSchemaUnion(\n * \t[ItemA, ItemB], // Future versions may add more members here\n * \tsf,\n * \t\"ExtensibleUnion\",\n * ) {}\n * // Instances of the union are created using `create`.\n * const anyItem = AnyItem.create(new ItemA({ x: \"hello\" }));\n * // Reading the content from the union is done via `child`,\n * // which can be `undefined` to handle the case where a future version of this schema allows a type unknown to the current version.\n * const childNode: ItemA | ItemB | undefined = anyItem.child;\n * // To determine which member of the union was present, its schema can be inspected:\n * const aSchema = Tree.schema(childNode ?? assert.fail(\"No child\"));\n * assert.equal(aSchema, ItemA);\n * ```\n * @alpha\n */\nexport namespace ExtensibleSchemaUnion {\n\t/**\n\t * Members for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.\n\t * @alpha\n\t */\n\texport interface Members<T> {\n\t\t/**\n\t\t * The child wrapped by this node, which is has one of the type allowed by the union,\n\t\t * or `undefined` if the type is one which was added to the union by a future version of this schema.\n\t\t */\n\t\treadonly child: T | undefined;\n\t}\n\n\t/**\n\t * Statics for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.\n\t * @alpha\n\t */\n\texport interface Statics<T extends readonly TreeNodeSchema[]> {\n\t\t/**\n\t\t * Create a {@link TreeNode} with `this` schema which wraps the provided child to create the union.\n\t\t */\n\t\tcreate<TThis extends TreeNodeSchema>(\n\t\t\tthis: TThis,\n\t\t\tchild: TreeNodeFromImplicitAllowedTypes<T>,\n\t\t): TreeFieldFromImplicitField<TThis>;\n\t}\n\n\t/**\n\t * Create an extensible schema union which currently supports the types in `types`,\n\t * but tolerates collaboration with future versions that may include additional types.\n\t * @remarks\n\t * See {@link ExtensibleSchemaUnion} for an example use.\n\t * @alpha\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\texport function extensibleSchemaUnion<\n\t\tconst T extends readonly TreeNodeSchema[],\n\t\tconst TScope extends string,\n\t\tconst TName extends string,\n\t>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName) {\n\t\tconst record: Record<string, ImplicitFieldSchema> = {};\n\t\tfor (const type of types) {\n\t\t\trecord[`_${type.identifier}`] = SchemaFactory.optional(type, { key: type.identifier });\n\t\t}\n\t\tconst schemaFactory = createCustomizedFluidFrameworkScopedFactory(\n\t\t\tinputSchemaFactory,\n\t\t\t\"extensibleSchemaUnion\",\n\t\t);\n\t\tclass Union\n\t\t\textends schemaFactory.object(name, record, { allowUnknownOptionalFields: true })\n\t\t\timplements Members<TreeNodeFromImplicitAllowedTypes<T>>\n\t\t{\n\t\t\tpublic get child(): TreeNodeFromImplicitAllowedTypes<T> | undefined {\n\t\t\t\tfor (const [_key, child] of TreeAlpha.children(this)) {\n\t\t\t\t\treturn child as TreeNodeFromImplicitAllowedTypes<T>;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tpublic static create<TThis extends TreeNodeSchema>(\n\t\t\t\tthis: TThis,\n\t\t\t\tchild: TreeNodeFromImplicitAllowedTypes<T>,\n\t\t\t): TreeFieldFromImplicitField<TThis> {\n\t\t\t\tconst schema = Tree.schema(child);\n\t\t\t\treturn TreeBeta.create(this, {\n\t\t\t\t\t[`_${schema.identifier}`]: child,\n\t\t\t\t} as unknown as InsertableTreeFieldFromImplicitField<\n\t\t\t\t\tTThis,\n\t\t\t\t\tUnionToIntersection<TThis>\n\t\t\t\t>);\n\t\t\t}\n\t\t}\n\t\treturn eraseSchemaDetailsSubclassable<\n\t\t\tMembers<TreeNodeFromImplicitAllowedTypes<T>>,\n\t\t\tStatics<T>\n\t\t>()(Union);\n\t}\n}\n"]}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import type { TreeNodeSchema, TreeNodeFromImplicitAllowedTypes, TreeFieldFromImplicitField, SchemaFactoryBeta } from "./simple-tree/index.js";
|
|
6
|
-
/**
|
|
7
|
-
* Utilities for creating extensible schema unions.
|
|
8
|
-
* @remarks
|
|
9
|
-
* Use {@link ExtensibleSchemaUnion.extensibleSchemaUnion} to create the union schema.
|
|
10
|
-
*
|
|
11
|
-
* Unlike a schema union created using {@link SchemaStaticsBeta.staged | staged} allowed types, this union allows for unknown future types to exist in addition to the known types.
|
|
12
|
-
* This allows for faster roll-outs of new types without waiting for old clients to be updated to be aware of them.
|
|
13
|
-
* This does mean however that old clients may see types they do not know about, which are simply exposed as `undefined` children.
|
|
14
|
-
*
|
|
15
|
-
* `staged` types are lower overhead, and might gain support for `unknown` types in the future, so prefer them when possible.
|
|
16
|
-
* This is simply an alternative for when future compatibility with unknown types is required.
|
|
17
|
-
* It is built on top of the existing {@link ObjectSchemaOptions.allowUnknownOptionalFields | allowUnknownOptionalFields} feature.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* const sf = new SchemaFactoryBeta("extensibleSchemaUnionExample.items");
|
|
22
|
-
* class ItemA extends sf.object("A", { x: sf.string }) {}
|
|
23
|
-
* class ItemB extends sf.object("B", { x: sf.number }) {}
|
|
24
|
-
*
|
|
25
|
-
* class AnyItem extends ExtensibleSchemaUnion.extensibleSchemaUnion(
|
|
26
|
-
* [ItemA, ItemB], // Future versions may add more members here
|
|
27
|
-
* sf,
|
|
28
|
-
* "ExtensibleUnion",
|
|
29
|
-
* ) {}
|
|
30
|
-
* // Instances of the union are created using `create`.
|
|
31
|
-
* const anyItem = AnyItem.create(new ItemA({ x: "hello" }));
|
|
32
|
-
* // Reading the content from the union is done via `child`,
|
|
33
|
-
* // which can be `undefined` to handle the case where a future version of this schema allows a type unknown to the current version.
|
|
34
|
-
* const childNode: ItemA | ItemB | undefined = anyItem.child;
|
|
35
|
-
* // To determine which member of the union was present, its schema can be inspected:
|
|
36
|
-
* const aSchema = Tree.schema(childNode ?? assert.fail("No child"));
|
|
37
|
-
* assert.equal(aSchema, ItemA);
|
|
38
|
-
* ```
|
|
39
|
-
* @alpha
|
|
40
|
-
*/
|
|
41
|
-
export declare namespace ExtensibleSchemaUnion {
|
|
42
|
-
/**
|
|
43
|
-
* Members for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.
|
|
44
|
-
* @alpha
|
|
45
|
-
*/
|
|
46
|
-
interface Members<T> {
|
|
47
|
-
/**
|
|
48
|
-
* The child wrapped by this node, which is has one of the type allowed by the union,
|
|
49
|
-
* or `undefined` if the type is one which was added to the union by a future version of this schema.
|
|
50
|
-
*/
|
|
51
|
-
readonly child: T | undefined;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Statics for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.
|
|
55
|
-
* @alpha
|
|
56
|
-
*/
|
|
57
|
-
interface Statics<T extends readonly TreeNodeSchema[]> {
|
|
58
|
-
/**
|
|
59
|
-
* Create a {@link TreeNode} with `this` schema which wraps the provided child to create the union.
|
|
60
|
-
*/
|
|
61
|
-
create<TThis extends TreeNodeSchema>(this: TThis, child: TreeNodeFromImplicitAllowedTypes<T>): TreeFieldFromImplicitField<TThis>;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Create an extensible schema union which currently supports the types in `types`,
|
|
65
|
-
* but tolerates collaboration with future versions that may include additional types.
|
|
66
|
-
* @remarks
|
|
67
|
-
* See {@link ExtensibleSchemaUnion} for an example use.
|
|
68
|
-
* @alpha
|
|
69
|
-
*/
|
|
70
|
-
function extensibleSchemaUnion<const T extends readonly TreeNodeSchema[], const TScope extends string, const TName extends string>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName): Statics<T> & import("./simple-tree/index.js").TreeNodeSchemaCore<import("./simple-tree/index.js").ScopedSchemaName<`com.fluidframework.extensibleSchemaUnion<${TScope}>`, TName>, import("./simple-tree/index.js").NodeKind, false, unknown, never, unknown> & (new (data: import("./simple-tree/index.js").InternalTreeNode) => Members<TreeNodeFromImplicitAllowedTypes<T>> & import("./simple-tree/index.js").TreeNode & import("./simple-tree/index.js").WithType<import("./simple-tree/index.js").ScopedSchemaName<`com.fluidframework.extensibleSchemaUnion<${TScope}>`, TName>, import("./simple-tree/index.js").NodeKind, unknown>);
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=extensibleSchemaUnion.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extensibleSchemaUnion.d.ts","sourceRoot":"","sources":["../src/extensibleSchemaUnion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,cAAc,EACd,gCAAgC,EAChC,0BAA0B,EAG1B,iBAAiB,EACjB,MAAM,wBAAwB,CAAC;AAShC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,yBAAiB,qBAAqB,CAAC;IACtC;;;OAGG;IACH,UAAiB,OAAO,CAAC,CAAC;QACzB;;;WAGG;QACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;KAC9B;IAED;;;OAGG;IACH,UAAiB,OAAO,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE;QAC3D;;WAEG;QACH,MAAM,CAAC,KAAK,SAAS,cAAc,EAClC,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,gCAAgC,CAAC,CAAC,CAAC,GACxC,0BAA0B,CAAC,KAAK,CAAC,CAAC;KACrC;IAED;;;;;;OAMG;IAEH,SAAgB,qBAAqB,CACpC,KAAK,CAAC,CAAC,SAAS,SAAS,cAAc,EAAE,EACzC,KAAK,CAAC,MAAM,SAAS,MAAM,EAC3B,KAAK,CAAC,KAAK,SAAS,MAAM,EACzB,KAAK,EAAE,CAAC,EAAE,kBAAkB,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,+mBAqCrE;CACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extensibleSchemaUnion.js","sourceRoot":"","sources":["../src/extensibleSchemaUnion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AASzD,OAAO,EACN,2CAA2C,EAC3C,8BAA8B,EAC9B,aAAa,EACb,QAAQ,GACR,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,KAAW,qBAAqB,CA6ErC;AA7ED,WAAiB,qBAAqB;IA2BrC;;;;;;OAMG;IACH,4EAA4E;IAC5E,SAAgB,qBAAqB,CAInC,KAAQ,EAAE,kBAA6C,EAAE,IAAW;QACrE,MAAM,MAAM,GAAwC,EAAE,CAAC;QACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,aAAa,GAAG,2CAA2C,CAChE,kBAAkB,EAClB,uBAAuB,CACvB,CAAC;QACF,MAAM,KACL,SAAQ,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,0BAA0B,EAAE,IAAI,EAAE,CAAC;YAGhF,IAAW,KAAK;gBACf,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtD,OAAO,KAA4C,CAAC;gBACrD,CAAC;gBACD,OAAO,SAAS,CAAC;YAClB,CAAC;YAEM,MAAM,CAAC,MAAM,CAEnB,KAA0C;gBAE1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClC,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;oBAC5B,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK;iBAIhC,CAAC,CAAC;YACJ,CAAC;SACD;QACD,OAAO,8BAA8B,EAGlC,CAAC,KAAK,CAAC,CAAC;IACZ,CAAC;IAzCe,2CAAqB,wBAyCpC,CAAA;AACF,CAAC,EA7EgB,qBAAqB,KAArB,qBAAqB,QA6ErC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TreeAlpha, Tree } from \"./shared-tree/index.js\";\nimport type {\n\tTreeNodeSchema,\n\tTreeNodeFromImplicitAllowedTypes,\n\tTreeFieldFromImplicitField,\n\tImplicitFieldSchema,\n\tInsertableTreeFieldFromImplicitField,\n\tSchemaFactoryBeta,\n} from \"./simple-tree/index.js\";\nimport {\n\tcreateCustomizedFluidFrameworkScopedFactory,\n\teraseSchemaDetailsSubclassable,\n\tSchemaFactory,\n\tTreeBeta,\n} from \"./simple-tree/index.js\";\nimport type { UnionToIntersection } from \"./util/index.js\";\n\n/**\n * Utilities for creating extensible schema unions.\n * @remarks\n * Use {@link ExtensibleSchemaUnion.extensibleSchemaUnion} to create the union schema.\n *\n * Unlike a schema union created using {@link SchemaStaticsBeta.staged | staged} allowed types, this union allows for unknown future types to exist in addition to the known types.\n * This allows for faster roll-outs of new types without waiting for old clients to be updated to be aware of them.\n * This does mean however that old clients may see types they do not know about, which are simply exposed as `undefined` children.\n *\n * `staged` types are lower overhead, and might gain support for `unknown` types in the future, so prefer them when possible.\n * This is simply an alternative for when future compatibility with unknown types is required.\n * It is built on top of the existing {@link ObjectSchemaOptions.allowUnknownOptionalFields | allowUnknownOptionalFields} feature.\n *\n * @example\n * ```typescript\n * const sf = new SchemaFactoryBeta(\"extensibleSchemaUnionExample.items\");\n * class ItemA extends sf.object(\"A\", { x: sf.string }) {}\n * class ItemB extends sf.object(\"B\", { x: sf.number }) {}\n *\n * class AnyItem extends ExtensibleSchemaUnion.extensibleSchemaUnion(\n * \t[ItemA, ItemB], // Future versions may add more members here\n * \tsf,\n * \t\"ExtensibleUnion\",\n * ) {}\n * // Instances of the union are created using `create`.\n * const anyItem = AnyItem.create(new ItemA({ x: \"hello\" }));\n * // Reading the content from the union is done via `child`,\n * // which can be `undefined` to handle the case where a future version of this schema allows a type unknown to the current version.\n * const childNode: ItemA | ItemB | undefined = anyItem.child;\n * // To determine which member of the union was present, its schema can be inspected:\n * const aSchema = Tree.schema(childNode ?? assert.fail(\"No child\"));\n * assert.equal(aSchema, ItemA);\n * ```\n * @alpha\n */\nexport namespace ExtensibleSchemaUnion {\n\t/**\n\t * Members for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.\n\t * @alpha\n\t */\n\texport interface Members<T> {\n\t\t/**\n\t\t * The child wrapped by this node, which is has one of the type allowed by the union,\n\t\t * or `undefined` if the type is one which was added to the union by a future version of this schema.\n\t\t */\n\t\treadonly child: T | undefined;\n\t}\n\n\t/**\n\t * Statics for classes created by {@link ExtensibleSchemaUnion.extensibleSchemaUnion}.\n\t * @alpha\n\t */\n\texport interface Statics<T extends readonly TreeNodeSchema[]> {\n\t\t/**\n\t\t * Create a {@link TreeNode} with `this` schema which wraps the provided child to create the union.\n\t\t */\n\t\tcreate<TThis extends TreeNodeSchema>(\n\t\t\tthis: TThis,\n\t\t\tchild: TreeNodeFromImplicitAllowedTypes<T>,\n\t\t): TreeFieldFromImplicitField<TThis>;\n\t}\n\n\t/**\n\t * Create an extensible schema union which currently supports the types in `types`,\n\t * but tolerates collaboration with future versions that may include additional types.\n\t * @remarks\n\t * See {@link ExtensibleSchemaUnion} for an example use.\n\t * @alpha\n\t */\n\t// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n\texport function extensibleSchemaUnion<\n\t\tconst T extends readonly TreeNodeSchema[],\n\t\tconst TScope extends string,\n\t\tconst TName extends string,\n\t>(types: T, inputSchemaFactory: SchemaFactoryBeta<TScope>, name: TName) {\n\t\tconst record: Record<string, ImplicitFieldSchema> = {};\n\t\tfor (const type of types) {\n\t\t\trecord[`_${type.identifier}`] = SchemaFactory.optional(type, { key: type.identifier });\n\t\t}\n\t\tconst schemaFactory = createCustomizedFluidFrameworkScopedFactory(\n\t\t\tinputSchemaFactory,\n\t\t\t\"extensibleSchemaUnion\",\n\t\t);\n\t\tclass Union\n\t\t\textends schemaFactory.object(name, record, { allowUnknownOptionalFields: true })\n\t\t\timplements Members<TreeNodeFromImplicitAllowedTypes<T>>\n\t\t{\n\t\t\tpublic get child(): TreeNodeFromImplicitAllowedTypes<T> | undefined {\n\t\t\t\tfor (const [_key, child] of TreeAlpha.children(this)) {\n\t\t\t\t\treturn child as TreeNodeFromImplicitAllowedTypes<T>;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tpublic static create<TThis extends TreeNodeSchema>(\n\t\t\t\tthis: TThis,\n\t\t\t\tchild: TreeNodeFromImplicitAllowedTypes<T>,\n\t\t\t): TreeFieldFromImplicitField<TThis> {\n\t\t\t\tconst schema = Tree.schema(child);\n\t\t\t\treturn TreeBeta.create(this, {\n\t\t\t\t\t[`_${schema.identifier}`]: child,\n\t\t\t\t} as unknown as InsertableTreeFieldFromImplicitField<\n\t\t\t\t\tTThis,\n\t\t\t\t\tUnionToIntersection<TThis>\n\t\t\t\t>);\n\t\t\t}\n\t\t}\n\t\treturn eraseSchemaDetailsSubclassable<\n\t\t\tMembers<TreeNodeFromImplicitAllowedTypes<T>>,\n\t\t\tStatics<T>\n\t\t>()(Union);\n\t}\n}\n"]}
|