tree: Cleanup related to contravariant input types (#22875)

## Description

Misc improvements found when working on
https://github.com/microsoft/FluidFramework/pull/22874 .

Many of these are places where schema types were not captured properly,
or incorrect typing wasn't detected due to the incorrect variance.

## Breaking Changes

The change to `InsertableObjectFromSchemaRecord` could impact something:
it's strictly a bug fix but its unclear what implications its wrong
version could have. I suspect no realistic code would be broken by these
more correct types, but it's possible something could be impacted.
This commit is contained in:
Craig Macomber (Microsoft) 2024-10-22 17:01:20 -07:00 коммит произвёл GitHub
Родитель b8e887ead4
Коммит 7405cf5ad2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
27 изменённых файлов: 108 добавлений и 89 удалений

1
packages/dds/tree/.vscode/settings.json поставляемый
Просмотреть файл

@ -22,6 +22,7 @@
"endregion",
"insertable",
"reentrantly",
"typeparam",
"unhydrated",
],

Просмотреть файл

@ -173,9 +173,9 @@ export type InsertableField<TSchema extends ImplicitFieldSchema | UnsafeUnknownS
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -771,7 +771,7 @@ export interface TreeViewAlpha<in out TSchema extends ImplicitFieldSchema | Unsa
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -103,9 +103,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -564,7 +564,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -103,9 +103,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -551,7 +551,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -103,9 +103,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -548,7 +548,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -103,9 +103,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -548,7 +548,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -144,7 +144,7 @@ export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitField
this.runSchemaEdit(() => {
const mapTree = mapTreeFromNodeData(
content as InsertableContent,
content as InsertableContent | undefined,
this.rootFieldSchema,
this.nodeKeyManager,
{
@ -359,7 +359,11 @@ export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitField
);
}
const view = this.getView();
setField(view.context.root, this.rootFieldSchema, newRoot as InsertableContent);
setField(
view.context.root,
this.rootFieldSchema,
newRoot as InsertableContent | undefined,
);
}
}

Просмотреть файл

@ -10,10 +10,11 @@ import type { ITreeCursorSynchronous, SchemaAndPolicy } from "../../core/index.j
import type {
TreeLeafValue,
ImplicitFieldSchema,
InsertableTreeFieldFromImplicitField,
TreeFieldFromImplicitField,
FieldSchema,
FieldKind,
UnsafeUnknownSchema,
InsertableField,
} from "../schemaTypes.js";
import {
getOrCreateNodeFromInnerNode,
@ -29,7 +30,7 @@ import {
} from "../../feature-libraries/index.js";
import { isFieldInSchema } from "../../feature-libraries/index.js";
import { toStoredSchema } from "../toFlexSchema.js";
import { inSchemaOrThrow, mapTreeFromNodeData, type InsertableContent } from "../toMapTree.js";
import { inSchemaOrThrow, mapTreeFromNodeData } from "../toMapTree.js";
import {
applySchemaToParserOptions,
cursorFromVerbose,
@ -55,7 +56,7 @@ import { getUnhydratedContext } from "../createContext.js";
*/
export function createFromInsertable<TSchema extends ImplicitFieldSchema>(
schema: TSchema,
data: InsertableTreeFieldFromImplicitField<TSchema>,
data: InsertableField<TSchema>,
context?: NodeKeyManager | undefined,
): Unhydrated<TreeFieldFromImplicitField<TSchema>> {
const cursor = cursorFromInsertable(schema, data, context);
@ -72,9 +73,13 @@ export function createFromInsertable<TSchema extends ImplicitFieldSchema>(
* this is the same as invoking its constructor except that an unhydrated node can also be provided and the returned value is a cursor.
* When `undefined` is provided (for an optional field), `undefined` is returned.
*/
export function cursorFromInsertable<TSchema extends ImplicitFieldSchema>(
schema: TSchema,
data: InsertableTreeFieldFromImplicitField<TSchema>,
export function cursorFromInsertable<
TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema,
>(
schema: UnsafeUnknownSchema extends TSchema
? ImplicitFieldSchema
: TSchema & ImplicitFieldSchema,
data: InsertableField<TSchema>,
context?: NodeKeyManager | undefined,
):
| ITreeCursorSynchronous
@ -87,7 +92,7 @@ export function cursorFromInsertable<TSchema extends ImplicitFieldSchema>(
};
const mapTree = mapTreeFromNodeData(
data as InsertableContent | undefined,
data as InsertableField<UnsafeUnknownSchema>,
schema,
context,
schemaValidationPolicy,

Просмотреть файл

@ -193,8 +193,9 @@ export interface ITreeViewConfiguration<
* Configuration for {@link ViewableTree.viewWith}.
* @sealed @public
*/
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema>
implements Required<ITreeViewConfiguration<TSchema>>
export class TreeViewConfiguration<
const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,
> implements Required<ITreeViewConfiguration<TSchema>>
{
protected _typeCheck!: MakeNominal;

Просмотреть файл

@ -12,7 +12,11 @@ import {
type Unhydrated,
type WithType,
} from "../core/index.js";
import type { ImplicitFieldSchema, TreeFieldFromImplicitField } from "../schemaTypes.js";
import type {
ImplicitFieldSchema,
TreeFieldFromImplicitField,
UnsafeUnknownSchema,
} from "../schemaTypes.js";
import { treeNodeApi } from "./treeNodeApi.js";
import { createFromCursor, cursorFromInsertable } from "./create.js";
import type { ITreeCursorSynchronous } from "../../core/index.js";
@ -145,7 +149,7 @@ export const TreeBeta: {
if (!kernel.isHydrated()) {
return createFromCursor(
kernel.schema,
cursorFromInsertable(kernel.schema, node),
cursorFromInsertable<UnsafeUnknownSchema>(kernel.schema, node),
) as Unhydrated<TreeFieldFromImplicitField<TSchema>>;
}

Просмотреть файл

@ -128,7 +128,10 @@ export interface TreeMapNode<T extends ImplicitAllowedTypes = ImplicitAllowedTyp
): void;
}
const handler: ProxyHandler<TreeMapNode> = {
// TreeMapNode is invariant over schema type, so for this handler to work with all schema, the only possible type for the schema is `any`.
// This is not ideal, but no alternatives are possible.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handler: ProxyHandler<TreeMapNode<any>> = {
getPrototypeOf: () => {
return Map.prototype;
},
@ -177,7 +180,7 @@ abstract class CustomMapNodeBase<const T extends ImplicitAllowedTypes> extends T
const node = this.innerNode;
return node.keys();
}
public set(key: string, value: InsertableTreeNodeFromImplicitAllowedTypes<T>): TreeMapNode {
public set(key: string, value: InsertableTreeNodeFromImplicitAllowedTypes<T>): this {
const kernel = getKernel(this);
const node = this.innerNode;
const mapTree = mapTreeFromNodeData(
@ -244,7 +247,7 @@ export function mapSchema<
flexNode: FlexTreeNode,
): TreeNodeValid<T2> {
if (useMapPrototype) {
return new Proxy<Schema>(instance as Schema, handler);
return new Proxy<Schema>(instance as Schema, handler as ProxyHandler<Schema>);
}
return instance;
}

Просмотреть файл

@ -107,13 +107,13 @@ export type InsertableObjectFromSchemaRecord<
> = FlattenKeys<
{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<
T[Property] & string
T[Property & string]
>;
} & {
// Field does not have a known default, make it required:
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false
? Property
: never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
: never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}
>;

Просмотреть файл

@ -57,13 +57,13 @@ import {
import {
MockTreeCheckout,
checkoutWithContent,
cursorFromInsertableTreeField,
forestWithContent,
mintRevisionTag,
testIdCompressor,
type SharedTreeWithConnectionStateSetter,
} from "../../utils.js";
import {
cursorFromInsertable,
numberSchema,
SchemaFactory,
stringSchema,
@ -108,7 +108,7 @@ class HasIdentifier extends schemaFactory.object("parent", {
}) {}
function getIdentifierEncodingContext(id: string) {
const initialTree = cursorFromInsertableTreeField(
const initialTree = cursorFromInsertable(
HasIdentifier,
new HasIdentifier({ identifier: id }),
new MockNodeKeyManager(),

Просмотреть файл

@ -13,17 +13,18 @@ import {
// eslint-disable-next-line import/no-internal-modules
} from "../../shared-tree/schematizingTreeView.js";
import {
cursorFromInsertable,
SchemaFactory,
TreeViewConfiguration,
type ImplicitFieldSchema,
type InsertableTreeFieldFromImplicitField,
type InsertableField,
type UnsafeUnknownSchema,
} from "../../simple-tree/index.js";
// eslint-disable-next-line import/no-internal-modules
import { toStoredSchema } from "../../simple-tree/toFlexSchema.js";
import {
checkoutWithContent,
createTestUndoRedoStacks,
cursorFromInsertableTreeField,
validateUsageError,
} from "../utils.js";
import { insert } from "../sequenceRootUtils.js";
@ -40,10 +41,10 @@ const configGeneralized2 = new TreeViewConfiguration({
function checkoutWithInitialTree(
viewConfig: TreeViewConfiguration,
unhydratedInitialTree: InsertableTreeFieldFromImplicitField,
unhydratedInitialTree: InsertableField<UnsafeUnknownSchema>,
nodeKeyManager = new MockNodeKeyManager(),
): TreeCheckout {
const initialTree = cursorFromInsertableTreeField(
const initialTree = cursorFromInsertable<UnsafeUnknownSchema>(
viewConfig.schema,
unhydratedInitialTree,
nodeKeyManager,

Просмотреть файл

@ -76,7 +76,7 @@ describe("getJsonSchema", () => {
it("Union root", async () => {
const schemaFactory = new SchemaFactory("test");
const Schema = [schemaFactory.number, schemaFactory.string];
const Schema = [schemaFactory.number, schemaFactory.string] as const;
const actual = getJsonSchema(Schema);

Просмотреть файл

@ -29,6 +29,7 @@ import {
} from "../../core/index.js";
import {
booleanSchema,
cursorFromInsertable,
handleSchema,
nullSchema,
numberSchema,
@ -59,7 +60,7 @@ import {
MockNodeKeyManager,
type NodeKeyManager,
} from "../../feature-libraries/index.js";
import { cursorFromInsertableTreeField, validateUsageError } from "../utils.js";
import { validateUsageError } from "../utils.js";
/**
* Helper for building {@link TreeFieldStoredSchema}.
@ -1513,15 +1514,16 @@ describe("toMapTree", () => {
new Map(),
);
describe("cursorFromInsertableTreeField", () => {
describe("cursorFromInsertable", () => {
it("Success", () => {
cursorFromInsertableTreeField(schemaFactory.string, "Hello world", nodeKeyManager);
cursorFromInsertable(schemaFactory.string, "Hello world", nodeKeyManager);
});
it("Failure", () => {
assert.throws(
() =>
cursorFromInsertableTreeField(schemaFactory.number, "Hello world", nodeKeyManager),
// @ts-expect-error invalid data for schema
cursorFromInsertable(schemaFactory.number, "Hello world", nodeKeyManager),
validateUsageError(/incompatible/),
);
});

Просмотреть файл

@ -28,7 +28,7 @@ interface TestCaseErased {
}
function test<T extends ImplicitFieldSchema>(t: TestCase<T>): TestCaseErased {
return t;
return t as TestCaseErased;
}
/**

Просмотреть файл

@ -170,7 +170,7 @@ describe("Primitives", () => {
describe("with schema [_.number, _.null]", () => {
// JSON coerces non-finite numbers to 'null'. This succeeds when 'null' is
// permitted by schema.
const schema = [schemaFactory.number, schemaFactory.null];
const schema = [schemaFactory.number, schemaFactory.null] as const;
[-Infinity, NaN, Infinity].forEach((value) => checkCoerced(schema, value));
});
});

Просмотреть файл

@ -17,7 +17,7 @@ import {
type WideTreeNode,
} from "./benchmarkUtilities.js";
import { SchemaFactory } from "../../simple-tree/index.js";
import { hydrate } from "./utils.js";
import { hydrate, hydrateUnsafe } from "./utils.js";
// number of nodes in test for wide trees
const nodesCountWide = [
@ -250,11 +250,11 @@ describe("SimpleTree benchmarks", () => {
title: `Read value from union of leaf and non-leaf`,
mapType: NumberObjectMap,
},
];
] as const;
for (const { title, mapType } of valueTestCases) {
const initUnhydrated = () => new mapType([["a", 1]]);
const initFlex = () => hydrate(mapType, initUnhydrated());
const initFlex = () => hydrateUnsafe(mapType, initUnhydrated());
const readFunction = (tree: CombinedTypes) => tree.get("a") as number;
generateBenchmarkPair(title, initUnhydrated, initFlex, readFunction, 1);
}
@ -282,7 +282,7 @@ describe("SimpleTree benchmarks", () => {
for (const { title, mapType } of undefinedTestCases) {
const initUnhydrated = () => new mapType([["a", 1]]);
const initFlex = () => hydrate(mapType, initUnhydrated());
const initFlex = () => hydrateUnsafe(mapType, initUnhydrated());
const readFunction = (tree: CombinedTypes) => tree.get("b") as number;
generateBenchmarkPair(title, initUnhydrated, initFlex, readFunction, undefined);
}
@ -314,7 +314,7 @@ describe("SimpleTree benchmarks", () => {
for (const { title, arrayType } of testCases) {
const initUnhydrated = () => new arrayType([1]);
const initFlex = () => hydrate(arrayType, initUnhydrated());
const initFlex = () => hydrateUnsafe(arrayType, initUnhydrated());
const read = (tree: NumArray | NumStringArray | NumObjectArray) => tree[0] as number;
generateBenchmarkPair(title, initUnhydrated, initFlex, read, 1);
}

Просмотреть файл

@ -21,12 +21,14 @@ import {
SimpleContextSlot,
type ImplicitFieldSchema,
type InsertableContent,
type InsertableField,
type InsertableTreeFieldFromImplicitField,
type NodeKind,
type TreeFieldFromImplicitField,
type TreeLeafValue,
type TreeNode,
type TreeNodeSchema,
type UnsafeUnknownSchema,
} from "../../simple-tree/index.js";
import {
getTreeNodeForField,
@ -114,7 +116,7 @@ export function describeHydration(
*
* TODO: determine and document if this produces "cooked" or "marinated" nodes.
*/
export function hydrate<TSchema extends ImplicitFieldSchema>(
export function hydrate<const TSchema extends ImplicitFieldSchema>(
schema: TSchema,
initialTree: InsertableTreeFieldFromImplicitField<TSchema>,
): TreeFieldFromImplicitField<TSchema> {
@ -145,6 +147,18 @@ export function hydrate<TSchema extends ImplicitFieldSchema>(
return getTreeNodeForField(field) as TreeFieldFromImplicitField<TSchema>;
}
/**
* {@link hydrate} but unsafe initialTree.
* This may be required when the schema is not entirely statically typed, for example when looping over multiple test cases and thus using a imprecise schema type.
* In such cases the "safe" version of hydrate may require `never` for the initial tree.
*/
export function hydrateUnsafe<const TSchema extends ImplicitFieldSchema>(
schema: TSchema,
initialTree: InsertableField<UnsafeUnknownSchema>,
): TreeFieldFromImplicitField<TSchema> {
return hydrate(schema, initialTree as InsertableTreeFieldFromImplicitField<TSchema>);
}
/**
* Similar to JSON stringify, but allows `undefined` at the root and returns numbers as-is at the root.
*/

Просмотреть файл

@ -35,7 +35,9 @@ import {
stringSchema,
toStoredSchema,
type ImplicitFieldSchema,
type InsertableField,
type InsertableTreeFieldFromImplicitField,
type UnsafeUnknownSchema,
type ValidateRecursiveSchema,
} from "../simple-tree/index.js";
// eslint-disable-next-line import/no-internal-modules
@ -51,7 +53,7 @@ interface TestSimpleTree {
/**
* InsertableTreeFieldFromImplicitField<TSchema>
*/
readonly root: InsertableTreeFieldFromImplicitField;
readonly root: InsertableField<UnsafeUnknownSchema>;
}
interface TestTree {
@ -66,11 +68,11 @@ function testSimpleTree<TSchema extends ImplicitFieldSchema>(
schema: TSchema,
root: InsertableTreeFieldFromImplicitField<TSchema>,
): TestSimpleTree {
return { name, schema, root };
return { name, schema, root: root as InsertableField<UnsafeUnknownSchema> };
}
function convertSimpleTreeTest(data: TestSimpleTree): TestTree {
const cursor = cursorFromInsertable(data.schema, data.root);
const cursor = cursorFromInsertable<UnsafeUnknownSchema>(data.schema, data.root);
return test(
data.name,
toStoredSchema(data.schema),

Просмотреть файл

@ -131,7 +131,6 @@ import {
type ImplicitFieldSchema,
type TreeViewConfiguration,
SchemaFactory,
type InsertableTreeFieldFromImplicitField,
toStoredSchema,
type TreeViewEvents,
type TreeView,
@ -146,7 +145,6 @@ import {
} from "../util/index.js";
import { isFluidHandle, toFluidHandleInternal } from "@fluidframework/runtime-utils/internal";
import type { Client } from "@fluid-private/test-dds-utils";
import { cursorFromInsertable } from "../simple-tree/index.js";
import { JsonUnion, cursorToJsonObject, singleJsonCursor } from "./json/index.js";
// eslint-disable-next-line import/no-internal-modules
import type { TreeSimpleContent } from "./feature-libraries/flex-tree/utils.js";
@ -1263,22 +1261,6 @@ export function validateUsageError(expectedErrorMsg: string | RegExp): (error: E
};
}
/**
* Returns a cursor (in nodes mode) for the root node.
*
* @privateRemarks
* Ideally this would work on any node, not just the root,
* and the schema would come from the unhydrated node.
* For now though, this is the only case that's needed, and we do have the data to make it work, so this is fine.
*/
export function cursorFromInsertableTreeField(
schema: ImplicitFieldSchema,
tree: InsertableTreeFieldFromImplicitField,
nodeKeyManager: NodeKeyManager,
): ITreeCursorSynchronous | undefined {
return cursorFromInsertable(schema, tree, nodeKeyManager);
}
function normalizeNewFieldContent(
content: readonly ITreeCursorSynchronous[] | ITreeCursorSynchronous | undefined,
): ITreeCursorSynchronous {

Просмотреть файл

@ -483,9 +483,9 @@ export type InsertableField<TSchema extends ImplicitFieldSchema | UnsafeUnknownS
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -1146,7 +1146,7 @@ export interface TreeViewAlpha<in out TSchema extends ImplicitFieldSchema | Unsa
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -410,9 +410,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -936,7 +936,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -510,9 +510,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -1321,7 +1321,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -438,9 +438,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -960,7 +960,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;

Просмотреть файл

@ -410,9 +410,9 @@ type _InlineTrick = 0;
// @public
type InsertableObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = FlattenKeys<{
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T]?: InsertableTreeFieldFromImplicitField<T[Property & string]>;
} & {
readonly [Property in keyof T as FieldHasDefault<T[Property] & string> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property] & string>;
readonly [Property in keyof T as FieldHasDefault<T[Property & string]> extends false ? Property : never]: InsertableTreeFieldFromImplicitField<T[Property & string]>;
}>;
// @public
@ -920,7 +920,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
}
// @public @sealed
export class TreeViewConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
constructor(props: ITreeViewConfiguration<TSchema>);
readonly enableSchemaValidation: boolean;
readonly preventAmbiguity: boolean;