@fluidframework/tree 2.4.0 → 2.5.0-302463
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/.vscode/settings.json +11 -1
- package/api-report/tree.alpha.api.md +148 -51
- package/api-report/tree.beta.api.md +83 -38
- package/api-report/tree.legacy.alpha.api.md +83 -38
- package/api-report/tree.legacy.public.api.md +83 -38
- package/api-report/tree.public.api.md +83 -38
- package/dist/alpha.d.ts +17 -2
- package/dist/beta.d.ts +6 -0
- package/dist/events/interop.d.ts +1 -7
- package/dist/events/interop.d.ts.map +1 -1
- package/dist/events/interop.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js +1 -1
- package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js +1 -1
- package/dist/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/treeCursorUtils.js +2 -2
- package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/internalTypes.d.ts +1 -1
- package/dist/internalTypes.d.ts.map +1 -1
- package/dist/internalTypes.js.map +1 -1
- package/dist/legacy.d.ts +6 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/public.d.ts +6 -0
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +1 -1
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/treeApi.d.ts +6 -6
- package/dist/shared-tree/treeApi.d.ts.map +1 -1
- package/dist/shared-tree/treeApi.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +2 -0
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/editManager.d.ts.map +1 -1
- package/dist/shared-tree-core/editManager.js +12 -7
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/simple-tree/api/create.d.ts +3 -3
- package/dist/simple-tree/api/create.d.ts.map +1 -1
- package/dist/simple-tree/api/create.js.map +1 -1
- package/dist/simple-tree/api/customTree.js +2 -2
- package/dist/simple-tree/api/customTree.js.map +1 -1
- package/dist/simple-tree/api/index.d.ts +3 -3
- package/dist/simple-tree/api/index.d.ts.map +1 -1
- package/dist/simple-tree/api/index.js +1 -2
- package/dist/simple-tree/api/index.js.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.d.ts +33 -25
- package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaCreationUtilities.js +31 -21
- package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +5 -1
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +4 -0
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +3 -3
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +13 -4
- 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/treeApiBeta.d.ts.map +1 -1
- package/dist/simple-tree/api/treeApiBeta.js.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.d.ts +69 -17
- package/dist/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/dist/simple-tree/api/typesUnsafe.js.map +1 -1
- package/dist/simple-tree/arrayNode.d.ts +14 -3
- package/dist/simple-tree/arrayNode.d.ts.map +1 -1
- package/dist/simple-tree/arrayNode.js.map +1 -1
- package/dist/simple-tree/core/treeNodeSchema.d.ts +10 -6
- 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/withType.d.ts +3 -1
- package/dist/simple-tree/core/withType.d.ts.map +1 -1
- package/dist/simple-tree/core/withType.js.map +1 -1
- package/dist/simple-tree/index.d.ts +4 -4
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js +1 -2
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/mapNode.d.ts.map +1 -1
- package/dist/simple-tree/mapNode.js +3 -0
- package/dist/simple-tree/mapNode.js.map +1 -1
- package/dist/simple-tree/objectNode.d.ts +4 -2
- package/dist/simple-tree/objectNode.d.ts.map +1 -1
- package/dist/simple-tree/objectNode.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +168 -14
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js +6 -1
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/toMapTree.d.ts +4 -2
- package/dist/simple-tree/toMapTree.d.ts.map +1 -1
- package/dist/simple-tree/toMapTree.js.map +1 -1
- package/dist/util/index.d.ts +2 -1
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +3 -1
- package/dist/util/index.js.map +1 -1
- package/dist/util/typeUtils.d.ts +61 -0
- package/dist/util/typeUtils.d.ts.map +1 -1
- package/dist/util/typeUtils.js +27 -0
- package/dist/util/typeUtils.js.map +1 -1
- package/lib/alpha.d.ts +17 -2
- package/lib/beta.d.ts +6 -0
- package/lib/events/interop.d.ts +1 -7
- package/lib/events/interop.d.ts.map +1 -1
- package/lib/events/interop.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js +1 -1
- package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js +1 -1
- package/lib/feature-libraries/chunked-forest/uniformChunk.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/treeCursorUtils.js +2 -2
- package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/internalTypes.d.ts +1 -1
- package/lib/internalTypes.d.ts.map +1 -1
- package/lib/internalTypes.js.map +1 -1
- package/lib/legacy.d.ts +6 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +6 -0
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +1 -1
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/treeApi.d.ts +6 -6
- package/lib/shared-tree/treeApi.d.ts.map +1 -1
- package/lib/shared-tree/treeApi.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +2 -0
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/editManager.d.ts.map +1 -1
- package/lib/shared-tree-core/editManager.js +12 -7
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/simple-tree/api/create.d.ts +3 -3
- package/lib/simple-tree/api/create.d.ts.map +1 -1
- package/lib/simple-tree/api/create.js.map +1 -1
- package/lib/simple-tree/api/customTree.js +2 -2
- package/lib/simple-tree/api/customTree.js.map +1 -1
- package/lib/simple-tree/api/index.d.ts +3 -3
- 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/schemaCreationUtilities.d.ts +33 -25
- package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaCreationUtilities.js +30 -19
- package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +5 -1
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +4 -0
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +3 -3
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +13 -4
- 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/treeApiBeta.d.ts.map +1 -1
- package/lib/simple-tree/api/treeApiBeta.js.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.d.ts +69 -17
- package/lib/simple-tree/api/typesUnsafe.d.ts.map +1 -1
- package/lib/simple-tree/api/typesUnsafe.js.map +1 -1
- package/lib/simple-tree/arrayNode.d.ts +14 -3
- package/lib/simple-tree/arrayNode.d.ts.map +1 -1
- package/lib/simple-tree/arrayNode.js.map +1 -1
- package/lib/simple-tree/core/treeNodeSchema.d.ts +10 -6
- 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/withType.d.ts +3 -1
- package/lib/simple-tree/core/withType.d.ts.map +1 -1
- package/lib/simple-tree/core/withType.js.map +1 -1
- package/lib/simple-tree/index.d.ts +4 -4
- 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/mapNode.d.ts.map +1 -1
- package/lib/simple-tree/mapNode.js +3 -0
- package/lib/simple-tree/mapNode.js.map +1 -1
- package/lib/simple-tree/objectNode.d.ts +4 -2
- package/lib/simple-tree/objectNode.d.ts.map +1 -1
- package/lib/simple-tree/objectNode.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +168 -14
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js +6 -1
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/toMapTree.d.ts +4 -2
- package/lib/simple-tree/toMapTree.d.ts.map +1 -1
- package/lib/simple-tree/toMapTree.js.map +1 -1
- package/lib/util/index.d.ts +2 -1
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +1 -0
- package/lib/util/index.js.map +1 -1
- package/lib/util/typeUtils.d.ts +61 -0
- package/lib/util/typeUtils.d.ts.map +1 -1
- package/lib/util/typeUtils.js +25 -1
- package/lib/util/typeUtils.js.map +1 -1
- package/package.json +48 -32
- package/src/events/interop.ts +1 -12
- package/src/feature-libraries/chunked-forest/basicChunk.ts +1 -1
- package/src/feature-libraries/chunked-forest/uniformChunk.ts +1 -1
- package/src/feature-libraries/object-forest/objectForest.ts +1 -1
- package/src/feature-libraries/treeCursorUtils.ts +2 -2
- package/src/index.ts +16 -1
- package/src/internalTypes.ts +4 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +6 -2
- package/src/shared-tree/sharedTree.ts +4 -2
- package/src/shared-tree/treeApi.ts +19 -9
- package/src/shared-tree/treeCheckout.ts +2 -0
- package/src/shared-tree-core/editManager.ts +16 -7
- package/src/simple-tree/api/create.ts +12 -7
- package/src/simple-tree/api/customTree.ts +2 -2
- package/src/simple-tree/api/index.ts +6 -1
- package/src/simple-tree/api/schemaCreationUtilities.ts +58 -35
- package/src/simple-tree/api/schemaFactory.ts +4 -0
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +3 -3
- package/src/simple-tree/api/tree.ts +27 -4
- package/src/simple-tree/api/treeApiBeta.ts +6 -2
- package/src/simple-tree/api/typesUnsafe.ts +126 -30
- package/src/simple-tree/arrayNode.ts +34 -14
- package/src/simple-tree/core/treeNodeSchema.ts +11 -6
- package/src/simple-tree/core/withType.ts +10 -1
- package/src/simple-tree/index.ts +19 -2
- package/src/simple-tree/mapNode.ts +6 -3
- package/src/simple-tree/objectNode.ts +5 -3
- package/src/simple-tree/schemaTypes.ts +215 -23
- package/src/simple-tree/toMapTree.ts +4 -1
- package/src/util/index.ts +6 -0
- package/src/util/typeUtils.ts +87 -0
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
normalizeAllowedTypes,
|
|
19
19
|
type ImplicitAllowedTypes,
|
|
20
20
|
type InsertableTreeNodeFromImplicitAllowedTypes,
|
|
21
|
+
type TreeLeafValue,
|
|
21
22
|
type TreeNodeFromImplicitAllowedTypes,
|
|
22
23
|
} from "./schemaTypes.js";
|
|
23
24
|
import {
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
type TreeNodeSchemaBoth,
|
|
35
36
|
getSimpleNodeSchemaFromInnerNode,
|
|
36
37
|
getOrCreateInnerNode,
|
|
38
|
+
type TreeNodeSchemaClass,
|
|
37
39
|
} from "./core/index.js";
|
|
38
40
|
import { type InsertableContent, mapTreeFromNodeData } from "./toMapTree.js";
|
|
39
41
|
import { fail } from "../util/index.js";
|
|
@@ -45,6 +47,19 @@ import {
|
|
|
45
47
|
import { TreeNodeValid, type MostDerivedData } from "./treeNodeValid.js";
|
|
46
48
|
import { getUnhydratedContext } from "./createContext.js";
|
|
47
49
|
|
|
50
|
+
/**
|
|
51
|
+
* A covariant base type for {@link (TreeArrayNode:interface)}.
|
|
52
|
+
*
|
|
53
|
+
* This provides the readonly subset of TreeArrayNode functionality, and is used as the source interface for moves since that needs to be covariant.
|
|
54
|
+
* @privateRemarks
|
|
55
|
+
* Ideally this would just include `TreeNode, WithType<string, NodeKind.Array>` in the extends list but https://github.com/microsoft/TypeScript/issues/16936 prevents that from compiling.
|
|
56
|
+
* As a workaround around for this TypeScript limitation, the conflicting type intersection is wrapped in `Awaited` (which has no effect on the type in this case) which allows it to compile.
|
|
57
|
+
* @system @sealed @public
|
|
58
|
+
*/
|
|
59
|
+
export interface ReadonlyArrayNode<out T = TreeNode | TreeLeafValue>
|
|
60
|
+
extends ReadonlyArray<T>,
|
|
61
|
+
Awaited<TreeNode & WithType<string, NodeKind.Array>> {}
|
|
62
|
+
|
|
48
63
|
/**
|
|
49
64
|
* A generic array type, used to defined types like {@link (TreeArrayNode:interface)}.
|
|
50
65
|
*
|
|
@@ -53,9 +68,8 @@ import { getUnhydratedContext } from "./createContext.js";
|
|
|
53
68
|
*
|
|
54
69
|
* @system @sealed @public
|
|
55
70
|
*/
|
|
56
|
-
export interface TreeArrayNodeBase<out T, in TNew, in TMoveFrom>
|
|
57
|
-
extends
|
|
58
|
-
TreeNode {
|
|
71
|
+
export interface TreeArrayNodeBase<out T, in TNew, in TMoveFrom = ReadonlyArrayNode>
|
|
72
|
+
extends ReadonlyArrayNode<T> {
|
|
59
73
|
/**
|
|
60
74
|
* Inserts new item(s) at a specified location.
|
|
61
75
|
* @param index - The index at which to insert `value`.
|
|
@@ -366,8 +380,7 @@ export interface TreeArrayNode<
|
|
|
366
380
|
TAllowedTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes,
|
|
367
381
|
> extends TreeArrayNodeBase<
|
|
368
382
|
TreeNodeFromImplicitAllowedTypes<TAllowedTypes>,
|
|
369
|
-
InsertableTreeNodeFromImplicitAllowedTypes<TAllowedTypes
|
|
370
|
-
TreeArrayNode
|
|
383
|
+
InsertableTreeNodeFromImplicitAllowedTypes<TAllowedTypes>
|
|
371
384
|
> {}
|
|
372
385
|
|
|
373
386
|
/**
|
|
@@ -417,9 +430,7 @@ export class IterableTreeArrayContent<T> implements Iterable<T> {
|
|
|
417
430
|
/**
|
|
418
431
|
* Given a array node proxy, returns its underlying LazySequence field.
|
|
419
432
|
*/
|
|
420
|
-
function getSequenceField
|
|
421
|
-
arrayNode: TreeArrayNode<TSimpleType>,
|
|
422
|
-
): FlexTreeSequenceField {
|
|
433
|
+
function getSequenceField(arrayNode: ReadonlyArrayNode): FlexTreeSequenceField {
|
|
423
434
|
return getOrCreateInnerNode(arrayNode).getBoxed(EmptyKey) as FlexTreeSequenceField;
|
|
424
435
|
}
|
|
425
436
|
|
|
@@ -799,6 +810,11 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
|
|
|
799
810
|
protected abstract get simpleSchema(): T;
|
|
800
811
|
protected abstract get allowedTypes(): ReadonlySet<TreeNodeSchema>;
|
|
801
812
|
|
|
813
|
+
public abstract override get [typeSchemaSymbol](): TreeNodeSchemaClass<
|
|
814
|
+
string,
|
|
815
|
+
NodeKind.Array
|
|
816
|
+
>;
|
|
817
|
+
|
|
802
818
|
public constructor(
|
|
803
819
|
input: Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>> | InternalTreeNode,
|
|
804
820
|
) {
|
|
@@ -901,13 +917,13 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
|
|
|
901
917
|
}
|
|
902
918
|
field.editor.remove(removeStart, removeEnd - removeStart);
|
|
903
919
|
}
|
|
904
|
-
public moveToStart(sourceIndex: number, source?:
|
|
920
|
+
public moveToStart(sourceIndex: number, source?: ReadonlyArrayNode): void {
|
|
905
921
|
const sourceArray = source ?? this;
|
|
906
922
|
const sourceField = getSequenceField(sourceArray);
|
|
907
923
|
validateIndex(sourceIndex, sourceField, "moveToStart");
|
|
908
924
|
this.moveRangeToIndex(0, sourceIndex, sourceIndex + 1, source);
|
|
909
925
|
}
|
|
910
|
-
public moveToEnd(sourceIndex: number, source?:
|
|
926
|
+
public moveToEnd(sourceIndex: number, source?: ReadonlyArrayNode): void {
|
|
911
927
|
const sourceArray = source ?? this;
|
|
912
928
|
const sourceField = getSequenceField(sourceArray);
|
|
913
929
|
validateIndex(sourceIndex, sourceField, "moveToEnd");
|
|
@@ -916,7 +932,7 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
|
|
|
916
932
|
public moveToIndex(
|
|
917
933
|
destinationGap: number,
|
|
918
934
|
sourceIndex: number,
|
|
919
|
-
source?:
|
|
935
|
+
source?: ReadonlyArrayNode,
|
|
920
936
|
): void {
|
|
921
937
|
const sourceArray = source ?? this;
|
|
922
938
|
const sourceField = getSequenceField(sourceArray);
|
|
@@ -928,7 +944,7 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
|
|
|
928
944
|
public moveRangeToStart(
|
|
929
945
|
sourceStart: number,
|
|
930
946
|
sourceEnd: number,
|
|
931
|
-
source?:
|
|
947
|
+
source?: ReadonlyArrayNode,
|
|
932
948
|
): void {
|
|
933
949
|
validateIndexRange(
|
|
934
950
|
sourceStart,
|
|
@@ -938,7 +954,11 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
|
|
|
938
954
|
);
|
|
939
955
|
this.moveRangeToIndex(0, sourceStart, sourceEnd, source);
|
|
940
956
|
}
|
|
941
|
-
public moveRangeToEnd(
|
|
957
|
+
public moveRangeToEnd(
|
|
958
|
+
sourceStart: number,
|
|
959
|
+
sourceEnd: number,
|
|
960
|
+
source?: ReadonlyArrayNode,
|
|
961
|
+
): void {
|
|
942
962
|
validateIndexRange(
|
|
943
963
|
sourceStart,
|
|
944
964
|
sourceEnd,
|
|
@@ -951,7 +971,7 @@ abstract class CustomArrayNodeBase<const T extends ImplicitAllowedTypes>
|
|
|
951
971
|
destinationGap: number,
|
|
952
972
|
sourceStart: number,
|
|
953
973
|
sourceEnd: number,
|
|
954
|
-
source?:
|
|
974
|
+
source?: ReadonlyArrayNode,
|
|
955
975
|
): void {
|
|
956
976
|
const destinationField = getSequenceField(this);
|
|
957
977
|
const destinationSchema = this.allowedTypes;
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { TreeLeafValue } from "../schemaTypes.js";
|
|
7
|
+
import type { InternalTreeNode, TreeNode, Unhydrated } from "./types.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
|
-
* Schema for a
|
|
10
|
+
* Schema for a {@link TreeNode} or {@link TreeLeafValue}.
|
|
11
|
+
*
|
|
10
12
|
* @typeParam Name - The full (including scope) name/identifier for the schema.
|
|
11
13
|
* @typeParam Kind - Which kind of node this schema is for.
|
|
12
14
|
* @typeParam TNode - API for nodes that use this schema.
|
|
@@ -14,12 +16,14 @@ import type { InternalTreeNode, Unhydrated } from "./types.js";
|
|
|
14
16
|
* @typeParam Info - Data used when defining this schema.
|
|
15
17
|
* @remarks
|
|
16
18
|
* Captures the schema both as runtime data and compile time type information.
|
|
19
|
+
* Use {@link SchemaFactory} to define schema.
|
|
20
|
+
* Use `Tree.schema(value)` to lookup the schema for a {@link TreeNode} or {@link TreeLeafValue}.
|
|
17
21
|
* @sealed @public
|
|
18
22
|
*/
|
|
19
23
|
export type TreeNodeSchema<
|
|
20
24
|
Name extends string = string,
|
|
21
25
|
Kind extends NodeKind = NodeKind,
|
|
22
|
-
TNode =
|
|
26
|
+
TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue,
|
|
23
27
|
TBuild = never,
|
|
24
28
|
ImplicitlyConstructable extends boolean = boolean,
|
|
25
29
|
Info = unknown,
|
|
@@ -38,7 +42,7 @@ export type TreeNodeSchema<
|
|
|
38
42
|
export interface TreeNodeSchemaNonClass<
|
|
39
43
|
out Name extends string = string,
|
|
40
44
|
out Kind extends NodeKind = NodeKind,
|
|
41
|
-
out TNode =
|
|
45
|
+
out TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue,
|
|
42
46
|
in TInsertable = never,
|
|
43
47
|
out ImplicitlyConstructable extends boolean = boolean,
|
|
44
48
|
out Info = unknown,
|
|
@@ -94,7 +98,8 @@ export interface TreeNodeSchemaNonClass<
|
|
|
94
98
|
export interface TreeNodeSchemaClass<
|
|
95
99
|
out Name extends string = string,
|
|
96
100
|
out Kind extends NodeKind = NodeKind,
|
|
97
|
-
|
|
101
|
+
// TODO: maybe this can be more specific (exclude leaves)
|
|
102
|
+
out TNode extends TreeNode | TreeLeafValue = TreeNode | TreeLeafValue,
|
|
98
103
|
in TInsertable = never,
|
|
99
104
|
out ImplicitlyConstructable extends boolean = boolean,
|
|
100
105
|
out Info = unknown,
|
|
@@ -115,7 +120,7 @@ export interface TreeNodeSchemaClass<
|
|
|
115
120
|
export type TreeNodeSchemaBoth<
|
|
116
121
|
Name extends string = string,
|
|
117
122
|
Kind extends NodeKind = NodeKind,
|
|
118
|
-
TNode =
|
|
123
|
+
TNode extends TreeNode = TreeNode,
|
|
119
124
|
TInsertable = never,
|
|
120
125
|
ImplicitlyConstructable extends boolean = boolean,
|
|
121
126
|
Info = unknown,
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import type { TreeLeafValue } from "../schemaTypes.js";
|
|
6
7
|
import type { NodeKind, TreeNodeSchemaClass } from "./treeNodeSchema.js";
|
|
8
|
+
import type { TreeNode } from "./types.js";
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* The type of a {@link TreeNode}.
|
|
@@ -87,5 +89,12 @@ export interface WithType<
|
|
|
87
89
|
/**
|
|
88
90
|
* Type symbol, marking a type in a way to increase type safety via strong type checking.
|
|
89
91
|
*/
|
|
90
|
-
get [typeSchemaSymbol](): TreeNodeSchemaClass<
|
|
92
|
+
get [typeSchemaSymbol](): TreeNodeSchemaClass<
|
|
93
|
+
TName,
|
|
94
|
+
TKind,
|
|
95
|
+
TreeNode | TreeLeafValue,
|
|
96
|
+
never,
|
|
97
|
+
boolean,
|
|
98
|
+
TInfo
|
|
99
|
+
>;
|
|
91
100
|
}
|
package/src/simple-tree/index.ts
CHANGED
|
@@ -40,7 +40,6 @@ export {
|
|
|
40
40
|
adaptEnum,
|
|
41
41
|
enumFromStrings,
|
|
42
42
|
singletonSchema,
|
|
43
|
-
typedObjectValues,
|
|
44
43
|
test_RecursiveObject,
|
|
45
44
|
test_RecursiveObject_base,
|
|
46
45
|
test_RecursiveObjectPojoMode,
|
|
@@ -92,6 +91,12 @@ export {
|
|
|
92
91
|
type NodeBuilderDataUnsafe,
|
|
93
92
|
type NodeFromSchemaUnsafe,
|
|
94
93
|
type ReadonlyMapInlined,
|
|
94
|
+
type TreeNodeSchemaClassUnsafe,
|
|
95
|
+
type TreeNodeSchemaUnsafe,
|
|
96
|
+
type AllowedTypesUnsafe,
|
|
97
|
+
type TreeNodeSchemaNonClassUnsafe,
|
|
98
|
+
type InsertableTreeNodeFromAllowedTypesUnsafe,
|
|
99
|
+
type TreeViewAlpha,
|
|
95
100
|
} from "./api/index.js";
|
|
96
101
|
export {
|
|
97
102
|
type NodeFromSchema,
|
|
@@ -113,6 +118,12 @@ export {
|
|
|
113
118
|
normalizeFieldSchema,
|
|
114
119
|
type ApplyKind,
|
|
115
120
|
type FieldSchemaMetadata,
|
|
121
|
+
type InsertableField,
|
|
122
|
+
type Insertable,
|
|
123
|
+
type UnsafeUnknownSchema,
|
|
124
|
+
type ApplyKindInput,
|
|
125
|
+
type InsertableTreeNodeFromAllowedTypes,
|
|
126
|
+
type Input,
|
|
116
127
|
} from "./schemaTypes.js";
|
|
117
128
|
export {
|
|
118
129
|
getTreeNodeForField,
|
|
@@ -122,6 +133,7 @@ export {
|
|
|
122
133
|
TreeArrayNode,
|
|
123
134
|
IterableTreeArrayContent,
|
|
124
135
|
type TreeArrayNodeBase,
|
|
136
|
+
type ReadonlyArrayNode,
|
|
125
137
|
} from "./arrayNode.js";
|
|
126
138
|
export {
|
|
127
139
|
type FieldHasDefault,
|
|
@@ -131,7 +143,12 @@ export {
|
|
|
131
143
|
setField,
|
|
132
144
|
} from "./objectNode.js";
|
|
133
145
|
export type { TreeMapNode, MapNodeInsertableData } from "./mapNode.js";
|
|
134
|
-
export {
|
|
146
|
+
export {
|
|
147
|
+
mapTreeFromNodeData,
|
|
148
|
+
type InsertableContent,
|
|
149
|
+
type FactoryContent,
|
|
150
|
+
type FactoryContentObject,
|
|
151
|
+
} from "./toMapTree.js";
|
|
135
152
|
export { toStoredSchema, getStoredSchema } from "./toFlexSchema.js";
|
|
136
153
|
export {
|
|
137
154
|
numberSchema,
|
|
@@ -128,7 +128,10 @@ export interface TreeMapNode<T extends ImplicitAllowedTypes = ImplicitAllowedTyp
|
|
|
128
128
|
): void;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
// TreeMapNode is invariant over schema type, so for this handler to work with all schema, the only possible type for the schema is `any`.
|
|
132
|
+
// This is not ideal, but no alternatives are possible.
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
134
|
+
const handler: ProxyHandler<TreeMapNode<any>> = {
|
|
132
135
|
getPrototypeOf: () => {
|
|
133
136
|
return Map.prototype;
|
|
134
137
|
},
|
|
@@ -177,7 +180,7 @@ abstract class CustomMapNodeBase<const T extends ImplicitAllowedTypes> extends T
|
|
|
177
180
|
const node = this.innerNode;
|
|
178
181
|
return node.keys();
|
|
179
182
|
}
|
|
180
|
-
public set(key: string, value: InsertableTreeNodeFromImplicitAllowedTypes<T>):
|
|
183
|
+
public set(key: string, value: InsertableTreeNodeFromImplicitAllowedTypes<T>): this {
|
|
181
184
|
const kernel = getKernel(this);
|
|
182
185
|
const node = this.innerNode;
|
|
183
186
|
const mapTree = mapTreeFromNodeData(
|
|
@@ -244,7 +247,7 @@ export function mapSchema<
|
|
|
244
247
|
flexNode: FlexTreeNode,
|
|
245
248
|
): TreeNodeValid<T2> {
|
|
246
249
|
if (useMapPrototype) {
|
|
247
|
-
return new Proxy<Schema>(instance as Schema, handler);
|
|
250
|
+
return new Proxy<Schema>(instance as Schema, handler as ProxyHandler<Schema>);
|
|
248
251
|
}
|
|
249
252
|
return instance;
|
|
250
253
|
}
|
|
@@ -98,6 +98,8 @@ export type FieldHasDefault<T extends ImplicitFieldSchema> = T extends FieldSche
|
|
|
98
98
|
*
|
|
99
99
|
* 3. Union of 1 and 2.
|
|
100
100
|
*
|
|
101
|
+
* @see {@link Input}
|
|
102
|
+
*
|
|
101
103
|
* @privateRemarks TODO: consider separating these cases into different types.
|
|
102
104
|
*
|
|
103
105
|
* @system @public
|
|
@@ -107,13 +109,13 @@ export type InsertableObjectFromSchemaRecord<
|
|
|
107
109
|
> = FlattenKeys<
|
|
108
110
|
{
|
|
109
111
|
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<
|
|
110
|
-
T[Property
|
|
112
|
+
T[Property & string]
|
|
111
113
|
>;
|
|
112
114
|
} & {
|
|
113
115
|
// Field does not have a known default, make it required:
|
|
114
|
-
readonly [Property in keyof T as FieldHasDefault<T[Property
|
|
116
|
+
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false
|
|
115
117
|
? Property
|
|
116
|
-
: never]: InsertableTreeFieldFromImplicitField<T[Property
|
|
118
|
+
: never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
|
|
117
119
|
}
|
|
118
120
|
>;
|
|
119
121
|
|
|
@@ -8,12 +8,18 @@ import { Lazy } from "@fluidframework/core-utils/internal";
|
|
|
8
8
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
9
9
|
|
|
10
10
|
import type { NodeKeyManager } from "../feature-libraries/index.js";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
type MakeNominal,
|
|
13
|
+
brand,
|
|
14
|
+
isReadonlyArray,
|
|
15
|
+
type UnionToIntersection,
|
|
16
|
+
} from "../util/index.js";
|
|
12
17
|
import type {
|
|
13
18
|
Unhydrated,
|
|
14
19
|
NodeKind,
|
|
15
20
|
TreeNodeSchema,
|
|
16
21
|
TreeNodeSchemaClass,
|
|
22
|
+
TreeNode,
|
|
17
23
|
} from "./core/index.js";
|
|
18
24
|
import type { FieldKey } from "../core/index.js";
|
|
19
25
|
import type { InsertableContent } from "./toMapTree.js";
|
|
@@ -25,7 +31,7 @@ import { isLazy, type FlexListToUnion, type LazyItem } from "./flexList.js";
|
|
|
25
31
|
export function isTreeNodeSchemaClass<
|
|
26
32
|
Name extends string,
|
|
27
33
|
Kind extends NodeKind,
|
|
28
|
-
TNode,
|
|
34
|
+
TNode extends TreeNode | TreeLeafValue,
|
|
29
35
|
TBuild,
|
|
30
36
|
ImplicitlyConstructable extends boolean,
|
|
31
37
|
Info,
|
|
@@ -39,8 +45,16 @@ export function isTreeNodeSchemaClass<
|
|
|
39
45
|
* Types for use in fields.
|
|
40
46
|
* @remarks
|
|
41
47
|
* Type constraint used in schema declaration APIs.
|
|
48
|
+
*
|
|
49
|
+
* The order of types in the array is not significant.
|
|
50
|
+
* Additionally, it is legal for users of this type to have the runtime and compile time order of items within this array not match.
|
|
51
|
+
* Therefor to ensure type safety, these arrays should not be indexed, and instead just be iterated.
|
|
52
|
+
*
|
|
53
|
+
* Ideally this restriction would be modeled in the type itself, but it is not ergonomic to do so as there is no easy (when compared to arrays)
|
|
54
|
+
* way to declare and manipulate unordered sets of types in TypeScript.
|
|
55
|
+
*
|
|
42
56
|
* Not intended for direct use outside of package.
|
|
43
|
-
* @public
|
|
57
|
+
* @system @public
|
|
44
58
|
*/
|
|
45
59
|
export type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];
|
|
46
60
|
|
|
@@ -381,39 +395,122 @@ export type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;
|
|
|
381
395
|
export type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes;
|
|
382
396
|
|
|
383
397
|
/**
|
|
384
|
-
* Converts ImplicitFieldSchema to
|
|
398
|
+
* Converts an `ImplicitFieldSchema` to a property type suitable for reading a field with this that schema.
|
|
399
|
+
*
|
|
400
|
+
* @typeparam TSchema - When non-exact schema are provided this errors on the side of returning too general of a type (a conservative union of all possibilities).
|
|
401
|
+
* This is ideal for "output APIs" - i.e. it converts the schema type to the runtime type that a user will _read_ from the tree.
|
|
402
|
+
* Examples of such "non-exact" schema include `ImplicitFieldSchema`, `ImplicitAllowedTypes`, and TypeScript unions of schema types.
|
|
385
403
|
* @public
|
|
386
404
|
*/
|
|
387
405
|
export type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> =
|
|
388
406
|
TSchema extends FieldSchema<infer Kind, infer Types>
|
|
389
|
-
? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind
|
|
407
|
+
? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind>
|
|
390
408
|
: TSchema extends ImplicitAllowedTypes
|
|
391
409
|
? TreeNodeFromImplicitAllowedTypes<TSchema>
|
|
392
|
-
:
|
|
410
|
+
: TreeNode | TreeLeafValue | undefined;
|
|
393
411
|
|
|
394
412
|
/**
|
|
395
413
|
* Type of content that can be inserted into the tree for a field of the given schema.
|
|
414
|
+
*
|
|
415
|
+
* @see {@link Input}
|
|
416
|
+
*
|
|
417
|
+
* @typeparam TSchemaInput - Schema to process.
|
|
418
|
+
* @typeparam TSchema - Do not specify: default value used as implementation detail.
|
|
396
419
|
* @public
|
|
397
420
|
*/
|
|
398
421
|
export type InsertableTreeFieldFromImplicitField<
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
422
|
+
TSchemaInput extends ImplicitFieldSchema,
|
|
423
|
+
TSchema = UnionToIntersection<TSchemaInput>,
|
|
424
|
+
> = [TSchema] extends [FieldSchema<infer Kind, infer Types>]
|
|
425
|
+
? ApplyKindInput<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind, true>
|
|
426
|
+
: [TSchema] extends [ImplicitAllowedTypes]
|
|
403
427
|
? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>
|
|
404
|
-
:
|
|
428
|
+
: never;
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* {@inheritdoc (UnsafeUnknownSchema:type)}
|
|
432
|
+
* @alpha
|
|
433
|
+
*/
|
|
434
|
+
export const UnsafeUnknownSchema: unique symbol = Symbol("UnsafeUnknownSchema");
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* A special type which can be provided to some APIs as the schema type parameter when schema cannot easily be provided at compile time and an unsafe (instead of disabled) editing API is desired.
|
|
438
|
+
* @remarks
|
|
439
|
+
* When used, this means the TypeScript typing should err on the side of completeness (allow all inputs that could be valid).
|
|
440
|
+
* This introduces the risk that out-of-schema data could be allowed at compile time, and only error at runtime.
|
|
441
|
+
*
|
|
442
|
+
* @privateRemarks
|
|
443
|
+
* This only applies to APIs which input data which is expected to be in schema, since APIs outputting have easy mechanisms to do so in a type safe way even when the schema is unknown.
|
|
444
|
+
* In most cases that amounts to returning `TreeNode | TreeLeafValue`.
|
|
445
|
+
*
|
|
446
|
+
* This can be contrasted with the default behavior of TypeScript, which is to require the intersection of the possible types for input APIs,
|
|
447
|
+
* which for unknown schema defining input trees results in the `never` type.
|
|
448
|
+
*
|
|
449
|
+
* Any APIs which use this must produce UsageErrors when out of schema data is encountered, and never produce unrecoverable errors,
|
|
450
|
+
* or silently accept invalid data.
|
|
451
|
+
* This is currently only type exported from the package: the symbol is just used as a way to get a named type.
|
|
452
|
+
* @alpha
|
|
453
|
+
*/
|
|
454
|
+
export type UnsafeUnknownSchema = typeof UnsafeUnknownSchema;
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Content which could be inserted into a tree.
|
|
458
|
+
*
|
|
459
|
+
* @see {@link Input}
|
|
460
|
+
* @remarks
|
|
461
|
+
* Extended version of {@link InsertableTreeNodeFromImplicitAllowedTypes} that also allows {@link (UnsafeUnknownSchema:type)}.
|
|
462
|
+
* @alpha
|
|
463
|
+
*/
|
|
464
|
+
export type Insertable<TSchema extends ImplicitAllowedTypes | UnsafeUnknownSchema> =
|
|
465
|
+
TSchema extends ImplicitAllowedTypes
|
|
466
|
+
? InsertableTreeNodeFromImplicitAllowedTypes<TSchema>
|
|
467
|
+
: InsertableContent;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Content which could be inserted into a field within a tree.
|
|
471
|
+
*
|
|
472
|
+
* @see {@link Input}
|
|
473
|
+
* @remarks
|
|
474
|
+
* Extended version of {@link InsertableTreeFieldFromImplicitField} that also allows {@link (UnsafeUnknownSchema:type)}.
|
|
475
|
+
* @alpha
|
|
476
|
+
*/
|
|
477
|
+
export type InsertableField<TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema> = [
|
|
478
|
+
TSchema,
|
|
479
|
+
] extends [ImplicitFieldSchema]
|
|
480
|
+
? InsertableTreeFieldFromImplicitField<TSchema>
|
|
481
|
+
: [TSchema] extends [UnsafeUnknownSchema]
|
|
482
|
+
? InsertableContent | undefined
|
|
483
|
+
: never;
|
|
405
484
|
|
|
406
485
|
/**
|
|
407
486
|
* Suitable for output.
|
|
408
487
|
* For input must error on side of excluding undefined instead.
|
|
409
488
|
* @system @public
|
|
410
489
|
*/
|
|
411
|
-
export type ApplyKind<T, Kind extends FieldKind
|
|
490
|
+
export type ApplyKind<T, Kind extends FieldKind> = {
|
|
412
491
|
[FieldKind.Required]: T;
|
|
413
492
|
[FieldKind.Optional]: T | undefined;
|
|
414
|
-
[FieldKind.Identifier]:
|
|
493
|
+
[FieldKind.Identifier]: T;
|
|
415
494
|
}[Kind];
|
|
416
495
|
|
|
496
|
+
/**
|
|
497
|
+
* Suitable for input.
|
|
498
|
+
*
|
|
499
|
+
* @see {@link Input}
|
|
500
|
+
* @system @public
|
|
501
|
+
*/
|
|
502
|
+
export type ApplyKindInput<T, Kind extends FieldKind, DefaultsAreOptional extends boolean> = [
|
|
503
|
+
Kind,
|
|
504
|
+
] extends [FieldKind.Required]
|
|
505
|
+
? T
|
|
506
|
+
: [Kind] extends [FieldKind.Optional]
|
|
507
|
+
? T | undefined
|
|
508
|
+
: [Kind] extends [FieldKind.Identifier]
|
|
509
|
+
? DefaultsAreOptional extends true
|
|
510
|
+
? T | undefined
|
|
511
|
+
: T
|
|
512
|
+
: never;
|
|
513
|
+
|
|
417
514
|
/**
|
|
418
515
|
* Type of tree node for a field of the given schema.
|
|
419
516
|
* @public
|
|
@@ -426,16 +523,91 @@ export type TreeNodeFromImplicitAllowedTypes<
|
|
|
426
523
|
? NodeFromSchema<FlexListToUnion<TSchema>>
|
|
427
524
|
: unknown;
|
|
428
525
|
|
|
526
|
+
/**
|
|
527
|
+
* This type exists only to be linked from documentation to provide a single linkable place to document some details of
|
|
528
|
+
* "Input" types and how they handle schema.
|
|
529
|
+
*
|
|
530
|
+
* When a schema is used to describe data which is an input into an API, the API is [contravariant](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)) over the schema.
|
|
531
|
+
* (See also, [TypeScript Variance Annotations](https://www.typescriptlang.org/docs/handbook/2/generics.html#variance-annotations)).
|
|
532
|
+
*
|
|
533
|
+
* 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.
|
|
534
|
+
*
|
|
535
|
+
* Consider a field with schema type of `A | B` (where A and B are types of schema).
|
|
536
|
+
*
|
|
537
|
+
* - Reading the field behaves covariantly so {@link NodeFromSchema} of `<A | B>` is the same as `NodeFromSchema<A> | NodeFromSchema<B>`, indicating that either type of node can be read from the field.
|
|
538
|
+
* - Writing to the field behaves contravariantly. Since it is unknown if the node actually has a schema `A` or a schema `B`, the only legal values (known to be in schema regardless of which schema the underlying node has) are values which are legal for both `A & B`.
|
|
539
|
+
*
|
|
540
|
+
* Note that this is distinct from the case where the schema is `[A, B]`.
|
|
541
|
+
* In this case it is known that the field allows both A and B (the field can be set to an A or a B value).
|
|
542
|
+
* When `A | B` is used, the field might allow
|
|
543
|
+
* A but not B (so assigning a B value would be out of schema),
|
|
544
|
+
* B but not A (so assigning an A value would be out of schema)
|
|
545
|
+
* or both A and B.
|
|
546
|
+
*
|
|
547
|
+
* This gets more extreme when given completely unspecified schema.
|
|
548
|
+
* For example if a field is just provided {@link ImplicitFieldSchema}, nothing is known about the content of the field.
|
|
549
|
+
* This means that reading the field (via {@link TreeFieldFromImplicitField}) can give any valid tree field content,
|
|
550
|
+
* but there are no safe values which could be written to the field (since it is unknown what values would be out of schema) so {@link InsertableTreeFieldFromImplicitField} gives `never`.
|
|
551
|
+
*
|
|
552
|
+
* To implement this variance correctly, the computation of types for input and output have to use separate utilities
|
|
553
|
+
* which take very different approaches when encountering non-exact schema like unions or `ImplicitFieldSchema`.
|
|
554
|
+
* The utilities which behave contravariantly (as required to handle input correctly) link this documentation to indicate that this is how they behave.
|
|
555
|
+
*
|
|
556
|
+
* In addition to behaving contravariantly, these input type computation utilities often have further limitations.
|
|
557
|
+
* This is due to TypeScript making it difficult to implement this contravariance exactly.
|
|
558
|
+
* When faced with these implementation limitations these contravariant type computation utilities error on the side of producing overly strict requirements.
|
|
559
|
+
* For example in the above case of `A | B`, the utilities might compute an allowed insertable type as `never` even if there happens to be a common value accepted by both `A` and `B`.
|
|
560
|
+
* Future versions of the API can relax these requirements as the type computations are made more accurate.
|
|
561
|
+
*
|
|
562
|
+
* For a more concrete example: if {@link InsertableTreeFieldFromImplicitField} produced `never` for a schema `A | OptionalField<A>`,
|
|
563
|
+
* a future version could instead return a more flexible but still safe type, like `A`.
|
|
564
|
+
*
|
|
565
|
+
* More generally: try to avoid providing non-exact schema, especially for the fields of other schema.
|
|
566
|
+
* While these APIs attempt to handle such cases correctly, there are limitations and known bugs in this handling.
|
|
567
|
+
* Code using non-exact schema is much more likely to have its compilation break due to updates of this package or even TypeScript,
|
|
568
|
+
* and thus compilation breaks due to edge cases of non-exact schema handling, especially with recursive schema, are not considered breaking changes.
|
|
569
|
+
* This may change as the API become more stable.
|
|
570
|
+
*
|
|
571
|
+
* @privateRemarks
|
|
572
|
+
* There likely is a better way to share this documentation, but none was found at the time of writing.
|
|
573
|
+
*
|
|
574
|
+
* TODO: Once {@link InsertableField} is public, consider using it in the examples above.
|
|
575
|
+
* @system @public
|
|
576
|
+
*/
|
|
577
|
+
export type Input<T extends never> = T;
|
|
578
|
+
|
|
429
579
|
/**
|
|
430
580
|
* Type of content that can be inserted into the tree for a node of the given schema.
|
|
581
|
+
*
|
|
582
|
+
* @see {@link Input}
|
|
583
|
+
*
|
|
584
|
+
* @typeparam TSchema - Schema to process.
|
|
585
|
+
*
|
|
586
|
+
* @privateRemarks
|
|
587
|
+
* This is a bit overly conservative, since cases like `A | [A]` give never and could give `A`.
|
|
431
588
|
* @public
|
|
432
589
|
*/
|
|
433
|
-
export type InsertableTreeNodeFromImplicitAllowedTypes<
|
|
434
|
-
TSchema extends
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
590
|
+
export type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> =
|
|
591
|
+
[TSchema] extends [TreeNodeSchema]
|
|
592
|
+
? InsertableTypedNode<TSchema>
|
|
593
|
+
: [TSchema] extends [AllowedTypes]
|
|
594
|
+
? InsertableTreeNodeFromAllowedTypes<TSchema>
|
|
595
|
+
: never;
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Type of content that can be inserted into the tree for a node of the given schema.
|
|
599
|
+
*
|
|
600
|
+
* @see {@link Input}
|
|
601
|
+
*
|
|
602
|
+
* @typeparam TList - AllowedTypes to process
|
|
603
|
+
* @system @public
|
|
604
|
+
*/
|
|
605
|
+
export type InsertableTreeNodeFromAllowedTypes<TList extends AllowedTypes> =
|
|
606
|
+
TList extends readonly [
|
|
607
|
+
LazyItem<infer TSchema extends TreeNodeSchema>,
|
|
608
|
+
...infer Rest extends AllowedTypes,
|
|
609
|
+
]
|
|
610
|
+
? InsertableTypedNode<TSchema> | InsertableTreeNodeFromAllowedTypes<Rest>
|
|
439
611
|
: never;
|
|
440
612
|
|
|
441
613
|
/**
|
|
@@ -453,11 +625,31 @@ export type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<
|
|
|
453
625
|
/**
|
|
454
626
|
* Data which can be used as a node to be inserted.
|
|
455
627
|
* Either an unhydrated node, or content to build a new node.
|
|
628
|
+
*
|
|
629
|
+
* @see {@link Input}
|
|
630
|
+
*
|
|
631
|
+
* @typeparam TSchemaInput - Schema to process.
|
|
632
|
+
* @typeparam T - Do not specify: default value used as implementation detail.
|
|
633
|
+
* @privateRemarks
|
|
634
|
+
* This can't really be fully correct, since TreeNodeSchema's TNode is generally use covariantly but this code uses it contravariantly.
|
|
635
|
+
* That makes this TreeNodeSchema actually invariant with respect to TNode, but doing that would break all `extends TreeNodeSchema` clauses.
|
|
636
|
+
* As is, this works correctly in most realistic use-cases.
|
|
637
|
+
*
|
|
638
|
+
* One special case this makes is if the result of NodeFromSchema contains TreeNode, this must be an under constrained schema, so the result is set to never.
|
|
639
|
+
* Note that applying UnionToIntersection on the result of NodeFromSchema<T> does not work since it breaks booleans.
|
|
640
|
+
*
|
|
456
641
|
* @public
|
|
457
642
|
*/
|
|
458
|
-
export type InsertableTypedNode<
|
|
459
|
-
|
|
460
|
-
|
|
643
|
+
export type InsertableTypedNode<
|
|
644
|
+
TSchema extends TreeNodeSchema,
|
|
645
|
+
T = UnionToIntersection<TSchema>,
|
|
646
|
+
> =
|
|
647
|
+
| (T extends TreeNodeSchema<string, NodeKind, TreeNode | TreeLeafValue, never, true>
|
|
648
|
+
? NodeBuilderData<T>
|
|
649
|
+
: never)
|
|
650
|
+
| (T extends TreeNodeSchema
|
|
651
|
+
? Unhydrated<TreeNode extends NodeFromSchema<T> ? never : NodeFromSchema<T>>
|
|
652
|
+
: never);
|
|
461
653
|
|
|
462
654
|
/**
|
|
463
655
|
* Given a node's schema, return the corresponding object from which the node could be built.
|
|
@@ -471,7 +663,7 @@ export type InsertableTypedNode<T extends TreeNodeSchema> =
|
|
|
471
663
|
export type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<
|
|
472
664
|
string,
|
|
473
665
|
NodeKind,
|
|
474
|
-
|
|
666
|
+
TreeNode | TreeLeafValue,
|
|
475
667
|
infer TBuild
|
|
476
668
|
>
|
|
477
669
|
? TBuild
|
|
@@ -726,6 +726,7 @@ function tryGetInnerNode(target: unknown): InnerNode | undefined {
|
|
|
726
726
|
* Content which can be used to build a node.
|
|
727
727
|
* @remarks
|
|
728
728
|
* Can contain unhydrated nodes, but can not be an unhydrated node at the root.
|
|
729
|
+
* @system @alpha
|
|
729
730
|
*/
|
|
730
731
|
export type FactoryContent =
|
|
731
732
|
| IFluidHandle
|
|
@@ -744,12 +745,14 @@ export type FactoryContent =
|
|
|
744
745
|
* Can contain unhydrated nodes, but can not be an unhydrated node at the root.
|
|
745
746
|
*
|
|
746
747
|
* Supports object and map nodes.
|
|
748
|
+
* @system @alpha
|
|
747
749
|
*/
|
|
748
|
-
type FactoryContentObject = {
|
|
750
|
+
export type FactoryContentObject = {
|
|
749
751
|
readonly [P in string]?: InsertableContent;
|
|
750
752
|
};
|
|
751
753
|
|
|
752
754
|
/**
|
|
753
755
|
* Content which can be inserted into a tree.
|
|
756
|
+
* @system @alpha
|
|
754
757
|
*/
|
|
755
758
|
export type InsertableContent = Unhydrated<TreeNode> | FactoryContent;
|