diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index e22fb75da886..d512f1598436 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -274,6 +274,8 @@ export class FieldSchemaAlpha; // (undocumented) get persistedMetadata(): JsonCompatibleReadOnlyObject | undefined; + // (undocumented) + get simpleAllowedTypes(): ReadonlyMap; } // @alpha @sealed @system @@ -1004,17 +1006,22 @@ export type SharedTreeOptions = Partial & Partial extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed export interface SimpleFieldSchema { - readonly allowedTypesIdentifiers: ReadonlySet; readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1024,7 +1031,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1053,7 +1060,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha diff --git a/packages/dds/tree/src/index.ts b/packages/dds/tree/src/index.ts index 6c29f006f5be..95adf131fec3 100644 --- a/packages/dds/tree/src/index.ts +++ b/packages/dds/tree/src/index.ts @@ -280,6 +280,7 @@ export { type TreeParsingOptions, type SchemaFactory_base, type NumberKeys, + type SimpleAllowedTypeAttributes, } from "./simple-tree/index.js"; export { SharedTree, diff --git a/packages/dds/tree/src/shared-tree/sharedTree.ts b/packages/dds/tree/src/shared-tree/sharedTree.ts index 07f70a37e3bc..3e14a3434b9e 100644 --- a/packages/dds/tree/src/shared-tree/sharedTree.ts +++ b/packages/dds/tree/src/shared-tree/sharedTree.ts @@ -42,6 +42,7 @@ import { type TreeStoredSchema, TreeStoredSchemaRepository, type TreeStoredSchemaSubscription, + type TreeTypeSet, getCodecTreeForDetachedFieldIndexFormat, makeDetachedFieldIndex, moveToDetachedField, @@ -98,6 +99,7 @@ import { FieldKind, type ITreeAlpha, type SimpleObjectFieldSchema, + type SimpleAllowedTypeAttributes, } from "../simple-tree/index.js"; import { SchematizingSimpleTreeView } from "./schematizingTreeView.js"; @@ -952,6 +954,24 @@ export const defaultSharedTreeOptions: Required = { shouldEncodeIncrementally: defaultIncrementalEncodingPolicy, }; +/** + * Build the allowed types for a Stored Schema. + * + * @remarks Staged upgrades do not apply to stored schemas, so we omit the {@link SimpleAllowedTypeAttributes.isStaged | staging flag } when building {@link SimpleAllowedTypeAttributes}. + * @param types - The types to create allowed types for. + * @returns The allowed types. + */ +function buildSimpleAllowedTypeAttributesForStoredSchema( + types: TreeTypeSet, +): ReadonlyMap { + const allowedTypesInfo = new Map(); + for (const type of types) { + // Stored schemas do not have staged upgrades + allowedTypesInfo.set(type, { isStaged: undefined }); + } + return allowedTypesInfo; +} + function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFieldSchema { let kind: FieldKind; switch (schema.kind) { @@ -973,7 +993,7 @@ function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFie } return { kind, - allowedTypesIdentifiers: schema.types, + simpleAllowedTypes: buildSimpleAllowedTypeAttributesForStoredSchema(schema.types), metadata: {}, persistedMetadata: schema.persistedMetadata, }; @@ -989,7 +1009,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS if (arrayTypes !== undefined) { return { kind: NodeKind.Array, - allowedTypesIdentifiers: arrayTypes, + simpleAllowedTypes: buildSimpleAllowedTypeAttributesForStoredSchema(arrayTypes), metadata: {}, persistedMetadata: schema.metadata, }; @@ -1008,7 +1028,9 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS ); return { kind: NodeKind.Map, - allowedTypesIdentifiers: schema.mapFields.types, + simpleAllowedTypes: buildSimpleAllowedTypeAttributesForStoredSchema( + schema.mapFields.types, + ), metadata: {}, persistedMetadata: schema.metadata, }; diff --git a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts index dd3ece77442b..0fe717923caa 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts @@ -13,6 +13,7 @@ import { type FieldProps, } from "../fieldSchema.js"; import type { + SimpleAllowedTypeAttributes, SimpleFieldSchema, SimpleNodeSchema, SimpleTreeSchema, @@ -65,7 +66,7 @@ function generateFieldSchema( context: Context, storedKey: string | undefined, ): FieldSchemaAlpha { - const allowed = generateAllowedTypes(simple.allowedTypesIdentifiers, context); + const allowed = generateAllowedTypes(simple.simpleAllowedTypes, context); const props: Omit = { metadata: simple.metadata, key: storedKey, @@ -84,8 +85,14 @@ function generateFieldSchema( } } -function generateAllowedTypes(allowed: ReadonlySet, context: Context): AllowedTypes { - return [...allowed].map((id) => context.get(id) ?? fail(0xb5a /* Missing schema */)); +function generateAllowedTypes( + allowed: ReadonlyMap, + context: Context, +): AllowedTypes { + return Array.from( + allowed.keys(), + (id) => context.get(id) ?? fail(0xb5a /* Missing schema */), + ); } function generateNode( @@ -104,21 +111,17 @@ function generateNode( return factory.objectAlpha(id, fields, { metadata: schema.metadata }); } case NodeKind.Array: - return factory.arrayAlpha( - id, - generateAllowedTypes(schema.allowedTypesIdentifiers, context), - { metadata: schema.metadata }, - ); + return factory.arrayAlpha(id, generateAllowedTypes(schema.simpleAllowedTypes, context), { + metadata: schema.metadata, + }); case NodeKind.Map: - return factory.mapAlpha( - id, - generateAllowedTypes(schema.allowedTypesIdentifiers, context), - { metadata: schema.metadata }, - ); + return factory.mapAlpha(id, generateAllowedTypes(schema.simpleAllowedTypes, context), { + metadata: schema.metadata, + }); case NodeKind.Record: return factory.recordAlpha( id, - generateAllowedTypes(schema.allowedTypesIdentifiers, context), + generateAllowedTypes(schema.simpleAllowedTypes, context), { metadata: schema.metadata }, ); case NodeKind.Leaf: diff --git a/packages/dds/tree/src/simple-tree/api/simpleSchemaToJsonSchema.ts b/packages/dds/tree/src/simple-tree/api/simpleSchemaToJsonSchema.ts index 4fd51b0c393d..4d9ac6b8a422 100644 --- a/packages/dds/tree/src/simple-tree/api/simpleSchemaToJsonSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/simpleSchemaToJsonSchema.ts @@ -107,7 +107,10 @@ function convertNodeSchema( function convertArrayNodeSchema(schema: SimpleArrayNodeSchema): JsonArrayNodeSchema { const allowedTypes: JsonSchemaRef[] = []; - schema.allowedTypesIdentifiers.forEach((type) => { + const allowedTypesIdentifiers: ReadonlySet = new Set( + schema.simpleAllowedTypes.keys(), + ); + allowedTypesIdentifiers.forEach((type) => { allowedTypes.push(createSchemaRef(type)); }); @@ -206,7 +209,10 @@ function convertRecordLikeNodeSchema( schema: SimpleRecordNodeSchema | SimpleMapNodeSchema, ): JsonMapNodeSchema | JsonRecordNodeSchema { const allowedTypes: JsonSchemaRef[] = []; - schema.allowedTypesIdentifiers.forEach((type) => { + const allowedTypesIdentifiers: ReadonlySet = new Set( + schema.simpleAllowedTypes.keys(), + ); + allowedTypesIdentifiers.forEach((type) => { allowedTypes.push(createSchemaRef(type)); }); diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index b0e25b1dbea4..735fedc9ec37 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -6,6 +6,7 @@ import { assert, unreachableCase } from "@fluidframework/core-utils/internal"; import { normalizeFieldSchema, type ImplicitFieldSchema } from "../fieldSchema.js"; import type { + SimpleAllowedTypeAttributes, SimpleArrayNodeSchema, SimpleFieldSchema, SimpleLeafNodeSchema, @@ -31,6 +32,7 @@ import { LeafNodeSchema } from "../leafNodeSchema.js"; * * @param schema - The schema to convert * @param copySchemaObjects - If true, TreeNodeSchema and FieldSchema are copied into plain JavaScript objects. Either way, custom metadata is referenced and not copied. + * @param isViewSchema - If true (default), properties used by view schema but not part of stored schema (for example, `isStaged` on allowed types) are preserved in the output. * * @remarks * Given that the Schema types used in {@link ImplicitFieldSchema} already implement the {@link SimpleNodeSchema} interfaces, there are limited use-cases for this function. @@ -45,6 +47,7 @@ import { LeafNodeSchema } from "../leafNodeSchema.js"; export function toSimpleTreeSchema( schema: ImplicitFieldSchema, copySchemaObjects: boolean, + isViewSchema: boolean = true, ): SimpleTreeSchema { const normalizedSchema = normalizeFieldSchema(schema); const definitions = new Map(); @@ -59,7 +62,9 @@ export function toSimpleTreeSchema( nodeSchema instanceof RecordNodeSchema, 0xb60 /* Invalid schema */, ); - const outSchema = copySchemaObjects ? copySimpleNodeSchema(nodeSchema) : nodeSchema; + const outSchema = copySchemaObjects + ? copySimpleNodeSchema(nodeSchema, isViewSchema) + : nodeSchema; definitions.set(nodeSchema.identifier, outSchema); }, }); @@ -67,7 +72,10 @@ export function toSimpleTreeSchema( return { root: copySchemaObjects ? ({ - allowedTypesIdentifiers: normalizedSchema.allowedTypesIdentifiers, + simpleAllowedTypes: normalizeSimpleAllowedTypes( + normalizedSchema.simpleAllowedTypes, + isViewSchema, + ), kind: normalizedSchema.kind, metadata: normalizedSchema.metadata, persistedMetadata: normalizedSchema.persistedMetadata, @@ -77,12 +85,36 @@ export function toSimpleTreeSchema( }; } +/** + * Normalizes the {@link SimpleAllowedTypeAttributes} by either preserving or omitting view-specific schema properties. + * @param simpleAllowedTypes - The simple allowed types to normalize. + * @param isViewSchema - If true, properties used by view schema but not part of stored schema (for example, `isStaged` on allowed types) are preserved in the output. + * @returns The normalized simple allowed types. + */ +function normalizeSimpleAllowedTypes( + simpleAllowedTypes: ReadonlyMap, + isViewSchema: boolean, +): ReadonlyMap { + if (isViewSchema) { + return simpleAllowedTypes; + } else { + const normalized = new Map(); + for (const [identifier, attributes] of simpleAllowedTypes.entries()) { + normalized.set(identifier, { ...attributes, isStaged: undefined }); + } + return normalized; + } +} + /** * Copies a {@link SimpleNodeSchema} into a new plain JavaScript object. * * @remarks Caches the result on the input schema for future calls. */ -function copySimpleNodeSchema(schema: SimpleNodeSchema): SimpleNodeSchema { +function copySimpleNodeSchema( + schema: SimpleNodeSchema, + isViewSchema: boolean, +): SimpleNodeSchema { const kind = schema.kind; switch (kind) { case NodeKind.Leaf: @@ -90,9 +122,9 @@ function copySimpleNodeSchema(schema: SimpleNodeSchema): SimpleNodeSchema { case NodeKind.Array: case NodeKind.Map: case NodeKind.Record: - return copySimpleSchemaWithAllowedTypes(schema); + return copySimpleSchemaWithAllowedTypes(schema, isViewSchema); case NodeKind.Object: - return copySimpleObjectSchema(schema); + return copySimpleObjectSchema(schema, isViewSchema); default: unreachableCase(kind); } @@ -109,22 +141,26 @@ function copySimpleLeafSchema(schema: SimpleLeafNodeSchema): SimpleLeafNodeSchem function copySimpleSchemaWithAllowedTypes( schema: SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema, + isViewSchema: boolean, ): SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema { return { kind: schema.kind, - allowedTypesIdentifiers: schema.allowedTypesIdentifiers, + simpleAllowedTypes: normalizeSimpleAllowedTypes(schema.simpleAllowedTypes, isViewSchema), metadata: schema.metadata, persistedMetadata: schema.persistedMetadata, }; } -function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): SimpleObjectNodeSchema { +function copySimpleObjectSchema( + schema: SimpleObjectNodeSchema, + isViewSchema: boolean, +): SimpleObjectNodeSchema { const fields: Map = new Map(); for (const [propertyKey, field] of schema.fields) { // field already is a SimpleObjectFieldSchema, but copy the subset of the properties needed by this interface to get a clean simple object. fields.set(propertyKey, { kind: field.kind, - allowedTypesIdentifiers: field.allowedTypesIdentifiers, + simpleAllowedTypes: normalizeSimpleAllowedTypes(field.simpleAllowedTypes, isViewSchema), metadata: field.metadata, persistedMetadata: field.persistedMetadata, storedKey: field.storedKey, diff --git a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts index 0082d509ae1b..b9497d4c1e37 100644 --- a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts +++ b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts @@ -25,6 +25,7 @@ import { type TreeNodeSchema, } from "./treeNodeSchema.js"; import { schemaAsTreeNodeValid } from "./treeNodeValid.js"; +import type { SimpleAllowedTypeAttributes } from "../simpleSchema.js"; /** * Schema for types allowed in some location in a tree (like a field, map entry or array). @@ -252,6 +253,21 @@ export class AnnotatedAllowedTypesInternal< return this.lazyEvaluate.value.identifiers; } + /** + * Get the {@link SimpleAllowedTypeAttributes} version of the allowed types set. + */ + public static evaluateSimpleAllowedTypes( + annotatedAllowedTypes: AnnotatedAllowedTypes, + ): ReadonlyMap { + const simpleAllowedTypes = new Map(); + for (const type of annotatedAllowedTypes.evaluate().types) { + simpleAllowedTypes.set(type.type.identifier, { + isStaged: type.metadata.stagedSchemaUpgrade !== undefined, + }); + } + return simpleAllowedTypes; + } + public static override [Symbol.hasInstance]( this: TThis, value: unknown, diff --git a/packages/dds/tree/src/simple-tree/fieldSchema.ts b/packages/dds/tree/src/simple-tree/fieldSchema.ts index 668ea5abc30f..994855450f85 100644 --- a/packages/dds/tree/src/simple-tree/fieldSchema.ts +++ b/packages/dds/tree/src/simple-tree/fieldSchema.ts @@ -31,7 +31,7 @@ import type { } from "./core/index.js"; import { normalizeAllowedTypes } from "./core/index.js"; -import type { SimpleFieldSchema } from "./simpleSchema.js"; +import type { SimpleAllowedTypeAttributes, SimpleFieldSchema } from "./simpleSchema.js"; import type { UnsafeUnknownSchema } from "./unsafeUnknownSchema.js"; import type { InsertableContent } from "./unhydratedFlexTreeFromInsertable.js"; @@ -412,6 +412,19 @@ export class FieldSchemaAlpha< return this.allowedTypesFull.evaluateIdentifiers(); } + public get simpleAllowedTypes(): ReadonlyMap { + const types = this.allowedTypesFull.evaluate().types; + const info = new Map(); + + for (const type of types) { + info.set(type.type.identifier, { + isStaged: type.metadata.stagedSchemaUpgrade !== undefined, + }); + } + + return info; + } + protected constructor( kind: Kind, types: Types, diff --git a/packages/dds/tree/src/simple-tree/index.ts b/packages/dds/tree/src/simple-tree/index.ts index 84a10c04700a..5c23b174daa6 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -198,6 +198,7 @@ export type { SimpleNodeSchemaBaseAlpha, SimpleObjectFieldSchema, SimpleRecordNodeSchema, + SimpleAllowedTypeAttributes, } from "./simpleSchema.js"; export { type ImplicitFieldSchema, diff --git a/packages/dds/tree/src/simple-tree/node-kinds/array/arrayNode.ts b/packages/dds/tree/src/simple-tree/node-kinds/array/arrayNode.ts index efd9e393706d..d01219ee6482 100644 --- a/packages/dds/tree/src/simple-tree/node-kinds/array/arrayNode.ts +++ b/packages/dds/tree/src/simple-tree/node-kinds/array/arrayNode.ts @@ -47,6 +47,7 @@ import { type TreeNodeSchemaPrivateData, convertAllowedTypes, withBufferedTreeEvents, + AnnotatedAllowedTypesInternal, } from "../../core/index.js"; import { type FactoryContent, @@ -68,6 +69,7 @@ import type { import { brand, type JsonCompatibleReadOnlyObject } from "../../../util/index.js"; import { nullSchema } from "../../leafNodeSchema.js"; import { arrayNodeStoredSchema } from "../../toStoredSchema.js"; +import type { SimpleAllowedTypeAttributes } from "../../simpleSchema.js"; /** * A covariant base type for {@link (TreeArrayNode:interface)}. @@ -1168,6 +1170,9 @@ export function arraySchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); + const lazySimpleAllowedTypes = new Lazy(() => { + return AnnotatedAllowedTypesInternal.evaluateSimpleAllowedTypes(normalizedTypes); + }); let privateData: TreeNodeSchemaPrivateData | undefined; @@ -1206,6 +1211,10 @@ export function arraySchema< return lazyAllowedTypesIdentifiers.value; } + public static get simpleAllowedTypes(): ReadonlyMap { + return lazySimpleAllowedTypes.value; + } + protected static override constructorCached: MostDerivedData | undefined = undefined; protected static override oneTimeSetup(): TreeNodeSchemaInitializedData { diff --git a/packages/dds/tree/src/simple-tree/node-kinds/map/mapNode.ts b/packages/dds/tree/src/simple-tree/node-kinds/map/mapNode.ts index 1b0da986f8f7..f05501dad65e 100644 --- a/packages/dds/tree/src/simple-tree/node-kinds/map/mapNode.ts +++ b/packages/dds/tree/src/simple-tree/node-kinds/map/mapNode.ts @@ -43,6 +43,7 @@ import { type FlexContent, type TreeNodeSchemaPrivateData, convertAllowedTypes, + AnnotatedAllowedTypesInternal, } from "../../core/index.js"; import { unhydratedFlexTreeFromInsertable, @@ -66,6 +67,7 @@ import type { import { recordLikeDataToFlexContent } from "../common.js"; import { MapNodeStoredSchema } from "../../../core/index.js"; import type { NodeSchemaOptionsAlpha } from "../../api/index.js"; +import type { SimpleAllowedTypeAttributes } from "../../simpleSchema.js"; /** * A map of string keys to tree objects. @@ -275,6 +277,9 @@ export function mapSchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); + const lazySimpleAllowedTypes = new Lazy(() => { + return AnnotatedAllowedTypesInternal.evaluateSimpleAllowedTypes(normalizedTypes); + }); let privateData: TreeNodeSchemaPrivateData | undefined; const persistedMetadata = nodeOptions.persistedMetadata; @@ -303,6 +308,10 @@ export function mapSchema< return lazyAllowedTypesIdentifiers.value; } + public static get simpleAllowedTypes(): ReadonlyMap { + return lazySimpleAllowedTypes.value; + } + protected static override constructorCached: MostDerivedData | undefined = undefined; protected static override oneTimeSetup(): TreeNodeSchemaInitializedData { diff --git a/packages/dds/tree/src/simple-tree/node-kinds/record/recordNode.ts b/packages/dds/tree/src/simple-tree/node-kinds/record/recordNode.ts index 19e63e7c145a..3ce793d0ad6a 100644 --- a/packages/dds/tree/src/simple-tree/node-kinds/record/recordNode.ts +++ b/packages/dds/tree/src/simple-tree/node-kinds/record/recordNode.ts @@ -32,6 +32,7 @@ import { CompatibilityLevel, type TreeNodeSchemaPrivateData, convertAllowedTypes, + AnnotatedAllowedTypesInternal, } from "../../core/index.js"; import { getTreeNodeSchemaInitializedData } from "../../createContext.js"; import { tryGetTreeNodeForField } from "../../getTreeNodeForField.js"; @@ -58,6 +59,7 @@ import { prepareForInsertion } from "../../prepareForInsertion.js"; import { recordLikeDataToFlexContent } from "../common.js"; import { MapNodeStoredSchema } from "../../../core/index.js"; import type { NodeSchemaOptionsAlpha } from "../../api/index.js"; +import type { SimpleAllowedTypeAttributes } from "../../simpleSchema.js"; /** * Create a proxy which implements the {@link TreeRecordNode} API. @@ -258,6 +260,9 @@ export function recordSchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); + const lazySimpleAllowedTypes = new Lazy(() => { + return AnnotatedAllowedTypesInternal.evaluateSimpleAllowedTypes(normalizedTypes); + }); let privateData: TreeNodeSchemaPrivateData | undefined; @@ -347,6 +352,10 @@ export function recordSchema< return lazyAllowedTypesIdentifiers.value; } + public static get simpleAllowedTypes(): ReadonlyMap { + return lazySimpleAllowedTypes.value; + } + protected static override constructorCached: MostDerivedData | undefined = undefined; public static readonly identifier = identifier; diff --git a/packages/dds/tree/src/simple-tree/simpleSchema.ts b/packages/dds/tree/src/simple-tree/simpleSchema.ts index 11f186e55507..9d9d41bc30be 100644 --- a/packages/dds/tree/src/simple-tree/simpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/simpleSchema.ts @@ -91,7 +91,7 @@ export interface SimpleArrayNodeSchema * @remarks Refers to the types by identifier. * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -108,7 +108,7 @@ export interface SimpleMapNodeSchema * @remarks Refers to the types by identifier. * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -125,7 +125,7 @@ export interface SimpleRecordNodeSchema * @remarks Refers to the types by identifier. * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -162,6 +162,23 @@ export type SimpleNodeSchema = | SimpleObjectNodeSchema | SimpleRecordNodeSchema; +/** + * Information about allowed types. + * + * @alpha + * @sealed + */ +export interface SimpleAllowedTypeAttributes { + /** + * True if this schema is included as a {@link SchemaStaticsAlpha.staged | staged} schema upgrade, + * allowing the view schema be compatible with stored schema with (post upgrade) or without it (pre-upgrade). + * New documents and schema upgrades will omit any staged schema. + * + * Undefined if derived from a stored schema. + */ + readonly isStaged: boolean | undefined; +} + /** * A simple, shallow representation of a schema for a field. * @@ -179,12 +196,12 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; /** - * The types allowed under the field. + * Information about the allowed types under this field. * * @remarks Refers to the types by identifier. * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; /** * {@inheritDoc FieldSchemaMetadata} diff --git a/packages/dds/tree/src/simple-tree/toStoredSchema.ts b/packages/dds/tree/src/simple-tree/toStoredSchema.ts index 1939435f18e7..ea785e776ff8 100644 --- a/packages/dds/tree/src/simple-tree/toStoredSchema.ts +++ b/packages/dds/tree/src/simple-tree/toStoredSchema.ts @@ -139,7 +139,10 @@ export function convertField( if (schema instanceof FieldSchemaAlpha) { types = convertAllowedTypes(schema.allowedTypes, options); } else { - types = schema.allowedTypesIdentifiers as TreeTypeSet; + const allowedTypesIdentifiers: ReadonlySet = new Set( + schema.simpleAllowedTypes.keys(), + ); + types = allowedTypesIdentifiers as TreeTypeSet; } return { kind, types, persistedMetadata: schema.persistedMetadata }; } @@ -175,7 +178,10 @@ export function getStoredSchema( } case NodeKind.Map: case NodeKind.Record: { - const types = schema.allowedTypesIdentifiers as TreeTypeSet; + const allowedTypesIdentifiers: ReadonlySet = new Set( + schema.simpleAllowedTypes.keys(), + ); + const types = allowedTypesIdentifiers as TreeTypeSet; return new MapNodeStoredSchema( { kind: FieldKinds.optional.identifier, @@ -187,7 +193,10 @@ export function getStoredSchema( ); } case NodeKind.Array: { - const types = schema.allowedTypesIdentifiers as TreeTypeSet; + const allowedTypesIdentifiers: ReadonlySet = new Set( + schema.simpleAllowedTypes.keys(), + ); + const types = allowedTypesIdentifiers as TreeTypeSet; return arrayNodeStoredSchema(types, schema.persistedMetadata); } case NodeKind.Object: { diff --git a/packages/dds/tree/src/test/shared-tree/sharedTree.spec.ts b/packages/dds/tree/src/test/shared-tree/sharedTree.spec.ts index d1f18693071c..3add685e39d3 100644 --- a/packages/dds/tree/src/test/shared-tree/sharedTree.spec.ts +++ b/packages/dds/tree/src/test/shared-tree/sharedTree.spec.ts @@ -2499,7 +2499,14 @@ describe("SharedTree", () => { view.initialize(10); assert.deepEqual(tree.exportVerbose(), 10); - assert.deepEqual(tree.exportSimpleSchema(), toSimpleTreeSchema(numberSchema, true)); + assert.deepEqual( + tree.exportSimpleSchema(), + toSimpleTreeSchema( + numberSchema, + true, + false /* Don't process this schema as a view schema (exclude isStaged from simpleAllowedTypes). */, + ), + ); }); it("supports multiple shared branches", () => { diff --git a/packages/dds/tree/src/test/simple-tree/api/getSimpleSchema.spec.ts b/packages/dds/tree/src/test/simple-tree/api/getSimpleSchema.spec.ts index ffc1dd055cd3..0ae5c6503800 100644 --- a/packages/dds/tree/src/test/simple-tree/api/getSimpleSchema.spec.ts +++ b/packages/dds/tree/src/test/simple-tree/api/getSimpleSchema.spec.ts @@ -63,7 +63,7 @@ describe("getSimpleSchema", () => { root: { kind: FieldKind.Optional, metadata: { description: "An optional string." }, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + simpleAllowedTypes: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), persistedMetadata: undefined, }, definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), @@ -80,7 +80,7 @@ describe("getSimpleSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + simpleAllowedTypes: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), persistedMetadata: undefined, }, definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), @@ -98,9 +98,9 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], ]), }, definitions: new Map([ @@ -122,14 +122,16 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.array"]), + simpleAllowedTypes: new Map([["test.array", { isStaged: false }]]), }, definitions: new Map([ [ "test.array", { kind: NodeKind.Array, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), metadata: {}, persistedMetadata: undefined, }, @@ -150,7 +152,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.map"]), + simpleAllowedTypes: new Map([["test.map", { isStaged: false }]]), }, definitions: new Map([ [ @@ -159,7 +161,9 @@ describe("getSimpleSchema", () => { kind: NodeKind.Map, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, ], ["com.fluidframework.leaf.string", simpleString], @@ -178,7 +182,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.record"]), + simpleAllowedTypes: new Map([["test.record", { isStaged: false }]]), }, definitions: new Map([ [ @@ -187,7 +191,9 @@ describe("getSimpleSchema", () => { kind: NodeKind.Record, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, ], ["com.fluidframework.leaf.string", simpleString], @@ -210,7 +216,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), + simpleAllowedTypes: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -226,7 +232,9 @@ describe("getSimpleSchema", () => { kind: FieldKind.Optional, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ]), storedKey: "foo", }, ], @@ -236,7 +244,9 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "bar", }, ], @@ -263,7 +273,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), + simpleAllowedTypes: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -279,7 +289,9 @@ describe("getSimpleSchema", () => { kind: FieldKind.Identifier, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "id", }, ], @@ -306,7 +318,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), + simpleAllowedTypes: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -322,9 +334,9 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], ]), storedKey: "foo", }, @@ -352,7 +364,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.recursive-object"]), + simpleAllowedTypes: new Map([["test.recursive-object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -368,9 +380,9 @@ describe("getSimpleSchema", () => { kind: FieldKind.Optional, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.string", - "test.recursive-object", + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ["test.recursive-object", { isStaged: false }], ]), storedKey: "foo", }, diff --git a/packages/dds/tree/src/test/simple-tree/api/simpleSchemaToJsonSchema.spec.ts b/packages/dds/tree/src/test/simple-tree/api/simpleSchemaToJsonSchema.spec.ts index 0083bd9ad5fc..6bb4a8ccb03a 100644 --- a/packages/dds/tree/src/test/simple-tree/api/simpleSchemaToJsonSchema.spec.ts +++ b/packages/dds/tree/src/test/simple-tree/api/simpleSchemaToJsonSchema.spec.ts @@ -21,6 +21,7 @@ import { } from "../../../simple-tree/index.js"; import { getJsonValidator } from "./jsonSchemaUtilities.js"; import type { + SimpleAllowedTypeAttributes, SimpleNodeSchema, SimpleTreeSchema, // eslint-disable-next-line import/no-internal-modules @@ -49,7 +50,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, definitions: new Map([ [stringSchema.identifier, stringSchema], @@ -85,7 +88,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.handle"]), + simpleAllowedTypes: new Map([ + ["test.handle", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -107,7 +112,9 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set(["test.array"]), + simpleAllowedTypes: new Map([ + ["test.array", { isStaged: false }], + ]), metadata: {}, }, definitions: new Map([ @@ -117,7 +124,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Array, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, ], [stringSchema.identifier, stringSchema], @@ -160,7 +169,9 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set(["test.map"]), + simpleAllowedTypes: new Map([ + ["test.map", { isStaged: false }], + ]), metadata: {}, }, definitions: new Map([ @@ -170,7 +181,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Map, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, ], [stringSchema.identifier, stringSchema], @@ -225,7 +238,9 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set(["test.record"]), + simpleAllowedTypes: new Map([ + ["test.record", { isStaged: false }], + ]), metadata: {}, }, definitions: new Map([ @@ -235,7 +250,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Record, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, ], [stringSchema.identifier, stringSchema], @@ -337,7 +354,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.object"]), + simpleAllowedTypes: new Map([ + ["test.object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -351,7 +370,9 @@ describe("simpleSchemaToJsonSchema", () => { "foo", { kind: FieldKind.Optional, - allowedTypesIdentifiers: new Set([numberSchema.identifier]), + simpleAllowedTypes: new Map([ + [numberSchema.identifier, { isStaged: false }], + ]), metadata: { description: "A number representing the concept of Foo." }, persistedMetadata: undefined, storedKey: "foo", @@ -361,7 +382,9 @@ describe("simpleSchemaToJsonSchema", () => { "bar", { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), metadata: { description: "A string representing the concept of Bar." }, persistedMetadata: undefined, storedKey: "bar", @@ -371,7 +394,9 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), metadata: { description: "Unique identifier for the test object.", }, @@ -474,7 +499,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.object"]), + simpleAllowedTypes: new Map([ + ["test.object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -488,7 +515,9 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), storedKey: "id", metadata: {}, }, @@ -530,7 +559,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.object"]), + simpleAllowedTypes: new Map([ + ["test.object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -546,9 +577,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - numberSchema.identifier, - stringSchema.identifier, + simpleAllowedTypes: new Map([ + [numberSchema.identifier, { isStaged: false }], + [stringSchema.identifier, { isStaged: false }], ]), storedKey: "foo", }, @@ -598,7 +629,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.recursive-object"]), + simpleAllowedTypes: new Map([ + ["test.recursive-object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -614,9 +647,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Optional, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - stringSchema.identifier, - "test.recursive-object", + simpleAllowedTypes: new Map([ + [stringSchema.identifier, { isStaged: false }], + ["test.recursive-object", { isStaged: false }], ]), storedKey: "foo", }, diff --git a/packages/framework/ai-collab/src/explicit-strategy/typeGeneration.ts b/packages/framework/ai-collab/src/explicit-strategy/typeGeneration.ts index 9b39f69387b3..d002061d2b8a 100644 --- a/packages/framework/ai-collab/src/explicit-strategy/typeGeneration.ts +++ b/packages/framework/ai-collab/src/explicit-strategy/typeGeneration.ts @@ -235,14 +235,14 @@ function getOrCreateType( // TODO: Remove when AI better if ( Array.from( - field.allowedTypesIdentifiers, + new Set(field.simpleAllowedTypes.keys()), (n) => definitionMap.get(n) ?? fail("Unknown definition"), ).some((n) => n.kind === NodeKind.Array) ) { continue; } modifyFieldSet.add(key); - for (const type of field.allowedTypesIdentifiers) { + for (const type of field.simpleAllowedTypes.keys()) { modifyTypeSet.add(type); } } @@ -270,7 +270,7 @@ function getOrCreateType( } case NodeKind.Array: { for (const [name] of Array.from( - nodeSchema.allowedTypesIdentifiers, + nodeSchema.simpleAllowedTypes.keys(), (n): [string, SimpleNodeSchema] => [ n, definitionMap.get(n) ?? fail("Unknown definition"), @@ -287,7 +287,7 @@ function getOrCreateType( insertSet, modifyFieldSet, modifyTypeSet, - nodeSchema.allowedTypesIdentifiers, + new Set(nodeSchema.simpleAllowedTypes.keys()), ), ); } @@ -332,7 +332,7 @@ function getOrCreateTypeForField( insertSet, modifyFieldSet, modifyTypeSet, - fieldSchema.allowedTypesIdentifiers, + new Set(fieldSchema.simpleAllowedTypes.keys()), ); } case FieldKind.Optional: { @@ -344,7 +344,7 @@ function getOrCreateTypeForField( insertSet, modifyFieldSet, modifyTypeSet, - fieldSchema.allowedTypesIdentifiers, + new Set(fieldSchema.simpleAllowedTypes.keys()), ), ]); } 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 900d7db7d0b3..105eaa53de77 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 @@ -328,6 +328,8 @@ export class FieldSchemaAlpha; // (undocumented) get persistedMetadata(): JsonCompatibleReadOnlyObject | undefined; + // (undocumented) + get simpleAllowedTypes(): ReadonlyMap; } // @alpha @sealed @system @@ -1383,17 +1385,22 @@ export type SharedTreeOptions = Partial & Partial extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed export interface SimpleFieldSchema { - readonly allowedTypesIdentifiers: ReadonlySet; readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1403,7 +1410,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1432,7 +1439,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha diff --git a/packages/framework/tree-agent/src/typeGeneration.ts b/packages/framework/tree-agent/src/typeGeneration.ts index 9125d322cb31..8b33817a2ced 100644 --- a/packages/framework/tree-agent/src/typeGeneration.ts +++ b/packages/framework/tree-agent/src/typeGeneration.ts @@ -228,7 +228,7 @@ function getOrCreateType( z.string(), getTypeForAllowedTypes( definitionMap, - simpleNodeSchema.allowedTypesIdentifiers, + new Set(simpleNodeSchema.simpleAllowedTypes.keys()), objectCache, bindableSchemas, ), @@ -245,7 +245,7 @@ function getOrCreateType( const zodType = z.record( getTypeForAllowedTypes( definitionMap, - simpleNodeSchema.allowedTypesIdentifiers, + new Set(simpleNodeSchema.simpleAllowedTypes.keys()), objectCache, bindableSchemas, ), @@ -262,7 +262,7 @@ function getOrCreateType( const zodType = z.array( getTypeForAllowedTypes( definitionMap, - simpleNodeSchema.allowedTypesIdentifiers, + new Set(simpleNodeSchema.simpleAllowedTypes.keys()), objectCache, bindableSchemas, ), @@ -327,7 +327,7 @@ function getOrCreateTypeForField( const field = getTypeForAllowedTypes( definitionMap, - fieldSchema.allowedTypesIdentifiers, + new Set(fieldSchema.simpleAllowedTypes.keys()), objectCache, bindableSchemas, ).describe( diff --git a/packages/tools/devtools/devtools-core/src/data-visualization/DefaultVisualizers.ts b/packages/tools/devtools/devtools-core/src/data-visualization/DefaultVisualizers.ts index ab37eedccb34..ae76e4826349 100644 --- a/packages/tools/devtools/devtools-core/src/data-visualization/DefaultVisualizers.ts +++ b/packages/tools/devtools/devtools-core/src/data-visualization/DefaultVisualizers.ts @@ -318,7 +318,7 @@ export const visualizeSharedTree: VisualizeSharedObject = async ( * Since the {@link SimpleTreeSchema.allowedTypes} of each children node is only accessible at the parent field level, * each node's allowed types are computed at the parent field level. */ - const allowedTypes = treeSimpleSchema.root.allowedTypesIdentifiers; + const allowedTypes = new Set(treeSimpleSchema.root.simpleAllowedTypes.keys()); const isRequired = treeSimpleSchema.root.kind === FieldKind.Required; if (treeView === undefined) { diff --git a/packages/tools/devtools/devtools-core/src/data-visualization/SharedTreeVisualizer.ts b/packages/tools/devtools/devtools-core/src/data-visualization/SharedTreeVisualizer.ts index 0515a2c4f011..ef48c401355f 100644 --- a/packages/tools/devtools/devtools-core/src/data-visualization/SharedTreeVisualizer.ts +++ b/packages/tools/devtools/devtools-core/src/data-visualization/SharedTreeVisualizer.ts @@ -223,7 +223,7 @@ async function visualizeObjectNode( const objectNodeSchemaProperties: Record = {}; for (const [fieldKey, treeFieldSimpleSchema] of schema.fields) { objectNodeSchemaProperties[fieldKey] = { - allowedTypes: treeFieldSimpleSchema.allowedTypesIdentifiers, + allowedTypes: new Set(treeFieldSimpleSchema.simpleAllowedTypes.keys()), isRequired: treeFieldSimpleSchema.kind === FieldKind.Required ? true : false, }; } @@ -257,7 +257,7 @@ async function visualizeMapNode( const mapNodeSchemaProperties: Record = {}; for (const key of Object.keys(tree.fields)) { mapNodeSchemaProperties[key] = { - allowedTypes: schema.allowedTypesIdentifiers, + allowedTypes: new Set(schema.simpleAllowedTypes.keys()), // Map values are always required. Don't display field requirement information, since that information is redundant. isRequired: undefined, }; @@ -297,7 +297,7 @@ async function visualizeArrayNode( const arrayNodeSchemaProperties: Record = {}; for (const [i] of children.entries()) { arrayNodeSchemaProperties[i] = { - allowedTypes: schema.allowedTypesIdentifiers, + allowedTypes: new Set(schema.simpleAllowedTypes.keys()), // Array values are always required. Don't display field requirement information, since that information is redundant. isRequired: undefined, };