import { type NostrFetcherBackendInitializer, type NostrFetcherCommonOptions } from "@nostr-fetch/kernel/fetcherBackend";
import { type EventVerifier, type NostrEvent } from "@nostr-fetch/kernel/nostr";
import { type DefaultFetcherBackendOptions } from "./fetcherBackend";
import { type RelayCapCheckerInitializer } from "./fetcherHelper";
import { type FetchFilter, type FetchFilterKeyElem, type FetchFilterKeyName, type FetchStatsListener, type FetchTimeRangeFilter } from "./types";
/**
 * Nostr event with extra fields.
 */
export type NostrEventExt<SeenOn extends boolean = false> = NostrEvent & {
    seenOn: SeenOn extends true ? string[] : undefined;
};
/**
 * Pair of the "key" of events and list of events which have that key.
 *
 * It is the type of elements of `AsyncIterable` returned from {@linkcode NostrFetcher.fetchLatestEventsPerKey}.
 */
export type NostrEventListWithKey<K extends FetchFilterKeyName, SeenOn extends boolean> = {
    key: FetchFilterKeyElem<K>;
    events: NostrEventExt<SeenOn>[];
};
/**
 * Pair of the "key" of an event and the event which has that key. If no event found matching the key, it will be `undefined`.
 *
 * It is the type of elements of `AsyncIterable` returned from {@linkcode NostrFetcher.fetchLastEventPerKey}.
 */
export type NostrEventWithKey<K extends FetchFilterKeyName, SeenOn extends boolean> = {
    key: FetchFilterKeyElem<K>;
    event: NostrEventExt<SeenOn> | undefined;
};
/**
 * Pair of the pubkey of event author and list of events from that author.
 *
 * It is the type of elements of `AsyncIterable` returned from {@linkcode NostrFetcher.fetchLatestEventsPerAuthor}.
 */
export type NostrEventListWithAuthor<SeenOn extends boolean> = {
    author: string;
    events: NostrEventExt<SeenOn>[];
};
/**
 * Pair of the pubkye of event author and an event from that author. If no event found from the author, it will be `undefined`.
 *
 * It is the type of elements of `AsyncIterable` returned from {@linkcode NostrFetcher.fetchLastEventPerAuthor}.
 */
export type NostrEventWithAuthor<SeenOn extends boolean> = {
    author: string;
    event: NostrEventExt<SeenOn> | undefined;
};
/**
 * Common options for all the fetch methods.
 */
export type FetchOptions<SeenOn extends boolean = false> = {
    /**
     * If specified, the fetcher uses the given function as an event signature verifier instead of the default one.
     *
     * The function must return `true` if the event signature is valid. Otherwise, it should return `false`.
     *
     * @example
     * // How to use nostr-wasm's verifyEvent() with nostr-fetch
     * import { NostrFetcher, type NostrEvent } from "nostr-fetch";
     * import { initNostrWasm } from "nostr-wasm";
     *
     * const nw = await initNostrWasm();
     * const nwVerifyEvent = (ev: NostrEvent) => {
     *   try {
     *     nw.verifyEvent(ev);
     *     return true;
     *   } catch {
     *     return false;
     *   }
     * };
     * const fetcher = NostrFetcher.init({
     *   eventVerifier: nwVerifyEvent,
     * });
     */
    eventVerifier?: EventVerifier;
    /**
     * If true, the fetcher skips event signature verification.
     *
     * Note: This option has no effect under some relay pool adapters.
     * Check the document of the relay pool adapter you want to use.
     *
     * @default false
     *
     * @deprecated This option will be removed in nostr-fetch v1. Set the `noopVerifier` to the `eventVerifier` option instead of turning this on.
     */
    skipVerification?: boolean;
    /**
     * If true, the fetcher skips a check that events from relays are certainly match with filters in REQuest.
     *
     * By default, fetchers perform the check to protect clients from malicious relays.
     *
     * @default false
     */
    skipFilterMatching?: boolean;
    /**
     * If true, `seenOn` property is appended to every returned events.
     * The value of `seenOn` is array of relay URLs on which the event have been seen.
     *
     * @default false
     */
    withSeenOn?: SeenOn;
    /**
     * The function for listening fetch statistics.
     *
     * @default undefined
     */
    statsListener?: FetchStatsListener | undefined;
    /**
     * How often fetch statistics is notified to the listener (specified via `statsListener`), in milliseconds.
     *
     * @default 1000
     */
    statsNotifIntervalMs?: number;
    /**
     * The maximum amount of time allowed to attempt to connect to relays, in milliseconds.
     *
     * @default 5000
     */
    connectTimeoutMs?: number;
    /**
     * The `AbortSignal` used to abort an event fetching.
     *
     * @default undefined
     */
    signal?: AbortSignal | undefined;
    /**
     * The `AbortSignal` used to abort an event fetching.
     *
     * @default undefined
     *
     * @deprecated Set `signal` option instead.
     */
    abortSignal?: AbortSignal | undefined;
    /**
     * The maximum amount of time to wait for events from relay before a subscription is automatically aborted before EOSE, in milliseconds.
     *
     * @default 10000
     */
    abortSubBeforeEoseTimeoutMs?: number;
    /**
     * `limit` value to be used in internal subscriptions.
     * You may want to lower this value if relays you use have limit on value of `limit`.
     *
     * @default 5000
     */
    limitPerReq?: number;
};
/**
 * Options for {@linkcode NostrFetcher.allEventsIterator}.
 */
export type AllEventsIterOptions<SeenOn extends boolean = false> = FetchOptions<SeenOn> & {
    /**
     * If true, the backpressure mode is enabled.
     *
     * In the backpressure mode, a fetcher is automatically slowed down when the consumer of events is slower than the fetcher (producer of events).
     *
     * This feature may be useful for jobs like transferring events from relays to other relays.
     *
     * @default false
     */
    enableBackpressure?: boolean;
};
/**
 * Options for {@linkcode NostrFetcher.fetchAllEvents}.
 */
export type FetchAllOptions<SeenOn extends boolean = false> = FetchOptions<SeenOn> & {
    /**
     * If true, resulting events are sorted in "newest to oldest" order.
     *
     * @default false
     */
    sort?: boolean;
};
/**
 * Options for "fetch latest N events" kind of fetchers, such as {@linkcode NostrFetcher.fetchLatestEvents}.
 */
export type FetchLatestOptions<SeenOn extends boolean = false> = FetchOptions<SeenOn> & {
    /**
     * Takes unixtime in second.  If specified, fetch latest events **as of the time**.
     *
     * Note: it is useful only for fetching *regular* events. Using this for replaceable events will result in an unexpected behavior.
     */
    asOf?: number | undefined;
    /**
     * If true, the "reduced verification" mode is enabled.
     *
     * In the reduced verification mode, event signature verification is performed only to minimum amount of events enough to ensure validity.
     *
     * @default false
     *
     * @deprecated This option will be removed in nostr-fetch v1. Fetch with `eventVerifier: noopVerifier` first, then verify fetched events by yourself.
     */
    reduceVerification?: boolean;
};
/**
 * Type of the first argument of {@linkcode NostrFetcher.fetchLatestEventsPerAuthor}/{@linkcode NostrFetcher.fetchLastEventPerAuthor}.
 */
export type KeysAndRelays<K extends FetchFilterKeyName> = {
    keys: FetchFilterKeyElem<K>[];
    relayUrls: string[];
} | Iterable<[key: FetchFilterKeyElem<K>, relayUrls: string[]]>;
/**
 * Type of the first argument of {@linkcode NostrFetcher.fetchLatestEventsPerAuthor}/{@linkcode NostrFetcher.fetchLastEventPerAuthor}.
 */
export type AuthorsAndRelays = RelaySetForAllAuthors | RelaySetsPerAuthor;
/**
 * Use same relay set for all authors
 */
type RelaySetForAllAuthors = {
    authors: string[];
    relayUrls: string[];
};
/**
 * Use saperate relay set for each author.  Typically `Map<string, string[]>`
 */
type RelaySetsPerAuthor = Iterable<[author: string, relayUrls: string[]]>;
/**
 * The entry point of the Nostr event fetching.
 *
 * It sits on top of a Nostr relay pool implementation which manages connections to Nostr relays. It is recommended to reuse single `NostrFetcher` instance in entire app.
 *
 * You must instantiate `NostrFetcher` with static methods like {@linkcode NostrFetcher.init} or {@linkcode NostrFetcher.withCustomPool} instead of the constructor.
 */
export declare class NostrFetcher {
    #private;
    private constructor();
    /**
     * Initializes {@linkcode NostrFetcher} with the default relay pool implementation.
     *
     * If you are on an runtime that doesn't have a native WebSocket implementation (e.g. Node.js < v22),
     * you may want to set custom `WebSocket` constructor imported from an external package as follows:
     *
     * ```ts
     * import { NostrFetcher } from "nostr-fetch";
     * import WebSocket from "ws";
     *
     * const fetcher = NostrFetcher.init({
     *   webSocketConstructor: WebSocket
     * });
     * ```
     */
    static init(options?: NostrFetcherCommonOptions & DefaultFetcherBackendOptions, initRelayCapChecker?: RelayCapCheckerInitializer): NostrFetcher;
    /**
     * Initializes {@linkcode NostrFetcher} with the given adapted custom relay pool implementation.
     *
     * @example
     * ```ts
     * const pool = new SimplePool();
     * const fetcher = NostrFetcher.withCustomPool(simplePoolAdapter(pool));
     * ```
     */
    static withCustomPool(poolAdapter: NostrFetcherBackendInitializer, options?: NostrFetcherCommonOptions, initRelayCapChecker?: RelayCapCheckerInitializer): NostrFetcher;
    /**
     * Returns an async iterable of all events matching the filter from Nostr relays specified by the array of URLs.
     *
     * You can iterate over events using `for-await-of` loop.
     *
     * Note: there are no guarantees about the order of returned events.
     *
     * Throws {@linkcode NostrFetchError} if `timeRangeFilter` is invalid (`since` > `until`).
     */
    allEventsIterator<SeenOn extends boolean = false>(relayUrls: string[], filter: FetchFilter, timeRangeFilter: FetchTimeRangeFilter, options?: AllEventsIterOptions<SeenOn>): AsyncIterable<NostrEventExt<SeenOn>>;
    /**
     * Fetches all events matching the filter from Nostr relays specified by the array of URLs,
     * and collect them into an array.
     *
     * Note: there are no guarantees about the order of returned events if `sort` options is not specified.
     *
     * Throws {@linkcode NostrFetchError} if `timeRangeFilter` is invalid (`since` > `until`).
     */
    fetchAllEvents<SeenOn extends boolean = false>(relayUrls: string[], filter: FetchFilter, timeRangeFilter: FetchTimeRangeFilter, options?: FetchAllOptions<SeenOn>): Promise<NostrEventExt<SeenOn>[]>;
    /**
     * Fetches latest events matching the filter from Nostr relays specified by the array of URLs.
     *
     * Events are sorted in "newest to oldest" order.
     *
     * Throws {@linkcode NostrFetchError} if `limit` is a non-positive number.
     */
    fetchLatestEvents<SeenOn extends boolean = false>(relayUrls: string[], filter: FetchFilter, limit: number, options?: FetchLatestOptions<SeenOn>): Promise<NostrEventExt<SeenOn>[]>;
    /**
     * Fetches the last event matching the filter from Nostr relays specified by the array of URLs.
     *
     * Returns `undefined` if no event matching the filter exists in any relay.
     */
    fetchLastEvent<SeenOn extends boolean = false>(relayUrls: string[], filter: FetchFilter, options?: FetchLatestOptions<SeenOn>): Promise<NostrEventExt<SeenOn> | undefined>;
    /**
     * Fetches latest up to `limit` events **for each key specified by `keyName` and `keysAndRelays`**.
     *
     * `keysAndRelays` can be either of two types:
     *
     * - `{ keys: K[], relayUrls: string[] }`: The fetcher will use the same relay set (`relayUrls`) for all `keys` to fetch events.
     * - `Map<K, string[]>`: Key must be the key of event and value must be relay set for that key. The fetcher will use separate relay set for each key to fetch events.
     *
     * Result is an async iterable of `{ key: <key of events>, events: <events which have that key> }` pairs.
     *
     * Each array of events in the result are sorted in "newest to oldest" order.
     *
     * Throws {@linkcode NostrFetchError} if `limit` is a non-positive number.
     */
    fetchLatestEventsPerKey<K extends FetchFilterKeyName, SeenOn extends boolean = false>(keyName: K, keysAndRelays: KeysAndRelays<K>, otherFilter: FetchFilter, limit: number, options?: FetchLatestOptions<SeenOn>): AsyncIterable<NostrEventListWithKey<K, SeenOn>>;
    /**
     * Fetches the last event **for each key specified by `keysAndRelays`**.
     *
     * `keysAndRelays` can be either of two types:
     *
     * - `{ keys: K[], relayUrls: string[] }`: The fetcher will use the same relay set (`relayUrls`) for all `keys` to fetch events.
     * - `Map<K, string[]>`: Key must be key of the event and value must be relay set for that key. The fetcher will use separate relay set for each key to fetch events.
     *
     * Result is an async iterable of `{ key: <key of events>, event: <the latest event which have that key> }` pairs.
     *
     * `event` in result will be `undefined` if no event matching the filter exists in any relay.
     */
    fetchLastEventPerKey<K extends FetchFilterKeyName, SeenOn extends boolean = false>(keyName: K, keysAndRelays: KeysAndRelays<K>, otherFilter: FetchFilter, options?: FetchLatestOptions<SeenOn>): AsyncIterable<NostrEventWithKey<K, SeenOn>>;
    /**
     * Fetches latest up to `limit` events **for each author specified by `authorsAndRelays`**.
     *
     * `authorsAndRelays` can be either of two types:
     *
     * - `{ authors: string[], relayUrls: string[] }`: The fetcher will use the same relay set (`relayUrls`) for all `authors` to fetch events.
     * - `Map<string, string[]>`: Key must be author's pubkey and value must be relay set for that author. The fetcher will use separate relay set for each author to fetch events.
     *
     * Result is an async iterable of `{ author: <author's pubkey>, events: <events from the author> }` pairs.
     *
     * Each array of events in the result are sorted in "newest to oldest" order.
     *
     * Throws {@linkcode NostrFetchError} if `limit` is a non-positive number.
     *
     * Note: it's just an wrapper of `fetchLatestEventsPerKey`.
     */
    fetchLatestEventsPerAuthor<SeenOn extends boolean = false>(authorsAndRelays: AuthorsAndRelays, otherFilter: Omit<FetchFilter, "authors">, limit: number, options?: FetchLatestOptions<SeenOn>): AsyncIterable<NostrEventListWithAuthor<SeenOn>>;
    /**
     * Fetches the last event **for each author specified by `authorsAndRelays`**.
     *
     * `authorsAndRelays` can be either of two types:
     *
     * - `{ authors: string[], relayUrls: string[] }`: The fetcher will use the same relay set (`relayUrls`) for all `authors` to fetch events.
     * - `Map<string, string[]>`: Key must be author's pubkey and value must be relay set for that author. The fetcher will use separate relay set for each author to fetch events.
     *
     * Result is an async iterable of `{ author: <author's pubkey>, event: <the latest event from the author> }` pairs.
     *
     * `event` in result will be `undefined` if no event matching the filter for the author exists in any relay.
     *
     * Note: it's just a wrapper of `fetchLastEventPerKey`.
     */
    fetchLastEventPerAuthor<SeenOn extends boolean = false>(authorsAndRelays: AuthorsAndRelays, otherFilter: Omit<FetchFilter, "authors">, options?: FetchLatestOptions<SeenOn>): AsyncIterable<NostrEventWithAuthor<SeenOn>>;
    /**
     * Cleans up all the internal states of the fetcher.
     */
    shutdown(): void;
    /**
     * Enables [explicit resource management](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management) for `NostrFetcher` instances.
     *
     * If you bind a `NostrFetcher` instance to a variable with `using` keyword, it will be automatically shut down when the scope of the variable ends.
     */
    [Symbol.dispose](): void;
}
export {};
//# sourceMappingURL=fetcher.d.ts.map