import type Nymph from './Nymph.js';
import { EntityConstructor, EntityData, EntityInterface, EntityJson, EntityPatch, EntityReference } from './Entity.types.js';
export type EntityDataType<T> = T extends Entity<infer DataType> ? DataType : never;
export type EntityInstanceType<T extends EntityConstructor> = T extends new () => infer E ? E & EntityDataType<E> : never;
export default class Entity<T extends EntityData = EntityData> implements EntityInterface {
    /**
     * The instance of Nymph to use for queries.
     */
    static nymph: Nymph;
    /**
     * The lookup name for this entity.
     *
     * This is used for reference arrays (and sleeping references) and server
     * requests.
     */
    static class: string;
    /**
     * The instance of Nymph to use for queries.
     */
    $nymph: Nymph;
    /**
     * The entity's Globally Unique ID.
     */
    guid: string | null;
    /**
     * The creation date of the entity as a high precision Unix timestamp.
     */
    cdate: number | null;
    /**
     * The modified date of the entity as a high precision Unix timestamp.
     */
    mdate: number | null;
    /**
     * Array of the entity's tags.
     */
    tags: string[];
    /**
     * Array of the entity's original tags (for patch).
     */
    protected $originalTags: string[];
    /**
     * A map of props to whether they're dirty (for patch).
     */
    protected $dirty: {
        [k: string]: boolean;
    };
    /**
     * The data proxy handler.
     */
    protected $dataHandler: Object;
    /**
     * The actual data store.
     */
    protected $dataStore: T;
    /**
     * The data proxy object.
     */
    protected $data: T;
    /**
     * Whether this instance is a sleeping reference.
     */
    protected $isASleepingReference: boolean;
    /**
     * The reference to use to wake.
     */
    protected $sleepingReference: EntityReference | null;
    /**
     * A promise that resolved when the entity's data is wake.
     */
    protected $wakePromise: Promise<Entity<T>> | null;
    /**
     * Initialize an entity.
     */
    constructor(..._rest: any[]);
    /**
     * Create or retrieve a new entity instance.
     *
     * Note that this will always return an entity, even if the GUID is not found.
     *
     * @param guid An optional GUID to retrieve.
     */
    static factory<E extends Entity>(this: {
        new (): E;
    }, guid?: string): Promise<E & EntityDataType<E>>;
    /**
     * Create a new entity instance.
     */
    static factorySync<E extends Entity>(this: {
        new (): E;
    }): E & EntityDataType<E>;
    /**
     * Create a new sleeping reference instance.
     *
     * Sleeping references won't retrieve their data from the server until they
     * are readied with `$wake()` or a parent's `$wakeAll()`.
     *
     * @param reference The Nymph Entity Reference to use to wake.
     * @returns The new instance.
     */
    static factoryReference<E extends Entity>(this: {
        new (): E;
    }, reference: EntityReference): E & EntityDataType<E>;
    /**
     * Call a static method on the server version of this entity.
     *
     * @param method The name of the method.
     * @param params The parameters to call the method with.
     * @returns The value that the method on the server returned.
     */
    static serverCallStatic(method: string, params: Iterable<any>): Promise<any>;
    /**
     * Call a static iterator method on the server version of this entity.
     *
     * @param method The name of the method.
     * @param params The parameters to call the method with.
     * @returns An iterator that iterates over values that the method on the server yields.
     */
    static serverCallStaticIterator(method: string, params: Iterable<any>): Promise<import("./HttpRequester.js").AbortableAsyncIterator<any>>;
    toJSON(): EntityJson;
    $init(entityJson: EntityJson | null): Entity<T>;
    $addTag(...tags: string[]): void;
    $arraySearch(array: any[], strict?: boolean): number;
    $delete(): Promise<boolean>;
    $equals(object: any): boolean;
    $getPatch(): EntityPatch;
    $hasTag(...tags: string[]): boolean;
    $isDirty(property: string): boolean | null;
    $inArray(array: any[], strict?: boolean): boolean;
    $is(object: any): boolean;
    $patch(): Promise<boolean>;
    /**
     * Check if this is a sleeping reference and throw an error if so.
     */
    protected $check(): void;
    /**
     * Check if this is a sleeping reference.
     */
    $asleep(): boolean;
    /**
     * Wake from a sleeping reference.
     */
    $wake(): Promise<Entity<T>>;
    $wakeAll(level?: number): Promise<Entity<T>>;
    protected $referenceSleep(reference: EntityReference): void;
    $refresh(): Promise<boolean | 0>;
    $removeTag(...tags: string[]): void;
    $save(): Promise<boolean>;
    $serverCall(method: string, params: Iterable<any>, stateless?: boolean): Promise<any>;
    $toReference(): EntityReference | EntityInterface;
}
export declare class EntityIsSleepingReferenceError extends Error {
    constructor(message: string);
}
export declare class InvalidStateError extends Error {
    constructor(message: string);
}
