import { type HttpEngineError, type WebSocketEngineError } from "@tai-kun/surrealdb/errors";
import type { Formatter } from "@tai-kun/surrealdb/formatter";
import type { BidirectionalRpcResponse, LiveResult, RpcRequest, RpcResponse } from "@tai-kun/surrealdb/types";
import { StatefulPromise, type TaskEmitter } from "@tai-kun/surrealdb/utils";
import type { SetOptional, Simplify } from "type-fest";
type OptionalOnNull<T> = SetOptional<T, {
    [P in keyof T]: null extends T[P] ? P : never;
}[keyof T]>;
type NonNullKeysOf<T> = {
    [P in keyof T]: null extends T[P] ? never : P;
}[keyof T];
export type ConnectionState = "connecting" | "open" | "closing" | "closed";
export declare namespace ConnectionInfo {
    type Info<TState extends ConnectionState, TEndpoint, TNamespace, TDatabase, TToken> = {
        state: TState;
        endpoint: TEndpoint;
        namespace: TNamespace;
        database: TDatabase;
        token: TToken;
    };
    export type Connecting = Info<"connecting", URL, null, null, null>;
    export type Open = Info<"open", URL, string | null, string | null, string | null>;
    export type Closing = Info<"closing", URL, string | null, string | null, string | null>;
    export type Closed = Info<"closed", null, null, null, null>;
    export {};
}
export type ConnectionInfo = ConnectionInfo.Connecting | ConnectionInfo.Open | ConnectionInfo.Closing | ConnectionInfo.Closed;
/**
 * {@link TransitionArgs}
 */
type _TransitionArgs<TState, TConnInfo> = OptionalOnNull<TConnInfo> | (NonNullKeysOf<TConnInfo> extends "state" ? TState : never);
export type TransitionArgs = {
    [TState in ConnectionState]: _TransitionArgs<TState, Extract<ConnectionInfo, {
        state: TState;
    }>>;
}[ConnectionState];
export type EngineEventMap = {
    [TState in ConnectionState]: [
        result: {
            state: TState;
            error?: never;
        } | {
            state: TState;
            error: unknown;
        }
    ];
} & {
    [_: `rpc_${BidirectionalRpcResponse["id"]}`]: [
        response: BidirectionalRpcResponse
    ];
    [_: `live_${string}`]: [response: Simplify<Omit<LiveResult, "id">>];
    error: [error: HttpEngineError | WebSocketEngineError];
};
export interface EngineAbcConfig {
    readonly emitter: TaskEmitter<EngineEventMap>;
    readonly formatter: Formatter;
}
export interface ConnectArgs {
    signal: AbortSignal;
    endpoint: URL;
}
export interface CloseArgs {
    signal: AbortSignal;
}
export interface RpcArgs {
    signal: AbortSignal;
    request: RpcRequest;
}
export default abstract class EngineAbc {
    protected ee: TaskEmitter<EngineEventMap>;
    protected fmt: Formatter;
    private _conn;
    constructor(config: EngineAbcConfig);
    protected transition(args: TransitionArgs, fallback: () => TransitionArgs): StatefulPromise<void>;
    get state(): ConnectionState;
    get endpoint(): URL | null;
    get namespace(): string | null;
    set namespace(ns: string | null);
    get database(): string | null;
    set database(db: string | null);
    get token(): string | null;
    set token(token: string | null);
    getConnectionInfo(): ConnectionInfo;
    abstract readonly name: string;
    abstract connect(args: ConnectArgs): PromiseLike<void>;
    abstract close(args: CloseArgs): PromiseLike<void>;
    abstract rpc(args: RpcArgs): PromiseLike<RpcResponse>;
}
export {};
//# sourceMappingURL=engine-abc.d.ts.map