diff --git a/.changeset/every-cases-enjoy.md b/.changeset/every-cases-enjoy.md new file mode 100644 index 000000000000..4e7abacca76e --- /dev/null +++ b/.changeset/every-cases-enjoy.md @@ -0,0 +1,8 @@ +--- +"fluid-framework": minor +"@fluidframework/tree": minor +"__section": tree +--- +Tree's enum schema utility are now beta + +The functions [singletonSchema](https://fluidframework.com/docs/api/tree/#singletonschema-function), [adaptEnum](https://fluidframework.com/docs/api/tree/#adaptenum-function) and [enumFromStrings](https://fluidframework.com/docs/api/tree/#enumfromstrings-function) are now `@beta` instead of `@alpha`. diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 50e9fce05e80..6993ca04d19b 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -4,7 +4,7 @@ ```ts -// @alpha +// @beta export function adaptEnum>(factory: SchemaFactory, members: TEnum): ((value: TValue) => TValue extends unknown ? TreeNode & { readonly value: TValue; } : never) & { readonly [Property in keyof TEnum]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { @@ -139,7 +139,7 @@ export function createSimpleTreeIndex { } -// @alpha +// @beta export function enumFromStrings(factory: SchemaFactory, members: Members): ((value: TValue) => TValue extends unknown ? TreeNode & { readonly value: TValue; } : never) & { [Index in Extract extends `${infer N extends number}` ? N : never as Members[Index]]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { @@ -620,7 +620,7 @@ export type Off = Off_2; // @alpha export function persistedToSimpleSchema(persisted: JsonCompatible, options: ICodecOptions): SimpleTreeSchema; -// @alpha @system +// @beta @system export type PopUnion void : never>> = AsOverloadedFunction extends (a: infer First) => void ? First : never; // @alpha @system @@ -897,7 +897,7 @@ export interface SimpleTreeSchema { readonly root: SimpleFieldSchema; } -// @alpha +// @beta export function singletonSchema(factory: SchemaFactory, name: TName): TreeNodeSchemaClass, NodeKind.Object, TreeNode & { readonly value: TName; }, Record, true, Record, undefined>; @@ -1491,7 +1491,7 @@ export type Unhydrated = T; // @public @system export type UnionToIntersection = (T extends T ? (k: T) => unknown : never) extends (k: infer U) => unknown ? U : never; -// @alpha +// @beta @system export type UnionToTuple> = IsUnion extends true ? UnionToTuple, [First, ...A]> : [Union, ...A]; // @alpha diff --git a/packages/dds/tree/api-report/tree.beta.api.md b/packages/dds/tree/api-report/tree.beta.api.md index 7534cd977477..152b24f02553 100644 --- a/packages/dds/tree/api-report/tree.beta.api.md +++ b/packages/dds/tree/api-report/tree.beta.api.md @@ -4,6 +4,17 @@ ```ts +// @beta +export function adaptEnum>(factory: SchemaFactory, members: TEnum): ((value: TValue) => TValue extends unknown ? TreeNode & { + readonly value: TValue; +} : never) & { readonly [Property in keyof TEnum]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: TEnum[Property]; + }, Record, true, Record, undefined>; } & { + readonly schema: UnionToTuple<{ readonly [Property in keyof TEnum]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: TEnum[Property]; + }, Record, true, Record, undefined>; }[keyof TEnum]>; +}; + // @public @system export type AllowedTypes = readonly LazyItem[]; @@ -36,6 +47,17 @@ export interface CommitMetadata { interface DefaultProvider extends ErasedType<"@fluidframework/tree.FieldProvider"> { } +// @beta +export function enumFromStrings(factory: SchemaFactory, members: Members): ((value: TValue) => TValue extends unknown ? TreeNode & { + readonly value: TValue; +} : never) & { [Index in Extract extends `${infer N extends number}` ? N : never as Members[Index]]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: Members[Index]; + }, Record, true, Record, undefined>; } & { + readonly schema: UnionToTuple extends `${infer N extends number}` ? N : never as Members[Index]]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: Members[Index]; + }, Record, true, Record, undefined>; }[Members[number]] : never>; +}; + // @public @system type ExtractItemType = Item extends () => infer Result ? Result : Item; @@ -242,6 +264,9 @@ export type ObjectFromSchemaRecord void : never>> = AsOverloadedFunction extends (a: infer First) => void ? First : never; + // @public @sealed @system export interface ReadonlyArrayNode extends ReadonlyArray, Awaited> { } @@ -377,6 +402,11 @@ export interface SimpleNodeSchemaBase; } +// @beta +export function singletonSchema(factory: SchemaFactory, name: TName): TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: TName; +}, Record, true, Record, undefined>; + // @public @system export namespace System_Unsafe { // @system @@ -641,6 +671,9 @@ export type Unhydrated = T; // @public @system export type UnionToIntersection = (T extends T ? (k: T) => unknown : never) extends (k: infer U) => unknown ? U : never; +// @beta @system +export type UnionToTuple> = IsUnion extends true ? UnionToTuple, [First, ...A]> : [Union, ...A]; + // @public export type ValidateRecursiveSchema> = true; diff --git a/packages/dds/tree/src/simple-tree/api/schemaCreationUtilities.ts b/packages/dds/tree/src/simple-tree/api/schemaCreationUtilities.ts index 52eda315d4d7..bc78ee571a32 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaCreationUtilities.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaCreationUtilities.ts @@ -32,7 +32,7 @@ import type { UnionToTuple } from "../../util/index.js"; * This is commonly used in unions when the only information needed is which kind of node the value is. * Enums are a common example of this pattern. * @see {@link adaptEnum} - * @alpha + * @beta */ // Return type is intentionally derived. // eslint-disable-next-line @typescript-eslint/explicit-function-return-type @@ -107,7 +107,7 @@ export function singletonSchema = (T extends T ? (k: T) => unknown : never) e * * @typeparam Union - The union to convert. * @typeparam AsOverloadedFunction - Implementation detail: do not specify. - * @system @alpha + * @system @beta */ export type PopUnion< Union, @@ -189,7 +189,7 @@ export type PopUnion< * * https://www.hacklewayne.com/typescript-convert-union-to-tuple-array-yes-but-how and https://catchts.com/union-array both explain the general approach this uses pretty well. * This implementation is inspired to those, but slightly different in implementation. - * @alpha + * @system @beta */ export type UnionToTuple< Union, diff --git a/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md b/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md index 29e0e67378a4..d993609c39be 100644 --- a/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md +++ b/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md @@ -4,7 +4,7 @@ ```ts -// @alpha +// @beta export function adaptEnum>(factory: SchemaFactory, members: TEnum): ((value: TValue) => TValue extends unknown ? TreeNode & { readonly value: TValue; } : never) & { readonly [Property in keyof TEnum]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { @@ -177,7 +177,7 @@ export function createSimpleTreeIndex { } -// @alpha +// @beta export function enumFromStrings(factory: SchemaFactory, members: Members): ((value: TValue) => TValue extends unknown ? TreeNode & { readonly value: TValue; } : never) & { [Index in Extract extends `${infer N extends number}` ? N : never as Members[Index]]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { @@ -975,7 +975,7 @@ export function onAssertionFailure(handler: (error: Error) => void): () => void; // @alpha export function persistedToSimpleSchema(persisted: JsonCompatible, options: ICodecOptions): SimpleTreeSchema; -// @alpha @system +// @beta @system export type PopUnion void : never>> = AsOverloadedFunction extends (a: infer First) => void ? First : never; // @alpha @system @@ -1265,7 +1265,7 @@ export interface SimpleTreeSchema { readonly root: SimpleFieldSchema; } -// @alpha +// @beta export function singletonSchema(factory: SchemaFactory, name: TName): TreeNodeSchemaClass, NodeKind.Object, TreeNode & { readonly value: TName; }, Record, true, Record, undefined>; @@ -1873,7 +1873,7 @@ export type Unhydrated = T; // @public @system export type UnionToIntersection = (T extends T ? (k: T) => unknown : never) extends (k: infer U) => unknown ? U : never; -// @alpha +// @beta @system export type UnionToTuple> = IsUnion extends true ? UnionToTuple, [First, ...A]> : [Union, ...A]; // @alpha diff --git a/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md b/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md index f4d6637ffabb..2cbf52c6070d 100644 --- a/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md +++ b/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md @@ -4,6 +4,17 @@ ```ts +// @beta +export function adaptEnum>(factory: SchemaFactory, members: TEnum): ((value: TValue) => TValue extends unknown ? TreeNode & { + readonly value: TValue; +} : never) & { readonly [Property in keyof TEnum]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: TEnum[Property]; + }, Record, true, Record, undefined>; } & { + readonly schema: UnionToTuple<{ readonly [Property in keyof TEnum]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: TEnum[Property]; + }, Record, true, Record, undefined>; }[keyof TEnum]>; +}; + // @public @system export type AllowedTypes = readonly LazyItem[]; @@ -71,6 +82,17 @@ export interface ContainerSchema { interface DefaultProvider extends ErasedType<"@fluidframework/tree.FieldProvider"> { } +// @beta +export function enumFromStrings(factory: SchemaFactory, members: Members): ((value: TValue) => TValue extends unknown ? TreeNode & { + readonly value: TValue; +} : never) & { [Index in Extract extends `${infer N extends number}` ? N : never as Members[Index]]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: Members[Index]; + }, Record, true, Record, undefined>; } & { + readonly schema: UnionToTuple extends `${infer N extends number}` ? N : never as Members[Index]]: TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: Members[Index]; + }, Record, true, Record, undefined>; }[Members[number]] : never>; +}; + // @public @sealed export abstract class ErasedType { static [Symbol.hasInstance](value: never): value is never; @@ -591,6 +613,9 @@ export type ObjectFromSchemaRecord void; +// @beta @system +export type PopUnion void : never>> = AsOverloadedFunction extends (a: infer First) => void ? First : never; + // @public @sealed @system export interface ReadonlyArrayNode extends ReadonlyArray, Awaited> { } @@ -739,6 +764,11 @@ export interface SimpleNodeSchemaBase; } +// @beta +export function singletonSchema(factory: SchemaFactory, name: TName): TreeNodeSchemaClass, NodeKind.Object, TreeNode & { + readonly value: TName; +}, Record, true, Record, undefined>; + // @public @system export namespace System_Unsafe { // @system @@ -1017,6 +1047,9 @@ export type Unhydrated = T; // @public @system export type UnionToIntersection = (T extends T ? (k: T) => unknown : never) extends (k: infer U) => unknown ? U : never; +// @beta @system +export type UnionToTuple> = IsUnion extends true ? UnionToTuple, [First, ...A]> : [Union, ...A]; + // @public export type ValidateRecursiveSchema> = true;