import { Noun } from '@urbit/nockjs';
import { UrbitHttpApiEvent } from './events';
import { AuthenticationInterface, NounPokeInterface, PokeInterface, Scry, SubscriptionRequestInterface, Thread } from './types';

type UrbitHttpApiEventMap = {
    [E in keyof UrbitHttpApiEvent]: (event: UrbitHttpApiEvent[E]) => void;
};
/**
 * A class for interacting with an urbit ship, given its URL and code
 */
export declare class Urbit {
    url: string;
    code?: string;
    desk?: string;
    /**
     * Event emitter for debugging, see events.ts for full list of events
     */
    private emitter;
    /**
     * UID will be used for the channel: The current unix time plus a random hex string
     */
    private uid;
    /**
     * lastEventId is an auto-updated index of which events have been *sent* over this channel.
     * lastHeardEventId is the latest event we have heard back about.
     * lastAcknowledgedEventId is the latest event we have sent an ack for.
     */
    private lastEventId;
    private lastHeardEventId;
    private lastAcknowledgedEventId;
    /**
     * SSE Client is null for now; we don't want to start polling until it the channel exists
     */
    private sseClientInitialized;
    /**
     * Cookie gets set when we log in.
     */
    cookie?: string;
    /**
     * A registry of requestId to successFunc/failureFunc
     *
     * These functions are registered during a +poke and are executed
     * in the onServerEvent()/onServerError() callbacks. Only one of
     * the functions will be called, and the outstanding poke will be
     * removed after calling the success or failure function.
     */
    private outstandingPokes;
    /**
     * A registry of requestId to subscription functions.
     *
     * These functions are registered during a +subscribe and are
     * executed in the onServerEvent()/onServerError() callbacks. The
     * event function will be called whenever a new piece of data on this
     * subscription is available, which may be 0, 1, or many times. The
     * disconnect function may be called exactly once.
     */
    private outstandingSubscriptions;
    /**
     * Our abort controller, used to close the connection
     */
    private channelAbort;
    /**
     * Identity of the ship we're connected to
     */
    nodeId?: string | null;
    /**
     * Our identity, with which we are authenticated into the ship
     */
    our?: string | null;
    /**
     * If verbose, logs output eagerly.
     */
    verbose?: boolean;
    /**
     * number of consecutive errors in connecting to the eventsource
     */
    private errorCount;
    /**
     * Custom fetch implementation to use.
     */
    fetchFn: typeof fetch;
    /** This is basic interpolation to get the channel URL of an instantiated Urbit connection. */
    private get channelUrl();
    private get fetchOptions();
    private fetchOptionsNoun;
    /**
     * Constructs a new Urbit connection.
     *
     * @param url  The URL (with protocol and port) of the ship to be accessed. If
     * the airlock is running in a webpage served by the ship, this should just
     * be the empty string.
     * @param code The access code for the ship at that address
     */
    constructor(url: string, code?: string, desk?: string, fetchFn?: typeof fetch);
    /**
     * All-in-one hook-me-up.
     *
     * Given a ship, url, and code, this returns an airlock connection
     * that is ready to go. It `|hi`s itself to create the channel,
     * then opens the channel via EventSource.
     *
     */
    static authenticate({ ship, url, code, verbose, }: AuthenticationInterface): Promise<Urbit>;
    private emit;
    on<T extends keyof UrbitHttpApiEventMap>(event: T, callback: UrbitHttpApiEventMap[T]): void;
    /**
     * Gets the name of the ship accessible at this.url and stores it to this.ship
     *
     */
    getShipName(): Promise<void>;
    /**
     * Gets the name of the ship accessible at this.url and stores it to this.ship
     *
     */
    getOurName(): Promise<void>;
    /**
     * Connects to the Urbit ship. Nothing can be done until this is called.
     * That's why we roll it into this.authenticate
     * TODO  as of urbit/urbit#6561, this is no longer true, and we are able
     *       to interact with the ship using a guest identity.
     */
    connect(): Promise<void>;
    /**
     * Initializes the SSE pipe for the appropriate channel.
     */
    eventSource(): Promise<void>;
    /**
     * Reset airlock, abandoning current subscriptions and wiping state
     *
     */
    reset(): void;
    seamlessReset(): void;
    /**
     * Autoincrements the next event ID for the appropriate channel.
     */
    private getEventId;
    /**
     * Acknowledges an event.
     *
     * @param eventId The event to acknowledge.
     */
    private ack;
    private sendNounsToChannel;
    private sendJSONtoChannel;
    /**
     * Validates the size of the poke body.
     * This prevents us from accidentally sending large payloads (eg base64 images)
     * @param body The body to validate.
     */
    validatePokeBodySize(body: string): void;
    /**
     * Creates a subscription, waits for a fact and then unsubscribes
     *
     * @param app Name of gall agent to subscribe to
     * @param path Path to subscribe to
     * @param timeout Optional timeout before ending subscription
     *
     * @returns The first fact on the subcription
     */
    subscribeOnce<T = any>(app: string, path: string, ship?: string, timeout?: number): Promise<T>;
    pokeNoun(params: NounPokeInterface): Promise<number>;
    /**
     * Pokes a ship with data.
     *
     * @param app The app to poke
     * @param mark The mark of the data being sent
     * @param json The data to send
     */
    poke<T>(params: PokeInterface<T>): Promise<number>;
    /**
     * Subscribes to a path on an app on a ship.
     *
     *
     * @param app The app to subsribe to
     * @param path The path to which to subscribe
     * @param handlers Handlers to deal with various events of the subscription
     */
    subscribe(params: SubscriptionRequestInterface): Promise<number>;
    /**
     * Unsubscribes to a given subscription.
     *
     * @param subscription
     */
    unsubscribe(subscription: number): Promise<void>;
    /**
     * Deletes the connection to a channel.
     */
    delete(): Promise<void>;
    checkIsNodeBusy(): Promise<'available' | 'busy' | 'unknown'>;
    /**
     * Scry into an gall agent at a path
     *
     * @typeParam T - Type of the scry result
     *
     * @remarks
     *
     * Equivalent to
     * ```hoon
     * .^(T %gx /(scot %p our)/[app]/(scot %da now)/[path]/json)
     * ```
     * The returned cage must have a conversion to JSON for the scry to succeed
     *
     * @param params The scry request
     * @returns The scry result
     */
    scry<T = any>(params: Scry): Promise<T>;
    scryWithInfo<T = any>(params: Scry): Promise<{
        responseStatus: number;
        responseSizeInBytes: number;
        result: T;
    }>;
    scryNoun(params: Scry): Promise<Noun>;
    scryNounWithInfo(params: Scry): Promise<{
        responseStatus: number;
        responseSizeInBytes: number;
        result: Noun;
    }>;
    /**
     * Run a thread
     *
     *
     * @param inputMark   The mark of the data being sent
     * @param outputMark  The mark of the data being returned
     * @param threadName  The thread to run
     * @param body        The data to send to the thread
     * @returns  The return value of the thread
     */
    thread<T = any>(params: Thread<T>): Promise<Response>;
    getSpinHints(): Promise<string>;
    /**
     * Perform a standard HTTP request using the channel's authentication
     *
     * @param path The path to request (relative to the ship's URL)
     * @param options Request options (method, headers, body, etc.)
     * @returns The response from the request
     */
    request<T>(path: string, options?: RequestInit, timeout?: number): Promise<T>;
    /**
     * Utility function to connect to a ship that has its *.arvo.network domain configured.
     *
     * @param name Name of the ship e.g. zod
     * @param code Code to log in
     */
    static onArvoNetwork(ship: string, code: string): Promise<Urbit>;
}
export default Urbit;
//# sourceMappingURL=Urbit.d.ts.map