import Client from './client.js';
import { State, HeadState } from './state/index.js';
import { FollowPromiseOne, FollowPromiseMany } from './follow-promise.js';
import { Link, LinkVariables } from './link.js';
import { EventEmitter } from '#events';
import { GetRequestOptions, PostRequestOptions, PatchRequestOptions, PutRequestOptions, HeadRequestOptions } from './types.js';
/**
 * A 'resource' represents an endpoint on a server.
 *
 * A resource has a uri, methods that correspond to HTTP methods,
 * and events to subscribe to state changes.
 */
export declare class Resource<T = any> extends EventEmitter {
    /**
     * URI of the current resource
     */
    uri: string;
    /**
     * Reference to the Client that created the resource
     */
    client: Client;
    /**
     * This object tracks all in-flight requests.
     *
     * When 2 identical requests are made in quick succession, this object is
     * used to de-duplicate the requests.
     */
    private readonly activeRefresh;
    /**
     * Create the resource.
     *
     * This is usually done by the Client.
     */
    constructor(client: Client, uri: string);
    /**
     * Gets the current state of the resource.
     *
     * This function will return a State object.
     */
    get(getOptions?: GetRequestOptions): Promise<State<T>>;
    /**
     * Does a HEAD request and returns a HeadState object.
     *
     * If there was a valid existing cache for a GET request, it will
     * still return that.
     */
    head(headOptions?: HeadRequestOptions): Promise<HeadState>;
    /**
     * Gets the current state of the resource, skipping
     * the cache.
     *
     * This function will return a State object.
     */
    refresh(getOptions?: GetRequestOptions): Promise<State<T>>;
    /**
     * Updates the server state with a PUT request
     */
    put(options: PutRequestOptions<T> | State): Promise<void>;
    /**
     * Deletes the resource
     */
    delete(): Promise<void>;
    /**
     * Sends a POST request to the resource.
     *
     * See the documentation for PostRequestOptions for more details.
     * This function is used for RPC-like endpoints and form submissions.
     *
     * This function will return the response as a State object.
     */
    post(options: PostRequestOptions): Promise<State>;
    /**
     * Sends a POST request, and follows to the next resource.
     *
     * If a server responds with a 201 Status code and a Location header,
     * it will automatically return the newly created resource.
     *
     * If the server responded with a 204 or 205, this function will return
     * `this`.
     */
    postFollow(options: PostRequestOptions): Promise<Resource>;
    /**
     * Sends a PATCH request to the resource.
     *
     * This function defaults to a application/json content-type header.
     *
     * If the server responds with 200 Status code this will return a State object
     */
    patch(options: PatchRequestOptions): Promise<undefined | State<T>>;
    /**
     * Follows a relationship, based on its reltype. For example, this might be
     * 'alternate', 'item', 'edit' or a custom url-based one.
     *
     * This function can also follow templated uris. You can specify uri
     * variables in the optional variables argument.
     */
    follow<TFollowedResource = any>(rel: string, variables?: LinkVariables): FollowPromiseOne<TFollowedResource>;
    /**
     * Follows a relationship based on its reltype. This function returns a
     * Promise that resolves to an array of Resource objects.
     *
     * If no resources were found, the array will be empty.
     */
    followAll<TFollowedResource = any>(rel: string): FollowPromiseMany<TFollowedResource>;
    /**
     * Resolves a new resource based on a relative uri.
     *
     * Use this function to manually get a Resource object via a uri. The uri
     * will be resolved based on the uri of the current resource.
     *
     * This function doesn't do any HTTP requests.
     */
    go<TGoResource = any>(uri: string | Link): Resource<TGoResource>;
    /**
     * Does a HTTP request on the current resource URI
     */
    fetch(init?: RequestInit): Promise<Response>;
    /**
     * Does a HTTP request on the current resource URI.
     *
     * If the response was a 4XX or 5XX, this function will throw
     * an exception.
     */
    fetchOrThrow(init?: RequestInit): Promise<Response>;
    /**
     * Updates the state cache, and emits events.
     *
     * This will update the local state but *not* update the server
     */
    updateCache(state: State<T>): void;
    /**
     * Clears the state cache for this resource.
     */
    clearCache(): void;
    /**
     * Retrieves the current cached resource state, and return `null` if it's
     * not available.
     */
    getCache(): State<T> | null;
    /**
     * Returns a Link object, by its REL.
     *
     * If the link does not exist, a LinkNotFound error will be thrown.
     *
     * @deprecated
     */
    link(rel: string): Promise<Link>;
    /**
     * Returns all links defined on this object.
     *
     * @deprecated
     */
    links(rel?: string): Promise<Link[]>;
    /**
     *
     * Returns true or false depending on if a link with the specified relation
     * type exists.
     *
     * @deprecated
     */
    hasLink(rel: string): Promise<boolean>;
}
export declare interface Resource<T = any> {
    /**
     * Subscribe to the 'update' event.
     *
     * This event will get triggered whenever a new State is received
     * from the server, either through a GET request or if it was
     * transcluded.
     *
     * It will also trigger when calling 'PUT' with a full state object,
     * and when updateCache() was used.
     */
    on(event: 'update', listener: (state: State) => void): this;
    /**
     * Subscribe to the 'stale' event.
     *
     * This event will get triggered whenever an unsafe method was
     * used, such as POST, PUT, PATCH, etc.
     *
     * When any of these methods are used, the local cache is stale.
     */
    on(event: 'stale', listener: () => void): this;
    /**
     * Subscribe to the 'delete' event.
     *
     * This event gets triggered when the `DELETE` http method is used.
     */
    on(event: 'delete', listener: () => void): this;
    /**
     * Subscribe to the 'update' event and unsubscribe after it was
     * emitted the first time.
     */
    once(event: 'update', listener: (state: State) => void): this;
    /**
     * Subscribe to the 'stale' event and unsubscribe after it was
     * emitted the first time.
     */
    once(event: 'stale', listener: () => void): this;
    /**
     * Subscribe to the 'delete' event and unsubscribe after it was
     * emitted the first time.
     */
    once(event: 'delete', listener: () => void): this;
    /**
     * Unsubscribe from the 'update' event
     */
    off(event: 'update', listener: (state: State) => void): this;
    /**
     * Unsubscribe from the 'stale' event
     */
    off(event: 'stale', listener: () => void): this;
    /**
     * Unsubscribe from the 'delete' event
     */
    off(event: 'delete', listener: () => void): this;
    /**
     * Emit an 'update' event.
     */
    emit(event: 'update', state: State): boolean;
    /**
     * Emit a 'stale' event.
     */
    emit(event: 'stale'): boolean;
    /**
     * Emit a 'delete' event.
     */
    emit(event: 'delete'): boolean;
}
export default Resource;
