import type { DwnMessageSubscription, EnboxAgent, PermissionsApi } from '@enbox/agent';
import type { PaginationCursor, ProgressToken, RecordsQueryReplyEntry } from '@enbox/dwn-sdk-js';
import { Record } from './record.js';
/**
 * The type of change that occurred to a record.
 */
export type RecordChangeType = 'create' | 'update' | 'delete';
/**
 * Describes a change to a record in a {@link LiveQuery}.
 */
export type RecordChange = {
    /** Whether the record was created, updated, or deleted. */
    type: RecordChangeType;
    /** The record affected by the change. */
    record: Record;
};
/**
 * Describes a terminal DWN subscription error surfaced by a {@link LiveQuery}.
 */
export type LiveQueryError = {
    /** The DWN error code associated with the terminal subscription failure. */
    code: string;
    /** Human-readable error detail from the DWN subscription. */
    detail: string;
    /** The event cursor that caused delivery to stop, when provided by the DWN. */
    cursor?: ProgressToken;
};
/**
 * A `CustomEvent` subclass carrying a {@link RecordChange} as its `detail`.
 *
 * Dispatched on the {@link LiveQuery} `EventTarget` for both the specific
 * change-type event (`create`, `update`, `delete`) and the catch-all `change`
 * event.
 */
export declare class RecordChangeEvent extends CustomEvent<RecordChange> {
    constructor(change: RecordChange);
}
/**
 * Options for creating a {@link LiveQuery}.
 * @internal — Constructed by `DwnApi.records.subscribe()`, not by end users.
 */
export type LiveQueryOptions = {
    /** The agent instance used to construct Record objects. */
    agent: EnboxAgent;
    /** The DID of the connected user. */
    connectedDid: string;
    /** Optional delegate DID for permission-delegated access. */
    delegateDid?: string;
    /** Optional protocol role for role-authorized access. */
    protocolRole?: string;
    /** Optional remote DWN origin if subscribing to a remote DWN. */
    remoteOrigin?: string;
    /** The permissions API instance for constructing Record objects. */
    permissionsApi?: PermissionsApi;
    /** The initial snapshot entries from the subscribe reply. */
    initialEntries: RecordsQueryReplyEntry[];
    /** Pagination cursor for fetching the next page of initial results. */
    cursor?: PaginationCursor;
    /** The underlying DWN subscription handle. */
    subscription: DwnMessageSubscription;
};
/**
 * Catch-all event type that fires for any record change (create, update, or delete).
 */
export type RecordCatchAllEvent = 'change';
/**
 * Lifecycle event type for connection state changes.
 */
export type LiveQueryLifecycleEvent = 'disconnected' | 'reconnecting' | 'reconnected' | 'eose';
/**
 * Terminal event type emitted when a DWN subscription fails after it is open.
 */
export type LiveQueryTerminalEvent = 'error';
/**
 * Union of all event types emitted by {@link LiveQuery}.
 */
export type LiveQueryEventType = RecordChangeType | RecordCatchAllEvent | LiveQueryLifecycleEvent | LiveQueryTerminalEvent;
/**
 * A live query that combines an initial snapshot of matching records with a
 * real-time stream of deduplicated, semantically-typed change events.
 *
 * `LiveQuery` extends `EventTarget` so that standard `addEventListener` /
 * `removeEventListener` work out of the box. For convenience, the typed
 * {@link LiveQuery.on | `.on()`} method provides a cleaner API that returns an
 * unsubscribe function.
 *
 * ### Events
 *
 * | Event name | `detail` type | Description |
 * |---|---|---|
 * | `create` | {@link RecordChange} | A new record was written |
 * | `update` | {@link RecordChange} | An existing record was updated |
 * | `delete` | {@link RecordChange} | A record was deleted |
 * | `change` | {@link RecordChange} | Catch-all for any of the above |
 * | `disconnected` | — | Transport connection lost |
 * | `reconnecting` | `{ attempt: number }` | Reconnection attempt in progress |
 * | `reconnected` | — | Connection restored, subscription resubscribed |
 * | `eose` | — | End-of-stored-events: catch-up replay complete, events are now live |
 * | `error` | {@link LiveQueryError} | Terminal subscription error; no further events will be delivered |
 *
 * @example
 * ```ts
 * const { liveQuery } = await dwn.records.subscribe({
 *   message: {
 *     filter: {
 *       protocol     : chatProtocol.protocol,
 *       protocolPath : 'thread/message',
 *     }
 *   }
 * });
 *
 * // Initial state
 * for (const record of liveQuery.records) {
 *   renderMessage(record);
 * }
 *
 * // Real-time changes
 * liveQuery.on('create', (record) => appendMessage(record));
 * liveQuery.on('update', (record) => refreshMessage(record));
 * liveQuery.on('delete', (record) => removeMessage(record));
 *
 * // Connection lifecycle
 * liveQuery.on('disconnected', () => showOfflineIndicator());
 * liveQuery.on('reconnected', () => hideOfflineIndicator());
 * liveQuery.on('eose', () => console.log('catch-up complete'));
 *
 * // Cleanup
 * await liveQuery.close();
 * ```
 */
export declare class LiveQuery extends EventTarget {
    /** The initial snapshot of matching records. */
    readonly records: Record[];
    /**
     * Pagination cursor for fetching the next page of initial results.
     *
     * When the initial snapshot was limited (via `pagination.limit`), this
     * cursor can be passed in a subsequent `records.subscribe()` call to
     * continue from where the previous snapshot left off.
     *
     * `undefined` when there are no more results.
     */
    readonly cursor?: PaginationCursor;
    /** The underlying DWN subscription handle. */
    private readonly _subscription;
    /** Tracks known record states for dedup and change-type classification. */
    private readonly _knownRecords;
    /** Whether the live query has been closed. */
    private _closed;
    /** Whether the transport connection is currently active. */
    private _connected;
    constructor(options: LiveQueryOptions);
    /** Whether the transport connection is currently active. */
    get isConnected(): boolean;
    /**
     * Process an incoming live event from the DWN subscription.
     * Deduplicates against the initial snapshot and classifies the change type.
     *
     * @internal — Called by `DwnApi.records.subscribe()` when wiring up the subscription handler.
     */
    handleEvent(record: Record): void;
    /**
     * Handle a transport lifecycle event (disconnected, reconnecting, reconnected)
     * or an EOSE marker from the subscription.
     *
     * @internal — Called by `DwnApi.records.subscribe()` when the handler receives
     * non-record subscription messages.
     */
    handleLifecycleEvent(type: 'disconnected'): void;
    handleLifecycleEvent(type: 'reconnecting', detail: {
        attempt: number;
    }): void;
    handleLifecycleEvent(type: 'reconnected'): void;
    handleLifecycleEvent(type: 'eose'): void;
    /**
     * Handle a terminal DWN subscription error.
     *
     * @internal — Called by `DwnApi.records.subscribe()` before closing the
     * underlying subscription.
     */
    handleError(error: LiveQueryError): void;
    /**
     * Register a typed event handler. Returns an unsubscribe function.
     *
     * @param event - The event type to listen for.
     * @param handler - The handler function.
     * @returns A function that removes the handler when called.
     *
     * @example
     * ```ts
     * const off = live.on('create', (record) => console.log(record.id));
     * off(); // stop listening
     * ```
     */
    on(event: 'change', handler: (change: RecordChange) => void): () => void;
    on(event: 'create', handler: (record: Record) => void): () => void;
    on(event: 'update', handler: (record: Record) => void): () => void;
    on(event: 'delete', handler: (record: Record) => void): () => void;
    on(event: 'disconnected', handler: () => void): () => void;
    on(event: 'reconnecting', handler: (detail: {
        attempt: number;
    }) => void): () => void;
    on(event: 'reconnected', handler: () => void): () => void;
    on(event: 'eose', handler: () => void): () => void;
    on(event: 'error', handler: (error: LiveQueryError) => void): () => void;
    /**
     * Close the underlying subscription and stop dispatching events.
     */
    close(): Promise<void>;
}
//# sourceMappingURL=live-query.d.ts.map