import type { WithDefaults } from "../common/types/index";
type ContextWatcherFn = () => void;
declare class Context<_T> {
    readonly name: string;
    constructor(name: string);
}
declare class ContextProvider<T> {
    private _context?;
    watchers: Set<ContextWatcherFn>;
    consume(): T | undefined;
    provide(nextContext: T): void;
}
export declare const __implEntityKeepOldPropValue: {};
/**
 * Entity Base Class. It has event handlers for attaching, detaching and updating props. Has a method for providing and using context.
 * @typeParam Props - Type of input props of the Entity.
 * @typeParam DefaultProps - Type of default input props of the Entity.
 * @typeParam Root - Root Entity Class.
 * @example
 * ```ts
 * type YMapSomeEntityProps = {
 *  name?: string;
 * };
 * const defaultProps = {
 *  name: 'entity'
 * };
 * class YMapSomeEntity extends GenericEntity<YMapSomeEntityProps, typeof defaultProps> {
 *  static defaultProps = defaultProps;
 *  public isAttached: boolean;
 *  constructor(props: YMapSomeEntityProps) {
 *      super(props);
 *      this.isAttached = false
 *      // Additional actions can be taken in the constructor of a class.
 *  }
 *  protected _onAttach(): void {
 *      this.isAttached = true;
 *      // Additional actions can be taken when an Entity is attached.
 *  }
 *  // ...
 * }
 * ```
 */
declare abstract class GenericEntity<Props, DefaultProps extends {} = {}, Root extends GenericRootEntity<unknown> = GenericRootEntity<unknown>> {
    /**
     * The value of input props.
     */
    protected _props: WithDefaults<Props, DefaultProps>;
    /**
     * @param props - The value of input props.
     */
    constructor(props: Props);
    /**
     * The method provides the default values for the properties of an Entity.
     * @param _props - Input props value for the Entity.
     * @returns Props with default values.
     */
    protected _getDefaultProps(_props: Props): DefaultProps | undefined;
    /**
     * Method for updating props of Entity.
     * @param changedProps - New props values.
     */
    update(changedProps: Partial<Props>): void;
    /**
     * Handler of the attachment event to the parent Entity.
     * @virtual
     */
    protected _onAttach?(): void;
    /**
     * Handler of the detachment event to the parent Entity.
     * @virtual
     */
    protected _onDetach?(): void;
    /**
     * Handler of the update event to the current Entity.
     * @param props - New props values.
     * @param oldProps - Previous props values.
     * @virtual
     */
    protected _onUpdate?(props: Partial<Props>, oldProps: Props): void;
    /**
     * Get parent entity.
     */
    get parent(): GenericComplexEntity<unknown> | null;
    /**
     * Get root entity.
     */
    get root(): Root | null;
    /**
     * Provides context in the Entity.
     * @param consumer - The context that provides access to the context value.
     * @param ctx - The value passed to the context.
     */
    protected _provideContext<T>(consumer: Context<T>, ctx: T): void;
    /**
     * Gets the value from the passed context.
     * @param consumer - The context that provides access to the context value.
     * @returns Context value.
     */
    protected _consumeContext<T>(consumer: Context<T>): T | undefined;
    /**
     * Subscribes to changes in a context
     * @param context - The context that provides access to the context value.
     * @param watcher - Callback function that is called when the context value is changed.
     * @param params - Params for watcher.
     * @param params.immediate - Calls watcher immediately. For most handlers it allows to inline watcher function.
     * @returns Function to unsubscribe from changes context.
     * For most handlers it can be, because it is called automatically on detach.
     */
    protected _watchContext<T>(context: Context<T>, watcher: ContextWatcherFn, params?: {
        immediate: boolean;
    }): () => void;
}
interface ComplexOptions<Root extends GenericRootEntity<unknown> = GenericRootEntity<unknown>> {
    children?: GenericEntity<unknown, {}, Root>[];
    container?: boolean;
}
/**
 * Entity that aggregates multiple Entities but looks basic from the outside.
 * @typeParam Props - Type of input props of the Entity.
 * @typeParam DefaultProps - Type of default input props of the Entity.
 * @typeParam Root - Root Entity Class.
 * @example
 * ```ts
 * type YMapSomeComplexEntityProps = {
 *  name?: string;
 * };
 * const defaultProps = {
 *  name: 'entity'
 * };
 * class YMapSomeComplexEntity extends GenericComplexEntity<YMapSomeComplexEntityProps, typeof defaultProps> {
 *  static defaultProps = defaultProps;
 *  private _someEntity?: YMapSomeEntity; // YMapSomeEntity extends GenericEntity
 *  protected _onAttach(): void {
 *      this._someEntity = new YMapSomeEntity();
 *      this.addChild(this._someEntity); // add someEntity as children
 *      // ...
 *  }
 *  // ...
 * }
 * ```
 */
declare class GenericComplexEntity<Props, DefaultProps extends {} = {}, Root extends GenericRootEntity<unknown> = GenericRootEntity<unknown>> extends GenericEntity<Props, DefaultProps, Root> {
    /**
     * Array of child Entities of the current ComplexEntity.
     */
    protected readonly children: readonly GenericEntity<unknown, {}, Root>[];
    protected readonly _childContainer: GenericComplexEntity<unknown, {}, Root>;
    /**
     * @param props - The value of input props.
     * @param options - Optional options object.
     * @param children - Array of child Entities of the current ComplexEntity.
     * @param options.children - Array of child Entities of the current ComplexEntity.
     * @param options.container - Creating a proxy container inside ComplexEntity.
     */
    constructor(props: Props, options?: ComplexOptions<Root>);
    constructor(props: Props, children?: GenericEntity<unknown, {}, Root>[], options?: Omit<ComplexOptions<Root>, 'children'>);
    protected __makeProxyContainer(): GenericComplexEntity<unknown, {}, Root>;
    /**
     * Adds a child directly to __implChildren, without _childContainer.
     * @param child - Child Entity to be added
     * @param index - 0-based ordinal number of the entity being added
     */
    protected _addDirectChild(child: GenericEntity<unknown, {}, Root>, index?: number): void;
    /**
     * Adds a child directly to  _childContainer
     * @param child - Child Entity to be added
     * @param index - 0-based ordinal number of the entity being added
     * @returns Current ComplexEntity
     */
    protected addChild(child: GenericEntity<unknown, {}, Root>, index?: number): this;
    /**
     * Deletes a child element directly in __implChildren, without _childContainer.
     * @param child - Child Entity to be removed
     */
    protected _removeDirectChild(child: GenericEntity<unknown, {}, Root>): void;
    /**
     * Deletes a child directly to  _childContainer
     * @param child - Child Entity to be removed
     * @returns Current ComplexEntity
     */
    protected removeChild(child: GenericEntity<unknown, {}, Root>): this;
}
/**
 * Entity that aggregates multiple Entities, and allows you to publicly add and remove entities to a subtree.
 * @typeParam Props - Type of input props of the Entity.
 * @typeParam DefaultProps - Type of default input props of the Entity.
 * @typeParam Root - Root Entity Class.
 * @example
 * ```ts
 * type YMapSomeGroupEntityProps = {
 *  name?: string;
 * };
 * const defaultProps = {
 *  name: 'entity'
 * };
 * class YMapSomeGroupEntity extends GenericGroupEntity<YMapSomeGroupEntityProps, typeof defaultProps> {
 *  static defaultProps = defaultProps;
 *  // ...
 * }
 * const groupEntity = new YMapSomeGroupEntity()
 * const someEntity = new YMapSomeEntity(); // YMapSomeEntity extends GenericEntity
 * groupEntity.addChild(someEntity); // add someEntity in YMapSomeGroupEntity object
 * groupEntity.removeChild(someEntity); // remove someEntity from YMapSomeGroupEntity object
 * ```
 */
declare class GenericGroupEntity<Props, DefaultProps extends {} = {}, Root extends GenericRootEntity<unknown> = GenericRootEntity<unknown>> extends GenericComplexEntity<Props, DefaultProps, Root> {
    readonly children: readonly GenericEntity<unknown, {}, Root>[];
    protected readonly _childContainer: GenericGroupEntity<unknown, {}, Root>;
    protected __makeProxyContainer(): GenericGroupEntity<unknown, {}, Root>;
    addChild(child: GenericEntity<unknown, {}, Root>, index?: number): this;
    removeChild(child: GenericEntity<unknown, {}, Root>): this;
}
/**
 * Entity that is root and cannot be added anywhere
 * @typeParam Props - Type of input props of the Entity.
 * @typeParam DefaultProps - Type of default input props of the Entity.
 * @example
 * type YMapProps = {
 *  name?: string;
 * };
 * class YMap extends GenericRootEntity<YMapProps, typeof defaultProps> {
 *  // ...
 * }
 * // Now we can specify their root element for the Entity
 * class YMapSomeEntity extends GenericEntity<YMapSomeEntityProps, typeof defaultProps, YMap> {
 *  static defaultProps = defaultProps;
 *  // ...
 * }
 */
declare abstract class GenericRootEntity<Props, DefaultProps extends {} = {}> extends GenericGroupEntity<Props, DefaultProps> {
    get root(): this;
    protected _onAttach: undefined;
    protected _onDetach: undefined;
    /**
     * Completely destroys the entity tree including the current entity
     */
    abstract destroy(): void;
}
type EntityProps<T extends GenericEntity<unknown>> = T extends GenericEntity<infer P> ? P : never;
type EntityConstructor<TEntity extends GenericEntity<unknown>> = new (...args: any[]) => TEntity;
export { GenericEntity, GenericComplexEntity, GenericGroupEntity, GenericRootEntity, Context, ContextProvider, EntityConstructor, EntityProps };
