import type { Applicative2 as RES } from 'fp-ts/Applicative';
import type { Apply2 } from 'fp-ts/Apply';
import type { Bifunctor2 } from 'fp-ts/Bifunctor';
import * as E from 'fp-ts/Either';
import * as Eq from 'fp-ts/Eq';
import type { Functor2 } from 'fp-ts/Functor';
import type { Monad2 } from 'fp-ts/Monad';
import type { Show } from 'fp-ts/Show';
import type { Predicate, Refinement } from 'fp-ts/function';
import type { AjaxError, AjaxResponse } from 'rxjs/ajax';
import type { StatusCode } from './statusCode';
export interface ResourceInit {
    readonly _tag: 'init';
}
export interface ResourceSubmitted {
    readonly _tag: 'submitted';
}
export interface ResourceData<S, P> {
    readonly status: S;
    readonly payload: P;
}
export interface ResourceDone<D> {
    readonly _tag: 'done';
    readonly data: D;
}
export interface AppErr<AE = never> {
    readonly type: 'appError';
    readonly detail: AE;
}
export type ResourceAjaxError<AE = never> = {
    readonly type: 'unknownError';
    readonly detail: unknown;
} | (AE extends never ? never : AppErr<AE>);
export type ResourceError<DE, AE = never, R = any> = {
    readonly type: 'decodeError';
    readonly statusCode: StatusCode;
    readonly detail: DE;
} | {
    readonly type: 'networkError';
    readonly detail: AjaxError;
} | {
    readonly type: 'unexpectedResponse';
    readonly detail: AjaxResponse<R> | AjaxError;
} | ResourceAjaxError<AE>;
export interface ResourceAjaxFail<AE = never> {
    readonly _tag: 'fail';
    readonly error: ResourceAjaxError<AE>;
}
export interface ResourceFail<E> {
    readonly _tag: 'fail';
    readonly error: E;
}
export type Resource<E, A> = ResourceInit | ResourceSubmitted | ResourceDone<A> | ResourceFail<E>;
export type ResourceAcknowledged<E, A> = ResourceDone<A> | ResourceFail<E>;
export type ResourceDecoders = {
    [k in StatusCode]?: (i: unknown) => E.Either<unknown, unknown>;
};
export type ResourceTypeOf<DS extends ResourceDecoders, AE = never> = ResourceInit | ResourceTypeOfStarted<DS, AE>;
export type ResourceTypeOfStarted<DS extends ResourceDecoders, AE = never> = ResourceSubmitted | ResourceTypeOfAcknowledged<DS, AE>;
export type ResourceTypeOfAcknowledged<DS extends ResourceDecoders, AE = never> = ResourceTypeOfDone<DS> | ResourceTypeOfFail<DS, AE>;
export type ResourceTypeOfDone<DS extends ResourceDecoders> = ResourceDone<DecodersToResourceData<DS>>;
type ExtractRight<C> = C extends (i: unknown) => E.Either<any, infer A> ? A : never;
export type DecodersToResourceData<DS> = {
    [S in keyof DS]: ResourceData<S, ExtractRight<DS[S]>>;
}[keyof DS];
export type ResourceTypeOfFail<DS extends ResourceDecoders, AE = never> = ResourceFail<DecodersToResourceError<DS, AE>>;
type ExtractLeft<C> = C extends (i: unknown) => E.Either<infer A, any> ? A : never;
export type DecodersToResourceError<DS extends ResourceDecoders, AE> = ResourceError<{
    [S in keyof DS]: ExtractLeft<DS[S]>;
}[keyof DS], AE>;
export declare const isInit: <E, D>(r: Resource<E, D>) => r is ResourceInit;
export declare const isSubmitted: <E, D>(r: Resource<E, D>) => r is ResourceSubmitted;
export declare const isDone: <E, D>(r: Resource<E, D>) => r is ResourceDone<D>;
export declare const isFail: <E, D>(r: Resource<E, D>) => r is ResourceFail<E>;
export declare const isPending: <E, D>(r: Resource<E, D>) => r is ResourceInit | ResourceSubmitted;
export declare const isStarted: <E, D>(r: Resource<E, D>) => r is ResourceSubmitted | ResourceDone<D> | ResourceFail<E>;
export declare const isAcknowledged: <E, D>(r: Resource<E, D>) => r is ResourceDone<D> | ResourceFail<E>;
export declare const init: Resource<never, never>;
export declare const submitted: Resource<never, never>;
export declare const done: <E = never, A = never>(d: A) => Resource<E, A>;
export declare const fail: <E = never, A = never>(error: E) => Resource<E, A>;
export declare const ajaxFail: <AE = never, A = never>(error: ResourceAjaxError<AE>) => Resource<ResourceAjaxError<AE>, A>;
export declare const failAppError: <AE, A = never>(detail: AE) => Resource<ResourceAjaxError<AE>, A>;
export declare const appError: <AE = never>(detail: AE) => AppErr<AE>;
export declare const ajaxFailOnly: <AE = never>(error: ResourceAjaxError<AE>) => ResourceFail<ResourceAjaxError<AE>>;
export declare const fromEither: <E, A>(e: E.Either<E, A>) => Resource<E, A>;
export declare const of: RES<URI>['of'];
export declare const match: <E, A, R>(onInit: () => R, onSubmitted: () => R, onDone: (r: A) => R, onFail: (r: E) => R) => (r: Resource<E, A>) => R;
export declare const matchD: <E, A, R>(dodo: {
    onInit: () => R;
    onSubmitted: () => R;
    onDone: (r: A) => R;
    onFail: (r: E) => R;
} | {
    onPending: () => R;
    onDone: (r: A) => R;
    onFail: (r: E) => R;
}) => (r: Resource<E, A>) => R;
export declare const match_: <E, D>(r: Resource<E, D>) => <R>(onInit: () => R, onSubmitted: () => R, onDone: (r: D) => R, onFail: (r: E) => R) => R;
export declare const URI = "Resource";
export type URI = typeof URI;
declare module 'fp-ts/HKT' {
    interface URItoKind2<E, A> {
        readonly [URI]: Resource<E, A>;
    }
}
export declare function getShow<E, A>(SE: Show<E>, SA: Show<A>): Show<Resource<E, A>>;
export declare function getEq<E, A>(EE: Eq.Eq<E>, EA: Eq.Eq<A>): Eq.Eq<Resource<E, A>>;
export declare const Functor: Functor2<URI>;
export declare const Apply: Apply2<URI>;
export declare const Bifunctor: Bifunctor2<URI>;
export declare const Applicative: RES<URI>;
export declare const Monad: Monad2<URI>;
export declare function swap<E, A>(ma: Resource<E, A>): Resource<A, E>;
export declare function orElseW<E, M, A, B>(onFail: (e: E) => Resource<M, B>): (ma: Resource<E, A>) => Resource<M, A | B>;
export declare const orElse: <E, A, M>(onFail: (e: E) => Resource<M, A>) => (ma: Resource<E, A>) => Resource<M, A>;
export declare const filterOrElseW: {
    <A, B extends A, E2>(refinement: Refinement<A, B>, onFalse: (a: A) => E2): <E1>(ma: Resource<E1, A>) => Resource<E1 | E2, B>;
    <A, E2>(predicate: Predicate<A>, onFalse: (a: A) => E2): <E1>(ma: Resource<E1, A>) => Resource<E1 | E2, A>;
};
export declare const filterOrElse: {
    <E, A, B extends A>(refinement: Refinement<A, B>, onFalse: (a: A) => E): (ma: Resource<E, A>) => Resource<E, B>;
    <E, A>(predicate: Predicate<A>, onFalse: (a: A) => E): (ma: Resource<E, A>) => Resource<E, A>;
};
export declare const map: <A, B>(f: (a: A) => B) => <E>(fa: Resource<E, A>) => Resource<E, B>;
export declare const bimap: <E, G, A, B>(f: (e: E) => G, g: (a: A) => B) => (fa: Resource<E, A>) => Resource<G, B>;
export declare const mapLeft: <E, G>(f: (e: E) => G) => <A>(fa: Resource<E, A>) => Resource<G, A>;
export declare const apW: <D, A>(fa: Resource<D, A>) => <E, B>(fab: Resource<E, (a: A) => B>) => Resource<D | E, B>;
export declare const ap: <E, A>(fa: Resource<E, A>) => <B>(fab: Resource<E, (a: A) => B>) => Resource<E, B>;
export declare const chainW: <D, A, B>(f: (a: A) => Resource<D, B>) => <E>(ma: Resource<E, A>) => Resource<D | E, B>;
export declare const chain: <E, A, B>(f: (a: A) => Resource<E, B>) => (ma: Resource<E, A>) => Resource<E, B>;
export {};
