import { FluidObject } from '@fluidframework/core-interfaces';
import { IChannel } from '@fluidframework/datastore-definitions';
import { IChannelAttributes } from '@fluidframework/datastore-definitions';
import { IChannelFactory } from '@fluidframework/datastore-definitions';
import { IChannelServices } from '@fluidframework/datastore-definitions';
import { IExperimentalIncrementalSummaryContext } from '@fluidframework/runtime-definitions';
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
import { IFluidHandle } from '@fluidframework/core-interfaces';
import { IFluidLoadable } from '@fluidframework/core-interfaces';
import { IGarbageCollectionData } from '@fluidframework/runtime-definitions';
import { ISharedObject } from '@fluidframework/shared-object-base';
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
import { ITelemetryContext } from '@fluidframework/runtime-definitions';
import { SessionSpaceCompressedId } from '@fluidframework/runtime-definitions';
import { StableId } from '@fluidframework/runtime-definitions';
import type { Static } from '@sinclair/typebox';
import type { TSchema } from '@sinclair/typebox';

/* Excluded from this release type: adaptEnum */

/* Excluded from this release type: Adapters */

/* Excluded from this release type: AllowedTypes */

/**
 * Types for use in fields.
 * @beta
 */
declare type AllowedTypes_2 = readonly LazyItem<TreeNodeSchema>[];

/* Excluded from this release type: AllowedTypeSet */

/* Excluded from this release type: AllowedTypesToFlexInsertableTree */

/* Excluded from this release type: AllowedUpdateType */

/* Excluded from this release type: AllowOptional */

/* Excluded from this release type: AllowOptionalNotFlattened */

/* Excluded from this release type: Anchor */

/* Excluded from this release type: AnchorEvents */

/* Excluded from this release type: AnchorLocator */

/* Excluded from this release type: AnchorNode */

/* Excluded from this release type: AnchorSet */

/* Excluded from this release type: AnchorSetRootEvents */

/* Excluded from this release type: AnchorSlot */

/* Excluded from this release type: anchorSlot */

/* Excluded from this release type: AnnouncedVisitor */

/* Excluded from this release type: Any */

/**
 * Suitable for output.
 * For input must error on side of excluding undefined instead.
 * @beta
 */
declare type ApplyKind<T, Kind extends FieldKind_2> = Kind extends FieldKind_2.Required ? T : undefined | T;

/* Excluded from this release type: ApplyMultiplicity */

/* Excluded from this release type: arrayLikeMarkerSymbol */

/* Excluded from this release type: ArrayLikeMut */

/**
 * Convert a Array type into the type of ReadonlySet.
 *
 * Same as `keyof ListToKeys<T, unknown>` but work for values that are not valid keys.
 * @beta
 */
declare type ArrayToUnion<T extends readonly unknown[]> = T extends readonly (infer TValue)[] ? TValue : never;

/* Excluded from this release type: AssignableFieldKinds */

/* Excluded from this release type: Assume */

/**
 * Allows boxed iteration of a tree/field
 */
declare const boxedIterator: unique symbol;

/* Excluded from this release type: Brand */

/* Excluded from this release type: brand */

/* Excluded from this release type: BrandedKey */

/* Excluded from this release type: BrandedKeyContent */

/* Excluded from this release type: BrandedMapSubset */

/* Excluded from this release type: BrandedType */

/* Excluded from this release type: buildTreeConfiguration */

/* Excluded from this release type: ChangesetLocalId */

/**
 * Events for {@link ITreeCheckout}.
 * @beta
 */
export declare interface CheckoutEvents {
    /**
     * A batch of changes has finished processing and the view is in a consistent state.
     * It is once again safe to access the EditableTree, Forest and AnchorSet.
     *
     * @remarks
     * This is mainly useful for knowing when to do followup work scheduled during events from Anchors.
     */
    afterBatch(): void;
    /**
     * A revertible change has been made to this view.
     * Applications which subscribe to this event are expected to revert or discard revertibles they acquire, if they so choose (failure to do so will leak memory).
     * The provided revertible is inherently bound to the view that raised the event, calling `revert` won't apply to forked views.
     *
     * @remarks
     * This event provides a {@link Revertible} object that can be used to revert the change.
     */
    revertible(revertible: Revertible): void;
}

/* Excluded from this release type: CheckTypesOverlap */

/* Excluded from this release type: ChildCollection */

/* Excluded from this release type: ChildLocation */

/* Excluded from this release type: CollectOptions */

/* Excluded from this release type: compareLocalNodeKeys */

/* Excluded from this release type: ContextuallyTypedFieldData */

/* Excluded from this release type: ContextuallyTypedNodeData */

/* Excluded from this release type: ContextuallyTypedNodeDataObject */

/* Excluded from this release type: Contravariant */

/* Excluded from this release type: Covariant */

/**
 * Non-exported symbol used to make IterableTreeListContent constructable only from within this file.
 */
declare const create: unique symbol;

/* Excluded from this release type: createEmitter */

/* Excluded from this release type: CursorAdapter */

/* Excluded from this release type: cursorForTypedTreeData */

/* Excluded from this release type: cursorFromContextualData */

/* Excluded from this release type: CursorLocationType */

/**
 * A symbol for marking an object as an {@link ITreeCursor}.
 *
 * Useful when APIs want to take in tree data in multiple formats, including cursors.
 */
declare const CursorMarker: unique symbol;

/* Excluded from this release type: CursorWithNode */

/* Excluded from this release type: defaultSchemaPolicy */

/* Excluded from this release type: DeltaDetachedNodeBuild */

/* Excluded from this release type: DeltaDetachedNodeChanges */

/* Excluded from this release type: DeltaDetachedNodeDestruction */

/* Excluded from this release type: DeltaDetachedNodeId */

/* Excluded from this release type: DeltaDetachedNodeRename */

/* Excluded from this release type: DeltaFieldChanges */

/* Excluded from this release type: DeltaFieldMap */

/* Excluded from this release type: DeltaMark */

/* Excluded from this release type: DeltaProtoNode */

/* Excluded from this release type: DeltaRoot */

/* Excluded from this release type: DeltaVisitor */

/* Excluded from this release type: DetachedField */

/* Excluded from this release type: DetachedPlaceUpPath */

/* Excluded from this release type: DetachedRangeUpPath */

/**
 * The result of a discard operation.
 *
 * @beta
 */
export declare enum DiscardResult {
    /** The discard was successful. */
    Success = 0,
    /** The discard failed. */
    Failure = 1
}

/**
 * Placeholder for `Symbol.dispose`.
 *
 * Replace this with `Symbol.dispose` when it is available.
 * @beta
 */
export declare const disposeSymbol: unique symbol;

/* Excluded from this release type: EditableTreeEvents */

/* Excluded from this release type: EmptyKey */

/* Excluded from this release type: EmptyObject */

/* Excluded from this release type: encodeTreeSchema */

/* Excluded from this release type: enumFromStrings */

/**
 * Used to specify the kinds of events emitted by an {@link ISubscribable}.
 *
 * @remarks
 *
 * Any object type is a valid {@link Events}, but only the event-like properties of that
 * type will be included.
 *
 * @example
 *
 * ```typescript
 * interface MyEvents {
 *   load: (user: string, data: IUserData) => void;
 *   error: (errorCode: number) => void;
 * }
 * ```
 *
 * @beta
 */
export declare type Events<E> = {
    [P in (string | symbol) & keyof E as IsEvent<E[P]> extends true ? P : never]: E[P];
};

/* Excluded from this release type: ExtractFromOpaque */

/* Excluded from this release type: extractFromOpaque */

/**
 * Get the `Item` type from a `LazyItem<Item>`.
 * @beta
 */
declare type ExtractItemType<Item extends LazyItem> = Item extends () => infer Result ? Result : Item;

/* Excluded from this release type: fail */

/* Excluded from this release type: FieldAnchor */

/* Excluded from this release type: FieldGenerator */

/* Excluded from this release type: FieldKey */

/* Excluded from this release type: FieldKind */

/**
 * Kind of a field on a node.
 * @beta
 */
declare enum FieldKind_2 {
    /**
     * A field which can be empty or filled.
     * @remarks
     * Allows 0 or one child.
     */
    Optional = 0,
    /**
     * A field which must always be filled.
     * @remarks
     * Only allows exactly one child.
     */
    Required = 1
}

/* Excluded from this release type: FieldKindIdentifier */

/* Excluded from this release type: FieldKinds */

/* Excluded from this release type: FieldKindSpecifier */

/* Excluded from this release type: FieldLocation */

/* Excluded from this release type: FieldMapObject */

/* Excluded from this release type: FieldNodeSchema */

/* Excluded from this release type: Fields */

/**
 * All policy for a specific field,
 * including functionality that does not have to be kept consistent across versions or deterministic.
 *
 * This can include policy for how to use this schema for "view" purposes, and well as how to expose editing APIs.
 * @sealed @beta
 */
declare class FieldSchema<out Kind extends FieldKind_2 = FieldKind_2, out Types extends ImplicitAllowedTypes_2 = ImplicitAllowedTypes_2> {
    readonly kind: Kind;
    readonly allowedTypes: Types;
    /**
     * This class is used with instanceof, and therefore should have nominal typing.
     * This field enforces that.
     */
    protected _typeCheck?: MakeNominal;
    /**
     * @param kind - The [kind](https://en.wikipedia.org/wiki/Kind_(type_theory)) of this field.
     * Determine the multiplicity, viewing and editing APIs as well as the merge resolution policy.
     * @param allowedTypes - What types of tree nodes are allowed in this field.
     */
    constructor(kind: Kind, allowedTypes: Types);
}

/* Excluded from this release type: FieldUpPath */

/* Excluded from this release type: FlattenKeys */

/* Excluded from this release type: FlexibleFieldContent */

/* Excluded from this release type: FlexibleNodeContent */

/* Excluded from this release type: FlexibleNodeSubSequence */

/* Excluded from this release type: FlexImplicitFieldSchema */

/**
 * A flexible way to list values.
 * Each item in the list can either be an "eager" **value** or a "lazy" **function that returns a value** (the latter allows cyclic references to work).
 * @privateRemarks
 * By default, items that are of type `"function"` will be considered lazy and all other items will be considered eager.
 * To force a `"function"` item to be treated as an eager item, call `markEager` before putting it in the list.
 * This is necessary e.g. when the eager list items are function types and the lazy items are functions that _return_ function types.
 * `FlexList`s are processed by `normalizeFlexList` and `normalizeFlexListEager`.
 * @beta
 */
declare type FlexList<Item = unknown> = readonly LazyItem<Item>[];

/**
 * Normalize FlexList type to a union.
 * @beta
 */
declare type FlexListToUnion<TList extends FlexList> = ExtractItemType<ArrayToUnion<TList>>;

/* Excluded from this release type: FlexTreeEntity */

/* Excluded from this release type: FlexTreeEntityKind */

/* Excluded from this release type: FlexTreeField */

/* Excluded from this release type: FlexTreeFieldNode */

/* Excluded from this release type: FlexTreeLeafNode */

/* Excluded from this release type: FlexTreeMapNode */

/* Excluded from this release type: flexTreeMarker */

/* Excluded from this release type: FlexTreeNode */

/* Excluded from this release type: FlexTreeNodeKeyField */

/* Excluded from this release type: FlexTreeNodeSchema */

/* Excluded from this release type: FlexTreeObjectNode */

/* Excluded from this release type: FlexTreeObjectNodeFields */

/* Excluded from this release type: FlexTreeObjectNodeTyped */

/* Excluded from this release type: FlexTreeOptionalField */

/* Excluded from this release type: FlexTreeRequiredField */

/* Excluded from this release type: FlexTreeSequenceField */

/* Excluded from this release type: FlexTreeTypedField */

/* Excluded from this release type: FlexTreeTypedFieldInner */

/* Excluded from this release type: FlexTreeTypedNode */

/* Excluded from this release type: FlexTreeTypedNodeUnion */

/* Excluded from this release type: FlexTreeUnboxField */

/* Excluded from this release type: FlexTreeUnboxFieldInner */

/* Excluded from this release type: FlexTreeUnboxNode */

/* Excluded from this release type: FlexTreeUnboxNodeUnion */

/* Excluded from this release type: FlexTreeUnknownUnboxed */

/* Excluded from this release type: FlexTreeView */

/* Excluded from this release type: Forbidden */

/* Excluded from this release type: forbiddenFieldKindIdentifier */

/* Excluded from this release type: ForestEvents */

/* Excluded from this release type: ForestLocation */

/* Excluded from this release type: ForestType */

/* Excluded from this release type: FullSchemaPolicy */

/* Excluded from this release type: GenericFieldsNode */

/* Excluded from this release type: GenericTreeNode */

/* Excluded from this release type: getPrimaryField */

/* Excluded from this release type: HasListeners */

/* Excluded from this release type: IChannel */

/* Excluded from this release type: IChannelAttributes */

/* Excluded from this release type: IChannelFactory */

/* Excluded from this release type: IChannelServices */

/* Excluded from this release type: ICodecOptions */

/* Excluded from this release type: IdAllocator */

/* Excluded from this release type: IDefaultEditBuilder */

/**
 * An object with an explicit lifetime that can be ended.
 * @privateRemarks
 * TODO: align this with core-utils/IDisposable and {@link https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management| TypeScript's Disposable}.
 * @beta
 */
export declare interface IDisposable {
    /**
     * Call to end the lifetime of this object.
     *
     * It is invalid to use this object after this,
     * except for operations which explicitly document they are valid after disposal.
     *
     * @remarks
     * May cleanup resources retained by this object.
     * Often includes un-registering from events and thus preventing other objects from retaining a reference to this indefinably.
     *
     * Usually the only operations allowed after disposal are querying if an object is already disposed,
     * but this can vary between implementations.
     */
    [disposeSymbol](): void;
}

/* Excluded from this release type: IEditableForest */

/* Excluded from this release type: IEmitter */

/* Excluded from this release type: IExperimentalIncrementalSummaryContext */

/* Excluded from this release type: IFluidDataStoreRuntime */

/* Excluded from this release type: IFluidHandle */

/* Excluded from this release type: IForestSubscription */

/* Excluded from this release type: IGarbageCollectionData */

/* Excluded from this release type: ImplicitAllowedTypes */

/**
 * Types allowed in a field.
 * @remarks
 * Implicitly treats a single type as an array of one type.
 * @beta
 */
declare type ImplicitAllowedTypes_2 = AllowedTypes_2 | TreeNodeSchema;

/**
 * Schema for a field of a tree node.
 * @remarks
 * Implicitly treats {@link ImplicitAllowedTypes} as a Required field of that type.
 * @beta
 */
export declare type ImplicitFieldSchema = FieldSchema | ImplicitAllowedTypes_2;

/* Excluded from this release type: InitializeAndSchematizeConfiguration */

/* Excluded from this release type: _InlineTrick */

/* Excluded from this release type: InsertableFlexField */

/* Excluded from this release type: InsertableFlexNode */

/**
 * Helper used to produce types for:
 *
 * 1. Insertable content which can be used to construct an object node.
 *
 * 2. Insertable content which is an unhydrated object node.
 *
 * 3. Union of 1 and 2.
 *
 * TODO: consider separating these cases into different types.
 * @beta
 */
declare type InsertableObjectFromSchemaRecord<T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>> = {
    readonly [Property in keyof T]: InsertableTreeFieldFromImplicitField<T[Property]>;
};

/**
 * Type of content that can be inserted into the tree for a field of the given schema.
 * @beta
 */
declare type InsertableTreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> = TSchema extends FieldSchema<infer Kind, infer Types> ? ApplyKind<InsertableTreeNodeFromImplicitAllowedTypes<Types>, Kind> : TSchema extends ImplicitAllowedTypes_2 ? InsertableTreeNodeFromImplicitAllowedTypes<TSchema> : unknown;

/**
 * Type of content that can be inserted into the tree for a node of the given schema.
 * @beta
 */
export declare type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes_2 = TreeNodeSchema> = TSchema extends TreeNodeSchema ? InsertableTypedNode<TSchema> : TSchema extends AllowedTypes_2 ? InsertableTypedNode<FlexListToUnion<TSchema>> : never;

/**
 * Data which can be used as a node to be inserted.
 * Either an unhydrated node, or content to build a new node.
 * @beta
 */
declare type InsertableTypedNode<T extends TreeNodeSchema> = (T["implicitlyConstructable"] extends true ? NodeBuilderData<T> : never) | Unhydrated<NodeFromSchema<T>>;

declare namespace InternalClassTreeTypes {
    export {
        ObjectFromSchemaRecord,
        InsertableObjectFromSchemaRecord,
        TreeNodeFromImplicitAllowedTypes,
        ImplicitAllowedTypes_2 as ImplicitAllowedTypes,
        FieldKind_2 as FieldKind,
        InsertableTreeFieldFromImplicitField,
        AllowedTypes_2 as AllowedTypes,
        FieldSchema,
        ApplyKind,
        InsertableTypedNode,
        NodeBuilderData
    }
}

declare namespace InternalTypedSchemaTypes {
    export {
        ArrayToUnion,
        FlexList,
        LazyItem,
        ExtractItemType,
        FlexListToUnion
    }
}
export { InternalTypedSchemaTypes }

declare namespace InternalTypes {
    export {
        MakeNominal,
        RestrictiveReadonlyRecord,
        NodeKind,
        TreeNodeSchemaClass,
        TreeNodeSchemaNonClass,
        TreeNodeSchemaCore,
        InternalClassTreeTypes,
        TreeListNodeBase
    }
}
export { InternalTypes }

/* Excluded from this release type: Invariant */

/* Excluded from this release type: isAny */

/* Excluded from this release type: IsArrayOfOne */

/* Excluded from this release type: isContextuallyTypedNodeDataObject */

/**
 * `true` iff the given type is an acceptable shape for an event
 * @beta
 */
export declare type IsEvent<Event> = Event extends (...args: any[]) => any ? true : false;

/* Excluded from this release type: ISharedObject */

/* Excluded from this release type: ISharedTree */

/* Excluded from this release type: isNeverField */

/**
 * An object which allows the registration of listeners so that subscribers can be notified when an event happens.
 *
 * {@link createEmitter} can help implement this interface via delegation.
 * `EventEmitter` can be used as a base class to implement this via extension.
 * @param E - All the events that this emitter supports
 * @example
 * ```ts
 * type MyEventEmitter = IEventEmitter<{
 *   load: (user: string, data: IUserData) => void;
 *   error: (errorCode: number) => void;
 * }>
 * ```
 * @beta
 */
export declare interface ISubscribable<E extends Events<E>> {
    /**
     * Register an event listener.
     * @param eventName - the name of the event
     * @param listener - the handler to run when the event is fired by the emitter
     * @returns a function which will deregister the listener when run. This function has undefined behavior
     * if called more than once.
     */
    on<K extends keyof Events<E>>(eventName: K, listener: E[K]): () => void;
}

/* Excluded from this release type: ISummaryTreeWithStats */

/* Excluded from this release type: ITelemetryContext */

/**
 * Used to insert iterable content into a {@link (TreeListNode:interface)}.
 * Use {@link (TreeListNode:variable).inline} to create an instance of this type.
 * @beta
 */
export declare class IterableTreeListContent<T> implements Iterable<T> {
    private readonly content;
    private constructor();
    /**
     * Package internal construction API.
     * Use {@link (TreeListNode:variable).inline} to create an instance of this type instead.
     */
    static [create]<T>(content: Iterable<T>): IterableTreeListContent<T>;
    /**
     * Iterates over content for nodes to insert.
     */
    [Symbol.iterator](): Iterator<T>;
}

/* Excluded from this release type: ITransaction */

/**
 * Channel for a Fluid Tree DDS.
 * @remarks
 * Allows storing and collaboratively editing schema-aware hierarchial data.
 * @beta
 */
export declare interface ITree extends IChannel {
    /**
     * Returns a tree that is known to be compatible with the provided schema. The returned tree exposes an API that is schema-aware.
     *
     * @remarks
     * If the tree is uninitialized (has no schema and no content), the tree is initialized with the `initialTree` and
     * view `schema` in the provided `config`.
     *
     * The tree (now known to have been initialized) has its stored schema checked against the provided view schema.
     *
     * If the schemas are compatible (including updating the stored schema if permitted via `allowedSchemaModifications`),
     * a {@link TreeView} is returned, with a schema-aware API based on the provided view schema.
     *
     * If the schemas are not compatible, an exception is thrown.
     *
     * @privateRemarks
     * TODO: make the mismatch case recoverable.
     * - Provide a way to make a generic view schema for any document.
     * - Produce/throw the error in a document-recoverable way (ex: specific exception type or return value).
     * TODO: Document and handle what happens when the stored schema changes after schematize has returned. Is some invalidation contract needed? How does editable tree behave?
     * TODO: Clarify lifetimes. Ensure calling schematize multiple times does not leak.
     * TODO: Support adapters for handling out-of-schema data.
     *
     * Doing initialization here, regardless of `AllowedUpdateType`, allows a small API that is hard to use incorrectly.
     * Other approaches tend to have easy-to-make mistakes.
     * For example, having a separate initialization function means apps can forget to call it, making an app that can only open existing documents,
     * or call it unconditionally leaving an app that can only create new documents.
     * It also would require the schema to be passed into separate places and could cause issues if they didn't match.
     * Since the initialization function couldn't return a typed tree, the type checking wouldn't help catch that.
     * Also, if an app manages to create a document, but the initialization fails to get persisted, an app that only calls the initialization function
     * on the create code-path (for example how a schematized factory might do it),
     * would leave the document in an unusable state which could not be repaired when it is reopened (by the same or other clients).
     * Additionally, once out of schema content adapters are properly supported (with lazy document updates),
     * this initialization could become just another out of schema content adapter: at that point it clearly belongs here in schematize.
     */
    schematize<TRoot extends ImplicitFieldSchema>(config: TreeConfiguration<TRoot>): TreeView<TreeFieldFromImplicitField<TRoot>>;
}

/* Excluded from this release type: ITreeCheckout */

/* Excluded from this release type: ITreeCheckoutFork */

/* Excluded from this release type: ITreeCursor */

/* Excluded from this release type: ITreeCursorSynchronous */

/* Excluded from this release type: ITreeSubscriptionCursor */

/* Excluded from this release type: ITreeSubscriptionCursorState */

/* Excluded from this release type: ITreeViewFork */

/* Excluded from this release type: JsonableTree */

/* Excluded from this release type: jsonableTreeFromCursor */

/* Excluded from this release type: JsonCompatible */

/* Excluded from this release type: JsonCompatibleObject */

/* Excluded from this release type: JsonCompatibleReadOnly */

/* Excluded from this release type: JsonValidator */

/**
 * An "eager" or "lazy" Item in a `FlexList`.
 * Lazy items are wrapped in a function to allow referring to themselves before they are declared.
 * This makes recursive and co-recursive items possible.
 * @beta
 */
declare type LazyItem<Item = unknown> = Item | (() => Item);

/* Excluded from this release type: LazyTreeNodeSchema */

/* Excluded from this release type: leaf */

/* Excluded from this release type: LeafNodeSchema */

/* Excluded from this release type: LocalNodeKey */

/**
 * Utilities for manipulating the typescript typechecker.
 *
 * @remarks
 * While it appears the the variance parts of this library are made obsolete by TypeScript 4.7's explicit variance annotations,
 * many cases still type check with incorrect variance even when using the explicit annotations,
 * and are fixed by using the patterns in this library.
 *
 * TypeScript uses structural typing if there are no private or protected members,
 * and variance of generic type parameters depends on their usages.
 * Thus when trying to constrain code by adding extra type information,
 * it often fails to actually constrain as desired, and these utilities can help with those cases.
 *
 * This library is designed so that the desired variance can be documented in a way that is easy to read, concise,
 * and allows easy navigation to documentation explaining what is being done
 * for readers who are not familiar with this library.
 * Additionally it constrains the types so the undesired usage patterns will not compile,
 * and will give somewhat intelligible errors.
 *
 * Additionally this library provides the tools needed to test that the type constraints are working as expected,
 * or test any other similar typing constraints in an application.
 *
 * This library assumes you are compiling with --strictFunctionTypes:
 * (Covariance and Contravariance is explained along with how these helpers cause it in typescript at this link)
 * {@link https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-6.html#strict-function-types}.
 * If compiled with a TypeScript configuration that is not strict enough for these features to work,
 * the test suite should fail to build.
 *
 * Classes in TypeScript by default allow all assignments:
 * its only though adding members that any type constraints actually get applied.
 * This library provides types that can be used on a protected member of a class to add the desired constraints.
 *
 * Typical usages (use one field like this at the top of a class):
 * ```typescript
 * protected _typeCheck?: MakeNominal;
 * protected _typeCheck?: Contravariant<T>;
 * protected _typeCheck?: Covariant<T>;
 * protected _typeCheck?: Invariant<T>;
 * protected _typeCheck?: Contravariant<T> & Invariant<K>;
 * ```
 *
 * See tests for examples.
 *
 * Note that all of these cause nominal typing.
 * If constraints on generic type parameter variance are desired, but nominal typing is not,
 * these types can be used on a public field. This case also works with interfaces.
 *
 * Be aware that other members of your type might apply further constraints
 * (ex: you might try and write a Contravariant<T> class, but it ends up being Invariant<T> due to a field of type T).
 *
 * Be aware of TypeScript Bug:
 * {@link https://github.com/microsoft/TypeScript/issues/36906}.
 * This bug is why the fields here are protected not private.
 * Note that this bug is closed as a duplicate of {@link https://github.com/microsoft/TypeScript/issues/20979}
 * which was closed because fixing it would be too large of a breaking change.
 * Thus we expect this bug to be part of TypeScript for the forseeable future.
 */
/**
 * Use this as the type of a protected field to cause a type to use nominal typing instead of structural.
 *
 * @remarks
 * Using nominal typing in this way prevents assignment of objects which are not instances of this class to values of this class's type.
 * Classes which are used with "instanceof", or are supposed to be instantiated in particular ways (not just made with object literals)
 * can use this to prevent undesired assignments.
 * @example
 * ```typescript
 * protected _typeCheck?: MakeNominal;
 * ```
 * @privateRemarks
 * See: {@link https://dev.azure.com/intentional/intent/_wiki/wikis/NP%20Platform/7146/Nominal-vs-Structural-Types}
 * @beta
 */
declare interface MakeNominal {
}

/* Excluded from this release type: MapFieldSchema */

/* Excluded from this release type: MapNodeSchema */

/* Excluded from this release type: MapTree */

/* Excluded from this release type: MarkedArrayLike */

/* Excluded from this release type: Multiplicity */

/* Excluded from this release type: Named */

/* Excluded from this release type: NameFromBranded */

/* Excluded from this release type: NestedMap */

/* Excluded from this release type: NewFieldContent */

/**
 * Base type which all nodes extend.
 * @beta
 */
export declare class NodeBase {
}

/**
 * Given a node's schema, return the corresponding object from which the node could be built.
 * @privateRemarks
 * Currently this assumes factory functions take exactly one argument.
 * This could be changed if needed.
 *
 * These factory functions can also take a FlexTreeNode, but this is not exposed in the public facing types.
 * @beta
 */
declare type NodeBuilderData<T extends TreeNodeSchema> = T extends TreeNodeSchema<string, NodeKind, unknown, infer TBuild> ? TBuild : never;

/* Excluded from this release type: NodeData */

/* Excluded from this release type: NodeExistsConstraint */

/**
 * Takes in `TreeNodeSchema[]` and returns a TypedNode union.
 * @beta
 */
export declare type NodeFromSchema<T extends TreeNodeSchema> = T extends TreeNodeSchema<string, NodeKind, infer TNode> ? TNode : never;

/* Excluded from this release type: NodeIndex */

/* Excluded from this release type: nodeKeyFieldKey */

/* Excluded from this release type: NodeKeyFieldKind */

/* Excluded from this release type: NodeKeys */

/**
 * Kind of tree node.
 * @beta
 */
declare enum NodeKind {
    /**
     * A node which serves as a map, storing children under string keys.
     */
    Map = 0,
    /**
     * A node which serves as a list, storing children in an ordered sequence.
     */
    List = 1,
    /**
     * A node which stores a heterogenous collection of children in named fields.
     * @remarks
     * Each field gets its own schema.
     */
    Object = 2,
    /**
     * A node which stores a single leaf value.
     */
    Leaf = 3
}

/* Excluded from this release type: NoListenersCallback */

/* Excluded from this release type: noopValidator */

/* Excluded from this release type: NormalizeAllowedTypes */

/* Excluded from this release type: NormalizeField */

/* Excluded from this release type: NormalizeFieldSchema */

/* Excluded from this release type: NormalizeObjectNodeFields */

/**
 * Helper used to produce types for object nodes.
 * @beta
 */
declare type ObjectFromSchemaRecord<T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>> = {
    -readonly [Property in keyof T]: TreeFieldFromImplicitField<T[Property]>;
};

/* Excluded from this release type: ObjectNodeSchema */

/* Excluded from this release type: oneFromSet */

/**
 * {@inheritdoc TreeNode.[onNextChange]}
 */
declare const onNextChange: unique symbol;

/* Excluded from this release type: Opaque */

/* Excluded from this release type: Optional */

/* Excluded from this release type: OptionalFieldEditBuilder */

/* Excluded from this release type: OptionalFields */

/* Excluded from this release type: PathRootPrefix */

/* Excluded from this release type: PathVisitor */

/* Excluded from this release type: PlaceIndex */

/* Excluded from this release type: PlaceUpPath */

/* Excluded from this release type: prefixFieldPath */

/* Excluded from this release type: prefixPath */

/* Excluded from this release type: ProtoNodes */

/* Excluded from this release type: Range_2 */

/* Excluded from this release type: RangeQueryResult */

/* Excluded from this release type: RangeUpPath */

/* Excluded from this release type: _RecursiveTrick */

/* Excluded from this release type: Required_2 */

/* Excluded from this release type: RequiredFields */

/**
 * Alternative to the built in Record type which does not permit unexpected members,
 * and is readonly.
 *
 * @privateRemarks
 * `number` is not allowed as a key here since doing so causes the compiler to reject recursive schema.
 * The cause for this is unclear, but empirically it was the case when this comment was written.
 * @beta
 */
declare type RestrictiveReadonlyRecord<K extends symbol | string, T> = {
    readonly [P in symbol | string]: P extends K ? T : never;
};

/**
 * Allows reversion of a change made to SharedTree.
 *
 * Applications wanting to implement undo/redo support might typically maintain two stacks of Revertibles, with optional eviction policy to free up memory.
 * @beta
 */
export declare interface Revertible {
    /** Indicates the type of edit that produced this revertible. */
    readonly kind: RevertibleKind;
    /**
     * Information about which client created the edit.
     */
    readonly origin: {
        /**
         * Indicates if the {@link Revertible} is from the local client (true) or a remote client (false).
         */
        readonly isLocal: boolean;
    };
    /**
     * Can be called in order to revert a change. A successful revert will automatically discard resources.
     */
    revert(): RevertResult;
    /**
     * Should be called to garbage collect any resources associated with the revertible.
     */
    discard(): DiscardResult;
}

/**
 * The type of revertible commit.
 *
 * @beta
 */
export declare enum RevertibleKind {
    /** A typical local commit */
    Default = 0,
    /** A revertible that is the result of an undo. */
    Undo = 1,
    /** A revertible that is the result of a redo. */
    Redo = 2,
    /**
     * A revertible that is the result of a rebase and should replace a previously generated revertible.
     * todo: improve error reporting in this case
     */
    Rebase = 3
}

/**
 * The result of a revert operation.
 *
 * @beta
 */
export declare enum RevertResult {
    /** The revert was successful. */
    Success = 0,
    /** The revert failed. */
    Failure = 1
}

/* Excluded from this release type: RootField */

/* Excluded from this release type: rootField */

/* Excluded from this release type: rootFieldKey */

/* Excluded from this release type: runSynchronous */

/* Excluded from this release type: SchemaBuilderBase */

/* Excluded from this release type: SchemaBuilderOptions */

/* Excluded from this release type: SchemaCollection */

/* Excluded from this release type: SchemaConfiguration */

/* Excluded from this release type: SchemaEvents */

/**
 * Builds schema libraries, and the schema within them.
 *
 * @typeParam TScope - Scope added as a prefix to the name of every schema produced by this factory.
 * @typeParam TName - Type of names used to identify each schema produced in this factory.
 * Typically this is just `string` but it is also possible to use `string` or `number` based enums if you prefer to identify your types that way.
 *
 * @sealed @beta
 */
export declare class SchemaFactory<TScope extends string = string, TName extends number | string = string> {
    readonly scope: TScope;
    private readonly structuralTypes;
    /**
     * @param scope - Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder.
     * Use of [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 is recommended to avoid collisions.
     */
    constructor(scope: TScope);
    private scoped;
    /**
     * {@link TreeNodeSchema} for holding a JavaScript `string`.
     *
     * @remarks
     * Strings containing unpaired UTF-16 surrogate pair code units may not be handled correctly.
     *
     * These limitations come from the use of UTF-8 encoding of the strings, which requires them to be valid unicode.
     * JavaScript does not make this requirement for its strings so not all possible JavaScript strings are supported.
     * @privateRemarks
     * TODO:
     * We should be much more clear about what happens if you use problematic values.
     * We should validate and/or normalize them when inserting content.
     */
    readonly string: TreeNodeSchema<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string>;
    /**
     * {@link TreeNodeSchema} for holding a JavaScript `number`.
     *
     * @remarks
     * The number is a [double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) value, however there are some exceptions:
     * - `NaN`, and the infinities are converted to `null` (and may therefore only be used where `null` is allowed by the schema).
     * - `-0` may be converted to `0` in some cases.
     *
     * These limitations match the limitations of JSON.
     * @privateRemarks
     * TODO:
     * We should be much more clear about what happens if you use problematic values.
     * We should validate and/or normalize them when inserting content.
     */
    readonly number: TreeNodeSchema<"com.fluidframework.leaf.number", NodeKind.Leaf, number, number>;
    /**
     * {@link TreeNodeSchema} for holding a boolean.
     */
    readonly boolean: TreeNodeSchema<"com.fluidframework.leaf.boolean", NodeKind.Leaf, boolean, boolean>;
    /**
     * {@link TreeNodeSchema} for JavaScript `null`.
     *
     * @remarks
     * There are good [reasons to avoid using null](https://www.npmjs.com/package/%40rushstack/eslint-plugin#rushstackno-new-null) in JavaScript, however sometimes it is desired.
     * This {@link TreeNodeSchema} node provides the option to include nulls in trees when desired.
     * Unless directly inter-operating with existing data using null, consider other approaches, like wrapping the value in an optional field, or using a more specifically named empty object node.
     */
    readonly null: TreeNodeSchema<"com.fluidframework.leaf.null", NodeKind.Leaf, null, null>;
    /**
     * {@link TreeNodeSchema} for holding an {@link @fluidframework/core-interfaces#IFluidHandle}.
     */
    readonly handle: TreeNodeSchema<"com.fluidframework.leaf.handle", NodeKind.Leaf, IFluidHandle<FluidObject & IFluidLoadable>, IFluidHandle<FluidObject & IFluidLoadable>>;
    /**
     * Construct a class that provides the common parts all TreeNodeSchemaClass share.
     * More specific schema extend this class.
     */
    private nodeSchema;
    /**
     * Define a {@link TreeNodeSchema} for an object node.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     */
    object<const Name extends TName, const T extends RestrictiveReadonlyRecord<string, ImplicitFieldSchema>>(name: Name, t: T): TreeNodeSchemaClass<`${TScope}.${Name}`, NodeKind.Object, ObjectFromSchemaRecord<T>, InsertableObjectFromSchemaRecord<T>, true>;
    /**
     * Define a structurally typed {@link TreeNodeSchema} for a {@link TreeMapNodeBase}.
     *
     * @remarks
     * The {@link TreeNodeSchemaIdentifier} for this Map is defined as a function of the provided types.
     * It is still scoped to this SchemaBuilder, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing.
     * This does not support recursive types.
     *
     * If using these structurally named maps, other types in this schema builder should avoid names of the form `Map<${string}>`.
     *
     * @example
     * The returned schema should be used as a schema directly:
     * ```typescript
     * const MyMap = factory.map(factory.number);
     * type MyMap = NodeFromSchema<typeof MyMap>;
     * ```
     * Or inline:
     * ```typescript
     * factory.object("Foo", {myMap: factory.map(factory.number)});
     * ```
     * @privateRemarks
     * See note on list.
     */
    map<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchema<`${TScope}.Map<${string}>`, NodeKind.Map, TreeMapNode<T>, ReadonlyMap<string, TreeNodeFromImplicitAllowedTypes<T>>, true>;
    /**
     * Define a {@link TreeNodeSchema} for a {@link TreeMapNodeBase}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     *
     * @example
     * ```typescript
     * class NamedMap extends factory.map("name", factory.number) {}
     * ```
     */
    map<Name extends TName, const T extends ImplicitAllowedTypes_2>(name: Name, allowedTypes: T): TreeNodeSchemaClass<`${TScope}.${Name}`, NodeKind.Map, TreeMapNode<T>, ReadonlyMap<string, InsertableTreeNodeFromImplicitAllowedTypes<T>>, true>;
    /**
     * Define a {@link TreeNodeSchema} for a {@link (TreeMapNode:interface)}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     *
     * @remarks See remarks on {@link SchemaFactory.namedList}.
     */
    namedMap<Name extends TName | string, const T extends ImplicitAllowedTypes_2, const ImplicitlyConstructable extends boolean>(name: Name, allowedTypes: T, customizable: boolean, implicitlyConstructable: ImplicitlyConstructable): TreeNodeSchemaClass<`${TScope}.${Name}`, NodeKind.Map, TreeMapNode<T>, ReadonlyMap<string, InsertableTreeNodeFromImplicitAllowedTypes<T>>, ImplicitlyConstructable>;
    /**
     * Define a structurally typed {@link TreeNodeSchema} for a {@link (TreeListNode:interface)}.
     *
     * @remarks
     * The identifier for this List is defined as a function of the provided types.
     * It is still scoped to this SchemaFactory, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing.
     * This does not support recursive types.
     *
     * If using these structurally named lists, other types in this schema builder should avoid names of the form `List<${string}>`.
     *
     * @example
     * The returned schema should be used as a schema directly:
     * ```typescript
     * const MyList = factory.list(factory.number);
     * type MyList = NodeFromSchema<typeof MyList>;
     * ```
     * Or inline:
     * ```typescript
     * factory.object("Foo", {myList: factory.list(factory.number)});
     * ```
     * @privateRemarks
     * The name produced at the type level here is not as specific as it could be, however doing type level sorting and escaping is a real mess.
     * There are cases where not having this full type provided will be less than ideal since TypeScript's structural types.
     * For example attempts to narrow unions of structural lists by name won't work.
     * Planned future changes to move to a class based schema system as well as factor function based node construction should mostly avoid these issues,
     * though there may still be some problematic cases even after that work is done.
     *
     * The return value is a class, but its the type is intentionally not specific enough to indicate it is a class.
     * This prevents callers of this from sub-classing it, which is unlikely to work well (due to the ease of accidentally giving two different calls o this different subclasses)
     * when working with structural typing.
     */
    list<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchema<`${TScope}.List<${string}>`, NodeKind.List, TreeListNode<T>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, true>;
    /**
     * Define (and add to this library) a {@link FieldNodeSchema} for a {@link (TreeListNode:interface)}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     *
     * @example
     * ```typescript
     * class NamedList extends factory.list("name", factory.number) {}
     * ```
     */
    list<const Name extends TName, const T extends ImplicitAllowedTypes_2>(name: Name, allowedTypes: T): TreeNodeSchemaClass<`${TScope}.${Name}`, NodeKind.List, TreeListNode<T>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, true>;
    /**
     * Define a {@link TreeNodeSchema} for a {@link (TreeListNode:interface)}.
     *
     * @param name - Unique identifier for this schema within this factory's scope.
     *
     * @remarks
     * This is not intended to be used directly, use the overload of `list` which takes a name instead.
     * This is only public to work around a compiler limitation.
     *
     * @privateRemarks
     * TODO: this should be made private or protected.
     * Doing so breaks due to:
     * `src/class-tree/schemaFactoryRecursive.ts:42:9 - error TS2310: Type 'List' recursively references itself as a base type.`
     * Once recursive APIs are better sorted out and integrated into this class, switch this back to private.
     */
    namedList<Name extends TName | string, const T extends ImplicitAllowedTypes_2, const ImplicitlyConstructable extends boolean>(name: Name, allowedTypes: T, customizable: boolean, implicitlyConstructable: ImplicitlyConstructable): TreeNodeSchemaClass<`${TScope}.${Name}`, NodeKind.List, TreeListNode<T>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, ImplicitlyConstructable>;
    /**
     * Make a field optional instead of the default which is required.
     */
    optional<const T extends ImplicitAllowedTypes_2>(t: T): FieldSchema<FieldKind_2.Optional, T>;
    /**
     * Function which can be used for its compile time side-effects to tweak the evaluation order of recursive types to make them compile.
     * @remarks
     * Some related information in https://github.com/microsoft/TypeScript/issues/55758.
     *
     * Also be aware that code which relies on this tends to break VSCode's IntelliSense every time anything related to that code (even comments) is edited.
     * Running the command `TypeScript: Restart TS Server` with the schema file focused should fix it.
     * Sometimes this does not work: closing all open files except the schema before running the command can help.
     * Real compile errors (for example elsewhere in the file) can also cause the IntelliSense to not work correctly ever after `TypeScript: Restart TS Server`.
     *
     * Intellisense has also shown problems when schema files with recursive types are part of a cyclic file dependency.
     * Splitting the schema into its own file with minimal dependencies can help with this.
     *
     * Ensure `"noImplicitAny": true` is set in the `tsconfig.json`.
     * Without it, recursive types that are not working properly can infer `any` and give very non-type-safe results instead of erroring.
     *
     * @example
     * ```typescript
     * const factory = new SchemaFactory("example");
     * const recursiveReference = () => RecursiveObject;
     * factory.fixRecursiveReference(recursiveReference);
     * export class RecursiveObject extends factory.object("exampleObject", {
     * 	recursive: [recursiveReference],
     * }) {}
     * ```
     */
    fixRecursiveReference<T extends AllowedTypes_2>(...types: T): void;
}

/* Excluded from this release type: schemaIsFieldNode */

/* Excluded from this release type: schemaIsLeaf */

/* Excluded from this release type: schemaIsMap */

/* Excluded from this release type: schemaIsObjectNode */

/* Excluded from this release type: SchemaLibrary */

/* Excluded from this release type: SchemaLibraryData */

/* Excluded from this release type: SchemaLintConfiguration */

/* Excluded from this release type: SchematizeConfiguration */

/* Excluded from this release type: SchemaValidationFunction */

/* Excluded from this release type: Sequence */

/* Excluded from this release type: SequenceFieldEditBuilder */

/* Excluded from this release type: SessionSpaceCompressedId */

/* Excluded from this release type: SharedTree */

/* Excluded from this release type: SharedTreeContentSnapshot */

/* Excluded from this release type: SharedTreeFactory */

/* Excluded from this release type: SharedTreeOptions */

/* Excluded from this release type: singleTextCursor */

/* Excluded from this release type: singletonSchema */

/* Excluded from this release type: StableId */

/* Excluded from this release type: StableNodeKey */

/* Excluded from this release type: stackTreeFieldCursor */

/* Excluded from this release type: stackTreeNodeCursor */

/* Excluded from this release type: StoredSchemaCollection */

/* Excluded from this release type: StoredSchemaRepository */

/* Excluded from this release type: test_RecursiveObject */

/* Excluded from this release type: test_RecursiveObject_base */

/* Excluded from this release type: TransactionResult */

/**
 * The `Tree` object holds various functions for analyzing {@link NodeBase}s.
 * @beta
 */
export declare const Tree: TreeApi;

/* Excluded from this release type: TreeAdapter */

/**
 * Provides various functions for analyzing {@link NodeBase}s.
 *
 * @privateRemarks
 * Inlining the typing of this interface onto the `Tree` object provides slightly different .d.ts generation,
 * which avoids typescript expanding the type of TreeNodeSchema and thus encountering
 * https://github.com/microsoft/rushstack/issues/1958.
 * @beta
 */
export declare interface TreeApi {
    /**
     * The schema information for this node.
     */
    schema<T extends NodeBase>(node: NodeBase): TreeNodeSchema<string, NodeKind, unknown, T>;
    /**
     * Narrow the type of the given value if it satisfies the given schema.
     * @example
     * ```ts
     * if (node.is(myNode, point)) {
     *     const y = myNode.y; // `myNode` is now known to satisfy the `point` schema and therefore has a `y` coordinate.
     * }
     * ```
     */
    is<TSchema extends TreeNodeSchema>(value: unknown, schema: TSchema): value is NodeFromSchema<TSchema>;
    /**
     * Return the node under which this node resides in the tree (or undefined if this is a root node of the tree).
     */
    parent(node: NodeBase): NodeBase | undefined;
    /**
     * The key of the given node under its parent.
     * @remarks
     * If `node` is an element in a {@link (TreeListNode:interface)}, this returns the index of `node` in the list (a `number`).
     * Otherwise, this returns the key of the field that it is under (a `string`).
     */
    key(node: NodeBase): string | number;
    /**
     * Register an event listener on the given node.
     * @returns A callback function which will deregister the event.
     * This callback should be called only once.
     */
    on<K extends keyof TreeNodeEvents>(node: NodeBase, eventName: K, listener: TreeNodeEvents[K]): () => void;
    /**
     * Returns the {@link TreeStatus} of the given node.
     */
    readonly status: (node: NodeBase) => TreeStatus;
}

/* Excluded from this release type: TreeCompressionStrategy */

/**
 * Configuration for how to {@link ITree.schematize|schematize} a tree.
 * @beta
 */
export declare class TreeConfiguration<TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> {
    readonly schema: TSchema;
    readonly initialTree: () => InsertableTreeFieldFromImplicitField<TSchema>;
    /**
     * @param schema - The schema which the application wants to view the tree with.
     * @param initialTree - A function that returns the default tree content to initialize the tree with iff the tree is uninitialized
     * (meaning it does not even have any schema set at all).
     * If `initialTree` returns any actual node instances, they should be recreated each time `initialTree` runs.
     * This is because if the config is used a second time any nodes that were not recreated could error since nodes cannot be inserted into the tree multiple times.
     */
    constructor(schema: TSchema, initialTree: () => InsertableTreeFieldFromImplicitField<TSchema>);
}

/* Excluded from this release type: TreeContent */

/* Excluded from this release type: TreeContext */

/* Excluded from this release type: TreeDataContext */

/* Excluded from this release type: TreeEvent */

/* Excluded from this release type: TreeFactory */

/**
 * Converts ImplicitFieldSchema to the corresponding tree node's field type.
 * @beta
 */
export declare type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> = TSchema extends FieldSchema<infer Kind, infer Types> ? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind> : TSchema extends ImplicitAllowedTypes_2 ? TreeNodeFromImplicitAllowedTypes<TSchema> : unknown;

/* Excluded from this release type: TreeFieldSchema */

/* Excluded from this release type: TreeFieldStoredSchema */

/**
 * A {@link NodeBase} which implements 'readonly T[]' and the list mutation APIs.
 * @beta
 */
export declare interface TreeListNode<T extends ImplicitAllowedTypes_2 = ImplicitAllowedTypes_2> extends TreeListNodeBase<TreeNodeFromImplicitAllowedTypes<T>, InsertableTreeNodeFromImplicitAllowedTypes<T>, TreeListNode> {
}

/**
 * A {@link NodeBase} which implements 'readonly T[]' and the list mutation APIs.
 * @beta
 */
export declare const TreeListNode: {
    /**
     * Wrap an iterable of items to inserted as consecutive items in a list.
     * @remarks
     * The object returned by this function can be inserted into a {@link (TreeListNode:interface)}.
     * Its contents will be inserted consecutively in the corresponding location in the list.
     * @example
     * ```ts
     * list.insertAtEnd(TreeListNode.inline(iterable))
     * ```
     */
    inline: <T>(content: Iterable<T>) => IterableTreeListContent<T>;
};

/**
 * A generic List type, used to defined types like {@link (TreeListNode:interface)}.
 * @beta
 */
declare interface TreeListNodeBase<out T, in TNew, in TMoveFrom> extends ReadonlyArray<T> {
    /**
     * Inserts new item(s) at a specified location.
     * @param index - The index at which to insert `value`.
     * @param value - The content to insert.
     * @throws Throws if `index` is not in the range [0, `list.length`).
     */
    insertAt(index: number, ...value: (TNew | IterableTreeListContent<TNew>)[]): void;
    /**
     * Inserts new item(s) at the start of the list.
     * @param value - The content to insert.
     */
    insertAtStart(...value: (TNew | IterableTreeListContent<TNew>)[]): void;
    /**
     * Inserts new item(s) at the end of the list.
     * @param value - The content to insert.
     */
    insertAtEnd(...value: (TNew | IterableTreeListContent<TNew>)[]): void;
    /**
     * Removes the item at the specified location.
     * @param index - The index at which to remove the item.
     * @throws Throws if `index` is not in the range [0, `list.length`).
     */
    removeAt(index: number): void;
    /**
     * Removes all items between the specified indices.
     * @param start - The starting index of the range to remove (inclusive). Defaults to the start of the list.
     * @param end - The ending index of the range to remove (exclusive).
     * @throws Throws if `start` is not in the range [0, `list.length`).
     * @throws Throws if `end` is less than `start`.
     * If `end` is not supplied or is greater than the length of the list, all items after `start` are deleted.
     */
    removeRange(start?: number, end?: number): void;
    /**
     * Moves the specified item to the start of the list.
     * @param sourceIndex - The index of the item to move.
     * @throws Throws if `sourceIndex` is not in the range [0, `list.length`).
     */
    moveToStart(sourceIndex: number): void;
    /**
     * Moves the specified item to the start of the list.
     * @param sourceIndex - The index of the item to move.
     * @param source - The source list to move the item out of.
     * @throws Throws if `sourceIndex` is not in the range [0, `list.length`).
     */
    moveToStart(sourceIndex: number, source: TMoveFrom): void;
    /**
     * Moves the specified item to the end of the list.
     * @param sourceIndex - The index of the item to move.
     * @throws Throws if `sourceIndex` is not in the range [0, `list.length`).
     */
    moveToEnd(sourceIndex: number): void;
    /**
     * Moves the specified item to the end of the list.
     * @param sourceIndex - The index of the item to move.
     * @param source - The source list to move the item out of.
     * @throws Throws if `sourceIndex` is not in the range [0, `list.length`).
     */
    moveToEnd(sourceIndex: number, source: TMoveFrom): void;
    /**
     * Moves the specified item to the desired location in the list.
     * @param index - The index to move the item to.
     * This is based on the state of the list before moving the source item.
     * @param sourceIndex - The index of the item to move.
     * @throws Throws if any of the input indices are not in the range [0, `list.length`).
     */
    moveToIndex(index: number, sourceIndex: number): void;
    /**
     * Moves the specified item to the desired location in the list.
     * @param index - The index to move the item to.
     * @param sourceIndex - The index of the item to move.
     * @param source - The source list to move the item out of.
     * @throws Throws if any of the input indices are not in the range [0, `list.length`).
     */
    moveToIndex(index: number, sourceIndex: number, source: TMoveFrom): void;
    /**
     * Moves the specified items to the start of the list.
     * @param sourceStart - The starting index of the range to move (inclusive).
     * @param sourceEnd - The ending index of the range to move (exclusive)
     * @throws Throws if either of the input indices are not in the range [0, `list.length`) or if `sourceStart` is greater than `sourceEnd`.
     */
    moveRangeToStart(sourceStart: number, sourceEnd: number): void;
    /**
     * Moves the specified items to the start of the list.
     * @param sourceStart - The starting index of the range to move (inclusive).
     * @param sourceEnd - The ending index of the range to move (exclusive)
     * @param source - The source list to move items out of.
     * @throws Throws if the types of any of the items being moved are not allowed in the destination list,
     * if either of the input indices are not in the range [0, `list.length`) or if `sourceStart` is greater than `sourceEnd`.
     */
    moveRangeToStart(sourceStart: number, sourceEnd: number, source: TMoveFrom): void;
    /**
     * Moves the specified items to the end of the list.
     * @param sourceStart - The starting index of the range to move (inclusive).
     * @param sourceEnd - The ending index of the range to move (exclusive)
     * @throws Throws if either of the input indices are not in the range [0, `list.length`) or if `sourceStart` is greater than `sourceEnd`.
     */
    moveRangeToEnd(sourceStart: number, sourceEnd: number): void;
    /**
     * Moves the specified items to the end of the list.
     * @param sourceStart - The starting index of the range to move (inclusive).
     * @param sourceEnd - The ending index of the range to move (exclusive)
     * @param source - The source list to move items out of.
     * @throws Throws if the types of any of the items being moved are not allowed in the destination list,
     * if either of the input indices are not in the range [0, `list.length`) or if `sourceStart` is greater than `sourceEnd`.
     */
    moveRangeToEnd(sourceStart: number, sourceEnd: number, source: TMoveFrom): void;
    /**
     * Moves the specified items to the desired location within the list.
     * @param index - The index to move the items to.
     * This is based on the state of the list before moving the source items.
     * @param sourceStart - The starting index of the range to move (inclusive).
     * @param sourceEnd - The ending index of the range to move (exclusive)
     * @throws Throws if any of the input indices are not in the range [0, `list.length`) or if `sourceStart` is greater than `sourceEnd`.
     */
    moveRangeToIndex(index: number, sourceStart: number, sourceEnd: number): void;
    /**
     * Moves the specified items to the desired location within the list.
     * @param index - The index to move the items to.
     * @param sourceStart - The starting index of the range to move (inclusive).
     * @param sourceEnd - The ending index of the range to move (exclusive)
     * @param source - The source list to move items out of.
     * @throws Throws if the types of any of the items being moved are not allowed in the destination list,
     * if any of the input indices are not in the range [0, `list.length`) or if `sourceStart` is greater than `sourceEnd`.
     */
    moveRangeToIndex(index: number, sourceStart: number, sourceEnd: number, source: TMoveFrom): void;
}

/* Excluded from this release type: TreeLocation */

/**
 * A map of string keys to tree objects.
 *
 * @beta
 */
export declare interface TreeMapNode<T extends ImplicitAllowedTypes_2> extends TreeMapNodeBase<TreeNodeFromImplicitAllowedTypes<T>, InsertableTreeNodeFromImplicitAllowedTypes<T>> {
}

/**
 * A map of string keys to tree objects.
 *
 * @privateRemarks
 * Add support for `clear` once we have established merge semantics for it.
 *
 * @beta
 */
export declare interface TreeMapNodeBase<TOut, TIn = TOut> extends ReadonlyMap<string, TOut> {
    /**
     * Adds or updates an entry in the map with a specified `key` and a `value`.
     *
     * @param key - The key of the element to add to the map.
     * @param value - The value of the element to add to the map.
     *
     * @remarks
     * Setting the value at a key to `undefined` is equivalent to calling {@link TreeMapNodeBase.delete} with that key.
     */
    set(key: string, value: TIn | undefined): void;
    /**
     * Removes the specified element from this map by its `key`.
     *
     * @remarks
     * Note: unlike JavaScript's Map API, this method does not return a flag indicating whether or not the value was
     * deleted.
     *
     * @privateRemarks
     * Regarding the choice to not return a boolean: Since this data structure is distributed in nature, it isn't
     * possible to tell whether or not the item was deleted as a result of this method call. Returning a "best guess"
     * is more likely to create issues / promote bad usage patterns than offer useful information.
     *
     * @param key - The key of the element to remove from the map.
     */
    delete(key: string): void;
}

/* Excluded from this release type: TreeNavigationResult */

/**
 * A collection of events that can be raised by a {@link NodeBase}.
 * @beta
 */
export declare interface TreeNodeEvents {
    /**
     * Raised on a node right after a change is applied to one of its fields or the fields of a descendant node.
     */
    afterChange(): void;
}

/**
 * Type of of tree node for a field of the given schema.
 * @beta
 */
declare type TreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes_2 = TreeNodeSchema> = TSchema extends TreeNodeSchema ? NodeFromSchema<TSchema> : TSchema extends AllowedTypes_2 ? NodeFromSchema<FlexListToUnion<TSchema>> : unknown;

/**
 * Schema for a tree node.
 * @typeParam Name - The full (including scope) name/identifier for the schema.
 * @typeParam Kind - Which kind of node this schema is for.
 * @typeParam TNode - API for nodes that use this schema.
 * @typeParam TBuild - Data which can be used to construct an unhydrated node of this type.
 * @remarks
 * Captures the schema both as runtime data and compile time type information.
 * @beta
 */
export declare type TreeNodeSchema<Name extends string = string, Kind extends NodeKind = NodeKind, TNode = unknown, TBuild = never, ImplicitlyConstructable extends boolean = boolean> = TreeNodeSchemaClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable> | TreeNodeSchemaNonClass<Name, Kind, TNode, TBuild, ImplicitlyConstructable>;

/* Excluded from this release type: TreeNodeSchemaBase */

/**
 * Tree node schema which is implemented using a class.
 * @remarks
 * Instances of this class are nodes in the tree.
 * This is also a constructor so that it can be subclassed.
 *
 * Using classes in this way allows introducing a named type and a named value at the same time, helping keep the runtime and compile time information together and easy to refer to un a uniform way.
 * Additionally, this works around https://github.com/microsoft/TypeScript/issues/55832 which causes similar patterns with less explicit types to infer "any" in the d.ts file.
 * @beta
 */
declare interface TreeNodeSchemaClass<out Name extends string = string, out Kind extends NodeKind = NodeKind, out TNode = unknown, in TInsertable = never, out ImplicitlyConstructable extends boolean = boolean> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable> {
    /**
     * Constructs an {@link Unhydrated} node with this schema.
     * @remarks
     * This constructor is also used internally to construct hydrated nodes with a different parameter type.
     * Therefor overriding this constructor is not type-safe and is not supported.
     * @sealed
     */
    new (data: TInsertable): Unhydrated<TNode>;
}

/**
 * Data common to all tree node schema.
 * @beta
 */
declare interface TreeNodeSchemaCore<out Name extends string, out Kind extends NodeKind, out ImplicitlyConstructable extends boolean> {
    readonly identifier: Name;
    readonly kind: Kind;
    readonly info: unknown;
    /**
     * When constructing insertable content,
     * data that could be passed to the node's constructor can be used instead of an {@link Unhydrated} node
     * iff implicitlyConstructable is true.
     * @privateRemarks
     * Currently the logic for traversing insertable content,
     * both to build trees and to hydrate them does not defer to the schema classes to handle the policy,
     * so if their constructors differ from what is supported, some cases will not work.
     * Setting this to false adjusts the insertable types to disallow cases which could be impacted by these inconsistencies.
     */
    readonly implicitlyConstructable: ImplicitlyConstructable;
}

/* Excluded from this release type: TreeNodeSchemaIdentifier */

/**
 * Schema which is not a class.
 * @remarks
 * This is used for schema which cannot have their instances constructed using constructors, like leaf schema.
 * @privateRemarks
 * Non-class based schema can have issues with recursive types due to https://github.com/microsoft/TypeScript/issues/55832.
 * @beta
 */
declare interface TreeNodeSchemaNonClass<out Name extends string = string, out Kind extends NodeKind = NodeKind, out TNode = unknown, in TInsertable = never, out ImplicitlyConstructable extends boolean = boolean> extends TreeNodeSchemaCore<Name, Kind, ImplicitlyConstructable> {
    create(data: TInsertable): TNode;
}

/* Excluded from this release type: TreeNodeStoredSchema */

/* Excluded from this release type: TreeOptions */

/* Excluded from this release type: TreeSchema */

/* Excluded from this release type: treeSchemaFromStoredSchema */

/**
 * Status of the tree that a particular node belongs to.
 * @beta
 */
export declare enum TreeStatus {
    /**
     * Is parented under the root field.
     */
    InDocument = 0,
    /**
     * Is not parented under the root field, but can be added back to the original document tree.
     */
    Removed = 1,
    /**
     * Is removed and cannot be added back to the original document tree.
     */
    Deleted = 2
}

/* Excluded from this release type: TreeStoredSchema */

/* Excluded from this release type: TreeType */

/* Excluded from this release type: TreeTypeSet */

/* Excluded from this release type: TreeValue */

/**
 * An editable view of a (version control style) branch of a shared tree.
 * @privateRemarks
 * This is a wrapper around ITreeView that adjusted it for the public package API.
 * TODO:
 * Establish a naming conversion between these internal and wrapper types.
 * @beta
 */
export declare interface TreeView<in out TRoot> extends IDisposable {
    /**
     * The current root of the tree.
     */
    readonly root: TRoot;
    /**
     * Events for the tree.
     */
    readonly events: ISubscribable<CheckoutEvents>;
}

/* Excluded from this release type: typeboxValidator */

/* Excluded from this release type: TypedFields */

/* Excluded from this release type: typedObjectValues */

/* Excluded from this release type: typeNameSymbol */

/* Excluded from this release type: UnbrandedName */

/* Excluded from this release type: Unenforced */

/**
 * Type alias to document which values are un-hydrated.
 *
 * Un-hydrated values are nodes produced from schema's create functions that haven't been inserted into a tree yet.
 *
 * Since un-hydrated nodes become hydrated when inserted, strong typing can't be used to distinguish them.
 * This no-op wrapper is used instead.
 * @beta
 */
export declare type Unhydrated<T> = T;

/* Excluded from this release type: UpPath */

/* Excluded from this release type: UpPathDefault */

/* Excluded from this release type: Value */

/* Excluded from this release type: ValueFieldEditBuilder */

/* Excluded from this release type: ValueFromBranded */

/* Excluded from this release type: ValueSchema */

/* Excluded from this release type: valueSymbol */

export { }
