import { MessageTransport, RequestMessage, ResponseMessage } from './MessageTransport';
export declare enum ConversationPerspective {
    Requester = "requester",
    Responder = "responder"
}
export interface ConversationSummary<T, R> {
    perspective: ConversationPerspective;
    request: RequestMessage<T>;
    responses: {
        message: ResponseMessage<R>;
        time: [number, number];
    }[];
}
export type ReceiveHandler<T, R> = (message: T) => Promise<R | AsyncIterableIterator<R> | void>;
interface MessageConnectionOptions<T, R> {
    signSalt?: string;
    marshalPayload?: (payload: T | R) => T | R;
    unmarshalPayload?: (payload: T | R) => T | R;
}
export declare class MessageConnection<T, R, A = never> {
    responseTimeout: number;
    private connId;
    readonly transport: MessageTransport<T, R>;
    private responseQueues;
    private signSalt?;
    private marshalPayload;
    private unmarshalPayload;
    private attributes;
    private receiveHandler?;
    onConversation?: (c: ConversationSummary<T, R>) => void;
    constructor(transport: MessageTransport<T, R>, { signSalt, marshalPayload, unmarshalPayload }?: MessageConnectionOptions<T, R>);
    get onReceive(): ReceiveHandler<T, R> | undefined;
    set onReceive(receiveHandler: ReceiveHandler<T, R> | undefined);
    get id(): string;
    getAttribute<K extends keyof A>(key: K): A[K] | undefined;
    /**
     * Set a keyed value on the connection. This key/value pair are cached on the
     * connection instance.
     * @param key the key
     * @param value the value
     */
    setAttribute<K extends keyof A>(key: K, value: A[K]): void;
    deleteAttribute<K extends keyof A>(key: K): void;
    send(data: T): Promise<void>;
    requestOne(data: T, expectResponse?: boolean): Promise<R>;
    requestMulti(data: T): Promise<AsyncIterableIterator<R>>;
    request(data: T, expectResponse?: boolean): Promise<AsyncIterableIterator<R> | R | undefined>;
    private marshalMessage;
    private unmarshalMessage;
    private signMessage;
    private doRequest;
    private handleRequest;
}
export {};
