import type { AsanaDbClient } from './client.js';
export declare const CLASS_FIELD = "_class";
export declare const KEY_FIELD = "_key";
export declare const ID_FIELD = "_id";
/**
 * A Compository document — a map-like object that also knows its label ({@link clazz}),
 * key field ({@link _key}), and vertex id ({@link _id}).
 *
 * @example
 * const doc = new Document('Article', '_id', 42n)
 *   .add('title', 'Hello')
 *   .add('body',  'World')
 *   .addChild(new Document('Tag').add('name', 'news'));
 *
 * @example
 * // From a plain object (class name inferred from constructor name)
 * const doc = Document.from(article, 'Article');
 *
 * Documents returned by {@link AsanaDbClient} are pre-bound so you can call
 * {@link save}, {@link fetch}, {@link update}, {@link delete} directly.
 */
export declare class Document {
    readonly clazz: string;
    readonly _key: string;
    protected _id?: bigint;
    /** @internal */
    _client?: AsanaDbClient;
    protected readonly _data: Map<string, unknown>;
    constructor(className?: string, keyField?: string, id?: bigint | number | string);
    get id(): bigint | undefined;
    /**
     * Build a Document from a plain object. Class name is taken from
     * `obj.constructor.name` unless overridden.
     */
    static from<T extends object>(obj: T, className?: string, keyField?: string, id?: bigint | number): Document;
    /** Parse a JSON string into a Document. Nested objects become child Documents. */
    static fromJSON(json: string): Document;
    /** @internal */
    static fromObject(obj: Record<string, unknown>): Document;
    get(key: string): unknown;
    set(key: string, value: unknown): this;
    has(key: string): boolean;
    remove(key: string): boolean;
    get size(): number;
    [Symbol.iterator](): IterableIterator<[string, unknown]>;
    keys(): IterableIterator<string>;
    values(): IterableIterator<unknown>;
    entries(): IterableIterator<[string, unknown]>;
    /** Flow-style setter. */
    add(key: string, value: unknown): this;
    /**
     * Attach a child Document under its {@link clazz} key.
     * First child stored directly; second of same class starts an array.
     */
    addChild(child: Document): this;
    removeChild(child: Document): this;
    getString(key: string): string | undefined;
    getNumber(key: string): number | undefined;
    getBigInt(key: string): bigint | undefined;
    getBoolean(key: string): boolean | undefined;
    getDocument(key: string): Document | undefined;
    getDocuments(key: string): Document[] | undefined;
    /** Persist this document. Uses {@link clazz} as the vertex label. */
    save(): Promise<void>;
    /**
     * Reload this document from the server.
     * Fetches by {@link id} when set, otherwise by the {@link _key} field value.
     */
    fetch(): Promise<Document | null>;
    /** Replace this document on the server by {@link id}. */
    update(): Promise<void>;
    /** Delete this document from the server by {@link id}. */
    delete(): Promise<void>;
    /** Return a plain object suitable for JSON serialization (including internal fields). */
    toJSON(): Record<string, unknown>;
    toString(): string;
    protected syncInternalFields(): void;
    protected extractInternalFields(): void;
    protected static convertValue(value: unknown): unknown;
    protected static serializeValue(value: unknown): unknown;
}
/** Result of an insertOne call. */
export interface InsertResult {
    insertedId?: bigint | number;
}
/** Thrown when the server responds with status !== "ok". */
export declare class AsanaDbError extends Error {
    constructor(message: string);
}
/** @internal */
export interface WireResponse {
    status: string;
    message: unknown;
}
//# sourceMappingURL=document.d.ts.map