/**
 * @since 1.0.0
 */
import type * as Data from "@effect/data/Data";
import type { Duration } from "@effect/data/Duration";
import type * as Option from "@effect/data/Option";
import type * as _Cache from "@effect/io/Cache";
import type { Deferred } from "@effect/io/Deferred";
import type * as Effect from "@effect/io/Effect";
import type * as Exit from "@effect/io/Exit";
import type { FiberId } from "@effect/io/Fiber/Id";
/**
 * @since 1.0.0
 * @category symbols
 */
export declare const RequestTypeId: unique symbol;
/**
 * @since 1.0.0
 * @category symbols
 */
export type RequestTypeId = typeof RequestTypeId;
/**
 * A `Request<E, A>` is a request from a data source for a value of type `A`
 * that may fail with an `E`.
 *
 * @since 1.0.0
 * @category models
 */
export interface Request<E, A> extends Request.Variance<E, A>, Data.Case {
}
/**
 * @since 1.0.0
 */
export declare namespace Request {
    /**
     * @since 1.0.0
     * @category models
     */
    interface Variance<E, A> {
        readonly [RequestTypeId]: {
            readonly _E: (_: never) => E;
            readonly _A: (_: never) => A;
        };
    }
    /**
     * @since 1.0.0
     * @category models
     */
    interface Constructor<R extends Request<any, any>, T extends keyof R = never> {
        (args: Omit<R, T | keyof (Data.Case & Request.Variance<Request.Error<R>, Request.Success<R>>)>): R;
    }
    /**
     * A utility type to extract the error type from a `Request`.
     *
     * @since 1.0.0
     * @category type-level
     */
    type Error<T extends Request<any, any>> = [T] extends [Request<infer _E, infer _A>] ? _E : never;
    /**
     * A utility type to extract the value type from a `Request`.
     *
     * @since 1.0.0
     * @category type-level
     */
    type Success<T extends Request<any, any>> = [T] extends [Request<infer _E, infer _A>] ? _A : never;
    /**
     * A utility type to extract the result type from a `Request`.
     *
     * @since 1.0.0
     * @category type-level
     */
    type Result<T extends Request<any, any>> = T extends Request<infer E, infer A> ? Exit.Exit<E, A> : never;
    /**
     * A utility type to extract the optional result type from a `Request`.
     *
     * @since 1.0.0
     * @category type-level
     */
    type OptionalResult<T extends Request<any, any>> = T extends Request<infer E, infer A> ? Exit.Exit<E, Option.Option<A>> : never;
}
/**
 * Returns `true` if the specified value is a `Request`, `false` otherwise.
 *
 * @since 1.0.0
 * @category refinements
 */
export declare const isRequest: (u: unknown) => u is Request<unknown, unknown>;
/**
 * Constructs a new `Request`.
 *
 * @since 1.0.0
 * @category constructors
 */
export declare const of: <R extends Request<any, any>>() => Request.Constructor<R>;
/**
 * Constructs a new `Request`.
 *
 * @since 1.0.0
 * @category constructors
 */
export declare const tagged: <R extends Request<any, any> & {
    _tag: string;
}>(tag: R["_tag"]) => Request.Constructor<R, "_tag">;
/**
 * Complete a `Request` with the specified result.
 *
 * @since 1.0.0
 * @category request completion
 */
export declare const complete: {
    <A extends Request<any, any>>(result: Request.Result<A>): (self: A) => Effect.Effect<never, never, void>;
    <A extends Request<any, any>>(self: A, result: Request.Result<A>): Effect.Effect<never, never, void>;
};
/**
 * Interrupts the child effect when requests are no longer needed
 *
 * @since 1.0.0
 * @category request completion
 */
export declare const interruptWhenPossible: {
    (all: Iterable<Request<any, any>>): <R, E, A>(self: Effect.Effect<R, E, A>) => Effect.Effect<R, E, void>;
    <R, E, A>(self: Effect.Effect<R, E, A>, all: Iterable<Request<any, any>>): Effect.Effect<R, E, void>;
};
/**
 * Complete a `Request` with the specified effectful computation, failing the
 * request with the error from the effect workflow if it fails, and completing
 * the request with the value of the effect workflow if it succeeds.
 *
 * @since 1.0.0
 * @category request completion
 */
export declare const completeEffect: {
    <A extends Request<any, any>, R>(effect: Effect.Effect<R, Request.Error<A>, Request.Success<A>>): (self: A) => Effect.Effect<R, never, void>;
    <A extends Request<any, any>, R>(self: A, effect: Effect.Effect<R, Request.Error<A>, Request.Success<A>>): Effect.Effect<R, never, void>;
};
/**
 * Complete a `Request` with the specified error.
 *
 * @since 1.0.0
 * @category request completion
 */
export declare const fail: {
    <A extends Request<any, any>>(error: Request.Error<A>): (self: A) => Effect.Effect<never, never, void>;
    <A extends Request<any, any>>(self: A, error: Request.Error<A>): Effect.Effect<never, never, void>;
};
/**
 * Complete a `Request` with the specified value.
 *
 * @since 1.0.0
 * @category request completion
 */
export declare const succeed: {
    <A extends Request<any, any>>(value: Request.Success<A>): (self: A) => Effect.Effect<never, never, void>;
    <A extends Request<any, any>>(self: A, value: Request.Success<A>): Effect.Effect<never, never, void>;
};
/**
 * @category models
 * @since 1.0.0
 */
export interface Listeners {
    count: number;
    observers: Set<(count: number) => void>;
    addObserver(f: (count: number) => void): void;
    removeObserver(f: (count: number) => void): void;
    increment(): void;
    decrement(): void;
}
/**
 * @category models
 * @since 1.0.0
 */
export interface Cache extends _Cache.ConsumerCache<Request<any, any>, never, {
    listeners: Listeners;
    handle: Deferred<unknown, unknown>;
}> {
}
/**
 * @since 1.0.0
 * @category models
 */
export declare const makeCache: (capacity: number, timeToLive: Duration) => Effect.Effect<never, never, Cache>;
/**
 * @since 1.0.0
 * @category symbols
 */
export declare const EntryTypeId: unique symbol;
/**
 * @since 1.0.0
 * @category symbols
 */
export type EntryTypeId = typeof EntryTypeId;
/**
 * A `Entry<A>` keeps track of a request of type `A` along with a
 * `Ref` containing the result of the request, existentially hiding the result
 * type. This is used internally by the library to support data sources that
 * return different result types for different requests while guaranteeing that
 * results will be of the type requested.
 *
 * @since 1.0.0
 * @category models
 */
export interface Entry<R> extends Entry.Variance<R> {
    readonly request: R;
    readonly result: Deferred<[
        R
    ] extends [Request<infer _E, infer _A>] ? _E : never, [
        R
    ] extends [Request<infer _E, infer _A>] ? _A : never>;
    readonly listeners: Listeners;
    readonly ownerId: FiberId;
    readonly state: {
        completed: boolean;
    };
}
/**
 * @since 1.0.0
 * @category models
 */
export declare namespace Entry {
    /**
     * @since 1.0.0
     * @category models
     */
    interface Variance<R> {
        readonly [EntryTypeId]: {
            readonly _R: (_: never) => R;
        };
    }
}
/**
 * @since 1.0.0
 * @category guards
 */
export declare const isEntry: (u: unknown) => u is Entry<unknown>;
/**
 * @since 1.0.0
 * @category constructors
 */
export declare const makeEntry: <A extends Request<any, any>>(request: A, result: Deferred<Request.Error<A>, Request.Success<A>>, listeners: Listeners, ownerId: FiberId, state: {
    completed: boolean;
}) => Entry<A>;
//# sourceMappingURL=Request.d.ts.map