From 45ed7f7a06336bae735215b62664b430c5cbfcd0 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 22 Oct 2025 17:11:22 -0700 Subject: [PATCH 01/23] Initial change. Implemented viewSchemaToViewCompatibilitySchema. No tests yet and I might be missing members. --- .../dds/tree/api-report/tree.alpha.api.md | 11 +- packages/dds/tree/src/index.ts | 1 + .../dds/tree/src/simple-tree/api/index.ts | 1 + .../api/viewSchemaToSimpleSchema.ts | 2 + .../viewSchemaToViewCompatibilitySchema.ts | 143 ++++++++++++++++++ .../dds/tree/src/simple-tree/fieldSchema.ts | 13 ++ packages/dds/tree/src/simple-tree/index.ts | 1 + .../dds/tree/src/simple-tree/simpleSchema.ts | 16 +- .../api-report/fluid-framework.alpha.api.md | 4 + 9 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index f812b7e7cc9f..92d8a0e27883 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -268,6 +268,8 @@ export class FieldSchemaAlpha; // (undocumented) get persistedMetadata(): JsonCompatibleReadOnlyObject | undefined; + // (undocumented) + get stagedSchemaUpgrades(): SchemaUpgrade[]; } // @alpha @sealed @system @@ -310,7 +312,7 @@ export namespace FluidSerializableAsTree { export type Data = JsonCompatible; const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2 typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, { - readonly [x: string]: string | number | IFluidHandle | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null; + readonly [x: string]: string | number | IFluidHandle | FluidSerializableObject | Array | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | null; }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>], undefined, unknown>; // @sealed export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase { @@ -510,7 +512,7 @@ export namespace JsonAsTree { } const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.json.object", NodeKind.Record, TreeRecordNodeUnsafe, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array]> & WithType<"com.fluidframework.json.object", NodeKind.Record, unknown>, { - readonly [x: string]: string | number | JsonObject | Array | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | null; + readonly [x: string]: string | number | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | JsonObject | Array | null; }, false, readonly [LeafSchema<"null", null>, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array], undefined, unknown>; export type Primitive = TreeNodeFromImplicitAllowedTypes; // @system @@ -1007,6 +1009,7 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; + readonly stagedSchemaUpgrades?: SchemaUpgrade[]; } // @alpha @sealed @@ -1040,6 +1043,7 @@ export interface SimpleObjectFieldSchema extends SimpleFieldSchema { // @alpha @sealed export interface SimpleObjectNodeSchema extends SimpleNodeSchemaBaseAlpha { + readonly allowUnknownOptionalFields?: boolean; readonly fields: ReadonlyMap; } @@ -1294,6 +1298,9 @@ export namespace TableSchema { }): System_TableSchema.TableSchemaBase; } +// @alpha +export function toViewCompatibilityTreeSchema(schema: TreeSchema, copySchemaObjects: boolean): SimpleTreeSchema; + // @alpha export function trackDirtyNodes(view: TreeViewAlpha, dirty: DirtyTreeMap): () => void; diff --git a/packages/dds/tree/src/index.ts b/packages/dds/tree/src/index.ts index 8b79e34740c6..56a5c8e34da3 100644 --- a/packages/dds/tree/src/index.ts +++ b/packages/dds/tree/src/index.ts @@ -338,3 +338,4 @@ export { JsonAsTree } from "./jsonDomainSchema.js"; export { FluidSerializableAsTree } from "./serializableDomainSchema.js"; export { TableSchema, type System_TableSchema } from "./tableSchema.js"; export { asAlpha } from "./api.js"; +export { toViewCompatibilityTreeSchema } from "./simple-tree/index.js"; diff --git a/packages/dds/tree/src/simple-tree/api/index.ts b/packages/dds/tree/src/simple-tree/api/index.ts index c42426cec935..63a9e4a0e32e 100644 --- a/packages/dds/tree/src/simple-tree/api/index.ts +++ b/packages/dds/tree/src/simple-tree/api/index.ts @@ -160,4 +160,5 @@ export { export { generateSchemaFromSimpleSchema } from "./schemaFromSimple.js"; export { toSimpleTreeSchema } from "./viewSchemaToSimpleSchema.js"; +export { toViewCompatibilityTreeSchema } from "./viewSchemaToViewCompatibilitySchema.js"; export type { TreeChangeEvents } from "./treeChangeEvents.js"; diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index b0e25b1dbea4..31450d1814f1 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -128,6 +128,7 @@ function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): SimpleObjectNod metadata: field.metadata, persistedMetadata: field.persistedMetadata, storedKey: field.storedKey, + stagedSchemaUpgrades: field.stagedSchemaUpgrades, }); } @@ -136,5 +137,6 @@ function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): SimpleObjectNod fields, metadata: schema.metadata, persistedMetadata: schema.persistedMetadata, + allowUnknownOptionalFields: schema.allowUnknownOptionalFields, }; } diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts new file mode 100644 index 000000000000..54f1454aeaec --- /dev/null +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts @@ -0,0 +1,143 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { assert, unreachableCase } from "@fluidframework/core-utils/internal"; +import { NodeKind } from "../core/index.js"; +import type { + SimpleArrayNodeSchema, + SimpleLeafNodeSchema, + SimpleMapNodeSchema, + SimpleNodeSchema, + SimpleObjectFieldSchema, + SimpleObjectNodeSchema, + SimpleRecordNodeSchema, + SimpleTreeSchema, +} from "../simpleSchema.js"; +import type { TreeSchema } from "./configuration.js"; +import { LeafNodeSchema } from "../leafNodeSchema.js"; +import { + ArrayNodeSchema, + MapNodeSchema, + ObjectNodeSchema, + RecordNodeSchema, +} from "../node-kinds/index.js"; + +/** + * Convert a stored schema to a SimpleSchema and preserve information needed for compatibility testing. + * + * @param schema - The stored schema to convert. + * @param copySchemaObjects - If true, copies the contents of the schema into new objects. + * @returns The converted SimpleTreeSchema. + * + * @alpha + */ +export function toViewCompatibilityTreeSchema( + schema: TreeSchema, + copySchemaObjects: boolean, +): SimpleTreeSchema { + const definitions = new Map(); + + // Walk the node definitions and convert them one by one. Recurse into fields used in compatibility checks. + for (const nodeSchema of schema.definitions.values()) { + // TODO: Move this assert to a common location so it can be used from both SimpleSchema builders. + // The set of node kinds is extensible, but the typing of SimpleNodeSchema is not, so we need to check that the schema is one of the known kinds. + assert( + nodeSchema instanceof ArrayNodeSchema || + nodeSchema instanceof MapNodeSchema || + nodeSchema instanceof LeafNodeSchema || + nodeSchema instanceof ObjectNodeSchema || + nodeSchema instanceof RecordNodeSchema, + // TODO: New error code. + 0xb60 /* Invalid schema */, + ); + + // TODO: Do we need walkNodeSchema to recurse into fields in this context? + // Probably not: we are walking all schema definitions unconditionally without worrying about tree order. + // It is probably enough to just walk the fields of object schema here. + + // Read properties that are needed for compatibility and copy them to a SimpleNodeSchema. + // TODO: Refactor copy methods to avoid duplication with viewSchemaToSimpleSchema. + // TODO: Does anything need to be done outside of `copyNodeSchema`? Are there any properties on TreeNodeSchema or the root field that need to be handled? + const simpleNodeSchema = copySchemaObjects ? copyNodeSchema(nodeSchema) : nodeSchema; + definitions.set(nodeSchema.identifier, simpleNodeSchema); + } + + return { + root: copySchemaObjects + ? { + kind: schema.root.kind, + allowedTypesIdentifiers: schema.root.allowedTypesIdentifiers, + metadata: schema.root.metadata, + persistedMetadata: schema.root.persistedMetadata, + stagedSchemaUpgrades: schema.root.stagedSchemaUpgrades, + } + : schema.root, // TODO: Convert the root field + definitions, + }; +} + +/** + * Copies a {@link SimpleNodeSchema} into a new plain JavaScript object. + * + * @remarks Caches the result on the input schema for future calls. + */ +function copyNodeSchema(schema: SimpleNodeSchema): SimpleNodeSchema { + const kind = schema.kind; + switch (kind) { + case NodeKind.Leaf: + return copyLeafSchema(schema); + case NodeKind.Array: + case NodeKind.Map: + case NodeKind.Record: + return copySchemaWithAllowedTypes(schema); + case NodeKind.Object: + return copyObjectSchema(schema); + default: + unreachableCase(kind); + } +} + +function copyLeafSchema(schema: SimpleLeafNodeSchema): SimpleLeafNodeSchema { + return { + kind: NodeKind.Leaf, + leafKind: schema.leafKind, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; +} + +function copySchemaWithAllowedTypes( + schema: SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema, +): SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema { + return { + kind: schema.kind, + allowedTypesIdentifiers: schema.allowedTypesIdentifiers, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; +} + +function copyObjectSchema(schema: SimpleObjectNodeSchema): 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, + metadata: field.metadata, + persistedMetadata: field.persistedMetadata, + storedKey: field.storedKey, + stagedSchemaUpgrades: field.stagedSchemaUpgrades, + }); + } + + return { + kind: NodeKind.Object, + fields, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + allowUnknownOptionalFields: schema.allowUnknownOptionalFields, + }; +} diff --git a/packages/dds/tree/src/simple-tree/fieldSchema.ts b/packages/dds/tree/src/simple-tree/fieldSchema.ts index 668ea5abc30f..c02736b63c1d 100644 --- a/packages/dds/tree/src/simple-tree/fieldSchema.ts +++ b/packages/dds/tree/src/simple-tree/fieldSchema.ts @@ -28,6 +28,7 @@ import type { TreeLeafValue, InsertableTreeNodeFromImplicitAllowedTypes, AllowedTypesFull, + SchemaUpgrade, } from "./core/index.js"; import { normalizeAllowedTypes } from "./core/index.js"; @@ -412,6 +413,18 @@ export class FieldSchemaAlpha< return this.allowedTypesFull.evaluateIdentifiers(); } + public get stagedSchemaUpgrades(): SchemaUpgrade[] { + const annotatedAllowedTypes = this.allowedTypesFull.evaluate().types; + const upgrades: SchemaUpgrade[] = []; + for (const type of annotatedAllowedTypes) { + if (type.metadata.stagedSchemaUpgrade !== undefined) { + upgrades.push(type.metadata.stagedSchemaUpgrade); + } + } + + return upgrades; + } + 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 2ffaef453983..61358fb9b8fa 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -274,3 +274,4 @@ export { nullSchema, } from "./leafNodeSchema.js"; export type { LeafSchema } from "./leafNodeSchema.js"; +export { toViewCompatibilityTreeSchema } from "./api/index.js"; diff --git a/packages/dds/tree/src/simple-tree/simpleSchema.ts b/packages/dds/tree/src/simple-tree/simpleSchema.ts index 11f186e55507..62788e40c4df 100644 --- a/packages/dds/tree/src/simple-tree/simpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/simpleSchema.ts @@ -5,7 +5,7 @@ import type { ValueSchema } from "../core/index.js"; import type { JsonCompatibleReadOnlyObject } from "../util/index.js"; -import type { NodeKind, SimpleNodeSchemaBase } from "./core/index.js"; +import type { NodeKind, SchemaUpgrade, SimpleNodeSchemaBase } from "./core/index.js"; import type { FieldKind, FieldSchemaMetadata } from "./fieldSchema.js"; /* @@ -58,6 +58,13 @@ export interface SimpleObjectNodeSchema * especially if/when TreeNodeSchema for objects provide more maps. */ readonly fields: ReadonlyMap; + + /** + * Whether the object node allows unknown optional fields. + * + * @remarks Used for compatibility checks (see {@link toViewCompatibilityTreeSchema}). Not available in all cases. + */ + readonly allowUnknownOptionalFields?: boolean; } /** @@ -186,6 +193,13 @@ export interface SimpleFieldSchema { */ readonly allowedTypesIdentifiers: ReadonlySet; + /** + * Staged schema upgrades for this field indexed by the allowed type identifier they apply to. + * + * @remarks Used for compatibility checks (see {@link toViewCompatibilityTreeSchema}). Not available in all cases. + */ + readonly stagedSchemaUpgrades?: SchemaUpgrade[]; + /** * {@inheritDoc FieldSchemaMetadata} */ 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 abe60272d3a4..4b40cd8bc394 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 @@ -322,6 +322,8 @@ export class FieldSchemaAlpha; // (undocumented) get persistedMetadata(): JsonCompatibleReadOnlyObject | undefined; + // (undocumented) + get stagedSchemaUpgrades(): SchemaUpgrade[]; } // @alpha @sealed @system @@ -1385,6 +1387,7 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; + readonly stagedSchemaUpgrades?: SchemaUpgrade[]; } // @alpha @sealed @@ -1418,6 +1421,7 @@ export interface SimpleObjectFieldSchema extends SimpleFieldSchema { // @alpha @sealed export interface SimpleObjectNodeSchema extends SimpleNodeSchemaBaseAlpha { + readonly allowUnknownOptionalFields?: boolean; readonly fields: ReadonlyMap; } From f76e1ebebe2b51c44845cba5e1a343c02cd20a77 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Thu, 23 Oct 2025 12:37:09 -0700 Subject: [PATCH 02/23] Added test coverage using the existing toSimpleSchema tests as a starting point. --- .../api/viewSchemaToSimpleSchema.ts | 2 - .../simple-tree/api/getSimpleSchema.spec.ts | 925 +++++++++++++----- 2 files changed, 654 insertions(+), 273 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index 31450d1814f1..b0e25b1dbea4 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -128,7 +128,6 @@ function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): SimpleObjectNod metadata: field.metadata, persistedMetadata: field.persistedMetadata, storedKey: field.storedKey, - stagedSchemaUpgrades: field.stagedSchemaUpgrades, }); } @@ -137,6 +136,5 @@ function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): SimpleObjectNod fields, metadata: schema.metadata, persistedMetadata: schema.persistedMetadata, - allowUnknownOptionalFields: schema.allowUnknownOptionalFields, }; } 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..b2b5a0755ac6 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 @@ -10,6 +10,8 @@ import { SchemaFactory, SchemaFactoryAlpha, stringSchema, + toViewCompatibilityTreeSchema, + TreeViewConfigurationAlpha, type SimpleLeafNodeSchema, type SimpleNodeSchema, type SimpleObjectFieldSchema, @@ -35,352 +37,733 @@ const simpleNumber: SimpleLeafNodeSchema = { }; describe("getSimpleSchema", () => { - it("non-copying", () => { + describe("non-copying", () => { const Schema = stringSchema; const root = SchemaFactoryAlpha.optional(Schema); - const actual = toSimpleTreeSchema(root, false); - const expected: SimpleTreeSchema = { root, definitions: new Map([[Schema.identifier, Schema]]), }; - assert.deepEqual(actual, expected); - assert.equal(actual.root, root); - assert.equal(actual.definitions.get(Schema.identifier), Schema); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(root, false); + + assert.deepEqual(actual, expected); + + assert.equal(actual.root, root); + assert.equal(actual.definitions.get(Schema.identifier), Schema); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: root }); + const actual = toViewCompatibilityTreeSchema(treeView, false); + + assert.deepEqual(actual, expected); + + assert.equal(actual.root, root); + assert.equal(actual.definitions.get(Schema.identifier), Schema); + }); }); - it("Field Schema", () => { + describe("Field Schema", () => { const schemaFactory = new SchemaFactory("test"); const Schema = schemaFactory.optional(schemaFactory.string, { metadata: { description: "An optional string." }, }); - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Optional, - metadata: { description: "An optional string." }, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - persistedMetadata: undefined, - }, - definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), - }; - assert.deepEqual(actual, expected); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Optional, + metadata: { description: "An optional string." }, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + persistedMetadata: undefined, + }, + definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), + }; + + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Optional, + metadata: { description: "An optional string." }, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + persistedMetadata: undefined, + stagedSchemaUpgrades: [], + }, + definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), + }; + + assert.deepEqual(actual, expected); + }); }); - it("Leaf node", () => { + describe("Leaf node", () => { const Schema = SchemaFactory.string; - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - persistedMetadata: undefined, - }, - definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), - }; - assert.deepEqual(actual, expected); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + persistedMetadata: undefined, + }, + definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), + }; + + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + persistedMetadata: undefined, + stagedSchemaUpgrades: [], + }, + definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), + }; + + assert.deepEqual(actual, expected); + }); }); - it("Union root", () => { + describe("Union root", () => { const Schema = [SchemaFactory.number, SchemaFactory.string]; - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set([ + "com.fluidframework.leaf.number", + "com.fluidframework.leaf.string", + ]), + }, + definitions: new Map([ + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set([ + "com.fluidframework.leaf.number", + "com.fluidframework.leaf.string", + ]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], ]), - }, - definitions: new Map([ - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + }; + + assert.deepEqual(actual, expected); + }); }); - it("Array schema", () => { + describe("Array schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.array("array", schemaFactory.string) {} - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.array"]), + }, + definitions: new Map([ + [ + "test.array", + { + kind: NodeKind.Array, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + metadata: {}, + persistedMetadata: undefined, + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.array"]), - }, - definitions: new Map([ - [ - "test.array", - { - kind: NodeKind.Array, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - metadata: {}, - persistedMetadata: undefined, - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.array"]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + [ + "test.array", + { + kind: NodeKind.Array, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + metadata: {}, + persistedMetadata: undefined, + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); }); - it("Map schema", () => { + describe("Map schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.map("map", schemaFactory.string) {} - const actual = toSimpleTreeSchema(Schema, true); - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.map"]), - }, - definitions: new Map([ - [ - "test.map", - { - kind: NodeKind.Map, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.map"]), + }, + definitions: new Map([ + [ + "test.map", + { + kind: NodeKind.Map, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.map"]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + [ + "test.map", + { + kind: NodeKind.Map, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); }); - it("Record schema", () => { + describe("Record schema", () => { const schemaFactory = new SchemaFactoryAlpha("test"); class Schema extends schemaFactory.record("record", schemaFactory.string) {} - const actual = toSimpleTreeSchema(Schema, true); - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.record"]), - }, - definitions: new Map([ - [ - "test.record", - { - kind: NodeKind.Record, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.record"]), + }, + definitions: new Map([ + [ + "test.record", + { + kind: NodeKind.Record, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.record"]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + [ + "test.record", + { + kind: NodeKind.Record, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); }); - it("Object schema", () => { + describe("Object schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.object("object", { foo: schemaFactory.optional(schemaFactory.number), bar: schemaFactory.required(schemaFactory.string), }) {} - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.object"]), + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Optional, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), + storedKey: "foo", + }, + ], + [ + "bar", + { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + storedKey: "bar", + }, + ], + ]), + } satisfies SimpleObjectNodeSchema, + ], + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Optional, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), - storedKey: "foo", - }, - ], - [ - "bar", - { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - storedKey: "bar", - }, - ], - ]), - } satisfies SimpleObjectNodeSchema, - ], - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.object"]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + allowUnknownOptionalFields: false, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Optional, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), + storedKey: "foo", + stagedSchemaUpgrades: [], + }, + ], + [ + "bar", + { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + storedKey: "bar", + stagedSchemaUpgrades: [], + }, + ], + ]), + } satisfies SimpleObjectNodeSchema, + ], + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); }); - it("Object schema including an identifier field", () => { + describe("Object schema including an identifier field", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.object("object", { id: schemaFactory.identifier, }) {} - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.object"]), + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "id", + { + kind: FieldKind.Identifier, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + storedKey: "id", + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "id", - { - kind: FieldKind.Identifier, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - storedKey: "id", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.object"]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + allowUnknownOptionalFields: false, + fields: new Map([ + [ + "id", + { + kind: FieldKind.Identifier, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + storedKey: "id", + stagedSchemaUpgrades: [], + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + const actual = toViewCompatibilityTreeSchema(treeView, true); + assert.deepEqual(actual, expected); + }); }); - it("Object schema including a union field", () => { + describe("Object schema including a union field", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.object("object", { foo: schemaFactory.required([schemaFactory.number, schemaFactory.string]), }) {} - // Must enable copy so deep equality passes. - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + // Must enable copy so deep equality passes. + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.object"]), + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set([ + "com.fluidframework.leaf.number", + "com.fluidframework.leaf.string", + ]), + storedKey: "foo", + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", - ]), - storedKey: "foo", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + + // Must enable copy so deep equality passes. + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.object"]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + allowUnknownOptionalFields: false, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set([ + "com.fluidframework.leaf.number", + "com.fluidframework.leaf.string", + ]), + storedKey: "foo", + stagedSchemaUpgrades: [], + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); }); - it("Recursive object schema", () => { + describe("Recursive object schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.objectRecursive("recursive-object", { foo: schemaFactory.optionalRecursive([schemaFactory.string, () => Schema]), }) {} - const actual = toSimpleTreeSchema(Schema, true); + it("toSimpleTreeSchema", () => { + const actual = toSimpleTreeSchema(Schema, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.recursive-object"]), + }, + definitions: new Map([ + [ + "test.recursive-object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Optional, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set([ + "com.fluidframework.leaf.string", + "test.recursive-object", + ]), + storedKey: "foo", + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.recursive-object"]), - }, - definitions: new Map([ - [ - "test.recursive-object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Optional, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.string", - "test.recursive-object", - ]), - storedKey: "foo", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - assert.deepEqual(actual, expected); + assert.deepEqual(actual, expected); + }); + + it("toViewCompatibilityTreeSchema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set(["test.recursive-object"]), + stagedSchemaUpgrades: [], + }, + definitions: new Map([ + [ + "test.recursive-object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + allowUnknownOptionalFields: false, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Optional, + metadata: {}, + persistedMetadata: undefined, + allowedTypesIdentifiers: new Set([ + "com.fluidframework.leaf.string", + "test.recursive-object", + ]), + storedKey: "foo", + stagedSchemaUpgrades: [], + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + + assert.deepEqual(actual, expected); + }); }); }); From 491c2edabef2dc887fe5424c71e715d981133ee2 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Thu, 23 Oct 2025 13:29:56 -0700 Subject: [PATCH 03/23] Refactored the schema copying code. --- .../dds/tree/api-report/tree.alpha.api.md | 4 +- .../api/viewSchemaToSimpleSchema.ts | 94 +++++++++++++++---- .../viewSchemaToViewCompatibilitySchema.ts | 85 ++--------------- 3 files changed, 85 insertions(+), 98 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 92d8a0e27883..5cefeb2e47fd 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -312,7 +312,7 @@ export namespace FluidSerializableAsTree { export type Data = JsonCompatible; const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2 typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, { - readonly [x: string]: string | number | IFluidHandle | FluidSerializableObject | Array | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | null; + readonly [x: string]: string | number | IFluidHandle | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null; }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>], undefined, unknown>; // @sealed export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase { @@ -512,7 +512,7 @@ export namespace JsonAsTree { } const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.json.object", NodeKind.Record, TreeRecordNodeUnsafe, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array]> & WithType<"com.fluidframework.json.object", NodeKind.Record, unknown>, { - readonly [x: string]: string | number | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | JsonObject | Array | null; + readonly [x: string]: string | number | JsonObject | Array | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | null; }, false, readonly [LeafSchema<"null", null>, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array], undefined, unknown>; export type Primitive = TreeNodeFromImplicitAllowedTypes; // @system diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index b0e25b1dbea4..d43366071219 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -59,7 +59,9 @@ export function toSimpleTreeSchema( nodeSchema instanceof RecordNodeSchema, 0xb60 /* Invalid schema */, ); - const outSchema = copySchemaObjects ? copySimpleNodeSchema(nodeSchema) : nodeSchema; + const outSchema = copySchemaObjects + ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyKind.SimpleSchema) + : nodeSchema; definitions.set(nodeSchema.identifier, outSchema); }, }); @@ -77,12 +79,24 @@ export function toSimpleTreeSchema( }; } +/** + * Specifies which fields are included when copying a Simple Schema. + */ +export enum SimpleSchemaCopyKind { + // TODO: Rename + SimpleSchema, + ViewCompatibilitySchema, +} + /** * 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 { +export function copySimpleNodeSchema( + schema: SimpleNodeSchema, + copyKind: SimpleSchemaCopyKind, +): SimpleNodeSchema { const kind = schema.kind; switch (kind) { case NodeKind.Leaf: @@ -92,7 +106,7 @@ function copySimpleNodeSchema(schema: SimpleNodeSchema): SimpleNodeSchema { case NodeKind.Record: return copySimpleSchemaWithAllowedTypes(schema); case NodeKind.Object: - return copySimpleObjectSchema(schema); + return copySimpleObjectSchema(schema, copyKind); default: unreachableCase(kind); } @@ -118,23 +132,69 @@ function copySimpleSchemaWithAllowedTypes( }; } -function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): SimpleObjectNodeSchema { +function copySimpleObjectSchema( + schema: SimpleObjectNodeSchema, + copyKind: SimpleSchemaCopyKind, +): 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, - metadata: field.metadata, - persistedMetadata: field.persistedMetadata, - storedKey: field.storedKey, - }); + let simpleField: SimpleObjectFieldSchema | undefined; + + switch (copyKind) { + case SimpleSchemaCopyKind.SimpleSchema: + simpleField = { + kind: field.kind, + allowedTypesIdentifiers: field.allowedTypesIdentifiers, + metadata: field.metadata, + persistedMetadata: field.persistedMetadata, + storedKey: field.storedKey, + }; + break; + + case SimpleSchemaCopyKind.ViewCompatibilitySchema: + simpleField = { + kind: field.kind, + allowedTypesIdentifiers: field.allowedTypesIdentifiers, + metadata: field.metadata, + persistedMetadata: field.persistedMetadata, + storedKey: field.storedKey, + stagedSchemaUpgrades: field.stagedSchemaUpgrades, + }; + break; + + default: + unreachableCase(copyKind); + } + + fields.set(propertyKey, simpleField); } - return { - kind: NodeKind.Object, - fields, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; + let simpleObject: SimpleObjectNodeSchema | undefined; + + switch (copyKind) { + case SimpleSchemaCopyKind.SimpleSchema: + simpleObject = { + kind: NodeKind.Object, + fields, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; + break; + + case SimpleSchemaCopyKind.ViewCompatibilitySchema: + simpleObject = { + kind: NodeKind.Object, + fields, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + allowUnknownOptionalFields: schema.allowUnknownOptionalFields, + }; + break; + + default: + unreachableCase(copyKind); + } + + return simpleObject; } diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts index 54f1454aeaec..09acd4d697e3 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts @@ -3,18 +3,8 @@ * Licensed under the MIT License. */ -import { assert, unreachableCase } from "@fluidframework/core-utils/internal"; -import { NodeKind } from "../core/index.js"; -import type { - SimpleArrayNodeSchema, - SimpleLeafNodeSchema, - SimpleMapNodeSchema, - SimpleNodeSchema, - SimpleObjectFieldSchema, - SimpleObjectNodeSchema, - SimpleRecordNodeSchema, - SimpleTreeSchema, -} from "../simpleSchema.js"; +import { assert } from "@fluidframework/core-utils/internal"; +import type { SimpleNodeSchema, SimpleTreeSchema } from "../simpleSchema.js"; import type { TreeSchema } from "./configuration.js"; import { LeafNodeSchema } from "../leafNodeSchema.js"; import { @@ -23,6 +13,7 @@ import { ObjectNodeSchema, RecordNodeSchema, } from "../node-kinds/index.js"; +import { copySimpleNodeSchema, SimpleSchemaCopyKind } from "./viewSchemaToSimpleSchema.js"; /** * Convert a stored schema to a SimpleSchema and preserve information needed for compatibility testing. @@ -58,9 +49,9 @@ export function toViewCompatibilityTreeSchema( // It is probably enough to just walk the fields of object schema here. // Read properties that are needed for compatibility and copy them to a SimpleNodeSchema. - // TODO: Refactor copy methods to avoid duplication with viewSchemaToSimpleSchema. - // TODO: Does anything need to be done outside of `copyNodeSchema`? Are there any properties on TreeNodeSchema or the root field that need to be handled? - const simpleNodeSchema = copySchemaObjects ? copyNodeSchema(nodeSchema) : nodeSchema; + const simpleNodeSchema = copySchemaObjects + ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyKind.ViewCompatibilitySchema) + : nodeSchema; definitions.set(nodeSchema.identifier, simpleNodeSchema); } @@ -77,67 +68,3 @@ export function toViewCompatibilityTreeSchema( definitions, }; } - -/** - * Copies a {@link SimpleNodeSchema} into a new plain JavaScript object. - * - * @remarks Caches the result on the input schema for future calls. - */ -function copyNodeSchema(schema: SimpleNodeSchema): SimpleNodeSchema { - const kind = schema.kind; - switch (kind) { - case NodeKind.Leaf: - return copyLeafSchema(schema); - case NodeKind.Array: - case NodeKind.Map: - case NodeKind.Record: - return copySchemaWithAllowedTypes(schema); - case NodeKind.Object: - return copyObjectSchema(schema); - default: - unreachableCase(kind); - } -} - -function copyLeafSchema(schema: SimpleLeafNodeSchema): SimpleLeafNodeSchema { - return { - kind: NodeKind.Leaf, - leafKind: schema.leafKind, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; -} - -function copySchemaWithAllowedTypes( - schema: SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema, -): SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema { - return { - kind: schema.kind, - allowedTypesIdentifiers: schema.allowedTypesIdentifiers, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; -} - -function copyObjectSchema(schema: SimpleObjectNodeSchema): 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, - metadata: field.metadata, - persistedMetadata: field.persistedMetadata, - storedKey: field.storedKey, - stagedSchemaUpgrades: field.stagedSchemaUpgrades, - }); - } - - return { - kind: NodeKind.Object, - fields, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - allowUnknownOptionalFields: schema.allowUnknownOptionalFields, - }; -} From 25eef862ab0489ebaa34f68f6eb8adad452f25f2 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Thu, 23 Oct 2025 13:39:56 -0700 Subject: [PATCH 04/23] Removed persistedMetadata and metadata from Node schemas copied in ViewCompatibility mode. --- .../api/viewSchemaToSimpleSchema.ts | 96 ++++++++++++------- .../viewSchemaToViewCompatibilitySchema.ts | 4 +- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index d43366071219..674ddfff5fb9 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -60,7 +60,7 @@ export function toSimpleTreeSchema( 0xb60 /* Invalid schema */, ); const outSchema = copySchemaObjects - ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyKind.SimpleSchema) + ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyMode.SimpleSchema) : nodeSchema; definitions.set(nodeSchema.identifier, outSchema); }, @@ -82,7 +82,7 @@ export function toSimpleTreeSchema( /** * Specifies which fields are included when copying a Simple Schema. */ -export enum SimpleSchemaCopyKind { +export enum SimpleSchemaCopyMode { // TODO: Rename SimpleSchema, ViewCompatibilitySchema, @@ -95,54 +95,84 @@ export enum SimpleSchemaCopyKind { */ export function copySimpleNodeSchema( schema: SimpleNodeSchema, - copyKind: SimpleSchemaCopyKind, + copyMode: SimpleSchemaCopyMode, ): SimpleNodeSchema { const kind = schema.kind; switch (kind) { case NodeKind.Leaf: - return copySimpleLeafSchema(schema); + return copySimpleLeafSchema(schema, copyMode); case NodeKind.Array: case NodeKind.Map: case NodeKind.Record: - return copySimpleSchemaWithAllowedTypes(schema); + return copySimpleSchemaWithAllowedTypes(schema, copyMode); case NodeKind.Object: - return copySimpleObjectSchema(schema, copyKind); + return copySimpleObjectSchema(schema, copyMode); default: unreachableCase(kind); } } -function copySimpleLeafSchema(schema: SimpleLeafNodeSchema): SimpleLeafNodeSchema { - return { - kind: NodeKind.Leaf, - leafKind: schema.leafKind, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; +function copySimpleLeafSchema( + schema: SimpleLeafNodeSchema, + copyMode: SimpleSchemaCopyMode, +): SimpleLeafNodeSchema { + switch (copyMode) { + case SimpleSchemaCopyMode.SimpleSchema: + return { + kind: NodeKind.Leaf, + leafKind: schema.leafKind, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; + case SimpleSchemaCopyMode.ViewCompatibilitySchema: + return { + kind: NodeKind.Leaf, + leafKind: schema.leafKind, + // Don't include metadata or persistedMetadata in view compatibility schema. + metadata: {}, + persistedMetadata: undefined, + }; + default: + unreachableCase(copyMode); + } } function copySimpleSchemaWithAllowedTypes( schema: SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema, + copyMode: SimpleSchemaCopyMode, ): SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema { - return { - kind: schema.kind, - allowedTypesIdentifiers: schema.allowedTypesIdentifiers, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; + switch (copyMode) { + case SimpleSchemaCopyMode.SimpleSchema: + return { + kind: schema.kind, + allowedTypesIdentifiers: schema.allowedTypesIdentifiers, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; + case SimpleSchemaCopyMode.ViewCompatibilitySchema: + return { + kind: schema.kind, + allowedTypesIdentifiers: schema.allowedTypesIdentifiers, + // Don't include metadata or persistedMetadata in view compatibility schema. + metadata: {}, + persistedMetadata: undefined, + }; + default: + unreachableCase(copyMode); + } } function copySimpleObjectSchema( schema: SimpleObjectNodeSchema, - copyKind: SimpleSchemaCopyKind, + copyMode: SimpleSchemaCopyMode, ): 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. let simpleField: SimpleObjectFieldSchema | undefined; - switch (copyKind) { - case SimpleSchemaCopyKind.SimpleSchema: + switch (copyMode) { + case SimpleSchemaCopyMode.SimpleSchema: simpleField = { kind: field.kind, allowedTypesIdentifiers: field.allowedTypesIdentifiers, @@ -152,19 +182,20 @@ function copySimpleObjectSchema( }; break; - case SimpleSchemaCopyKind.ViewCompatibilitySchema: + case SimpleSchemaCopyMode.ViewCompatibilitySchema: simpleField = { kind: field.kind, allowedTypesIdentifiers: field.allowedTypesIdentifiers, - metadata: field.metadata, - persistedMetadata: field.persistedMetadata, + // Don't include metadata or persistedMetadata in view compatibility schema. + metadata: {}, + persistedMetadata: undefined, storedKey: field.storedKey, stagedSchemaUpgrades: field.stagedSchemaUpgrades, }; break; default: - unreachableCase(copyKind); + unreachableCase(copyMode); } fields.set(propertyKey, simpleField); @@ -172,8 +203,8 @@ function copySimpleObjectSchema( let simpleObject: SimpleObjectNodeSchema | undefined; - switch (copyKind) { - case SimpleSchemaCopyKind.SimpleSchema: + switch (copyMode) { + case SimpleSchemaCopyMode.SimpleSchema: simpleObject = { kind: NodeKind.Object, fields, @@ -182,18 +213,19 @@ function copySimpleObjectSchema( }; break; - case SimpleSchemaCopyKind.ViewCompatibilitySchema: + case SimpleSchemaCopyMode.ViewCompatibilitySchema: simpleObject = { kind: NodeKind.Object, fields, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, + // Don't include metadata or persistedMetadata in view compatibility schema. + metadata: {}, + persistedMetadata: undefined, allowUnknownOptionalFields: schema.allowUnknownOptionalFields, }; break; default: - unreachableCase(copyKind); + unreachableCase(copyMode); } return simpleObject; diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts index 09acd4d697e3..894b0ff6476b 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts @@ -13,7 +13,7 @@ import { ObjectNodeSchema, RecordNodeSchema, } from "../node-kinds/index.js"; -import { copySimpleNodeSchema, SimpleSchemaCopyKind } from "./viewSchemaToSimpleSchema.js"; +import { copySimpleNodeSchema, SimpleSchemaCopyMode } from "./viewSchemaToSimpleSchema.js"; /** * Convert a stored schema to a SimpleSchema and preserve information needed for compatibility testing. @@ -50,7 +50,7 @@ export function toViewCompatibilityTreeSchema( // Read properties that are needed for compatibility and copy them to a SimpleNodeSchema. const simpleNodeSchema = copySchemaObjects - ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyKind.ViewCompatibilitySchema) + ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyMode.ViewCompatibilitySchema) : nodeSchema; definitions.set(nodeSchema.identifier, simpleNodeSchema); } From d80bee6910f07d17cf2573fb38b1ed902199f9ad Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Thu, 23 Oct 2025 16:21:46 -0700 Subject: [PATCH 05/23] Minor: better typing in copy methods. --- .../dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index 674ddfff5fb9..deced9ee939a 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -169,7 +169,7 @@ function copySimpleObjectSchema( 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. - let simpleField: SimpleObjectFieldSchema | undefined; + let simpleField: SimpleObjectFieldSchema; switch (copyMode) { case SimpleSchemaCopyMode.SimpleSchema: @@ -201,7 +201,7 @@ function copySimpleObjectSchema( fields.set(propertyKey, simpleField); } - let simpleObject: SimpleObjectNodeSchema | undefined; + let simpleObject: SimpleObjectNodeSchema; switch (copyMode) { case SimpleSchemaCopyMode.SimpleSchema: From 15fa315a664a7e430bd5b7b2dac0091082879d1e Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Thu, 23 Oct 2025 17:30:38 -0700 Subject: [PATCH 06/23] Added snapshot tests. --- .../viewSchemaToViewCompatibilitySchema.ts | 4 - .../simple-tree/api/getSimpleSchema.spec.ts | 76 +++++++++++++++++++ ...ith JSON serialization - Array schema.json | 9 +++ ...ith JSON serialization - Field Schema.json | 11 +++ ...a with JSON serialization - Leaf node.json | 9 +++ ... with JSON serialization - Map schema.json | 9 +++ ...Object schema including a union field.json | 9 +++ ... schema including an identifier field.json | 9 +++ ...th JSON serialization - Object schema.json | 9 +++ ...th JSON serialization - Record schema.json | 9 +++ ...rialization - Recursive object schema.json | 9 +++ ... with JSON serialization - Union root.json | 9 +++ 12 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts index 894b0ff6476b..fe4b2db8199f 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts @@ -44,10 +44,6 @@ export function toViewCompatibilityTreeSchema( 0xb60 /* Invalid schema */, ); - // TODO: Do we need walkNodeSchema to recurse into fields in this context? - // Probably not: we are walking all schema definitions unconditionally without worrying about tree order. - // It is probably enough to just walk the fields of object schema here. - // Read properties that are needed for compatibility and copy them to a SimpleNodeSchema. const simpleNodeSchema = copySchemaObjects ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyMode.ViewCompatibilitySchema) 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 b2b5a0755ac6..e7b6bacfc3dc 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 @@ -12,6 +12,7 @@ import { stringSchema, toViewCompatibilityTreeSchema, TreeViewConfigurationAlpha, + type ImplicitFieldSchema, type SimpleLeafNodeSchema, type SimpleNodeSchema, type SimpleObjectFieldSchema, @@ -21,6 +22,8 @@ import { import { ValueSchema } from "../../../core/index.js"; // eslint-disable-next-line import/no-internal-modules import { toSimpleTreeSchema } from "../../../simple-tree/api/viewSchemaToSimpleSchema.js"; +import { takeJsonSnapshot, useSnapshotDirectory } from "../../snapshots/index.js"; +import type { JsonCompatible } from "../../../util/index.js"; const simpleString: SimpleLeafNodeSchema = { leafKind: ValueSchema.String, @@ -36,7 +39,20 @@ const simpleNumber: SimpleLeafNodeSchema = { persistedMetadata: undefined, }; +function toSerializableCompatibilitySchema( + treeView: TreeViewConfigurationAlpha, +): JsonCompatible { + const serializableSchema = toViewCompatibilityTreeSchema( + treeView, + // Copying is required for JSON serialization to avoid circular references in metadata/etc. + true, + ) as unknown as JsonCompatible; + return serializableSchema; +} + describe("getSimpleSchema", () => { + useSnapshotDirectory("get-simple-schema"); + describe("non-copying", () => { const Schema = stringSchema; const root = SchemaFactoryAlpha.optional(Schema); @@ -105,6 +121,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Field Schema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Leaf node", () => { @@ -143,6 +165,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Leaf node", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Union root", () => { @@ -193,6 +221,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Union root", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Array schema", () => { @@ -254,6 +288,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Array schema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Map schema", () => { @@ -315,6 +355,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Map schema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Record schema", () => { @@ -376,6 +422,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Record schema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Object schema", () => { @@ -487,6 +539,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Object schema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Object schema including an identifier field", () => { @@ -574,6 +632,12 @@ describe("getSimpleSchema", () => { const actual = toViewCompatibilityTreeSchema(treeView, true); assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Object schema including a union field", () => { @@ -672,6 +736,12 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); describe("Recursive object schema", () => { @@ -765,5 +835,11 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); + + it("toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); }); }); diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json new file mode 100644 index 000000000000..c7f188a4293e --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json @@ -0,0 +1,11 @@ +{ + "root": { + "kind": 0, + "allowedTypesIdentifiers": {}, + "metadata": { + "description": "An optional string." + }, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json new file mode 100644 index 000000000000..cb51003abbb9 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json @@ -0,0 +1,9 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": {}, + "metadata": {}, + "stagedSchemaUpgrades": [] + }, + "definitions": {} +} \ No newline at end of file From a239d8880eb4051aa3d556168462aee040b68595 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Fri, 24 Oct 2025 14:06:17 -0700 Subject: [PATCH 07/23] Got snapshotting working correctly. It currently involves a lot of careful serialization of each type, though I think this safer and more durable than a more generic approach. --- .../dds/tree/src/simple-tree/api/index.ts | 1 + .../api/serializableCompatibilitySchema.ts | 177 ++++++++++++++++++ packages/dds/tree/src/simple-tree/index.ts | 5 +- .../simple-tree/api/getSimpleSchema.spec.ts | 34 ++-- ...ith JSON serialization - Array schema.json | 9 - ...ith JSON serialization - Field Schema.json | 11 -- ...a with JSON serialization - Leaf node.json | 9 - ... with JSON serialization - Map schema.json | 9 - ...Object schema including a union field.json | 9 - ... schema including an identifier field.json | 9 - ...th JSON serialization - Object schema.json | 9 - ...th JSON serialization - Record schema.json | 9 - ...rialization - Recursive object schema.json | 9 - ... with JSON serialization - Union root.json | 9 - ...w compatibility schema - Array schema.json | 21 +++ ...w compatibility schema - Field Schema.json | 15 ++ ...view compatibility schema - Leaf node.json | 15 ++ ...iew compatibility schema - Map schema.json | 21 +++ ...Object schema including a union field.json | 34 ++++ ... schema including an identifier field.json | 29 +++ ... compatibility schema - Object schema.json | 41 ++++ ... compatibility schema - Record schema.json | 21 +++ ...lity schema - Recursive object schema.json | 30 +++ ...iew compatibility schema - Union root.json | 20 ++ 24 files changed, 440 insertions(+), 116 deletions(-) create mode 100644 packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json create mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json diff --git a/packages/dds/tree/src/simple-tree/api/index.ts b/packages/dds/tree/src/simple-tree/api/index.ts index 63a9e4a0e32e..55e1ee27d04c 100644 --- a/packages/dds/tree/src/simple-tree/api/index.ts +++ b/packages/dds/tree/src/simple-tree/api/index.ts @@ -162,3 +162,4 @@ export { generateSchemaFromSimpleSchema } from "./schemaFromSimple.js"; export { toSimpleTreeSchema } from "./viewSchemaToSimpleSchema.js"; export { toViewCompatibilityTreeSchema } from "./viewSchemaToViewCompatibilitySchema.js"; export type { TreeChangeEvents } from "./treeChangeEvents.js"; +export { toSerializableCompatibilitySchema } from "./serializableCompatibilitySchema.js"; diff --git a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts new file mode 100644 index 000000000000..b8dad4ce888b --- /dev/null +++ b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts @@ -0,0 +1,177 @@ +import type { JsonCompatible, JsonCompatibleObject } from "../../util/index.js"; +import type { ImplicitFieldSchema } from "../fieldSchema.js"; +import type { TreeViewConfigurationAlpha } from "./configuration.js"; +import { toViewCompatibilityTreeSchema } from "./viewSchemaToViewCompatibilitySchema.js"; +import { fail, unreachableCase } from "@fluidframework/core-utils/internal"; +import type { + SimpleArrayNodeSchema, + SimpleFieldSchema, + SimpleLeafNodeSchema, + SimpleMapNodeSchema, + SimpleNodeSchema, + SimpleObjectFieldSchema, + SimpleObjectNodeSchema, + SimpleRecordNodeSchema, +} from "../simpleSchema.js"; +import { NodeKind } from "../core/index.js"; + +/** + * Convert a view schema to a serializable format for compatibility testing. + * @remarks The JSON-compatible schema returned from this method is only intended for use in snapshots/comparisons of view schemas. + * It is not possible to reconstruct a full view schema from the serialized format. + * @param treeView - The tree view schema to convert. + * @returns A serializable representation of the view schema. + */ +export function toSerializableCompatibilitySchema( + treeView: TreeViewConfigurationAlpha, +): JsonCompatible { + const simpleSchema = toViewCompatibilityTreeSchema( + treeView, + // Copying is required for JSON serialization to avoid potential circular references in metadata/etc., as well as to ensure + // that the Map type serialization approach below does not modify the original schema. + true, + ); + + // Convert types to serializable forms + const serializableDefinitions = new Map(); + + for (const [identifier, schema] of simpleSchema.definitions) { + const serializableDefinition = nodeSchemaToSerializable(schema); + serializableDefinitions.set(identifier, serializableDefinition); + } + + const serializableSchema = { + root: toSerializableField(simpleSchema.root), + definitions: mapToRecord(serializableDefinitions), + } as unknown as JsonCompatible; + + return serializableSchema; +} + +/** + * Converts a node schema to a serializable object. + * @param schema - The node schema to convert. + * @returns A serializable representation of the node schema. + */ +function nodeSchemaToSerializable(schema: SimpleNodeSchema): JsonCompatibleObject { + const kind = schema.kind; + switch (kind) { + case NodeKind.Leaf: + return leafNodeToSerializable(schema); + case NodeKind.Array: + case NodeKind.Map: + case NodeKind.Record: + return containerNodeToSerializable(schema); + case NodeKind.Object: + return objectNodeToSerializable(schema); + default: { + unreachableCase(kind); + } + } +} + +/** + * Converts a leaf node schema to a serializable object. + * @param schema - The leaf node schema to convert. + * @returns A serializable representation of the leaf node schema. + */ +function leafNodeToSerializable(schema: SimpleLeafNodeSchema): JsonCompatibleObject { + return { + kind: schema.kind, + leafKind: schema.leafKind, + }; +} + +/** + * Converts a container node schema to a serializable object. + * @param schema - The container node schema to convert. + * @returns A serializable representation of the container node schema. Includes the `kind` for disambiguation between different + * container kinds. + */ +function containerNodeToSerializable( + schema: SimpleArrayNodeSchema | SimpleMapNodeSchema | SimpleRecordNodeSchema, +): JsonCompatibleObject { + return { + kind: schema.kind, + allowedTypesIdentifiers: setToArray(schema.allowedTypesIdentifiers), + }; +} + +/** + * Converts an object node schema to a serializable object. + * @param schema - The object node schema to convert. + * @returns A serializable representation of the object node schema. + */ +function objectNodeToSerializable(schema: SimpleObjectNodeSchema): JsonCompatibleObject { + const serializableFields: Record = {}; + for (const [fieldKey, fieldSchema] of schema.fields) { + serializableFields[fieldKey] = toSerializableObjectField(fieldSchema); + } + + return { + kind: schema.kind, + fields: serializableFields, + allowUnknownOptionalFields: schema.allowUnknownOptionalFields, + }; +} + +/** + * Converts an object field schema to a serializable object. + * @param fieldSchema - The object field schema to convert. + * @returns A serializable representation of the object field schema. + */ +function toSerializableObjectField( + fieldSchema: SimpleObjectFieldSchema, +): JsonCompatibleObject { + const serializableField = toSerializableField(fieldSchema); + serializableField.storedKey = fieldSchema.storedKey; + return serializableField; +} + +/** + * Converts a field schema to a serializable object. + * @param fieldSchema - The field schema to convert. + * @returns A serializable representation of the field schema. + */ +function toSerializableField(fieldSchema: SimpleFieldSchema): JsonCompatibleObject { + return { + kind: fieldSchema.kind, + allowedTypesIdentifiers: setToArray(fieldSchema.allowedTypesIdentifiers), + + // We can't serialize SchemaUpgrades, but the presence of staged upgrades is useful information for compatibility testing. + hasStagedSchemaUpgrades: + fieldSchema.stagedSchemaUpgrades !== undefined && + fieldSchema.stagedSchemaUpgrades.length > 0, + }; +} + +/** + * Convert a Map to a Record for serialization. + * @remarks This is needed because the JSON serializer does not support Maps. + * It is possible that the keys may not be stringify-able types, so this method is a best-effort implementation and its output + * should only be used in snapshots or debugging scenarios. + * @param map - The Map to convert. + * @returns A Record with the contents of the Map. + */ +function mapToRecord(map: ReadonlyMap): Record { + const resultObject: Record = {}; + const sortedKeys = Array.from(map.keys()).sort(); + + for (const key of sortedKeys) { + const value = + map.get(key) ?? fail("Invalid map: key present in keys() but not found in map."); + resultObject[`${key}`] = value; + } + + return resultObject; +} + +/** + * Convert a Set to a sorted Array for serialization. + * @remarks This is needed because the JSON serializer does not support Sets. + * @param set - The set to convert. + * @returns An Array with the contents of the Set sorted lexicographically. + */ +function setToArray(set: ReadonlySet): Value[] { + return Array.from(set).sort(); +} diff --git a/packages/dds/tree/src/simple-tree/index.ts b/packages/dds/tree/src/simple-tree/index.ts index 61358fb9b8fa..fadbe4d77e14 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -274,4 +274,7 @@ export { nullSchema, } from "./leafNodeSchema.js"; export type { LeafSchema } from "./leafNodeSchema.js"; -export { toViewCompatibilityTreeSchema } from "./api/index.js"; +export { + toViewCompatibilityTreeSchema, + toSerializableCompatibilitySchema, +} from "./api/index.js"; 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 e7b6bacfc3dc..b7eb83b465a7 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 @@ -10,9 +10,9 @@ import { SchemaFactory, SchemaFactoryAlpha, stringSchema, + toSerializableCompatibilitySchema, toViewCompatibilityTreeSchema, TreeViewConfigurationAlpha, - type ImplicitFieldSchema, type SimpleLeafNodeSchema, type SimpleNodeSchema, type SimpleObjectFieldSchema, @@ -23,7 +23,6 @@ import { ValueSchema } from "../../../core/index.js"; // eslint-disable-next-line import/no-internal-modules import { toSimpleTreeSchema } from "../../../simple-tree/api/viewSchemaToSimpleSchema.js"; import { takeJsonSnapshot, useSnapshotDirectory } from "../../snapshots/index.js"; -import type { JsonCompatible } from "../../../util/index.js"; const simpleString: SimpleLeafNodeSchema = { leafKind: ValueSchema.String, @@ -39,17 +38,6 @@ const simpleNumber: SimpleLeafNodeSchema = { persistedMetadata: undefined, }; -function toSerializableCompatibilitySchema( - treeView: TreeViewConfigurationAlpha, -): JsonCompatible { - const serializableSchema = toViewCompatibilityTreeSchema( - treeView, - // Copying is required for JSON serialization to avoid circular references in metadata/etc. - true, - ) as unknown as JsonCompatible; - return serializableSchema; -} - describe("getSimpleSchema", () => { useSnapshotDirectory("get-simple-schema"); @@ -122,7 +110,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Field Schema", () => { + it("view compatibility schema - Field Schema", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -166,7 +154,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Leaf node", () => { + it("view compatibility schema - Leaf node", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -222,7 +210,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Union root", () => { + it("view compatibility schema - Union root", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -289,7 +277,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Array schema", () => { + it("view compatibility schema - Array schema", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -356,7 +344,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Map schema", () => { + it("view compatibility schema - Map schema", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -423,7 +411,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Record schema", () => { + it("view compatibility schema - Record schema", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -540,7 +528,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Object schema", () => { + it("view compatibility schema - Object schema", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -633,7 +621,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field", () => { + it("view compatibility schema - Object schema including an identifier field", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -737,7 +725,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field", () => { + it("view compatibility schema - Object schema including a union field", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); @@ -836,7 +824,7 @@ describe("getSimpleSchema", () => { assert.deepEqual(actual, expected); }); - it("toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema", () => { + it("view compatibility schema - Recursive object schema", () => { const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Array schema.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json deleted file mode 100644 index c7f188a4293e..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Field Schema.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "root": { - "kind": 0, - "allowedTypesIdentifiers": {}, - "metadata": { - "description": "An optional string." - }, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Leaf node.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Map schema.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including a union field.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema including an identifier field.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Object schema.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Record schema.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Recursive object schema.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json deleted file mode 100644 index cb51003abbb9..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/toViewCompatibilityTreeSchema with JSON serialization - Union root.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesIdentifiers": {}, - "metadata": {}, - "stagedSchemaUpgrades": [] - }, - "definitions": {} -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json new file mode 100644 index 000000000000..921ada79ba2b --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json @@ -0,0 +1,21 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "test.array" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + }, + "test.array": { + "kind": 1, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ] + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json new file mode 100644 index 000000000000..48e3e0243dcd --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json @@ -0,0 +1,15 @@ +{ + "root": { + "kind": 0, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json new file mode 100644 index 000000000000..c22dcc3e517d --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json @@ -0,0 +1,15 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json new file mode 100644 index 000000000000..c693f05ea2a1 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json @@ -0,0 +1,21 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "test.map" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + }, + "test.map": { + "kind": 0, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ] + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json new file mode 100644 index 000000000000..b1d0cf45ee3d --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json @@ -0,0 +1,34 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "test.object" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.number": { + "kind": 3, + "leafKind": 0 + }, + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + }, + "test.object": { + "kind": 2, + "fields": { + "foo": { + "kind": 1, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.number", + "com.fluidframework.leaf.string" + ], + "hasStagedSchemaUpgrades": false, + "storedKey": "foo" + } + }, + "allowUnknownOptionalFields": false + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json new file mode 100644 index 000000000000..205c107e1713 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json @@ -0,0 +1,29 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "test.object" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + }, + "test.object": { + "kind": 2, + "fields": { + "id": { + "kind": 2, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ], + "hasStagedSchemaUpgrades": false, + "storedKey": "id" + } + }, + "allowUnknownOptionalFields": false + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json new file mode 100644 index 000000000000..b97cc5763501 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json @@ -0,0 +1,41 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "test.object" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.number": { + "kind": 3, + "leafKind": 0 + }, + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + }, + "test.object": { + "kind": 2, + "fields": { + "foo": { + "kind": 0, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.number" + ], + "hasStagedSchemaUpgrades": false, + "storedKey": "foo" + }, + "bar": { + "kind": 1, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ], + "hasStagedSchemaUpgrades": false, + "storedKey": "bar" + } + }, + "allowUnknownOptionalFields": false + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json new file mode 100644 index 000000000000..b1d0c0d72715 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json @@ -0,0 +1,21 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "test.record" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + }, + "test.record": { + "kind": 4, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ] + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json new file mode 100644 index 000000000000..43025e2a5112 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json @@ -0,0 +1,30 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "test.recursive-object" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + }, + "test.recursive-object": { + "kind": 2, + "fields": { + "foo": { + "kind": 0, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string", + "test.recursive-object" + ], + "hasStagedSchemaUpgrades": false, + "storedKey": "foo" + } + }, + "allowUnknownOptionalFields": false + } + } +} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json new file mode 100644 index 000000000000..2d6ae2f7b54b --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json @@ -0,0 +1,20 @@ +{ + "root": { + "kind": 1, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.number", + "com.fluidframework.leaf.string" + ], + "hasStagedSchemaUpgrades": false + }, + "definitions": { + "com.fluidframework.leaf.number": { + "kind": 3, + "leafKind": 0 + }, + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + } + } +} \ No newline at end of file From b168cd457ef0eb51091a27f7c25d1d6616e7907f Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Fri, 24 Oct 2025 14:29:04 -0700 Subject: [PATCH 08/23] Cleanup. --- .../api/serializableCompatibilitySchema.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts index b8dad4ce888b..adfe4d48e802 100644 --- a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts +++ b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts @@ -1,6 +1,5 @@ import type { JsonCompatible, JsonCompatibleObject } from "../../util/index.js"; -import type { ImplicitFieldSchema } from "../fieldSchema.js"; -import type { TreeViewConfigurationAlpha } from "./configuration.js"; +import type { TreeSchema } from "./configuration.js"; import { toViewCompatibilityTreeSchema } from "./viewSchemaToViewCompatibilitySchema.js"; import { fail, unreachableCase } from "@fluidframework/core-utils/internal"; import type { @@ -19,16 +18,13 @@ import { NodeKind } from "../core/index.js"; * Convert a view schema to a serializable format for compatibility testing. * @remarks The JSON-compatible schema returned from this method is only intended for use in snapshots/comparisons of view schemas. * It is not possible to reconstruct a full view schema from the serialized format. - * @param treeView - The tree view schema to convert. + * @param treeSchema - The tree schema to convert. * @returns A serializable representation of the view schema. */ -export function toSerializableCompatibilitySchema( - treeView: TreeViewConfigurationAlpha, -): JsonCompatible { +export function toSerializableCompatibilitySchema(treeSchema: TreeSchema): JsonCompatible { const simpleSchema = toViewCompatibilityTreeSchema( - treeView, - // Copying is required for JSON serialization to avoid potential circular references in metadata/etc., as well as to ensure - // that the Map type serialization approach below does not modify the original schema. + treeSchema, + // Copying strips out references to metadata and other non-essential information. true, ); From 95c255a81bf00dbd97937c007d7d72f16cffd739 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Fri, 24 Oct 2025 15:49:50 -0700 Subject: [PATCH 09/23] Added a test around hasStagedSchemaUpgrades. --- .../api/serializableCompatibilitySchema.ts | 2 +- .../getViewCompatibilityTreeSchema.spec.ts | 48 +++++++++++++++++++ ...lity schema - hasStagedSchemaUpgrades.json | 15 ++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts create mode 100644 packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - hasStagedSchemaUpgrades.json diff --git a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts index adfe4d48e802..a36ad1dd2f2c 100644 --- a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts +++ b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts @@ -15,7 +15,7 @@ import type { import { NodeKind } from "../core/index.js"; /** - * Convert a view schema to a serializable format for compatibility testing. + * Converts a view schema to a serializable format for compatibility testing. * @remarks The JSON-compatible schema returned from this method is only intended for use in snapshots/comparisons of view schemas. * It is not possible to reconstruct a full view schema from the serialized format. * @param treeSchema - The tree schema to convert. diff --git a/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts b/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts new file mode 100644 index 000000000000..cab1e9096d66 --- /dev/null +++ b/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts @@ -0,0 +1,48 @@ +import { + FieldKind, + SchemaFactoryAlpha, + stringSchema, + toSerializableCompatibilitySchema, + toViewCompatibilityTreeSchema, + TreeViewConfigurationAlpha, + type SimpleTreeSchema, +} from "../../../simple-tree/index.js"; +import { strict as assert } from "node:assert"; +import { takeJsonSnapshot, useSnapshotDirectory } from "../../snapshots/index.js"; + +describe("getViewCompatibilityTreeSchema", () => { + useSnapshotDirectory("get-view-compatibility-tree-schema"); + + describe("With staged schema upgrades", () => { + const leafSchema = stringSchema; + const schemaFactory = new SchemaFactoryAlpha("test"); + const root = schemaFactory.optional( + schemaFactory.types([schemaFactory.staged(leafSchema)]), + ); + + const stagedSchemaUpgrades = root.stagedSchemaUpgrades; + + it("Should preserve staged schema upgrades when converting to SimpleTreeSchema", () => { + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Optional, + allowedTypesIdentifiers: new Set([leafSchema.identifier]), + metadata: {}, + persistedMetadata: undefined, + stagedSchemaUpgrades, + }, + definitions: new Map([[leafSchema.identifier, leafSchema]]), + }; + + const treeView = new TreeViewConfigurationAlpha({ schema: root }); + const actual = toViewCompatibilityTreeSchema(treeView, true); + assert.deepEqual(actual.root.stagedSchemaUpgrades, expected.root.stagedSchemaUpgrades); + }); + + it("view compatibility schema - hasStagedSchemaUpgrades", () => { + const treeView = new TreeViewConfigurationAlpha({ schema: root }); + const actual = toSerializableCompatibilitySchema(treeView); + takeJsonSnapshot(actual); + }); + }); +}); diff --git a/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - hasStagedSchemaUpgrades.json b/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - hasStagedSchemaUpgrades.json new file mode 100644 index 000000000000..8cdf4d83e361 --- /dev/null +++ b/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - hasStagedSchemaUpgrades.json @@ -0,0 +1,15 @@ +{ + "root": { + "kind": 0, + "allowedTypesIdentifiers": [ + "com.fluidframework.leaf.string" + ], + "hasStagedSchemaUpgrades": true + }, + "definitions": { + "com.fluidframework.leaf.string": { + "kind": 3, + "leafKind": 1 + } + } +} \ No newline at end of file From 7559289ca970d6176b29945e3b50b21dc8d6f63e Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Tue, 28 Oct 2025 14:02:00 -0700 Subject: [PATCH 10/23] Added staged allowed type info to SimpleSchema. Started replacing allowedTypesIdentifiers with allowedTypesInfo. --- .../dds/tree/api-report/tree.alpha.api.md | 30 ++++-- packages/dds/tree/src/index.ts | 1 + .../dds/tree/src/shared-tree/sharedTree.ts | 16 ++++ .../api/serializableCompatibilitySchema.ts | 16 ++-- .../api/viewSchemaToSimpleSchema.ts | 6 +- .../viewSchemaToViewCompatibilitySchema.ts | 2 +- .../dds/tree/src/simple-tree/fieldSchema.ts | 31 +++++-- packages/dds/tree/src/simple-tree/index.ts | 1 + .../simple-tree/node-kinds/array/arrayNode.ts | 14 +++ .../src/simple-tree/node-kinds/map/mapNode.ts | 14 +++ .../node-kinds/record/recordNode.ts | 14 +++ .../dds/tree/src/simple-tree/simpleSchema.ts | 37 +++++++- .../simple-tree/api/getSimpleSchema.spec.ts | 93 ++++++++++++++++--- .../getViewCompatibilityTreeSchema.spec.ts | 11 +-- .../api/simpleSchemaToJsonSchema.spec.ts | 57 ++++++++++++ ...w compatibility schema - Array schema.json | 10 +- ...w compatibility schema - Field Schema.json | 10 +- ...view compatibility schema - Leaf node.json | 10 +- ...iew compatibility schema - Map schema.json | 10 +- ...Object schema including a union field.json | 23 +++-- ... schema including an identifier field.json | 18 ++-- ... compatibility schema - Object schema.json | 26 ++++-- ... compatibility schema - Record schema.json | 10 +- ...lity schema - Recursive object schema.json | 23 +++-- ...iew compatibility schema - Union root.json | 15 ++- ...ity schema - allowedTypesIdentifiers.json} | 10 +- 26 files changed, 393 insertions(+), 115 deletions(-) rename packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/{view compatibility schema - hasStagedSchemaUpgrades.json => view compatibility schema - allowedTypesIdentifiers.json} (51%) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 5cefeb2e47fd..0ca84653f09c 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -15,6 +15,11 @@ export function adaptEnum, true, Record, undefined>; }[keyof TEnum]>; }; +// @alpha @sealed +export interface AllowedTypeInfo { + readonly isStaged?: boolean; +} + // @alpha @input export interface AllowedTypeMetadata { readonly custom?: unknown; @@ -267,9 +272,11 @@ export class FieldSchemaAlpha; // (undocumented) + get allowedTypesInfo(): Map; + // (undocumented) get persistedMetadata(): JsonCompatibleReadOnlyObject | undefined; // (undocumented) - get stagedSchemaUpgrades(): SchemaUpgrade[]; + get readonlyAllowedTypesIdentifiers(): ReadonlySet; } // @alpha @sealed @system @@ -1001,15 +1008,16 @@ export type SharedTreeOptionsBeta = ForestOptions; // @alpha @sealed export interface SimpleArrayNodeSchema extends SimpleNodeSchemaBaseAlpha { readonly allowedTypesIdentifiers: ReadonlySet; + readonly allowedTypesInfo: ReadonlyMap; } // @alpha @sealed export interface SimpleFieldSchema { readonly allowedTypesIdentifiers: ReadonlySet; + readonly allowedTypesInfo: ReadonlyMap; readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; - readonly stagedSchemaUpgrades?: SchemaUpgrade[]; } // @alpha @sealed @@ -1020,6 +1028,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { readonly allowedTypesIdentifiers: ReadonlySet; + readonly allowedTypesInfo: ReadonlyMap; } // @alpha @@ -1050,6 +1059,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { readonly allowedTypesIdentifiers: ReadonlySet; + readonly allowedTypesInfo: ReadonlyMap; } // @alpha @@ -1100,18 +1110,18 @@ export namespace System_TableSchema { }>; // @system export function createTableSchema, const TRowSchema extends RowSchemaBase>(inputSchemaFactory: SchemaFactoryBeta, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): TreeNodeSchemaCore_2, "Table">, NodeKind.Object, true, { - readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; - readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; + readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; + readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; }, object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }, unknown> & (new (data: InternalTreeNode | (object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; })) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>) & { empty, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>>(this: TThis): InstanceType; }; // @system diff --git a/packages/dds/tree/src/index.ts b/packages/dds/tree/src/index.ts index 56a5c8e34da3..4fa6c43efbe6 100644 --- a/packages/dds/tree/src/index.ts +++ b/packages/dds/tree/src/index.ts @@ -277,6 +277,7 @@ export { type TreeParsingOptions, type SchemaFactory_base, type NumberKeys, + type AllowedTypeInfo, } 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 d5167388efd2..70cb9ccf56ee 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 AllowedTypeInfo, } from "../simple-tree/index.js"; import { SchematizingSimpleTreeView } from "./schematizingTreeView.js"; @@ -950,6 +952,16 @@ export const defaultSharedTreeOptions: Required = { shouldEncodeIncrementally: defaultIncrementalEncodingPolicy, }; +function buildAllowedTypesInfo(types: TreeTypeSet): ReadonlyMap { + const allowedTypesInfo = new Map(); + for (const type of types) { + allowedTypesInfo.set(type, { + isStaged: false, + }); + } + return allowedTypesInfo; +} + function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFieldSchema { let kind: FieldKind; switch (schema.kind) { @@ -971,7 +983,9 @@ function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFie } return { kind, + // TODO: Refactor allowedTypesIdentifiers: schema.types, + allowedTypesInfo: buildAllowedTypesInfo(schema.types), metadata: {}, persistedMetadata: schema.persistedMetadata, }; @@ -988,6 +1002,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS return { kind: NodeKind.Array, allowedTypesIdentifiers: arrayTypes, + allowedTypesInfo: buildAllowedTypesInfo(arrayTypes), metadata: {}, persistedMetadata: schema.metadata, }; @@ -1007,6 +1022,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS return { kind: NodeKind.Map, allowedTypesIdentifiers: schema.mapFields.types, + allowedTypesInfo: buildAllowedTypesInfo(schema.mapFields.types), metadata: {}, persistedMetadata: schema.metadata, }; diff --git a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts index a36ad1dd2f2c..37f9082dc0a3 100644 --- a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts +++ b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts @@ -3,6 +3,7 @@ import type { TreeSchema } from "./configuration.js"; import { toViewCompatibilityTreeSchema } from "./viewSchemaToViewCompatibilitySchema.js"; import { fail, unreachableCase } from "@fluidframework/core-utils/internal"; import type { + AllowedTypeInfo, SimpleArrayNodeSchema, SimpleFieldSchema, SimpleLeafNodeSchema, @@ -130,14 +131,17 @@ function toSerializableObjectField( * @returns A serializable representation of the field schema. */ function toSerializableField(fieldSchema: SimpleFieldSchema): JsonCompatibleObject { + const allowedTypesInfo: JsonCompatibleObject[] = []; + for (const [identifier, typeInfo] of fieldSchema.allowedTypesInfo ?? + new Map()) { + allowedTypesInfo.push({ + identifier, + isReadOnly: typeInfo.isStaged, + }); + } return { kind: fieldSchema.kind, - allowedTypesIdentifiers: setToArray(fieldSchema.allowedTypesIdentifiers), - - // We can't serialize SchemaUpgrades, but the presence of staged upgrades is useful information for compatibility testing. - hasStagedSchemaUpgrades: - fieldSchema.stagedSchemaUpgrades !== undefined && - fieldSchema.stagedSchemaUpgrades.length > 0, + allowedTypesInfo, }; } diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index deced9ee939a..8a5bc1b60d53 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -70,6 +70,7 @@ export function toSimpleTreeSchema( root: copySchemaObjects ? ({ allowedTypesIdentifiers: normalizedSchema.allowedTypesIdentifiers, + allowedTypesInfo: normalizedSchema.allowedTypesInfo, kind: normalizedSchema.kind, metadata: normalizedSchema.metadata, persistedMetadata: normalizedSchema.persistedMetadata, @@ -146,6 +147,7 @@ function copySimpleSchemaWithAllowedTypes( return { kind: schema.kind, allowedTypesIdentifiers: schema.allowedTypesIdentifiers, + allowedTypesInfo: schema.allowedTypesInfo, metadata: schema.metadata, persistedMetadata: schema.persistedMetadata, }; @@ -153,6 +155,7 @@ function copySimpleSchemaWithAllowedTypes( return { kind: schema.kind, allowedTypesIdentifiers: schema.allowedTypesIdentifiers, + allowedTypesInfo: schema.allowedTypesInfo, // Don't include metadata or persistedMetadata in view compatibility schema. metadata: {}, persistedMetadata: undefined, @@ -176,6 +179,7 @@ function copySimpleObjectSchema( simpleField = { kind: field.kind, allowedTypesIdentifiers: field.allowedTypesIdentifiers, + allowedTypesInfo: field.allowedTypesInfo, metadata: field.metadata, persistedMetadata: field.persistedMetadata, storedKey: field.storedKey, @@ -186,11 +190,11 @@ function copySimpleObjectSchema( simpleField = { kind: field.kind, allowedTypesIdentifiers: field.allowedTypesIdentifiers, + allowedTypesInfo: field.allowedTypesInfo, // Don't include metadata or persistedMetadata in view compatibility schema. metadata: {}, persistedMetadata: undefined, storedKey: field.storedKey, - stagedSchemaUpgrades: field.stagedSchemaUpgrades, }; break; diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts index fe4b2db8199f..afbf9ca28376 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts @@ -56,9 +56,9 @@ export function toViewCompatibilityTreeSchema( ? { kind: schema.root.kind, allowedTypesIdentifiers: schema.root.allowedTypesIdentifiers, + allowedTypesInfo: schema.root.allowedTypesInfo, metadata: schema.root.metadata, persistedMetadata: schema.root.persistedMetadata, - stagedSchemaUpgrades: schema.root.stagedSchemaUpgrades, } : schema.root, // TODO: Convert the root field definitions, diff --git a/packages/dds/tree/src/simple-tree/fieldSchema.ts b/packages/dds/tree/src/simple-tree/fieldSchema.ts index c02736b63c1d..bd5f3625f1f5 100644 --- a/packages/dds/tree/src/simple-tree/fieldSchema.ts +++ b/packages/dds/tree/src/simple-tree/fieldSchema.ts @@ -28,11 +28,10 @@ import type { TreeLeafValue, InsertableTreeNodeFromImplicitAllowedTypes, AllowedTypesFull, - SchemaUpgrade, } from "./core/index.js"; import { normalizeAllowedTypes } from "./core/index.js"; -import type { SimpleFieldSchema } from "./simpleSchema.js"; +import type { AllowedTypeInfo, SimpleFieldSchema } from "./simpleSchema.js"; import type { UnsafeUnknownSchema } from "./unsafeUnknownSchema.js"; import type { InsertableContent } from "./unhydratedFlexTreeFromInsertable.js"; @@ -413,16 +412,30 @@ export class FieldSchemaAlpha< return this.allowedTypesFull.evaluateIdentifiers(); } - public get stagedSchemaUpgrades(): SchemaUpgrade[] { + public get allowedTypesInfo(): Map { + 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; + } + + // TODO: Refactor allowedTypesIdentifiers and readonlyAllowedTypesIdentifiers so that there is an intermediate type containing + // the identifier and any other information needed for compatibility checks. + public get readonlyAllowedTypesIdentifiers(): ReadonlySet { const annotatedAllowedTypes = this.allowedTypesFull.evaluate().types; - const upgrades: SchemaUpgrade[] = []; - for (const type of annotatedAllowedTypes) { - if (type.metadata.stagedSchemaUpgrade !== undefined) { - upgrades.push(type.metadata.stagedSchemaUpgrade); + const readonlyTypes = new Set(); + for (const allowedType of annotatedAllowedTypes) { + if (allowedType.metadata.stagedSchemaUpgrade !== undefined) { + readonlyTypes.add(allowedType.type.identifier); } } - - return upgrades; + return readonlyTypes; } protected constructor( diff --git a/packages/dds/tree/src/simple-tree/index.ts b/packages/dds/tree/src/simple-tree/index.ts index fadbe4d77e14..0f83afc9ab0f 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -193,6 +193,7 @@ export type { SimpleNodeSchemaBaseAlpha, SimpleObjectFieldSchema, SimpleRecordNodeSchema, + AllowedTypeInfo, } 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 4573827927a8..217c427a28cb 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 @@ -68,6 +68,7 @@ import type { import { brand, type JsonCompatibleReadOnlyObject } from "../../../util/index.js"; import { nullSchema } from "../../leafNodeSchema.js"; import { arrayNodeStoredSchema } from "../../toStoredSchema.js"; +import type { AllowedTypeInfo } from "../../simpleSchema.js"; /** * A covariant base type for {@link (TreeArrayNode:interface)}. @@ -1168,6 +1169,15 @@ export function arraySchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); + const lazyAllowedTypesInfo = new Lazy(() => { + const map = new Map(); + for (const type of normalizedTypes.evaluate()) { + map.set(type.identifier, { + isStaged: false, + }); + } + return map; + }); let privateData: TreeNodeSchemaPrivateData | undefined; @@ -1206,6 +1216,10 @@ export function arraySchema< return lazyAllowedTypesIdentifiers.value; } + public static get allowedTypesInfo(): ReadonlyMap { + return lazyAllowedTypesInfo.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 3129feb44657..ab0a5d37d4cd 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 @@ -66,6 +66,7 @@ import type { import { recordLikeDataToFlexContent } from "../common.js"; import { MapNodeStoredSchema } from "../../../core/index.js"; import type { NodeSchemaOptionsAlpha } from "../../api/index.js"; +import type { AllowedTypeInfo } from "../../simpleSchema.js"; /** * A map of string keys to tree objects. @@ -275,6 +276,15 @@ export function mapSchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); + const lazyAllowedTypesInfo = new Lazy(() => { + const map = new Map(); + for (const type of normalizedTypes.evaluate()) { + map.set(type.identifier, { + isStaged: false, + }); + } + return map; + }); let privateData: TreeNodeSchemaPrivateData | undefined; const persistedMetadata = nodeOptions.persistedMetadata; @@ -303,6 +313,10 @@ export function mapSchema< return lazyAllowedTypesIdentifiers.value; } + public static get allowedTypesInfo(): ReadonlyMap { + return lazyAllowedTypesInfo.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 e257ddb56bfe..fb62d5b02d88 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 @@ -58,6 +58,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 { AllowedTypeInfo } from "../../simpleSchema.js"; /** * Create a proxy which implements the {@link TreeRecordNode} API. @@ -258,6 +259,15 @@ export function recordSchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); + const lazyAllowedTypesInfo = new Lazy(() => { + const map = new Map(); + for (const type of normalizedTypes.evaluate()) { + map.set(type.identifier, { + isStaged: false, + }); + } + return map; + }); let privateData: TreeNodeSchemaPrivateData | undefined; @@ -347,6 +357,10 @@ export function recordSchema< return lazyAllowedTypesIdentifiers.value; } + public static get allowedTypesInfo(): ReadonlyMap { + return lazyAllowedTypesInfo.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 62788e40c4df..862ac434e138 100644 --- a/packages/dds/tree/src/simple-tree/simpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/simpleSchema.ts @@ -5,7 +5,7 @@ import type { ValueSchema } from "../core/index.js"; import type { JsonCompatibleReadOnlyObject } from "../util/index.js"; -import type { NodeKind, SchemaUpgrade, SimpleNodeSchemaBase } from "./core/index.js"; +import type { NodeKind, SimpleNodeSchemaBase } from "./core/index.js"; import type { FieldKind, FieldSchemaMetadata } from "./fieldSchema.js"; /* @@ -99,6 +99,11 @@ export interface SimpleArrayNodeSchema * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ readonly allowedTypesIdentifiers: ReadonlySet; + + /** + * Information about the allowed types. + */ + readonly allowedTypesInfo: ReadonlyMap; } /** @@ -116,6 +121,11 @@ export interface SimpleMapNodeSchema * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ readonly allowedTypesIdentifiers: ReadonlySet; + + /** + * Information about the allowed types. + */ + readonly allowedTypesInfo: ReadonlyMap; } /** @@ -133,6 +143,11 @@ export interface SimpleRecordNodeSchema * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ readonly allowedTypesIdentifiers: ReadonlySet; + + /** + * Information about the allowed types. + */ + readonly allowedTypesInfo: ReadonlyMap; } /** @@ -169,6 +184,20 @@ export type SimpleNodeSchema = | SimpleObjectNodeSchema | SimpleRecordNodeSchema; +/** + * Information about allowed types under a field. + * + * @alpha + * @sealed + */ +export interface AllowedTypeInfo { + /** + * True if there is an associated schema upgrade that makes this type read-only. + * Undefined if derived from a stored schema, which has no concept of staged allowed type upgrades. + */ + readonly isStaged?: boolean; +} + /** * A simple, shallow representation of a schema for a field. * @@ -194,11 +223,9 @@ export interface SimpleFieldSchema { readonly allowedTypesIdentifiers: ReadonlySet; /** - * Staged schema upgrades for this field indexed by the allowed type identifier they apply to. - * - * @remarks Used for compatibility checks (see {@link toViewCompatibilityTreeSchema}). Not available in all cases. + * Information about the allowed types under this field. */ - readonly stagedSchemaUpgrades?: SchemaUpgrade[]; + readonly allowedTypesInfo: ReadonlyMap; /** * {@inheritDoc FieldSchemaMetadata} 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 b7eb83b465a7..7d9fe1a35c1f 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 @@ -84,6 +84,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Optional, metadata: { description: "An optional string." }, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), persistedMetadata: undefined, }, definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), @@ -101,8 +102,8 @@ describe("getSimpleSchema", () => { kind: FieldKind.Optional, metadata: { description: "An optional string." }, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), persistedMetadata: undefined, - stagedSchemaUpgrades: [], }, definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), }; @@ -128,6 +129,7 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), persistedMetadata: undefined, }, definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), @@ -145,8 +147,8 @@ describe("getSimpleSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), persistedMetadata: undefined, - stagedSchemaUpgrades: [], }, definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), }; @@ -176,6 +178,10 @@ describe("getSimpleSchema", () => { "com.fluidframework.leaf.number", "com.fluidframework.leaf.string", ]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, definitions: new Map([ ["com.fluidframework.leaf.number", simpleNumber], @@ -199,7 +205,10 @@ describe("getSimpleSchema", () => { "com.fluidframework.leaf.number", "com.fluidframework.leaf.string", ]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, definitions: new Map([ ["com.fluidframework.leaf.number", simpleNumber], @@ -230,6 +239,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.array"]), + allowedTypesInfo: new Map([["test.array", { isStaged: false }]]), }, definitions: new Map([ [ @@ -237,6 +247,9 @@ describe("getSimpleSchema", () => { { kind: NodeKind.Array, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), metadata: {}, persistedMetadata: undefined, }, @@ -258,7 +271,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.array"]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([["test.array", { isStaged: false }]]), }, definitions: new Map([ [ @@ -266,6 +279,9 @@ describe("getSimpleSchema", () => { { kind: NodeKind.Array, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), metadata: {}, persistedMetadata: undefined, }, @@ -297,6 +313,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.map"]), + allowedTypesInfo: new Map([["test.map", { isStaged: false }]]), }, definitions: new Map([ [ @@ -306,6 +323,9 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, ], ["com.fluidframework.leaf.string", simpleString], @@ -325,7 +345,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.map"]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([["test.map", { isStaged: false }]]), }, definitions: new Map([ [ @@ -335,6 +355,9 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, ], ["com.fluidframework.leaf.string", simpleString], @@ -364,6 +387,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.record"]), + allowedTypesInfo: new Map([["test.record", { isStaged: false }]]), }, definitions: new Map([ [ @@ -373,6 +397,9 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, ], ["com.fluidframework.leaf.string", simpleString], @@ -392,7 +419,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.record"]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([["test.record", { isStaged: false }]]), }, definitions: new Map([ [ @@ -402,6 +429,9 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), }, ], ["com.fluidframework.leaf.string", simpleString], @@ -434,6 +464,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.object"]), + allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -450,6 +481,9 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ]), storedKey: "foo", }, ], @@ -460,6 +494,9 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "bar", }, ], @@ -484,7 +521,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.object"]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -502,8 +539,10 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ]), storedKey: "foo", - stagedSchemaUpgrades: [], }, ], [ @@ -513,8 +552,10 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "bar", - stagedSchemaUpgrades: [], }, ], ]), @@ -550,6 +591,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.object"]), + allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -566,6 +608,9 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "id", }, ], @@ -588,7 +633,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.object"]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -606,8 +651,10 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "id", - stagedSchemaUpgrades: [], }, ], ]), @@ -644,6 +691,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.object"]), + allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -663,6 +711,10 @@ describe("getSimpleSchema", () => { "com.fluidframework.leaf.number", "com.fluidframework.leaf.string", ]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "foo", }, ], @@ -689,7 +741,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.object"]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -710,8 +762,11 @@ describe("getSimpleSchema", () => { "com.fluidframework.leaf.number", "com.fluidframework.leaf.string", ]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), storedKey: "foo", - stagedSchemaUpgrades: [], }, ], ]), @@ -747,6 +802,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.recursive-object"]), + allowedTypesInfo: new Map([["test.recursive-object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -766,6 +822,10 @@ describe("getSimpleSchema", () => { "com.fluidframework.leaf.string", "test.recursive-object", ]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ["test.recursive-object", { isStaged: false }], + ]), storedKey: "foo", }, ], @@ -789,7 +849,7 @@ describe("getSimpleSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set(["test.recursive-object"]), - stagedSchemaUpgrades: [], + allowedTypesInfo: new Map([["test.recursive-object", { isStaged: false }]]), }, definitions: new Map([ [ @@ -810,8 +870,11 @@ describe("getSimpleSchema", () => { "com.fluidframework.leaf.string", "test.recursive-object", ]), + allowedTypesInfo: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ["test.recursive-object", { isStaged: false }], + ]), storedKey: "foo", - stagedSchemaUpgrades: [], }, ], ]), diff --git a/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts b/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts index cab1e9096d66..4fc8d78e5719 100644 --- a/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts +++ b/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts @@ -17,29 +17,28 @@ describe("getViewCompatibilityTreeSchema", () => { const leafSchema = stringSchema; const schemaFactory = new SchemaFactoryAlpha("test"); const root = schemaFactory.optional( + // Staged allowed types are read-only for the sake of schema migrations schemaFactory.types([schemaFactory.staged(leafSchema)]), ); - const stagedSchemaUpgrades = root.stagedSchemaUpgrades; - - it("Should preserve staged schema upgrades when converting to SimpleTreeSchema", () => { + it("Should preserve isReadOnly when converting to SimpleTreeSchema", () => { const expected: SimpleTreeSchema = { root: { kind: FieldKind.Optional, + allowedTypesInfo: new Map([[leafSchema.identifier, { isStaged: true }]]), allowedTypesIdentifiers: new Set([leafSchema.identifier]), metadata: {}, persistedMetadata: undefined, - stagedSchemaUpgrades, }, definitions: new Map([[leafSchema.identifier, leafSchema]]), }; const treeView = new TreeViewConfigurationAlpha({ schema: root }); const actual = toViewCompatibilityTreeSchema(treeView, true); - assert.deepEqual(actual.root.stagedSchemaUpgrades, expected.root.stagedSchemaUpgrades); + assert.deepEqual(actual.root.allowedTypesInfo, expected.root.allowedTypesInfo); }); - it("view compatibility schema - hasStagedSchemaUpgrades", () => { + it("view compatibility schema - allowedTypesIdentifiers", () => { const treeView = new TreeViewConfigurationAlpha({ schema: root }); const actual = toSerializableCompatibilitySchema(treeView); takeJsonSnapshot(actual); 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..f62fc8968d1f 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 { + AllowedTypeInfo, SimpleNodeSchema, SimpleTreeSchema, // eslint-disable-next-line import/no-internal-modules @@ -50,6 +51,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set([stringSchema.identifier]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, definitions: new Map([ [stringSchema.identifier, stringSchema], @@ -86,6 +90,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set(["test.handle"]), + allowedTypesInfo: new Map([ + ["test.handle", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -108,6 +115,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, allowedTypesIdentifiers: new Set(["test.array"]), + allowedTypesInfo: new Map([ + ["test.array", { isStaged: false }], + ]), metadata: {}, }, definitions: new Map([ @@ -118,6 +128,9 @@ describe("simpleSchemaToJsonSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set([stringSchema.identifier]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, ], [stringSchema.identifier, stringSchema], @@ -161,6 +174,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, allowedTypesIdentifiers: new Set(["test.map"]), + allowedTypesInfo: new Map([ + ["test.map", { isStaged: false }], + ]), metadata: {}, }, definitions: new Map([ @@ -171,6 +187,9 @@ describe("simpleSchemaToJsonSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set([stringSchema.identifier]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, ], [stringSchema.identifier, stringSchema], @@ -226,6 +245,9 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, allowedTypesIdentifiers: new Set(["test.record"]), + allowedTypesInfo: new Map([ + ["test.record", { isStaged: false }], + ]), metadata: {}, }, definitions: new Map([ @@ -236,6 +258,9 @@ describe("simpleSchemaToJsonSchema", () => { metadata: {}, persistedMetadata: undefined, allowedTypesIdentifiers: new Set([stringSchema.identifier]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), }, ], [stringSchema.identifier, stringSchema], @@ -338,6 +363,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set(["test.object"]), + allowedTypesInfo: new Map([ + ["test.object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -352,6 +380,9 @@ describe("simpleSchemaToJsonSchema", () => { { kind: FieldKind.Optional, allowedTypesIdentifiers: new Set([numberSchema.identifier]), + allowedTypesInfo: new Map([ + [numberSchema.identifier, { isStaged: false }], + ]), metadata: { description: "A number representing the concept of Foo." }, persistedMetadata: undefined, storedKey: "foo", @@ -362,6 +393,9 @@ describe("simpleSchemaToJsonSchema", () => { { kind: FieldKind.Required, allowedTypesIdentifiers: new Set([stringSchema.identifier]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), metadata: { description: "A string representing the concept of Bar." }, persistedMetadata: undefined, storedKey: "bar", @@ -372,6 +406,9 @@ describe("simpleSchemaToJsonSchema", () => { { kind: FieldKind.Identifier, allowedTypesIdentifiers: new Set([stringSchema.identifier]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), metadata: { description: "Unique identifier for the test object.", }, @@ -475,6 +512,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set(["test.object"]), + allowedTypesInfo: new Map([ + ["test.object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -489,6 +529,9 @@ describe("simpleSchemaToJsonSchema", () => { { kind: FieldKind.Identifier, allowedTypesIdentifiers: new Set([stringSchema.identifier]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ]), storedKey: "id", metadata: {}, }, @@ -531,6 +574,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set(["test.object"]), + allowedTypesInfo: new Map([ + ["test.object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -550,6 +596,10 @@ describe("simpleSchemaToJsonSchema", () => { numberSchema.identifier, stringSchema.identifier, ]), + allowedTypesInfo: new Map([ + [numberSchema.identifier, { isStaged: false }], + [stringSchema.identifier, { isStaged: false }], + ]), storedKey: "foo", }, ], @@ -599,6 +649,9 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, allowedTypesIdentifiers: new Set(["test.recursive-object"]), + allowedTypesInfo: new Map([ + ["test.recursive-object", { isStaged: false }], + ]), }, definitions: new Map([ [ @@ -618,6 +671,10 @@ describe("simpleSchemaToJsonSchema", () => { stringSchema.identifier, "test.recursive-object", ]), + allowedTypesInfo: new Map([ + [stringSchema.identifier, { isStaged: false }], + ["test.recursive-object", { isStaged: false }], + ]), storedKey: "foo", }, ], diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json index 921ada79ba2b..5e47334f1ab3 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "test.array" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "test.array", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.string": { diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json index 48e3e0243dcd..8f241c679833 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json @@ -1,10 +1,12 @@ { "root": { "kind": 0, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.string": { diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json index c22dcc3e517d..607f716b6e59 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.string": { diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json index c693f05ea2a1..0eb0719b8250 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "test.map" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "test.map", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.string": { diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json index b1d0cf45ee3d..7a1bf683304f 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "test.object" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "test.object", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.number": { @@ -20,11 +22,16 @@ "fields": { "foo": { "kind": 1, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string" + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.number", + "isReadOnly": false + }, + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": false + } ], - "hasStagedSchemaUpgrades": false, "storedKey": "foo" } }, diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json index 205c107e1713..15e6f78db6df 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "test.object" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "test.object", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.string": { @@ -16,10 +18,12 @@ "fields": { "id": { "kind": 2, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": false + } ], - "hasStagedSchemaUpgrades": false, "storedKey": "id" } }, diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json index b97cc5763501..006c0ff80071 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "test.object" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "test.object", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.number": { @@ -20,18 +22,22 @@ "fields": { "foo": { "kind": 0, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.number" + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.number", + "isReadOnly": false + } ], - "hasStagedSchemaUpgrades": false, "storedKey": "foo" }, "bar": { "kind": 1, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": false + } ], - "hasStagedSchemaUpgrades": false, "storedKey": "bar" } }, diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json index b1d0c0d72715..ac96d7074949 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "test.record" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "test.record", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.string": { diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json index 43025e2a5112..9569637fcc5a 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json @@ -1,10 +1,12 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "test.recursive-object" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "test.recursive-object", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.string": { @@ -16,11 +18,16 @@ "fields": { "foo": { "kind": 0, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string", - "test.recursive-object" + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": false + }, + { + "identifier": "test.recursive-object", + "isReadOnly": false + } ], - "hasStagedSchemaUpgrades": false, "storedKey": "foo" } }, diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json index 2d6ae2f7b54b..2a900a4635ed 100644 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json +++ b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json @@ -1,11 +1,16 @@ { "root": { "kind": 1, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string" - ], - "hasStagedSchemaUpgrades": false + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.number", + "isReadOnly": false + }, + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": false + } + ] }, "definitions": { "com.fluidframework.leaf.number": { diff --git a/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - hasStagedSchemaUpgrades.json b/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - allowedTypesIdentifiers.json similarity index 51% rename from packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - hasStagedSchemaUpgrades.json rename to packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - allowedTypesIdentifiers.json index 8cdf4d83e361..d85b1242c0c8 100644 --- a/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - hasStagedSchemaUpgrades.json +++ b/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - allowedTypesIdentifiers.json @@ -1,10 +1,12 @@ { "root": { "kind": 0, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" - ], - "hasStagedSchemaUpgrades": true + "allowedTypesInfo": [ + { + "identifier": "com.fluidframework.leaf.string", + "isReadOnly": true + } + ] }, "definitions": { "com.fluidframework.leaf.string": { From 2e443d4becd85b5423b16887cee97c6a30d86bc7 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Tue, 28 Oct 2025 17:30:13 -0700 Subject: [PATCH 11/23] Replaced SimpleSchema allowedTypesIdentifiers with simpleAllowedTypes. --- .../dds/tree/api-report/tree.alpha.api.md | 19 +- packages/dds/tree/src/index.ts | 1 - .../dds/tree/src/shared-tree/sharedTree.ts | 11 +- .../dds/tree/src/simple-tree/api/index.ts | 2 - .../src/simple-tree/api/schemaFromSimple.ts | 30 +- .../api/serializableCompatibilitySchema.ts | 177 --- .../api/simpleSchemaToJsonSchema.ts | 10 +- .../api/viewSchemaToSimpleSchema.ts | 162 +-- .../viewSchemaToViewCompatibilitySchema.ts | 66 - .../dds/tree/src/simple-tree/fieldSchema.ts | 19 +- packages/dds/tree/src/simple-tree/index.ts | 6 +- .../simple-tree/node-kinds/array/arrayNode.ts | 10 +- .../src/simple-tree/node-kinds/map/mapNode.ts | 10 +- .../node-kinds/record/recordNode.ts | 10 +- .../dds/tree/src/simple-tree/simpleSchema.ts | 43 +- .../tree/src/simple-tree/toStoredSchema.ts | 15 +- .../simple-tree/api/getSimpleSchema.spec.ts | 1064 +++++------------ .../getViewCompatibilityTreeSchema.spec.ts | 47 - .../api/simpleSchemaToJsonSchema.spec.ts | 62 +- ...w compatibility schema - Array schema.json | 23 - ...w compatibility schema - Field Schema.json | 17 - ...view compatibility schema - Leaf node.json | 17 - ...iew compatibility schema - Map schema.json | 23 - ...Object schema including a union field.json | 41 - ... schema including an identifier field.json | 33 - ... compatibility schema - Object schema.json | 47 - ... compatibility schema - Record schema.json | 23 - ...lity schema - Recursive object schema.json | 37 - ...iew compatibility schema - Union root.json | 25 - ...lity schema - allowedTypesIdentifiers.json | 17 - 30 files changed, 412 insertions(+), 1655 deletions(-) delete mode 100644 packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts delete mode 100644 packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts delete mode 100644 packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json delete mode 100644 packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - allowedTypesIdentifiers.json diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 0ca84653f09c..74c2f789c4df 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -272,11 +272,9 @@ export class FieldSchemaAlpha; // (undocumented) - get allowedTypesInfo(): Map; - // (undocumented) get persistedMetadata(): JsonCompatibleReadOnlyObject | undefined; // (undocumented) - get readonlyAllowedTypesIdentifiers(): ReadonlySet; + get simpleAllowedTypes(): Map; } // @alpha @sealed @system @@ -1007,17 +1005,15 @@ export type SharedTreeOptionsBeta = ForestOptions; // @alpha @sealed export interface SimpleArrayNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; - readonly allowedTypesInfo: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed export interface SimpleFieldSchema { - readonly allowedTypesIdentifiers: ReadonlySet; - readonly allowedTypesInfo: ReadonlyMap; readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1027,8 +1023,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; - readonly allowedTypesInfo: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1058,8 +1053,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; - readonly allowedTypesInfo: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1308,9 +1302,6 @@ export namespace TableSchema { }): System_TableSchema.TableSchemaBase; } -// @alpha -export function toViewCompatibilityTreeSchema(schema: TreeSchema, copySchemaObjects: boolean): SimpleTreeSchema; - // @alpha export function trackDirtyNodes(view: TreeViewAlpha, dirty: DirtyTreeMap): () => void; diff --git a/packages/dds/tree/src/index.ts b/packages/dds/tree/src/index.ts index 4fa6c43efbe6..fe5b4dc865b6 100644 --- a/packages/dds/tree/src/index.ts +++ b/packages/dds/tree/src/index.ts @@ -339,4 +339,3 @@ export { JsonAsTree } from "./jsonDomainSchema.js"; export { FluidSerializableAsTree } from "./serializableDomainSchema.js"; export { TableSchema, type System_TableSchema } from "./tableSchema.js"; export { asAlpha } from "./api.js"; -export { toViewCompatibilityTreeSchema } from "./simple-tree/index.js"; diff --git a/packages/dds/tree/src/shared-tree/sharedTree.ts b/packages/dds/tree/src/shared-tree/sharedTree.ts index 70cb9ccf56ee..689c67f71fe2 100644 --- a/packages/dds/tree/src/shared-tree/sharedTree.ts +++ b/packages/dds/tree/src/shared-tree/sharedTree.ts @@ -952,7 +952,7 @@ export const defaultSharedTreeOptions: Required = { shouldEncodeIncrementally: defaultIncrementalEncodingPolicy, }; -function buildAllowedTypesInfo(types: TreeTypeSet): ReadonlyMap { +function buildSimpleAllowedTypes(types: TreeTypeSet): ReadonlyMap { const allowedTypesInfo = new Map(); for (const type of types) { allowedTypesInfo.set(type, { @@ -984,8 +984,7 @@ function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFie return { kind, // TODO: Refactor - allowedTypesIdentifiers: schema.types, - allowedTypesInfo: buildAllowedTypesInfo(schema.types), + simpleAllowedTypes: buildSimpleAllowedTypes(schema.types), metadata: {}, persistedMetadata: schema.persistedMetadata, }; @@ -1001,8 +1000,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS if (arrayTypes !== undefined) { return { kind: NodeKind.Array, - allowedTypesIdentifiers: arrayTypes, - allowedTypesInfo: buildAllowedTypesInfo(arrayTypes), + simpleAllowedTypes: buildSimpleAllowedTypes(arrayTypes), metadata: {}, persistedMetadata: schema.metadata, }; @@ -1021,8 +1019,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS ); return { kind: NodeKind.Map, - allowedTypesIdentifiers: schema.mapFields.types, - allowedTypesInfo: buildAllowedTypesInfo(schema.mapFields.types), + simpleAllowedTypes: buildSimpleAllowedTypes(schema.mapFields.types), metadata: {}, persistedMetadata: schema.metadata, }; diff --git a/packages/dds/tree/src/simple-tree/api/index.ts b/packages/dds/tree/src/simple-tree/api/index.ts index 55e1ee27d04c..c42426cec935 100644 --- a/packages/dds/tree/src/simple-tree/api/index.ts +++ b/packages/dds/tree/src/simple-tree/api/index.ts @@ -160,6 +160,4 @@ export { export { generateSchemaFromSimpleSchema } from "./schemaFromSimple.js"; export { toSimpleTreeSchema } from "./viewSchemaToSimpleSchema.js"; -export { toViewCompatibilityTreeSchema } from "./viewSchemaToViewCompatibilitySchema.js"; export type { TreeChangeEvents } from "./treeChangeEvents.js"; -export { toSerializableCompatibilitySchema } from "./serializableCompatibilitySchema.js"; diff --git a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts index dd3ece77442b..d8f2b3e8e7ce 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 { + SimpleAllowedTypes, 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,13 @@ 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 [...new Set(allowed.keys())].map( + (id) => context.get(id) ?? fail(0xb5a /* Missing schema */), + ); } function generateNode( @@ -104,21 +110,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/serializableCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts deleted file mode 100644 index 37f9082dc0a3..000000000000 --- a/packages/dds/tree/src/simple-tree/api/serializableCompatibilitySchema.ts +++ /dev/null @@ -1,177 +0,0 @@ -import type { JsonCompatible, JsonCompatibleObject } from "../../util/index.js"; -import type { TreeSchema } from "./configuration.js"; -import { toViewCompatibilityTreeSchema } from "./viewSchemaToViewCompatibilitySchema.js"; -import { fail, unreachableCase } from "@fluidframework/core-utils/internal"; -import type { - AllowedTypeInfo, - SimpleArrayNodeSchema, - SimpleFieldSchema, - SimpleLeafNodeSchema, - SimpleMapNodeSchema, - SimpleNodeSchema, - SimpleObjectFieldSchema, - SimpleObjectNodeSchema, - SimpleRecordNodeSchema, -} from "../simpleSchema.js"; -import { NodeKind } from "../core/index.js"; - -/** - * Converts a view schema to a serializable format for compatibility testing. - * @remarks The JSON-compatible schema returned from this method is only intended for use in snapshots/comparisons of view schemas. - * It is not possible to reconstruct a full view schema from the serialized format. - * @param treeSchema - The tree schema to convert. - * @returns A serializable representation of the view schema. - */ -export function toSerializableCompatibilitySchema(treeSchema: TreeSchema): JsonCompatible { - const simpleSchema = toViewCompatibilityTreeSchema( - treeSchema, - // Copying strips out references to metadata and other non-essential information. - true, - ); - - // Convert types to serializable forms - const serializableDefinitions = new Map(); - - for (const [identifier, schema] of simpleSchema.definitions) { - const serializableDefinition = nodeSchemaToSerializable(schema); - serializableDefinitions.set(identifier, serializableDefinition); - } - - const serializableSchema = { - root: toSerializableField(simpleSchema.root), - definitions: mapToRecord(serializableDefinitions), - } as unknown as JsonCompatible; - - return serializableSchema; -} - -/** - * Converts a node schema to a serializable object. - * @param schema - The node schema to convert. - * @returns A serializable representation of the node schema. - */ -function nodeSchemaToSerializable(schema: SimpleNodeSchema): JsonCompatibleObject { - const kind = schema.kind; - switch (kind) { - case NodeKind.Leaf: - return leafNodeToSerializable(schema); - case NodeKind.Array: - case NodeKind.Map: - case NodeKind.Record: - return containerNodeToSerializable(schema); - case NodeKind.Object: - return objectNodeToSerializable(schema); - default: { - unreachableCase(kind); - } - } -} - -/** - * Converts a leaf node schema to a serializable object. - * @param schema - The leaf node schema to convert. - * @returns A serializable representation of the leaf node schema. - */ -function leafNodeToSerializable(schema: SimpleLeafNodeSchema): JsonCompatibleObject { - return { - kind: schema.kind, - leafKind: schema.leafKind, - }; -} - -/** - * Converts a container node schema to a serializable object. - * @param schema - The container node schema to convert. - * @returns A serializable representation of the container node schema. Includes the `kind` for disambiguation between different - * container kinds. - */ -function containerNodeToSerializable( - schema: SimpleArrayNodeSchema | SimpleMapNodeSchema | SimpleRecordNodeSchema, -): JsonCompatibleObject { - return { - kind: schema.kind, - allowedTypesIdentifiers: setToArray(schema.allowedTypesIdentifiers), - }; -} - -/** - * Converts an object node schema to a serializable object. - * @param schema - The object node schema to convert. - * @returns A serializable representation of the object node schema. - */ -function objectNodeToSerializable(schema: SimpleObjectNodeSchema): JsonCompatibleObject { - const serializableFields: Record = {}; - for (const [fieldKey, fieldSchema] of schema.fields) { - serializableFields[fieldKey] = toSerializableObjectField(fieldSchema); - } - - return { - kind: schema.kind, - fields: serializableFields, - allowUnknownOptionalFields: schema.allowUnknownOptionalFields, - }; -} - -/** - * Converts an object field schema to a serializable object. - * @param fieldSchema - The object field schema to convert. - * @returns A serializable representation of the object field schema. - */ -function toSerializableObjectField( - fieldSchema: SimpleObjectFieldSchema, -): JsonCompatibleObject { - const serializableField = toSerializableField(fieldSchema); - serializableField.storedKey = fieldSchema.storedKey; - return serializableField; -} - -/** - * Converts a field schema to a serializable object. - * @param fieldSchema - The field schema to convert. - * @returns A serializable representation of the field schema. - */ -function toSerializableField(fieldSchema: SimpleFieldSchema): JsonCompatibleObject { - const allowedTypesInfo: JsonCompatibleObject[] = []; - for (const [identifier, typeInfo] of fieldSchema.allowedTypesInfo ?? - new Map()) { - allowedTypesInfo.push({ - identifier, - isReadOnly: typeInfo.isStaged, - }); - } - return { - kind: fieldSchema.kind, - allowedTypesInfo, - }; -} - -/** - * Convert a Map to a Record for serialization. - * @remarks This is needed because the JSON serializer does not support Maps. - * It is possible that the keys may not be stringify-able types, so this method is a best-effort implementation and its output - * should only be used in snapshots or debugging scenarios. - * @param map - The Map to convert. - * @returns A Record with the contents of the Map. - */ -function mapToRecord(map: ReadonlyMap): Record { - const resultObject: Record = {}; - const sortedKeys = Array.from(map.keys()).sort(); - - for (const key of sortedKeys) { - const value = - map.get(key) ?? fail("Invalid map: key present in keys() but not found in map."); - resultObject[`${key}`] = value; - } - - return resultObject; -} - -/** - * Convert a Set to a sorted Array for serialization. - * @remarks This is needed because the JSON serializer does not support Sets. - * @param set - The set to convert. - * @returns An Array with the contents of the Set sorted lexicographically. - */ -function setToArray(set: ReadonlySet): Value[] { - return Array.from(set).sort(); -} 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 8a5bc1b60d53..15a6e1d3017e 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -59,9 +59,7 @@ export function toSimpleTreeSchema( nodeSchema instanceof RecordNodeSchema, 0xb60 /* Invalid schema */, ); - const outSchema = copySchemaObjects - ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyMode.SimpleSchema) - : nodeSchema; + const outSchema = copySchemaObjects ? copySimpleNodeSchema(nodeSchema) : nodeSchema; definitions.set(nodeSchema.identifier, outSchema); }, }); @@ -69,8 +67,7 @@ export function toSimpleTreeSchema( return { root: copySchemaObjects ? ({ - allowedTypesIdentifiers: normalizedSchema.allowedTypesIdentifiers, - allowedTypesInfo: normalizedSchema.allowedTypesInfo, + simpleAllowedTypes: normalizedSchema.simpleAllowedTypes, kind: normalizedSchema.kind, metadata: normalizedSchema.metadata, persistedMetadata: normalizedSchema.persistedMetadata, @@ -80,157 +77,64 @@ export function toSimpleTreeSchema( }; } -/** - * Specifies which fields are included when copying a Simple Schema. - */ -export enum SimpleSchemaCopyMode { - // TODO: Rename - SimpleSchema, - ViewCompatibilitySchema, -} - /** * Copies a {@link SimpleNodeSchema} into a new plain JavaScript object. * * @remarks Caches the result on the input schema for future calls. */ -export function copySimpleNodeSchema( - schema: SimpleNodeSchema, - copyMode: SimpleSchemaCopyMode, -): SimpleNodeSchema { +function copySimpleNodeSchema(schema: SimpleNodeSchema): SimpleNodeSchema { const kind = schema.kind; switch (kind) { case NodeKind.Leaf: - return copySimpleLeafSchema(schema, copyMode); + return copySimpleLeafSchema(schema); case NodeKind.Array: case NodeKind.Map: case NodeKind.Record: - return copySimpleSchemaWithAllowedTypes(schema, copyMode); + return copySimpleSchemaWithAllowedTypes(schema); case NodeKind.Object: - return copySimpleObjectSchema(schema, copyMode); + return copySimpleObjectSchema(schema); default: unreachableCase(kind); } } -function copySimpleLeafSchema( - schema: SimpleLeafNodeSchema, - copyMode: SimpleSchemaCopyMode, -): SimpleLeafNodeSchema { - switch (copyMode) { - case SimpleSchemaCopyMode.SimpleSchema: - return { - kind: NodeKind.Leaf, - leafKind: schema.leafKind, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; - case SimpleSchemaCopyMode.ViewCompatibilitySchema: - return { - kind: NodeKind.Leaf, - leafKind: schema.leafKind, - // Don't include metadata or persistedMetadata in view compatibility schema. - metadata: {}, - persistedMetadata: undefined, - }; - default: - unreachableCase(copyMode); - } +function copySimpleLeafSchema(schema: SimpleLeafNodeSchema): SimpleLeafNodeSchema { + return { + kind: NodeKind.Leaf, + leafKind: schema.leafKind, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; } function copySimpleSchemaWithAllowedTypes( schema: SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema, - copyMode: SimpleSchemaCopyMode, ): SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema { - switch (copyMode) { - case SimpleSchemaCopyMode.SimpleSchema: - return { - kind: schema.kind, - allowedTypesIdentifiers: schema.allowedTypesIdentifiers, - allowedTypesInfo: schema.allowedTypesInfo, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; - case SimpleSchemaCopyMode.ViewCompatibilitySchema: - return { - kind: schema.kind, - allowedTypesIdentifiers: schema.allowedTypesIdentifiers, - allowedTypesInfo: schema.allowedTypesInfo, - // Don't include metadata or persistedMetadata in view compatibility schema. - metadata: {}, - persistedMetadata: undefined, - }; - default: - unreachableCase(copyMode); - } + return { + kind: schema.kind, + simpleAllowedTypes: schema.simpleAllowedTypes, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; } -function copySimpleObjectSchema( - schema: SimpleObjectNodeSchema, - copyMode: SimpleSchemaCopyMode, -): SimpleObjectNodeSchema { +function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): 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. - let simpleField: SimpleObjectFieldSchema; - - switch (copyMode) { - case SimpleSchemaCopyMode.SimpleSchema: - simpleField = { - kind: field.kind, - allowedTypesIdentifiers: field.allowedTypesIdentifiers, - allowedTypesInfo: field.allowedTypesInfo, - metadata: field.metadata, - persistedMetadata: field.persistedMetadata, - storedKey: field.storedKey, - }; - break; - - case SimpleSchemaCopyMode.ViewCompatibilitySchema: - simpleField = { - kind: field.kind, - allowedTypesIdentifiers: field.allowedTypesIdentifiers, - allowedTypesInfo: field.allowedTypesInfo, - // Don't include metadata or persistedMetadata in view compatibility schema. - metadata: {}, - persistedMetadata: undefined, - storedKey: field.storedKey, - }; - break; - - default: - unreachableCase(copyMode); - } - - fields.set(propertyKey, simpleField); - } - - let simpleObject: SimpleObjectNodeSchema; - - switch (copyMode) { - case SimpleSchemaCopyMode.SimpleSchema: - simpleObject = { - kind: NodeKind.Object, - fields, - metadata: schema.metadata, - persistedMetadata: schema.persistedMetadata, - }; - break; - - case SimpleSchemaCopyMode.ViewCompatibilitySchema: - simpleObject = { - kind: NodeKind.Object, - fields, - // Don't include metadata or persistedMetadata in view compatibility schema. - metadata: {}, - persistedMetadata: undefined, - allowUnknownOptionalFields: schema.allowUnknownOptionalFields, - }; - break; - - default: - unreachableCase(copyMode); + fields.set(propertyKey, { + kind: field.kind, + simpleAllowedTypes: field.simpleAllowedTypes, + metadata: field.metadata, + persistedMetadata: field.persistedMetadata, + storedKey: field.storedKey, + }); } - return simpleObject; + return { + kind: NodeKind.Object, + fields, + metadata: schema.metadata, + persistedMetadata: schema.persistedMetadata, + }; } diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts deleted file mode 100644 index afbf9ca28376..000000000000 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToViewCompatibilitySchema.ts +++ /dev/null @@ -1,66 +0,0 @@ -/*! - * Copyright (c) Microsoft Corporation and contributors. All rights reserved. - * Licensed under the MIT License. - */ - -import { assert } from "@fluidframework/core-utils/internal"; -import type { SimpleNodeSchema, SimpleTreeSchema } from "../simpleSchema.js"; -import type { TreeSchema } from "./configuration.js"; -import { LeafNodeSchema } from "../leafNodeSchema.js"; -import { - ArrayNodeSchema, - MapNodeSchema, - ObjectNodeSchema, - RecordNodeSchema, -} from "../node-kinds/index.js"; -import { copySimpleNodeSchema, SimpleSchemaCopyMode } from "./viewSchemaToSimpleSchema.js"; - -/** - * Convert a stored schema to a SimpleSchema and preserve information needed for compatibility testing. - * - * @param schema - The stored schema to convert. - * @param copySchemaObjects - If true, copies the contents of the schema into new objects. - * @returns The converted SimpleTreeSchema. - * - * @alpha - */ -export function toViewCompatibilityTreeSchema( - schema: TreeSchema, - copySchemaObjects: boolean, -): SimpleTreeSchema { - const definitions = new Map(); - - // Walk the node definitions and convert them one by one. Recurse into fields used in compatibility checks. - for (const nodeSchema of schema.definitions.values()) { - // TODO: Move this assert to a common location so it can be used from both SimpleSchema builders. - // The set of node kinds is extensible, but the typing of SimpleNodeSchema is not, so we need to check that the schema is one of the known kinds. - assert( - nodeSchema instanceof ArrayNodeSchema || - nodeSchema instanceof MapNodeSchema || - nodeSchema instanceof LeafNodeSchema || - nodeSchema instanceof ObjectNodeSchema || - nodeSchema instanceof RecordNodeSchema, - // TODO: New error code. - 0xb60 /* Invalid schema */, - ); - - // Read properties that are needed for compatibility and copy them to a SimpleNodeSchema. - const simpleNodeSchema = copySchemaObjects - ? copySimpleNodeSchema(nodeSchema, SimpleSchemaCopyMode.ViewCompatibilitySchema) - : nodeSchema; - definitions.set(nodeSchema.identifier, simpleNodeSchema); - } - - return { - root: copySchemaObjects - ? { - kind: schema.root.kind, - allowedTypesIdentifiers: schema.root.allowedTypesIdentifiers, - allowedTypesInfo: schema.root.allowedTypesInfo, - metadata: schema.root.metadata, - persistedMetadata: schema.root.persistedMetadata, - } - : schema.root, // TODO: Convert the root field - definitions, - }; -} diff --git a/packages/dds/tree/src/simple-tree/fieldSchema.ts b/packages/dds/tree/src/simple-tree/fieldSchema.ts index bd5f3625f1f5..2dfd85cfe0f4 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 { AllowedTypeInfo, SimpleFieldSchema } from "./simpleSchema.js"; +import type { SimpleAllowedTypes, SimpleFieldSchema } from "./simpleSchema.js"; import type { UnsafeUnknownSchema } from "./unsafeUnknownSchema.js"; import type { InsertableContent } from "./unhydratedFlexTreeFromInsertable.js"; @@ -412,9 +412,9 @@ export class FieldSchemaAlpha< return this.allowedTypesFull.evaluateIdentifiers(); } - public get allowedTypesInfo(): Map { + public get simpleAllowedTypes(): Map { const types = this.allowedTypesFull.evaluate().types; - const info = new Map(); + const info = new Map(); for (const type of types) { info.set(type.type.identifier, { @@ -425,19 +425,6 @@ export class FieldSchemaAlpha< return info; } - // TODO: Refactor allowedTypesIdentifiers and readonlyAllowedTypesIdentifiers so that there is an intermediate type containing - // the identifier and any other information needed for compatibility checks. - public get readonlyAllowedTypesIdentifiers(): ReadonlySet { - const annotatedAllowedTypes = this.allowedTypesFull.evaluate().types; - const readonlyTypes = new Set(); - for (const allowedType of annotatedAllowedTypes) { - if (allowedType.metadata.stagedSchemaUpgrade !== undefined) { - readonlyTypes.add(allowedType.type.identifier); - } - } - return readonlyTypes; - } - 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 0f83afc9ab0f..031a61717d6e 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -193,7 +193,7 @@ export type { SimpleNodeSchemaBaseAlpha, SimpleObjectFieldSchema, SimpleRecordNodeSchema, - AllowedTypeInfo, + SimpleAllowedTypes as AllowedTypeInfo, } from "./simpleSchema.js"; export { type ImplicitFieldSchema, @@ -275,7 +275,3 @@ export { nullSchema, } from "./leafNodeSchema.js"; export type { LeafSchema } from "./leafNodeSchema.js"; -export { - toViewCompatibilityTreeSchema, - toSerializableCompatibilitySchema, -} from "./api/index.js"; 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 217c427a28cb..087197963854 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 @@ -68,7 +68,7 @@ import type { import { brand, type JsonCompatibleReadOnlyObject } from "../../../util/index.js"; import { nullSchema } from "../../leafNodeSchema.js"; import { arrayNodeStoredSchema } from "../../toStoredSchema.js"; -import type { AllowedTypeInfo } from "../../simpleSchema.js"; +import type { SimpleAllowedTypes } from "../../simpleSchema.js"; /** * A covariant base type for {@link (TreeArrayNode:interface)}. @@ -1169,8 +1169,8 @@ export function arraySchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); - const lazyAllowedTypesInfo = new Lazy(() => { - const map = new Map(); + const lazySimpleAllowedTypes = new Lazy(() => { + const map = new Map(); for (const type of normalizedTypes.evaluate()) { map.set(type.identifier, { isStaged: false, @@ -1216,8 +1216,8 @@ export function arraySchema< return lazyAllowedTypesIdentifiers.value; } - public static get allowedTypesInfo(): ReadonlyMap { - return lazyAllowedTypesInfo.value; + public static get simpleAllowedTypes(): ReadonlyMap { + return lazySimpleAllowedTypes.value; } protected static override constructorCached: MostDerivedData | undefined = undefined; 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 ab0a5d37d4cd..c3fb433a66a4 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 @@ -66,7 +66,7 @@ import type { import { recordLikeDataToFlexContent } from "../common.js"; import { MapNodeStoredSchema } from "../../../core/index.js"; import type { NodeSchemaOptionsAlpha } from "../../api/index.js"; -import type { AllowedTypeInfo } from "../../simpleSchema.js"; +import type { SimpleAllowedTypes } from "../../simpleSchema.js"; /** * A map of string keys to tree objects. @@ -276,8 +276,8 @@ export function mapSchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); - const lazyAllowedTypesInfo = new Lazy(() => { - const map = new Map(); + const lazySimpleAllowedTypes = new Lazy(() => { + const map = new Map(); for (const type of normalizedTypes.evaluate()) { map.set(type.identifier, { isStaged: false, @@ -313,8 +313,8 @@ export function mapSchema< return lazyAllowedTypesIdentifiers.value; } - public static get allowedTypesInfo(): ReadonlyMap { - return lazyAllowedTypesInfo.value; + public static get simpleAllowedTypes(): ReadonlyMap { + return lazySimpleAllowedTypes.value; } protected static override constructorCached: MostDerivedData | undefined = undefined; 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 fb62d5b02d88..fa554babfda0 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 @@ -58,7 +58,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 { AllowedTypeInfo } from "../../simpleSchema.js"; +import type { SimpleAllowedTypes } from "../../simpleSchema.js"; /** * Create a proxy which implements the {@link TreeRecordNode} API. @@ -259,8 +259,8 @@ export function recordSchema< const lazyAllowedTypesIdentifiers = new Lazy( () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); - const lazyAllowedTypesInfo = new Lazy(() => { - const map = new Map(); + const lazySimpleAllowedTypes = new Lazy(() => { + const map = new Map(); for (const type of normalizedTypes.evaluate()) { map.set(type.identifier, { isStaged: false, @@ -357,8 +357,8 @@ export function recordSchema< return lazyAllowedTypesIdentifiers.value; } - public static get allowedTypesInfo(): ReadonlyMap { - return lazyAllowedTypesInfo.value; + public static get simpleAllowedTypes(): ReadonlyMap { + return lazySimpleAllowedTypes.value; } protected static override constructorCached: MostDerivedData | undefined = undefined; diff --git a/packages/dds/tree/src/simple-tree/simpleSchema.ts b/packages/dds/tree/src/simple-tree/simpleSchema.ts index 862ac434e138..bffc698dd640 100644 --- a/packages/dds/tree/src/simple-tree/simpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/simpleSchema.ts @@ -62,7 +62,7 @@ export interface SimpleObjectNodeSchema /** * Whether the object node allows unknown optional fields. * - * @remarks Used for compatibility checks (see {@link toViewCompatibilityTreeSchema}). Not available in all cases. + * @remarks Used for compatibility checks. Not available in all cases. */ readonly allowUnknownOptionalFields?: boolean; } @@ -98,12 +98,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; - - /** - * Information about the allowed types. - */ - readonly allowedTypesInfo: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -120,12 +115,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; - - /** - * Information about the allowed types. - */ - readonly allowedTypesInfo: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -142,12 +132,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; - - /** - * Information about the allowed types. - */ - readonly allowedTypesInfo: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -185,15 +170,18 @@ export type SimpleNodeSchema = | SimpleRecordNodeSchema; /** - * Information about allowed types under a field. + * Information about allowed types. * * @alpha * @sealed */ -export interface AllowedTypeInfo { +export interface SimpleAllowedTypes { /** - * True if there is an associated schema upgrade that makes this type read-only. - * Undefined if derived from a stored schema, which has no concept of staged allowed type upgrades. + * 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; } @@ -215,17 +203,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; - - /** - * Information about the allowed types under this field. - */ - readonly allowedTypesInfo: ReadonlyMap; + 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/simple-tree/api/getSimpleSchema.spec.ts b/packages/dds/tree/src/test/simple-tree/api/getSimpleSchema.spec.ts index 7d9fe1a35c1f..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 @@ -10,9 +10,6 @@ import { SchemaFactory, SchemaFactoryAlpha, stringSchema, - toSerializableCompatibilitySchema, - toViewCompatibilityTreeSchema, - TreeViewConfigurationAlpha, type SimpleLeafNodeSchema, type SimpleNodeSchema, type SimpleObjectFieldSchema, @@ -22,7 +19,6 @@ import { import { ValueSchema } from "../../../core/index.js"; // eslint-disable-next-line import/no-internal-modules import { toSimpleTreeSchema } from "../../../simple-tree/api/viewSchemaToSimpleSchema.js"; -import { takeJsonSnapshot, useSnapshotDirectory } from "../../snapshots/index.js"; const simpleString: SimpleLeafNodeSchema = { leafKind: ValueSchema.String, @@ -39,858 +35,364 @@ const simpleNumber: SimpleLeafNodeSchema = { }; describe("getSimpleSchema", () => { - useSnapshotDirectory("get-simple-schema"); - - describe("non-copying", () => { + it("non-copying", () => { const Schema = stringSchema; const root = SchemaFactoryAlpha.optional(Schema); + const actual = toSimpleTreeSchema(root, false); + const expected: SimpleTreeSchema = { root, definitions: new Map([[Schema.identifier, Schema]]), }; + assert.deepEqual(actual, expected); - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(root, false); - - assert.deepEqual(actual, expected); - - assert.equal(actual.root, root); - assert.equal(actual.definitions.get(Schema.identifier), Schema); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: root }); - const actual = toViewCompatibilityTreeSchema(treeView, false); - - assert.deepEqual(actual, expected); - - assert.equal(actual.root, root); - assert.equal(actual.definitions.get(Schema.identifier), Schema); - }); + assert.equal(actual.root, root); + assert.equal(actual.definitions.get(Schema.identifier), Schema); }); - describe("Field Schema", () => { + it("Field Schema", () => { const schemaFactory = new SchemaFactory("test"); const Schema = schemaFactory.optional(schemaFactory.string, { metadata: { description: "An optional string." }, }); - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Optional, - metadata: { description: "An optional string." }, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), - persistedMetadata: undefined, - }, - definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), - }; - - assert.deepEqual(actual, expected); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Optional, - metadata: { description: "An optional string." }, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), - persistedMetadata: undefined, - }, - definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), - }; - - assert.deepEqual(actual, expected); - }); + const actual = toSimpleTreeSchema(Schema, true); - it("view compatibility schema - Field Schema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Optional, + metadata: { description: "An optional string." }, + simpleAllowedTypes: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), + persistedMetadata: undefined, + }, + definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), + }; + assert.deepEqual(actual, expected); }); - describe("Leaf node", () => { + it("Leaf node", () => { const Schema = SchemaFactory.string; - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), - persistedMetadata: undefined, - }, - definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), - }; - - assert.deepEqual(actual, expected); - }); + const actual = toSimpleTreeSchema(Schema, true); - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), - persistedMetadata: undefined, - }, - definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), - }; - - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Leaf node", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + simpleAllowedTypes: new Map([["com.fluidframework.leaf.string", { isStaged: false }]]), + persistedMetadata: undefined, + }, + definitions: new Map([["com.fluidframework.leaf.string", simpleString]]), + }; + assert.deepEqual(actual, expected); }); - describe("Union root", () => { + it("Union root", () => { const Schema = [SchemaFactory.number, SchemaFactory.string]; - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", - ]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.number", { isStaged: false }], - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - }, - definitions: new Map([ - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); + const actual = toSimpleTreeSchema(Schema, true); - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", - ]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.number", { isStaged: false }], - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - }, - definitions: new Map([ - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Union root", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + }, + definitions: new Map([ + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); - describe("Array schema", () => { + it("Array schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.array("array", schemaFactory.string) {} - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.array"]), - allowedTypesInfo: new Map([["test.array", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.array", - { - kind: NodeKind.Array, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - metadata: {}, - persistedMetadata: undefined, - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); + const actual = toSimpleTreeSchema(Schema, true); - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.array"]), - allowedTypesInfo: new Map([["test.array", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.array", - { - kind: NodeKind.Array, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - metadata: {}, - persistedMetadata: undefined, - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Array schema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([["test.array", { isStaged: false }]]), + }, + definitions: new Map([ + [ + "test.array", + { + kind: NodeKind.Array, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), + metadata: {}, + persistedMetadata: undefined, + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); - describe("Map schema", () => { + it("Map schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.map("map", schemaFactory.string) {} - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.map"]), - allowedTypesInfo: new Map([["test.map", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.map", - { - kind: NodeKind.Map, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.map"]), - allowedTypesInfo: new Map([["test.map", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.map", - { - kind: NodeKind.Map, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Map schema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const actual = toSimpleTreeSchema(Schema, true); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([["test.map", { isStaged: false }]]), + }, + definitions: new Map([ + [ + "test.map", + { + kind: NodeKind.Map, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); - describe("Record schema", () => { + it("Record schema", () => { const schemaFactory = new SchemaFactoryAlpha("test"); class Schema extends schemaFactory.record("record", schemaFactory.string) {} - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.record"]), - allowedTypesInfo: new Map([["test.record", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.record", - { - kind: NodeKind.Record, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.record"]), - allowedTypesInfo: new Map([["test.record", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.record", - { - kind: NodeKind.Record, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Record schema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const actual = toSimpleTreeSchema(Schema, true); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([["test.record", { isStaged: false }]]), + }, + definitions: new Map([ + [ + "test.record", + { + kind: NodeKind.Record, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); - describe("Object schema", () => { + it("Object schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.object("object", { foo: schemaFactory.optional(schemaFactory.number), bar: schemaFactory.required(schemaFactory.string), }) {} - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Optional, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.number", { isStaged: false }], - ]), - storedKey: "foo", - }, - ], - [ - "bar", - { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - storedKey: "bar", - }, - ], - ]), - } satisfies SimpleObjectNodeSchema, - ], - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - allowUnknownOptionalFields: false, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Optional, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.number"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.number", { isStaged: false }], - ]), - storedKey: "foo", - }, - ], - [ - "bar", - { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - storedKey: "bar", - }, - ], - ]), - } satisfies SimpleObjectNodeSchema, - ], - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; + const actual = toSimpleTreeSchema(Schema, true); - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Object schema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([["test.object", { isStaged: false }]]), + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Optional, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ]), + storedKey: "foo", + }, + ], + [ + "bar", + { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), + storedKey: "bar", + }, + ], + ]), + } satisfies SimpleObjectNodeSchema, + ], + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); - describe("Object schema including an identifier field", () => { + it("Object schema including an identifier field", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.object("object", { id: schemaFactory.identifier, }) {} - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "id", - { - kind: FieldKind.Identifier, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - storedKey: "id", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - allowUnknownOptionalFields: false, - fields: new Map([ - [ - "id", - { - kind: FieldKind.Identifier, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["com.fluidframework.leaf.string"]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - storedKey: "id", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; + const actual = toSimpleTreeSchema(Schema, true); - const actual = toViewCompatibilityTreeSchema(treeView, true); - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Object schema including an identifier field", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([["test.object", { isStaged: false }]]), + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "id", + { + kind: FieldKind.Identifier, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), + storedKey: "id", + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); - describe("Object schema including a union field", () => { + it("Object schema including a union field", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.object("object", { foo: schemaFactory.required([schemaFactory.number, schemaFactory.string]), }) {} - it("toSimpleTreeSchema", () => { - // Must enable copy so deep equality passes. - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", - ]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.number", { isStaged: false }], - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - storedKey: "foo", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; + // Must enable copy so deep equality passes. + const actual = toSimpleTreeSchema(Schema, true); - assert.deepEqual(actual, expected); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - - // Must enable copy so deep equality passes. - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([["test.object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - allowUnknownOptionalFields: false, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.number", - "com.fluidframework.leaf.string", - ]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.number", { isStaged: false }], - ["com.fluidframework.leaf.string", { isStaged: false }], - ]), - storedKey: "foo", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.number", simpleNumber], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("view compatibility schema - Object schema including a union field", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([["test.object", { isStaged: false }]]), + }, + definitions: new Map([ + [ + "test.object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.number", { isStaged: false }], + ["com.fluidframework.leaf.string", { isStaged: false }], + ]), + storedKey: "foo", + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.number", simpleNumber], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); - describe("Recursive object schema", () => { + it("Recursive object schema", () => { const schemaFactory = new SchemaFactory("test"); class Schema extends schemaFactory.objectRecursive("recursive-object", { foo: schemaFactory.optionalRecursive([schemaFactory.string, () => Schema]), }) {} - it("toSimpleTreeSchema", () => { - const actual = toSimpleTreeSchema(Schema, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.recursive-object"]), - allowedTypesInfo: new Map([["test.recursive-object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.recursive-object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Optional, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.string", - "test.recursive-object", - ]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ["test.recursive-object", { isStaged: false }], - ]), - storedKey: "foo", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); - - it("toViewCompatibilityTreeSchema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Required, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set(["test.recursive-object"]), - allowedTypesInfo: new Map([["test.recursive-object", { isStaged: false }]]), - }, - definitions: new Map([ - [ - "test.recursive-object", - { - kind: NodeKind.Object, - metadata: {}, - persistedMetadata: undefined, - allowUnknownOptionalFields: false, - fields: new Map([ - [ - "foo", - { - kind: FieldKind.Optional, - metadata: {}, - persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - "com.fluidframework.leaf.string", - "test.recursive-object", - ]), - allowedTypesInfo: new Map([ - ["com.fluidframework.leaf.string", { isStaged: false }], - ["test.recursive-object", { isStaged: false }], - ]), - storedKey: "foo", - }, - ], - ]), - }, - ], - ["com.fluidframework.leaf.string", simpleString], - ]), - }; - - assert.deepEqual(actual, expected); - }); + const actual = toSimpleTreeSchema(Schema, true); - it("view compatibility schema - Recursive object schema", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: Schema }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); + const expected: SimpleTreeSchema = { + root: { + kind: FieldKind.Required, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([["test.recursive-object", { isStaged: false }]]), + }, + definitions: new Map([ + [ + "test.recursive-object", + { + kind: NodeKind.Object, + metadata: {}, + persistedMetadata: undefined, + fields: new Map([ + [ + "foo", + { + kind: FieldKind.Optional, + metadata: {}, + persistedMetadata: undefined, + simpleAllowedTypes: new Map([ + ["com.fluidframework.leaf.string", { isStaged: false }], + ["test.recursive-object", { isStaged: false }], + ]), + storedKey: "foo", + }, + ], + ]), + }, + ], + ["com.fluidframework.leaf.string", simpleString], + ]), + }; + assert.deepEqual(actual, expected); }); }); diff --git a/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts b/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts deleted file mode 100644 index 4fc8d78e5719..000000000000 --- a/packages/dds/tree/src/test/simple-tree/api/getViewCompatibilityTreeSchema.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - FieldKind, - SchemaFactoryAlpha, - stringSchema, - toSerializableCompatibilitySchema, - toViewCompatibilityTreeSchema, - TreeViewConfigurationAlpha, - type SimpleTreeSchema, -} from "../../../simple-tree/index.js"; -import { strict as assert } from "node:assert"; -import { takeJsonSnapshot, useSnapshotDirectory } from "../../snapshots/index.js"; - -describe("getViewCompatibilityTreeSchema", () => { - useSnapshotDirectory("get-view-compatibility-tree-schema"); - - describe("With staged schema upgrades", () => { - const leafSchema = stringSchema; - const schemaFactory = new SchemaFactoryAlpha("test"); - const root = schemaFactory.optional( - // Staged allowed types are read-only for the sake of schema migrations - schemaFactory.types([schemaFactory.staged(leafSchema)]), - ); - - it("Should preserve isReadOnly when converting to SimpleTreeSchema", () => { - const expected: SimpleTreeSchema = { - root: { - kind: FieldKind.Optional, - allowedTypesInfo: new Map([[leafSchema.identifier, { isStaged: true }]]), - allowedTypesIdentifiers: new Set([leafSchema.identifier]), - metadata: {}, - persistedMetadata: undefined, - }, - definitions: new Map([[leafSchema.identifier, leafSchema]]), - }; - - const treeView = new TreeViewConfigurationAlpha({ schema: root }); - const actual = toViewCompatibilityTreeSchema(treeView, true); - assert.deepEqual(actual.root.allowedTypesInfo, expected.root.allowedTypesInfo); - }); - - it("view compatibility schema - allowedTypesIdentifiers", () => { - const treeView = new TreeViewConfigurationAlpha({ schema: root }); - const actual = toSerializableCompatibilitySchema(treeView); - takeJsonSnapshot(actual); - }); - }); -}); 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 f62fc8968d1f..9f67b9ecc7a8 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,7 +21,7 @@ import { } from "../../../simple-tree/index.js"; import { getJsonValidator } from "./jsonSchemaUtilities.js"; import type { - AllowedTypeInfo, + SimpleAllowedTypes, SimpleNodeSchema, SimpleTreeSchema, // eslint-disable-next-line import/no-internal-modules @@ -50,8 +50,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -89,8 +88,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.handle"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.handle", { isStaged: false }], ]), }, @@ -114,8 +112,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set(["test.array"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.array", { isStaged: false }], ]), metadata: {}, @@ -127,8 +124,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Array, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -173,8 +169,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set(["test.map"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.map", { isStaged: false }], ]), metadata: {}, @@ -186,8 +181,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Map, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -244,8 +238,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set(["test.record"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.record", { isStaged: false }], ]), metadata: {}, @@ -257,8 +250,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Record, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -362,8 +354,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -379,8 +370,7 @@ describe("simpleSchemaToJsonSchema", () => { "foo", { kind: FieldKind.Optional, - allowedTypesIdentifiers: new Set([numberSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [numberSchema.identifier, { isStaged: false }], ]), metadata: { description: "A number representing the concept of Foo." }, @@ -392,8 +382,7 @@ describe("simpleSchemaToJsonSchema", () => { "bar", { kind: FieldKind.Required, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), metadata: { description: "A string representing the concept of Bar." }, @@ -405,8 +394,7 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), metadata: { @@ -511,8 +499,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -528,8 +515,7 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - allowedTypesIdentifiers: new Set([stringSchema.identifier]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), storedKey: "id", @@ -573,8 +559,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.object"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -592,11 +577,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - numberSchema.identifier, - stringSchema.identifier, - ]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [numberSchema.identifier, { isStaged: false }], [stringSchema.identifier, { isStaged: false }], ]), @@ -648,8 +629,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - allowedTypesIdentifiers: new Set(["test.recursive-object"]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ ["test.recursive-object", { isStaged: false }], ]), }, @@ -667,11 +647,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Optional, metadata: {}, persistedMetadata: undefined, - allowedTypesIdentifiers: new Set([ - stringSchema.identifier, - "test.recursive-object", - ]), - allowedTypesInfo: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ["test.recursive-object", { isStaged: false }], ]), diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json deleted file mode 100644 index 5e47334f1ab3..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Array schema.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "test.array", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - }, - "test.array": { - "kind": 1, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" - ] - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json deleted file mode 100644 index 8f241c679833..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Field Schema.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "root": { - "kind": 0, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json deleted file mode 100644 index 607f716b6e59..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Leaf node.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json deleted file mode 100644 index 0eb0719b8250..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Map schema.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "test.map", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - }, - "test.map": { - "kind": 0, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" - ] - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json deleted file mode 100644 index 7a1bf683304f..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including a union field.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "test.object", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.number": { - "kind": 3, - "leafKind": 0 - }, - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - }, - "test.object": { - "kind": 2, - "fields": { - "foo": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.number", - "isReadOnly": false - }, - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": false - } - ], - "storedKey": "foo" - } - }, - "allowUnknownOptionalFields": false - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json deleted file mode 100644 index 15e6f78db6df..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema including an identifier field.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "test.object", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - }, - "test.object": { - "kind": 2, - "fields": { - "id": { - "kind": 2, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": false - } - ], - "storedKey": "id" - } - }, - "allowUnknownOptionalFields": false - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json deleted file mode 100644 index 006c0ff80071..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Object schema.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "test.object", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.number": { - "kind": 3, - "leafKind": 0 - }, - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - }, - "test.object": { - "kind": 2, - "fields": { - "foo": { - "kind": 0, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.number", - "isReadOnly": false - } - ], - "storedKey": "foo" - }, - "bar": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": false - } - ], - "storedKey": "bar" - } - }, - "allowUnknownOptionalFields": false - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json deleted file mode 100644 index ac96d7074949..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Record schema.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "test.record", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - }, - "test.record": { - "kind": 4, - "allowedTypesIdentifiers": [ - "com.fluidframework.leaf.string" - ] - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json deleted file mode 100644 index 9569637fcc5a..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Recursive object schema.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "test.recursive-object", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - }, - "test.recursive-object": { - "kind": 2, - "fields": { - "foo": { - "kind": 0, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": false - }, - { - "identifier": "test.recursive-object", - "isReadOnly": false - } - ], - "storedKey": "foo" - } - }, - "allowUnknownOptionalFields": false - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json b/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json deleted file mode 100644 index 2a900a4635ed..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-simple-schema/view compatibility schema - Union root.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "root": { - "kind": 1, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.number", - "isReadOnly": false - }, - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": false - } - ] - }, - "definitions": { - "com.fluidframework.leaf.number": { - "kind": 3, - "leafKind": 0 - }, - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - } - } -} \ No newline at end of file diff --git a/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - allowedTypesIdentifiers.json b/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - allowedTypesIdentifiers.json deleted file mode 100644 index d85b1242c0c8..000000000000 --- a/packages/dds/tree/src/test/snapshots/get-view-compatibility-tree-schema/view compatibility schema - allowedTypesIdentifiers.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "root": { - "kind": 0, - "allowedTypesInfo": [ - { - "identifier": "com.fluidframework.leaf.string", - "isReadOnly": true - } - ] - }, - "definitions": { - "com.fluidframework.leaf.string": { - "kind": 3, - "leafKind": 1 - } - } -} \ No newline at end of file From 4e970d2e4fd239d15a398331ede6cee8f586117c Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 12:34:37 -0700 Subject: [PATCH 12/23] - Fixed a couple references to allowedTypesIdentifiers. - Regenerated API files. --- .../dds/tree/api-report/tree.alpha.api.md | 4 +-- .../src/explicit-strategy/typeGeneration.ts | 12 +++---- .../api-report/fluid-framework.alpha.api.md | 36 ++++++++++--------- .../tree-agent/src/typeGeneration.ts | 8 ++--- .../data-visualization/DefaultVisualizers.ts | 2 +- .../SharedTreeVisualizer.ts | 6 ++-- 6 files changed, 36 insertions(+), 32 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 74c2f789c4df..eefa403492bf 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -317,7 +317,7 @@ export namespace FluidSerializableAsTree { export type Data = JsonCompatible; const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2 typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, { - readonly [x: string]: string | number | IFluidHandle | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null; + readonly [x: string]: string | number | IFluidHandle | FluidSerializableObject | Array | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | null; }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>], undefined, unknown>; // @sealed export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase { @@ -517,7 +517,7 @@ export namespace JsonAsTree { } const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.json.object", NodeKind.Record, TreeRecordNodeUnsafe, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array]> & WithType<"com.fluidframework.json.object", NodeKind.Record, unknown>, { - readonly [x: string]: string | number | JsonObject | Array | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | null; + readonly [x: string]: string | number | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | JsonObject | Array | null; }, false, readonly [LeafSchema<"null", null>, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array], undefined, unknown>; export type Primitive = TreeNodeFromImplicitAllowedTypes; // @system 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 4b40cd8bc394..5027d34a81be 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 @@ -15,6 +15,11 @@ export function adaptEnum, true, Record, undefined>; }[keyof TEnum]>; }; +// @alpha @sealed +export interface AllowedTypeInfo { + readonly isStaged?: boolean; +} + // @alpha @input export interface AllowedTypeMetadata { readonly custom?: unknown; @@ -323,7 +328,7 @@ export class FieldSchemaAlpha; } // @alpha @sealed @system @@ -374,7 +379,7 @@ export namespace FluidSerializableAsTree { export type Data = JsonCompatible; const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2 typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, { - readonly [x: string]: string | number | IFluidHandle | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null; + readonly [x: string]: string | number | IFluidHandle | FluidSerializableObject | Array | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | null; }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>], undefined, unknown>; // @sealed export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase { @@ -861,7 +866,7 @@ export namespace JsonAsTree { } const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.json.object", NodeKind.Record, TreeRecordNodeUnsafe, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array]> & WithType<"com.fluidframework.json.object", NodeKind.Record, unknown>, { - readonly [x: string]: string | number | JsonObject | Array | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | null; + readonly [x: string]: string | number | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | JsonObject | Array | null; }, false, readonly [LeafSchema<"null", null>, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array], undefined, unknown>; export type Primitive = TreeNodeFromImplicitAllowedTypes; // @system @@ -1378,16 +1383,15 @@ export type SharedTreeOptionsBeta = ForestOptions; // @alpha @sealed export interface SimpleArrayNodeSchema 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 stagedSchemaUpgrades?: SchemaUpgrade[]; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1397,7 +1401,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1427,7 +1431,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly allowedTypesIdentifiers: ReadonlySet; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1478,18 +1482,18 @@ export namespace System_TableSchema { }>; // @system export function createTableSchema, const TRowSchema extends RowSchemaBase>(inputSchemaFactory: SchemaFactoryBeta, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): TreeNodeSchemaCore_2, "Table">, NodeKind.Object, true, { - readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; - readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; + readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; + readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; }, object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }, unknown> & (new (data: InternalTreeNode | (object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; })) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>) & { empty, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>>(this: TThis): InstanceType; }; // @system 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 1657897e9205..6e0d7d372280 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, }; From 55ca84b1bafc5d4e678f4863d5b3b0c53df2a021 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 13:06:11 -0700 Subject: [PATCH 13/23] Minor refactors. Addressed some PR feedback. --- .../dds/tree/api-report/tree.alpha.api.md | 20 +++++++-------- packages/dds/tree/src/index.ts | 2 +- .../dds/tree/src/shared-tree/sharedTree.ts | 25 ++++++++++++------- packages/dds/tree/src/simple-tree/index.ts | 2 +- .../api-report/fluid-framework.alpha.api.md | 20 +++++++-------- 5 files changed, 38 insertions(+), 31 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index eefa403492bf..3b6a8d4ef28e 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -15,11 +15,6 @@ export function adaptEnum, true, Record, undefined>; }[keyof TEnum]>; }; -// @alpha @sealed -export interface AllowedTypeInfo { - readonly isStaged?: boolean; -} - // @alpha @input export interface AllowedTypeMetadata { readonly custom?: unknown; @@ -274,7 +269,7 @@ export class FieldSchemaAlpha; + get simpleAllowedTypes(): Map; } // @alpha @sealed @system @@ -1003,9 +998,14 @@ export type SharedTreeOptions = Partial & Partial extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1013,7 +1013,7 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1023,7 +1023,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1053,7 +1053,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha diff --git a/packages/dds/tree/src/index.ts b/packages/dds/tree/src/index.ts index fe5b4dc865b6..3f2234a7f9c6 100644 --- a/packages/dds/tree/src/index.ts +++ b/packages/dds/tree/src/index.ts @@ -277,7 +277,7 @@ export { type TreeParsingOptions, type SchemaFactory_base, type NumberKeys, - type AllowedTypeInfo, + type SimpleAllowedTypes, } 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 689c67f71fe2..875b01fdd7c3 100644 --- a/packages/dds/tree/src/shared-tree/sharedTree.ts +++ b/packages/dds/tree/src/shared-tree/sharedTree.ts @@ -99,7 +99,7 @@ import { FieldKind, type ITreeAlpha, type SimpleObjectFieldSchema, - type AllowedTypeInfo, + type SimpleAllowedTypes, } from "../simple-tree/index.js"; import { SchematizingSimpleTreeView } from "./schematizingTreeView.js"; @@ -952,12 +952,19 @@ export const defaultSharedTreeOptions: Required = { shouldEncodeIncrementally: defaultIncrementalEncodingPolicy, }; -function buildSimpleAllowedTypes(types: TreeTypeSet): ReadonlyMap { - const allowedTypesInfo = new Map(); +/** + * Build the allowed types for a Stored Schema. + * + * @remarks Staged upgrades do not apply to stored schemas, so we omit the flag when building {@link SimpleAllowedTypes}. + * @param types - The types to create allowed types for. + * @returns The allowed types. + */ +function buildSimpleAllowedTypesForStoredSchema( + types: TreeTypeSet, +): ReadonlyMap { + const allowedTypesInfo = new Map(); for (const type of types) { - allowedTypesInfo.set(type, { - isStaged: false, - }); + allowedTypesInfo.set(type, {}); } return allowedTypesInfo; } @@ -984,7 +991,7 @@ function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFie return { kind, // TODO: Refactor - simpleAllowedTypes: buildSimpleAllowedTypes(schema.types), + simpleAllowedTypes: buildSimpleAllowedTypesForStoredSchema(schema.types), metadata: {}, persistedMetadata: schema.persistedMetadata, }; @@ -1000,7 +1007,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS if (arrayTypes !== undefined) { return { kind: NodeKind.Array, - simpleAllowedTypes: buildSimpleAllowedTypes(arrayTypes), + simpleAllowedTypes: buildSimpleAllowedTypesForStoredSchema(arrayTypes), metadata: {}, persistedMetadata: schema.metadata, }; @@ -1019,7 +1026,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS ); return { kind: NodeKind.Map, - simpleAllowedTypes: buildSimpleAllowedTypes(schema.mapFields.types), + simpleAllowedTypes: buildSimpleAllowedTypesForStoredSchema(schema.mapFields.types), metadata: {}, persistedMetadata: schema.metadata, }; diff --git a/packages/dds/tree/src/simple-tree/index.ts b/packages/dds/tree/src/simple-tree/index.ts index 031a61717d6e..f44069c2aaa7 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -193,7 +193,7 @@ export type { SimpleNodeSchemaBaseAlpha, SimpleObjectFieldSchema, SimpleRecordNodeSchema, - SimpleAllowedTypes as AllowedTypeInfo, + SimpleAllowedTypes, } from "./simpleSchema.js"; export { type ImplicitFieldSchema, 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 5027d34a81be..c48b98040b7e 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 @@ -15,11 +15,6 @@ export function adaptEnum, true, Record, undefined>; }[keyof TEnum]>; }; -// @alpha @sealed -export interface AllowedTypeInfo { - readonly isStaged?: boolean; -} - // @alpha @input export interface AllowedTypeMetadata { readonly custom?: unknown; @@ -328,7 +323,7 @@ export class FieldSchemaAlpha; + get simpleAllowedTypes(): Map; } // @alpha @sealed @system @@ -1381,9 +1376,14 @@ export type SharedTreeOptions = Partial & Partial extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1391,7 +1391,7 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1401,7 +1401,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1431,7 +1431,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha From f48aa8a5f3dd217340e8c61719c9a79ba1b863bd Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 13:59:32 -0700 Subject: [PATCH 14/23] - PR feedback. - Regenerated API Extractor output. --- .../dds/tree/api-report/tree.alpha.api.md | 21 ++++++++++--------- .../tree/src/simple-tree/core/allowedTypes.ts | 16 ++++++++++++++ .../simple-tree/node-kinds/array/arrayNode.ts | 8 +------ .../src/simple-tree/node-kinds/map/mapNode.ts | 8 +------ .../node-kinds/record/recordNode.ts | 8 +------ .../api-report/fluid-framework.alpha.api.md | 21 ++++++++++--------- 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 3b6a8d4ef28e..981688968504 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -68,6 +68,7 @@ export interface AnnotatedAllowedTypes exte evaluate(): AllowedTypesFullEvaluated; evaluateIdentifiers(): ReadonlySet; evaluateSet(): ReadonlySet; + evaluateSimpleAllowedTypes(): ReadonlyMap; readonly metadata: AllowedTypesMetadata; readonly types: T; } @@ -312,7 +313,7 @@ export namespace FluidSerializableAsTree { export type Data = JsonCompatible; const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2 typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, { - readonly [x: string]: string | number | IFluidHandle | FluidSerializableObject | Array | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | null; + readonly [x: string]: string | number | IFluidHandle | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null; }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>], undefined, unknown>; // @sealed export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase { @@ -512,7 +513,7 @@ export namespace JsonAsTree { } const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.json.object", NodeKind.Record, TreeRecordNodeUnsafe, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array]> & WithType<"com.fluidframework.json.object", NodeKind.Record, unknown>, { - readonly [x: string]: string | number | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | JsonObject | Array | null; + readonly [x: string]: string | number | JsonObject | Array | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | null; }, false, readonly [LeafSchema<"null", null>, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array], undefined, unknown>; export type Primitive = TreeNodeFromImplicitAllowedTypes; // @system @@ -1104,18 +1105,18 @@ export namespace System_TableSchema { }>; // @system export function createTableSchema, const TRowSchema extends RowSchemaBase>(inputSchemaFactory: SchemaFactoryBeta, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): TreeNodeSchemaCore_2, "Table">, NodeKind.Object, true, { - readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; - readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; + readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; + readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; }, object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }, unknown> & (new (data: InternalTreeNode | (object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; })) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>) & { empty, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>>(this: TThis): InstanceType; }; // @system diff --git a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts index fccac8a0bb99..22932b6549de 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 { SimpleAllowedTypes } from "../simpleSchema.js"; /** * Schema for types allowed in some location in a tree (like a field, map entry or array). @@ -133,6 +134,11 @@ export interface AnnotatedAllowedTypes * rather than identifiers where possible since its more type safe and it is possible that two schema with the same identifier exist. */ evaluateIdentifiers(): ReadonlySet; + + /** + * Get the {@link SimpleAllowedTypes} version of the allowed types set. + */ + evaluateSimpleAllowedTypes(): ReadonlyMap; } /** @@ -253,6 +259,16 @@ export class AnnotatedAllowedTypesInternal< return this.lazyEvaluate.value.identifiers; } + public evaluateSimpleAllowedTypes(): ReadonlyMap { + const simpleAllowedTypes = new Map(); + for (const type of this.evaluate().types) { + simpleAllowedTypes.set(type.type.identifier, { + isStaged: type.metadata.stagedSchemaUpgrade !== undefined, + }); + } + return simpleAllowedTypes; + } + public static override [Symbol.hasInstance]< TThis extends | (abstract new ( 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 087197963854..872cbea84caa 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 @@ -1170,13 +1170,7 @@ export function arraySchema< () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); const lazySimpleAllowedTypes = new Lazy(() => { - const map = new Map(); - for (const type of normalizedTypes.evaluate()) { - map.set(type.identifier, { - isStaged: false, - }); - } - return map; + return normalizedTypes.evaluateSimpleAllowedTypes(); }); let privateData: TreeNodeSchemaPrivateData | undefined; 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 c3fb433a66a4..72f795a41e97 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 @@ -277,13 +277,7 @@ export function mapSchema< () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); const lazySimpleAllowedTypes = new Lazy(() => { - const map = new Map(); - for (const type of normalizedTypes.evaluate()) { - map.set(type.identifier, { - isStaged: false, - }); - } - return map; + return normalizedTypes.evaluateSimpleAllowedTypes(); }); let privateData: TreeNodeSchemaPrivateData | undefined; 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 fa554babfda0..b30051686eda 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 @@ -260,13 +260,7 @@ export function recordSchema< () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); const lazySimpleAllowedTypes = new Lazy(() => { - const map = new Map(); - for (const type of normalizedTypes.evaluate()) { - map.set(type.identifier, { - isStaged: false, - }); - } - return map; + return normalizedTypes.evaluateSimpleAllowedTypes(); }); let privateData: TreeNodeSchemaPrivateData | undefined; 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 c48b98040b7e..9e1bb78fe46a 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 @@ -68,6 +68,7 @@ export interface AnnotatedAllowedTypes exte evaluate(): AllowedTypesFullEvaluated; evaluateIdentifiers(): ReadonlySet; evaluateSet(): ReadonlySet; + evaluateSimpleAllowedTypes(): ReadonlyMap; readonly metadata: AllowedTypesMetadata; readonly types: T; } @@ -374,7 +375,7 @@ export namespace FluidSerializableAsTree { export type Data = JsonCompatible; const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass_2<"com.fluidframework.serializable.object", NodeKind_2.Record, TreeRecordNodeUnsafe_2 typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>]> & WithType_2<"com.fluidframework.serializable.object", NodeKind_2.Record, unknown>, { - readonly [x: string]: string | number | IFluidHandle | FluidSerializableObject | Array | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | null; + readonly [x: string]: string | number | IFluidHandle | System_Unsafe_2.InsertableTypedNodeUnsafe, LeafSchema_2<"boolean", boolean>> | FluidSerializableObject | Array | null; }, false, readonly [() => typeof FluidSerializableObject, () => typeof Array, LeafSchema_2<"string", string>, LeafSchema_2<"number", number>, LeafSchema_2<"boolean", boolean>, LeafSchema_2<"null", null>, LeafSchema_2<"handle", IFluidHandle>], undefined, unknown>; // @sealed export class FluidSerializableObject extends _APIExtractorWorkaroundObjectBase { @@ -861,7 +862,7 @@ export namespace JsonAsTree { } const // @system _APIExtractorWorkaroundObjectBase: TreeNodeSchemaClass<"com.fluidframework.json.object", NodeKind.Record, TreeRecordNodeUnsafe, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array]> & WithType<"com.fluidframework.json.object", NodeKind.Record, unknown>, { - readonly [x: string]: string | number | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | JsonObject | Array | null; + readonly [x: string]: string | number | JsonObject | Array | System_Unsafe.InsertableTypedNodeUnsafe, LeafSchema<"boolean", boolean>> | null; }, false, readonly [LeafSchema<"null", null>, LeafSchema<"number", number>, LeafSchema<"string", string>, LeafSchema<"boolean", boolean>, () => typeof JsonObject, () => typeof Array], undefined, unknown>; export type Primitive = TreeNodeFromImplicitAllowedTypes; // @system @@ -1482,18 +1483,18 @@ export namespace System_TableSchema { }>; // @system export function createTableSchema, const TRowSchema extends RowSchemaBase>(inputSchemaFactory: SchemaFactoryBeta, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): TreeNodeSchemaCore_2, "Table">, NodeKind.Object, true, { - readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; - readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; + readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; + readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; }, object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }, unknown> & (new (data: InternalTreeNode | (object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; })) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>) & { empty, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>>(this: TThis): InstanceType; }; // @system From ee473df21324edfdfd937baf7b0ef376ceb6f114 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 14:02:34 -0700 Subject: [PATCH 15/23] Removed change that shouldn't be in this PR. --- packages/dds/tree/src/simple-tree/simpleSchema.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/simpleSchema.ts b/packages/dds/tree/src/simple-tree/simpleSchema.ts index bffc698dd640..b1b8eaf4b633 100644 --- a/packages/dds/tree/src/simple-tree/simpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/simpleSchema.ts @@ -58,13 +58,6 @@ export interface SimpleObjectNodeSchema * especially if/when TreeNodeSchema for objects provide more maps. */ readonly fields: ReadonlyMap; - - /** - * Whether the object node allows unknown optional fields. - * - * @remarks Used for compatibility checks. Not available in all cases. - */ - readonly allowUnknownOptionalFields?: boolean; } /** From 9bf18105fc95d3577f305a0603aa48e710246acc Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 15:53:05 -0700 Subject: [PATCH 16/23] - Removed evaluateSimpleAllowedTypes from AnnotatedAllowedTypes (which is beta). - PR feedback. --- .../dds/tree/api-report/tree.alpha.api.md | 22 +++++++++---------- .../dds/tree/src/shared-tree/sharedTree.ts | 4 ++-- .../src/simple-tree/api/schemaFromSimple.ts | 3 ++- .../tree/src/simple-tree/core/allowedTypes.ts | 14 ++++++------ .../dds/tree/src/simple-tree/fieldSchema.ts | 2 +- .../simple-tree/node-kinds/array/arrayNode.ts | 3 ++- .../src/simple-tree/node-kinds/map/mapNode.ts | 3 ++- .../node-kinds/record/recordNode.ts | 3 ++- .../dds/tree/src/simple-tree/simpleSchema.ts | 2 +- 9 files changed, 29 insertions(+), 27 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 1e6d7a64b4e8..405687750927 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -68,7 +68,6 @@ export interface AnnotatedAllowedTypes exte evaluate(): AllowedTypesFullEvaluated; evaluateIdentifiers(): ReadonlySet; evaluateSet(): ReadonlySet; - evaluateSimpleAllowedTypes(): ReadonlyMap; readonly metadata: AllowedTypesMetadata; readonly types: T; } @@ -276,7 +275,7 @@ export class FieldSchemaAlpha; + get simpleAllowedTypes(): ReadonlyMap; } // @alpha @sealed @system @@ -1009,7 +1008,7 @@ export type SharedTreeOptionsBeta = ForestOptions; // @alpha @sealed export interface SimpleAllowedTypes { - readonly isStaged?: boolean; + readonly isStaged: boolean | undefined; } // @alpha @sealed @@ -1056,7 +1055,6 @@ export interface SimpleObjectFieldSchema extends SimpleFieldSchema { // @alpha @sealed export interface SimpleObjectNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly allowUnknownOptionalFields?: boolean; readonly fields: ReadonlyMap; } @@ -1113,18 +1111,18 @@ export namespace System_TableSchema { }>; // @system export function createTableSchema, const TRowSchema extends RowSchemaBase>(inputSchemaFactory: SchemaFactoryBeta, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): TreeNodeSchemaCore_2, "Table">, NodeKind.Object, true, { - readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; - readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; + readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; + readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; }, object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }, unknown> & (new (data: InternalTreeNode | (object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; })) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>) & { empty, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>>(this: TThis): InstanceType; }; // @system diff --git a/packages/dds/tree/src/shared-tree/sharedTree.ts b/packages/dds/tree/src/shared-tree/sharedTree.ts index 2d4819dc7252..bfc0dbe860d9 100644 --- a/packages/dds/tree/src/shared-tree/sharedTree.ts +++ b/packages/dds/tree/src/shared-tree/sharedTree.ts @@ -966,7 +966,8 @@ function buildSimpleAllowedTypesForStoredSchema( ): ReadonlyMap { const allowedTypesInfo = new Map(); for (const type of types) { - allowedTypesInfo.set(type, {}); + // Stored schemas do not have staged upgrades + allowedTypesInfo.set(type, { isStaged: undefined }); } return allowedTypesInfo; } @@ -992,7 +993,6 @@ function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFie } return { kind, - // TODO: Refactor simpleAllowedTypes: buildSimpleAllowedTypesForStoredSchema(schema.types), metadata: {}, persistedMetadata: schema.persistedMetadata, diff --git a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts index d8f2b3e8e7ce..f396ae0cef75 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts @@ -89,7 +89,8 @@ function generateAllowedTypes( allowed: ReadonlyMap, context: Context, ): AllowedTypes { - return [...new Set(allowed.keys())].map( + return Array.from( + allowed.keys(), (id) => context.get(id) ?? fail(0xb5a /* Missing schema */), ); } diff --git a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts index 3e936f0cb02f..27b6dcc24bd6 100644 --- a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts +++ b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts @@ -134,11 +134,6 @@ export interface AnnotatedAllowedTypes * rather than identifiers where possible since its more type safe and it is possible that two schema with the same identifier exist. */ evaluateIdentifiers(): ReadonlySet; - - /** - * Get the {@link SimpleAllowedTypes} version of the allowed types set. - */ - evaluateSimpleAllowedTypes(): ReadonlyMap; } /** @@ -258,9 +253,14 @@ export class AnnotatedAllowedTypesInternal< return this.lazyEvaluate.value.identifiers; } - public evaluateSimpleAllowedTypes(): ReadonlyMap { + /** + * Get the {@link SimpleAllowedTypes} version of the allowed types set. + */ + public static evaluateSimpleAllowedTypes( + annotatedAllowedTypes: AnnotatedAllowedTypes, + ): ReadonlyMap { const simpleAllowedTypes = new Map(); - for (const type of this.evaluate().types) { + for (const type of annotatedAllowedTypes.evaluate().types) { simpleAllowedTypes.set(type.type.identifier, { isStaged: type.metadata.stagedSchemaUpgrade !== undefined, }); diff --git a/packages/dds/tree/src/simple-tree/fieldSchema.ts b/packages/dds/tree/src/simple-tree/fieldSchema.ts index 2dfd85cfe0f4..3ce6e9e44298 100644 --- a/packages/dds/tree/src/simple-tree/fieldSchema.ts +++ b/packages/dds/tree/src/simple-tree/fieldSchema.ts @@ -412,7 +412,7 @@ export class FieldSchemaAlpha< return this.allowedTypesFull.evaluateIdentifiers(); } - public get simpleAllowedTypes(): Map { + public get simpleAllowedTypes(): ReadonlyMap { const types = this.allowedTypesFull.evaluate().types; const info = new Map(); 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 c202df58274e..5d2d3973ba6f 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, @@ -1170,7 +1171,7 @@ export function arraySchema< () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); const lazySimpleAllowedTypes = new Lazy(() => { - return normalizedTypes.evaluateSimpleAllowedTypes(); + return AnnotatedAllowedTypesInternal.evaluateSimpleAllowedTypes(normalizedTypes); }); let privateData: TreeNodeSchemaPrivateData | undefined; 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 99c62dd134b2..b9bfdf0d9589 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, @@ -277,7 +278,7 @@ export function mapSchema< () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); const lazySimpleAllowedTypes = new Lazy(() => { - return normalizedTypes.evaluateSimpleAllowedTypes(); + return AnnotatedAllowedTypesInternal.evaluateSimpleAllowedTypes(normalizedTypes); }); let privateData: TreeNodeSchemaPrivateData | undefined; 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 ec9db6c90c33..e26b7427a905 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"; @@ -260,7 +261,7 @@ export function recordSchema< () => new Set(normalizedTypes.evaluate().map((type) => type.identifier)), ); const lazySimpleAllowedTypes = new Lazy(() => { - return normalizedTypes.evaluateSimpleAllowedTypes(); + return AnnotatedAllowedTypesInternal.evaluateSimpleAllowedTypes(normalizedTypes); }); let privateData: TreeNodeSchemaPrivateData | undefined; diff --git a/packages/dds/tree/src/simple-tree/simpleSchema.ts b/packages/dds/tree/src/simple-tree/simpleSchema.ts index b1b8eaf4b633..00703432aecf 100644 --- a/packages/dds/tree/src/simple-tree/simpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/simpleSchema.ts @@ -176,7 +176,7 @@ export interface SimpleAllowedTypes { * * Undefined if derived from a stored schema. */ - readonly isStaged?: boolean; + readonly isStaged: boolean | undefined; } /** From 97e1b12774e871086a7a5dc394d1d9fdcdca1358 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 15:54:43 -0700 Subject: [PATCH 17/23] Apply suggestion from @noencke Co-authored-by: Noah Encke <78610362+noencke@users.noreply.github.com> --- packages/dds/tree/src/shared-tree/sharedTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dds/tree/src/shared-tree/sharedTree.ts b/packages/dds/tree/src/shared-tree/sharedTree.ts index bfc0dbe860d9..2d623a9cf567 100644 --- a/packages/dds/tree/src/shared-tree/sharedTree.ts +++ b/packages/dds/tree/src/shared-tree/sharedTree.ts @@ -957,7 +957,7 @@ export const defaultSharedTreeOptions: Required = { /** * Build the allowed types for a Stored Schema. * - * @remarks Staged upgrades do not apply to stored schemas, so we omit the flag when building {@link SimpleAllowedTypes}. + * @remarks Staged upgrades do not apply to stored schemas, so we omit the {@link SimpleAllowedTypes.isStaged | staging flag } when building {@link SimpleAllowedTypes}. * @param types - The types to create allowed types for. * @returns The allowed types. */ From 6eddd774ea48be02511bcaa23cf98ca1fc9998ec Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 16:04:01 -0700 Subject: [PATCH 18/23] Rename. --- .../dds/tree/api-report/tree.alpha.api.md | 16 ++++---- .../src/simple-tree/api/schemaFromSimple.ts | 4 +- .../tree/src/simple-tree/core/allowedTypes.ts | 8 ++-- .../dds/tree/src/simple-tree/fieldSchema.ts | 6 +-- packages/dds/tree/src/simple-tree/index.ts | 2 +- .../simple-tree/node-kinds/array/arrayNode.ts | 4 +- .../src/simple-tree/node-kinds/map/mapNode.ts | 4 +- .../node-kinds/record/recordNode.ts | 4 +- .../dds/tree/src/simple-tree/simpleSchema.ts | 10 ++--- .../api/simpleSchemaToJsonSchema.spec.ts | 38 +++++++++---------- 10 files changed, 48 insertions(+), 48 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 405687750927..49849db9e795 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -1111,18 +1111,18 @@ export namespace System_TableSchema { }>; // @system export function createTableSchema, const TRowSchema extends RowSchemaBase>(inputSchemaFactory: SchemaFactoryBeta, _cellSchema: TCellSchema, columnSchema: TColumnSchema, rowSchema: TRowSchema): TreeNodeSchemaCore_2, "Table">, NodeKind.Object, true, { - readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; - readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; + readonly rows: TreeNodeSchemaClass, "Table.rows">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>, Iterable>, true, TRowSchema, undefined>; + readonly columns: TreeNodeSchemaClass, "Table.columns">, NodeKind.Array, TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>, Iterable>, true, TColumnSchema, undefined>; }, object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }, unknown> & (new (data: InternalTreeNode | (object & { - readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; })) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>) & { empty, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; - readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; + readonly rows: (InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.rows">, NodeKind.Array, true, TRowSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TRowSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.rows">, NodeKind.Array, unknown>)>; + readonly columns: (InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)> | undefined) & InsertableTypedNode_2, "Table.columns">, NodeKind.Array, true, TColumnSchema, Iterable>, unknown> & (new (data?: InternalTreeNode | Iterable> | undefined) => TreeArrayNode : TreeNodeFromImplicitAllowedTypes, [TColumnSchema] extends [ImplicitAllowedTypes] ? InsertableTreeNodeFromImplicitAllowedTypes : never, ReadonlyArrayNode_2> & WithType, "Table.columns">, NodeKind.Array, unknown>)>; }) => TreeNode & TableSchema.Table & WithType, "Table">, NodeKind, unknown>>(this: TThis): InstanceType; }; // @system diff --git a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts index f396ae0cef75..0892005387b5 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts @@ -13,7 +13,7 @@ import { type FieldProps, } from "../fieldSchema.js"; import type { - SimpleAllowedTypes, + SimpleAllowedTypesAttributes, SimpleFieldSchema, SimpleNodeSchema, SimpleTreeSchema, @@ -86,7 +86,7 @@ function generateFieldSchema( } function generateAllowedTypes( - allowed: ReadonlyMap, + allowed: ReadonlyMap, context: Context, ): AllowedTypes { return Array.from( diff --git a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts index 27b6dcc24bd6..e4b667ce729d 100644 --- a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts +++ b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts @@ -25,7 +25,7 @@ import { type TreeNodeSchema, } from "./treeNodeSchema.js"; import { schemaAsTreeNodeValid } from "./treeNodeValid.js"; -import type { SimpleAllowedTypes } from "../simpleSchema.js"; +import type { SimpleAllowedTypesAttributes } from "../simpleSchema.js"; /** * Schema for types allowed in some location in a tree (like a field, map entry or array). @@ -254,12 +254,12 @@ export class AnnotatedAllowedTypesInternal< } /** - * Get the {@link SimpleAllowedTypes} version of the allowed types set. + * Get the {@link SimpleAllowedTypesAttributes} version of the allowed types set. */ public static evaluateSimpleAllowedTypes( annotatedAllowedTypes: AnnotatedAllowedTypes, - ): ReadonlyMap { - const simpleAllowedTypes = new Map(); + ): ReadonlyMap { + const simpleAllowedTypes = new Map(); for (const type of annotatedAllowedTypes.evaluate().types) { simpleAllowedTypes.set(type.type.identifier, { isStaged: type.metadata.stagedSchemaUpgrade !== undefined, diff --git a/packages/dds/tree/src/simple-tree/fieldSchema.ts b/packages/dds/tree/src/simple-tree/fieldSchema.ts index 3ce6e9e44298..ecaff7cb0849 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 { SimpleAllowedTypes, SimpleFieldSchema } from "./simpleSchema.js"; +import type { SimpleAllowedTypesAttributes, SimpleFieldSchema } from "./simpleSchema.js"; import type { UnsafeUnknownSchema } from "./unsafeUnknownSchema.js"; import type { InsertableContent } from "./unhydratedFlexTreeFromInsertable.js"; @@ -412,9 +412,9 @@ export class FieldSchemaAlpha< return this.allowedTypesFull.evaluateIdentifiers(); } - public get simpleAllowedTypes(): ReadonlyMap { + public get simpleAllowedTypes(): ReadonlyMap { const types = this.allowedTypesFull.evaluate().types; - const info = new Map(); + const info = new Map(); for (const type of types) { info.set(type.type.identifier, { diff --git a/packages/dds/tree/src/simple-tree/index.ts b/packages/dds/tree/src/simple-tree/index.ts index 4f5ccf858dce..8bbdd17254cd 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -198,7 +198,7 @@ export type { SimpleNodeSchemaBaseAlpha, SimpleObjectFieldSchema, SimpleRecordNodeSchema, - SimpleAllowedTypes, + SimpleAllowedTypesAttributes as SimpleAllowedTypes, } 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 5d2d3973ba6f..b93c36e80de8 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 @@ -69,7 +69,7 @@ import type { import { brand, type JsonCompatibleReadOnlyObject } from "../../../util/index.js"; import { nullSchema } from "../../leafNodeSchema.js"; import { arrayNodeStoredSchema } from "../../toStoredSchema.js"; -import type { SimpleAllowedTypes } from "../../simpleSchema.js"; +import type { SimpleAllowedTypesAttributes } from "../../simpleSchema.js"; /** * A covariant base type for {@link (TreeArrayNode:interface)}. @@ -1211,7 +1211,7 @@ export function arraySchema< return lazyAllowedTypesIdentifiers.value; } - public static get simpleAllowedTypes(): ReadonlyMap { + public static get simpleAllowedTypes(): ReadonlyMap { return lazySimpleAllowedTypes.value; } 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 b9bfdf0d9589..b5df401197f7 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 @@ -67,7 +67,7 @@ import type { import { recordLikeDataToFlexContent } from "../common.js"; import { MapNodeStoredSchema } from "../../../core/index.js"; import type { NodeSchemaOptionsAlpha } from "../../api/index.js"; -import type { SimpleAllowedTypes } from "../../simpleSchema.js"; +import type { SimpleAllowedTypesAttributes } from "../../simpleSchema.js"; /** * A map of string keys to tree objects. @@ -308,7 +308,7 @@ export function mapSchema< return lazyAllowedTypesIdentifiers.value; } - public static get simpleAllowedTypes(): ReadonlyMap { + public static get simpleAllowedTypes(): ReadonlyMap { return lazySimpleAllowedTypes.value; } 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 e26b7427a905..784a99bbcad8 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 @@ -59,7 +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 { SimpleAllowedTypes } from "../../simpleSchema.js"; +import type { SimpleAllowedTypesAttributes } from "../../simpleSchema.js"; /** * Create a proxy which implements the {@link TreeRecordNode} API. @@ -352,7 +352,7 @@ export function recordSchema< return lazyAllowedTypesIdentifiers.value; } - public static get simpleAllowedTypes(): ReadonlyMap { + public static get simpleAllowedTypes(): ReadonlyMap { return lazySimpleAllowedTypes.value; } diff --git a/packages/dds/tree/src/simple-tree/simpleSchema.ts b/packages/dds/tree/src/simple-tree/simpleSchema.ts index 00703432aecf..ea73b1dff1dd 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 simpleAllowedTypes: ReadonlyMap; + 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 simpleAllowedTypes: ReadonlyMap; + 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 simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -168,7 +168,7 @@ export type SimpleNodeSchema = * @alpha * @sealed */ -export interface SimpleAllowedTypes { +export interface SimpleAllowedTypesAttributes { /** * 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). @@ -201,7 +201,7 @@ export interface SimpleFieldSchema { * @remarks Refers to the types by identifier. * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; /** * {@inheritDoc FieldSchemaMetadata} 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 9f67b9ecc7a8..b42ed1d8551c 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,7 +21,7 @@ import { } from "../../../simple-tree/index.js"; import { getJsonValidator } from "./jsonSchemaUtilities.js"; import type { - SimpleAllowedTypes, + SimpleAllowedTypesAttributes, SimpleNodeSchema, SimpleTreeSchema, // eslint-disable-next-line import/no-internal-modules @@ -50,7 +50,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -88,7 +88,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.handle", { isStaged: false }], ]), }, @@ -112,7 +112,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.array", { isStaged: false }], ]), metadata: {}, @@ -124,7 +124,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Array, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -169,7 +169,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.map", { isStaged: false }], ]), metadata: {}, @@ -181,7 +181,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Map, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -238,7 +238,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.record", { isStaged: false }], ]), metadata: {}, @@ -250,7 +250,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Record, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -354,7 +354,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -370,7 +370,7 @@ describe("simpleSchemaToJsonSchema", () => { "foo", { kind: FieldKind.Optional, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [numberSchema.identifier, { isStaged: false }], ]), metadata: { description: "A number representing the concept of Foo." }, @@ -382,7 +382,7 @@ describe("simpleSchemaToJsonSchema", () => { "bar", { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), metadata: { description: "A string representing the concept of Bar." }, @@ -394,7 +394,7 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), metadata: { @@ -499,7 +499,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -515,7 +515,7 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), storedKey: "id", @@ -559,7 +559,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -577,7 +577,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [numberSchema.identifier, { isStaged: false }], [stringSchema.identifier, { isStaged: false }], ]), @@ -629,7 +629,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.recursive-object", { isStaged: false }], ]), }, @@ -647,7 +647,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Optional, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ["test.recursive-object", { isStaged: false }], ]), From f4e16ea69627124ec8dcc0b1fbc6ab6d81f4559c Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 16:32:24 -0700 Subject: [PATCH 19/23] API Extractor. --- .../api-report/fluid-framework.alpha.api.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) 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 2cefa7f013db..363233850da2 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 @@ -68,7 +68,6 @@ export interface AnnotatedAllowedTypes exte evaluate(): AllowedTypesFullEvaluated; evaluateIdentifiers(): ReadonlySet; evaluateSet(): ReadonlySet; - evaluateSimpleAllowedTypes(): ReadonlyMap; readonly metadata: AllowedTypesMetadata; readonly types: T; } @@ -330,7 +329,7 @@ export class FieldSchemaAlpha; + get simpleAllowedTypes(): ReadonlyMap; } // @alpha @sealed @system @@ -1386,13 +1385,13 @@ export type SharedTreeOptions = Partial & Partial extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1400,7 +1399,7 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1410,7 +1409,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1434,13 +1433,12 @@ export interface SimpleObjectFieldSchema extends SimpleFieldSchema { // @alpha @sealed export interface SimpleObjectNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly allowUnknownOptionalFields?: boolean; readonly fields: ReadonlyMap; } // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha From d00a237b30ca1435a460cb75a73e07680acb8778 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 16:43:09 -0700 Subject: [PATCH 20/23] Rename. --- .../src/simple-tree/api/schemaFromSimple.ts | 4 +- .../tree/src/simple-tree/core/allowedTypes.ts | 8 ++-- .../dds/tree/src/simple-tree/fieldSchema.ts | 6 +-- packages/dds/tree/src/simple-tree/index.ts | 2 +- .../simple-tree/node-kinds/array/arrayNode.ts | 4 +- .../src/simple-tree/node-kinds/map/mapNode.ts | 4 +- .../node-kinds/record/recordNode.ts | 4 +- .../dds/tree/src/simple-tree/simpleSchema.ts | 10 ++--- .../api/simpleSchemaToJsonSchema.spec.ts | 38 +++++++++---------- .../api-report/fluid-framework.alpha.api.md | 12 +++--- 10 files changed, 46 insertions(+), 46 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts index 0892005387b5..0fe717923caa 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFromSimple.ts @@ -13,7 +13,7 @@ import { type FieldProps, } from "../fieldSchema.js"; import type { - SimpleAllowedTypesAttributes, + SimpleAllowedTypeAttributes, SimpleFieldSchema, SimpleNodeSchema, SimpleTreeSchema, @@ -86,7 +86,7 @@ function generateFieldSchema( } function generateAllowedTypes( - allowed: ReadonlyMap, + allowed: ReadonlyMap, context: Context, ): AllowedTypes { return Array.from( diff --git a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts index e4b667ce729d..957bb57daaac 100644 --- a/packages/dds/tree/src/simple-tree/core/allowedTypes.ts +++ b/packages/dds/tree/src/simple-tree/core/allowedTypes.ts @@ -25,7 +25,7 @@ import { type TreeNodeSchema, } from "./treeNodeSchema.js"; import { schemaAsTreeNodeValid } from "./treeNodeValid.js"; -import type { SimpleAllowedTypesAttributes } from "../simpleSchema.js"; +import type { SimpleAllowedTypeAttributes } from "../simpleSchema.js"; /** * Schema for types allowed in some location in a tree (like a field, map entry or array). @@ -254,12 +254,12 @@ export class AnnotatedAllowedTypesInternal< } /** - * Get the {@link SimpleAllowedTypesAttributes} version of the allowed types set. + * Get the {@link SimpleAllowedTypeAttributes} version of the allowed types set. */ public static evaluateSimpleAllowedTypes( annotatedAllowedTypes: AnnotatedAllowedTypes, - ): ReadonlyMap { - const simpleAllowedTypes = new Map(); + ): ReadonlyMap { + const simpleAllowedTypes = new Map(); for (const type of annotatedAllowedTypes.evaluate().types) { simpleAllowedTypes.set(type.type.identifier, { isStaged: type.metadata.stagedSchemaUpgrade !== undefined, diff --git a/packages/dds/tree/src/simple-tree/fieldSchema.ts b/packages/dds/tree/src/simple-tree/fieldSchema.ts index ecaff7cb0849..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 { SimpleAllowedTypesAttributes, SimpleFieldSchema } from "./simpleSchema.js"; +import type { SimpleAllowedTypeAttributes, SimpleFieldSchema } from "./simpleSchema.js"; import type { UnsafeUnknownSchema } from "./unsafeUnknownSchema.js"; import type { InsertableContent } from "./unhydratedFlexTreeFromInsertable.js"; @@ -412,9 +412,9 @@ export class FieldSchemaAlpha< return this.allowedTypesFull.evaluateIdentifiers(); } - public get simpleAllowedTypes(): ReadonlyMap { + public get simpleAllowedTypes(): ReadonlyMap { const types = this.allowedTypesFull.evaluate().types; - const info = new Map(); + const info = new Map(); for (const type of types) { info.set(type.type.identifier, { diff --git a/packages/dds/tree/src/simple-tree/index.ts b/packages/dds/tree/src/simple-tree/index.ts index 8bbdd17254cd..d27f31165506 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -198,7 +198,7 @@ export type { SimpleNodeSchemaBaseAlpha, SimpleObjectFieldSchema, SimpleRecordNodeSchema, - SimpleAllowedTypesAttributes as SimpleAllowedTypes, + SimpleAllowedTypeAttributes as SimpleAllowedTypes, } 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 b93c36e80de8..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 @@ -69,7 +69,7 @@ import type { import { brand, type JsonCompatibleReadOnlyObject } from "../../../util/index.js"; import { nullSchema } from "../../leafNodeSchema.js"; import { arrayNodeStoredSchema } from "../../toStoredSchema.js"; -import type { SimpleAllowedTypesAttributes } from "../../simpleSchema.js"; +import type { SimpleAllowedTypeAttributes } from "../../simpleSchema.js"; /** * A covariant base type for {@link (TreeArrayNode:interface)}. @@ -1211,7 +1211,7 @@ export function arraySchema< return lazyAllowedTypesIdentifiers.value; } - public static get simpleAllowedTypes(): ReadonlyMap { + public static get simpleAllowedTypes(): ReadonlyMap { return lazySimpleAllowedTypes.value; } 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 b5df401197f7..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 @@ -67,7 +67,7 @@ import type { import { recordLikeDataToFlexContent } from "../common.js"; import { MapNodeStoredSchema } from "../../../core/index.js"; import type { NodeSchemaOptionsAlpha } from "../../api/index.js"; -import type { SimpleAllowedTypesAttributes } from "../../simpleSchema.js"; +import type { SimpleAllowedTypeAttributes } from "../../simpleSchema.js"; /** * A map of string keys to tree objects. @@ -308,7 +308,7 @@ export function mapSchema< return lazyAllowedTypesIdentifiers.value; } - public static get simpleAllowedTypes(): ReadonlyMap { + public static get simpleAllowedTypes(): ReadonlyMap { return lazySimpleAllowedTypes.value; } 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 784a99bbcad8..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 @@ -59,7 +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 { SimpleAllowedTypesAttributes } from "../../simpleSchema.js"; +import type { SimpleAllowedTypeAttributes } from "../../simpleSchema.js"; /** * Create a proxy which implements the {@link TreeRecordNode} API. @@ -352,7 +352,7 @@ export function recordSchema< return lazyAllowedTypesIdentifiers.value; } - public static get simpleAllowedTypes(): ReadonlyMap { + public static get simpleAllowedTypes(): ReadonlyMap { return lazySimpleAllowedTypes.value; } diff --git a/packages/dds/tree/src/simple-tree/simpleSchema.ts b/packages/dds/tree/src/simple-tree/simpleSchema.ts index ea73b1dff1dd..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 simpleAllowedTypes: ReadonlyMap; + 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 simpleAllowedTypes: ReadonlyMap; + 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 simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } /** @@ -168,7 +168,7 @@ export type SimpleNodeSchema = * @alpha * @sealed */ -export interface SimpleAllowedTypesAttributes { +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). @@ -201,7 +201,7 @@ export interface SimpleFieldSchema { * @remarks Refers to the types by identifier. * A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}. */ - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; /** * {@inheritDoc FieldSchemaMetadata} 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 b42ed1d8551c..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,7 +21,7 @@ import { } from "../../../simple-tree/index.js"; import { getJsonValidator } from "./jsonSchemaUtilities.js"; import type { - SimpleAllowedTypesAttributes, + SimpleAllowedTypeAttributes, SimpleNodeSchema, SimpleTreeSchema, // eslint-disable-next-line import/no-internal-modules @@ -50,7 +50,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -88,7 +88,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.handle", { isStaged: false }], ]), }, @@ -112,7 +112,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.array", { isStaged: false }], ]), metadata: {}, @@ -124,7 +124,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Array, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -169,7 +169,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.map", { isStaged: false }], ]), metadata: {}, @@ -181,7 +181,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Map, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -238,7 +238,7 @@ describe("simpleSchemaToJsonSchema", () => { const input: SimpleTreeSchema = { root: { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.record", { isStaged: false }], ]), metadata: {}, @@ -250,7 +250,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: NodeKind.Record, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), }, @@ -354,7 +354,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -370,7 +370,7 @@ describe("simpleSchemaToJsonSchema", () => { "foo", { kind: FieldKind.Optional, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [numberSchema.identifier, { isStaged: false }], ]), metadata: { description: "A number representing the concept of Foo." }, @@ -382,7 +382,7 @@ describe("simpleSchemaToJsonSchema", () => { "bar", { kind: FieldKind.Required, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), metadata: { description: "A string representing the concept of Bar." }, @@ -394,7 +394,7 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), metadata: { @@ -499,7 +499,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -515,7 +515,7 @@ describe("simpleSchemaToJsonSchema", () => { "id", { kind: FieldKind.Identifier, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ]), storedKey: "id", @@ -559,7 +559,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.object", { isStaged: false }], ]), }, @@ -577,7 +577,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Required, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [numberSchema.identifier, { isStaged: false }], [stringSchema.identifier, { isStaged: false }], ]), @@ -629,7 +629,7 @@ describe("simpleSchemaToJsonSchema", () => { root: { kind: FieldKind.Required, metadata: {}, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ ["test.recursive-object", { isStaged: false }], ]), }, @@ -647,7 +647,7 @@ describe("simpleSchemaToJsonSchema", () => { kind: FieldKind.Optional, metadata: {}, persistedMetadata: undefined, - simpleAllowedTypes: new Map([ + simpleAllowedTypes: new Map([ [stringSchema.identifier, { isStaged: false }], ["test.recursive-object", { isStaged: false }], ]), 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 363233850da2..0e2137f1dfaa 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 @@ -329,7 +329,7 @@ export class FieldSchemaAlpha; + get simpleAllowedTypes(): ReadonlyMap; } // @alpha @sealed @system @@ -1385,13 +1385,13 @@ export type SharedTreeOptions = Partial & Partial extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1399,7 +1399,7 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1409,7 +1409,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1438,7 +1438,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha From 550240b9aa31186a9a3ea65b8bacbb1c0e8d2c48 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Wed, 29 Oct 2025 20:41:15 -0700 Subject: [PATCH 21/23] Fixed exports. --- packages/dds/tree/api-report/tree.alpha.api.md | 12 ++++++------ packages/dds/tree/src/index.ts | 2 +- .../dds/tree/src/shared-tree/sharedTree.ts | 18 ++++++++++-------- packages/dds/tree/src/simple-tree/index.ts | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 49849db9e795..d512f1598436 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -275,7 +275,7 @@ export class FieldSchemaAlpha; + get simpleAllowedTypes(): ReadonlyMap; } // @alpha @sealed @system @@ -1007,13 +1007,13 @@ export type SharedTreeOptions = Partial & Partial extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1021,7 +1021,7 @@ export interface SimpleFieldSchema { readonly kind: FieldKind; readonly metadata: FieldSchemaMetadata; readonly persistedMetadata?: JsonCompatibleReadOnlyObject | undefined; - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @sealed @@ -1031,7 +1031,7 @@ export interface SimpleLeafNodeSchema extends SimpleNodeSchemaBaseAlpha extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha @@ -1060,7 +1060,7 @@ export interface SimpleObjectNodeSchema extends S // @alpha @sealed export interface SimpleRecordNodeSchema extends SimpleNodeSchemaBaseAlpha { - readonly simpleAllowedTypes: ReadonlyMap; + readonly simpleAllowedTypes: ReadonlyMap; } // @alpha diff --git a/packages/dds/tree/src/index.ts b/packages/dds/tree/src/index.ts index 77304ad20c3d..95adf131fec3 100644 --- a/packages/dds/tree/src/index.ts +++ b/packages/dds/tree/src/index.ts @@ -280,7 +280,7 @@ export { type TreeParsingOptions, type SchemaFactory_base, type NumberKeys, - type SimpleAllowedTypes, + 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 2d623a9cf567..3e14a3434b9e 100644 --- a/packages/dds/tree/src/shared-tree/sharedTree.ts +++ b/packages/dds/tree/src/shared-tree/sharedTree.ts @@ -99,7 +99,7 @@ import { FieldKind, type ITreeAlpha, type SimpleObjectFieldSchema, - type SimpleAllowedTypes, + type SimpleAllowedTypeAttributes, } from "../simple-tree/index.js"; import { SchematizingSimpleTreeView } from "./schematizingTreeView.js"; @@ -957,14 +957,14 @@ export const defaultSharedTreeOptions: Required = { /** * Build the allowed types for a Stored Schema. * - * @remarks Staged upgrades do not apply to stored schemas, so we omit the {@link SimpleAllowedTypes.isStaged | staging flag } when building {@link SimpleAllowedTypes}. + * @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 buildSimpleAllowedTypesForStoredSchema( +function buildSimpleAllowedTypeAttributesForStoredSchema( types: TreeTypeSet, -): ReadonlyMap { - const allowedTypesInfo = new Map(); +): ReadonlyMap { + const allowedTypesInfo = new Map(); for (const type of types) { // Stored schemas do not have staged upgrades allowedTypesInfo.set(type, { isStaged: undefined }); @@ -993,7 +993,7 @@ function exportSimpleFieldSchemaStored(schema: TreeFieldStoredSchema): SimpleFie } return { kind, - simpleAllowedTypes: buildSimpleAllowedTypesForStoredSchema(schema.types), + simpleAllowedTypes: buildSimpleAllowedTypeAttributesForStoredSchema(schema.types), metadata: {}, persistedMetadata: schema.persistedMetadata, }; @@ -1009,7 +1009,7 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS if (arrayTypes !== undefined) { return { kind: NodeKind.Array, - simpleAllowedTypes: buildSimpleAllowedTypesForStoredSchema(arrayTypes), + simpleAllowedTypes: buildSimpleAllowedTypeAttributesForStoredSchema(arrayTypes), metadata: {}, persistedMetadata: schema.metadata, }; @@ -1028,7 +1028,9 @@ function exportSimpleNodeSchemaStored(schema: TreeNodeStoredSchema): SimpleNodeS ); return { kind: NodeKind.Map, - simpleAllowedTypes: buildSimpleAllowedTypesForStoredSchema(schema.mapFields.types), + simpleAllowedTypes: buildSimpleAllowedTypeAttributesForStoredSchema( + schema.mapFields.types, + ), metadata: {}, persistedMetadata: schema.metadata, }; diff --git a/packages/dds/tree/src/simple-tree/index.ts b/packages/dds/tree/src/simple-tree/index.ts index d27f31165506..5c23b174daa6 100644 --- a/packages/dds/tree/src/simple-tree/index.ts +++ b/packages/dds/tree/src/simple-tree/index.ts @@ -198,7 +198,7 @@ export type { SimpleNodeSchemaBaseAlpha, SimpleObjectFieldSchema, SimpleRecordNodeSchema, - SimpleAllowedTypeAttributes as SimpleAllowedTypes, + SimpleAllowedTypeAttributes, } from "./simpleSchema.js"; export { type ImplicitFieldSchema, From 7a218b11737332b6e2dd5e042cf8396761e45421 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Thu, 30 Oct 2025 12:56:49 -0700 Subject: [PATCH 22/23] Fix for failing test and cases where `toSimpleTreeSchema` should not preserve view-specific attributes. --- .../api/viewSchemaToSimpleSchema.ts | 58 ++++++++++++++++--- .../src/test/shared-tree/sharedTree.spec.ts | 9 ++- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index 15a6e1d3017e..eaf866ecf6e4 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 preserveViewSchemaProperties - 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, + preserveViewSchemaProperties: 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, preserveViewSchemaProperties) + : nodeSchema; definitions.set(nodeSchema.identifier, outSchema); }, }); @@ -67,7 +72,10 @@ export function toSimpleTreeSchema( return { root: copySchemaObjects ? ({ - simpleAllowedTypes: normalizedSchema.simpleAllowedTypes, + simpleAllowedTypes: normalizeSimpleAllowedTypes( + normalizedSchema.simpleAllowedTypes, + preserveViewSchemaProperties, + ), 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 preserveViewSchemaProperties - 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, + preserveViewSchemaProperties: boolean, +): ReadonlyMap { + if (preserveViewSchemaProperties) { + 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, + preserveViewSchemaProperties: 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, preserveViewSchemaProperties); case NodeKind.Object: - return copySimpleObjectSchema(schema); + return copySimpleObjectSchema(schema, preserveViewSchemaProperties); default: unreachableCase(kind); } @@ -109,22 +141,32 @@ function copySimpleLeafSchema(schema: SimpleLeafNodeSchema): SimpleLeafNodeSchem function copySimpleSchemaWithAllowedTypes( schema: SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema, + preserveViewSchemaProperties: boolean, ): SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema { return { kind: schema.kind, - simpleAllowedTypes: schema.simpleAllowedTypes, + simpleAllowedTypes: normalizeSimpleAllowedTypes( + schema.simpleAllowedTypes, + preserveViewSchemaProperties, + ), metadata: schema.metadata, persistedMetadata: schema.persistedMetadata, }; } -function copySimpleObjectSchema(schema: SimpleObjectNodeSchema): SimpleObjectNodeSchema { +function copySimpleObjectSchema( + schema: SimpleObjectNodeSchema, + preserveViewSchemaProperties: 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, - simpleAllowedTypes: field.simpleAllowedTypes, + simpleAllowedTypes: normalizeSimpleAllowedTypes( + field.simpleAllowedTypes, + preserveViewSchemaProperties, + ), metadata: field.metadata, persistedMetadata: field.persistedMetadata, storedKey: field.storedKey, 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", () => { From 69c367451b2f8074ea91594f0063c839a261f582 Mon Sep 17 00:00:00 2001 From: Tommy Brosman Date: Thu, 30 Oct 2025 13:29:15 -0700 Subject: [PATCH 23/23] Minor rename. --- .../api/viewSchemaToSimpleSchema.ts | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts index eaf866ecf6e4..735fedc9ec37 100644 --- a/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts +++ b/packages/dds/tree/src/simple-tree/api/viewSchemaToSimpleSchema.ts @@ -32,7 +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 preserveViewSchemaProperties - 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. + * @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. @@ -47,7 +47,7 @@ import { LeafNodeSchema } from "../leafNodeSchema.js"; export function toSimpleTreeSchema( schema: ImplicitFieldSchema, copySchemaObjects: boolean, - preserveViewSchemaProperties: boolean = true, + isViewSchema: boolean = true, ): SimpleTreeSchema { const normalizedSchema = normalizeFieldSchema(schema); const definitions = new Map(); @@ -63,7 +63,7 @@ export function toSimpleTreeSchema( 0xb60 /* Invalid schema */, ); const outSchema = copySchemaObjects - ? copySimpleNodeSchema(nodeSchema, preserveViewSchemaProperties) + ? copySimpleNodeSchema(nodeSchema, isViewSchema) : nodeSchema; definitions.set(nodeSchema.identifier, outSchema); }, @@ -74,7 +74,7 @@ export function toSimpleTreeSchema( ? ({ simpleAllowedTypes: normalizeSimpleAllowedTypes( normalizedSchema.simpleAllowedTypes, - preserveViewSchemaProperties, + isViewSchema, ), kind: normalizedSchema.kind, metadata: normalizedSchema.metadata, @@ -88,14 +88,14 @@ 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 preserveViewSchemaProperties - If true, properties used by view schema but not part of stored schema (for example, `isStaged` on allowed types) are preserved in the output. + * @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, - preserveViewSchemaProperties: boolean, + isViewSchema: boolean, ): ReadonlyMap { - if (preserveViewSchemaProperties) { + if (isViewSchema) { return simpleAllowedTypes; } else { const normalized = new Map(); @@ -113,7 +113,7 @@ function normalizeSimpleAllowedTypes( */ function copySimpleNodeSchema( schema: SimpleNodeSchema, - preserveViewSchemaProperties: boolean, + isViewSchema: boolean, ): SimpleNodeSchema { const kind = schema.kind; switch (kind) { @@ -122,9 +122,9 @@ function copySimpleNodeSchema( case NodeKind.Array: case NodeKind.Map: case NodeKind.Record: - return copySimpleSchemaWithAllowedTypes(schema, preserveViewSchemaProperties); + return copySimpleSchemaWithAllowedTypes(schema, isViewSchema); case NodeKind.Object: - return copySimpleObjectSchema(schema, preserveViewSchemaProperties); + return copySimpleObjectSchema(schema, isViewSchema); default: unreachableCase(kind); } @@ -141,14 +141,11 @@ function copySimpleLeafSchema(schema: SimpleLeafNodeSchema): SimpleLeafNodeSchem function copySimpleSchemaWithAllowedTypes( schema: SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema, - preserveViewSchemaProperties: boolean, + isViewSchema: boolean, ): SimpleMapNodeSchema | SimpleArrayNodeSchema | SimpleRecordNodeSchema { return { kind: schema.kind, - simpleAllowedTypes: normalizeSimpleAllowedTypes( - schema.simpleAllowedTypes, - preserveViewSchemaProperties, - ), + simpleAllowedTypes: normalizeSimpleAllowedTypes(schema.simpleAllowedTypes, isViewSchema), metadata: schema.metadata, persistedMetadata: schema.persistedMetadata, }; @@ -156,17 +153,14 @@ function copySimpleSchemaWithAllowedTypes( function copySimpleObjectSchema( schema: SimpleObjectNodeSchema, - preserveViewSchemaProperties: boolean, + 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, - simpleAllowedTypes: normalizeSimpleAllowedTypes( - field.simpleAllowedTypes, - preserveViewSchemaProperties, - ), + simpleAllowedTypes: normalizeSimpleAllowedTypes(field.simpleAllowedTypes, isViewSchema), metadata: field.metadata, persistedMetadata: field.persistedMetadata, storedKey: field.storedKey,