import { Proxy } from '../each';
export declare type TConfig = {
    [key: string]: any;
};
export interface IBuilder<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy extends TServerOneWay, TServerTwoWayProxy extends TServerTwoWay, TClientOneWayProxy extends TClientOneWay, TClientTwoWayProxy extends TClientTwoWay> {
    api: Api<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy>;
}
export interface IServerProxyBuilder<T, TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy extends TServerOneWay, TServerTwoWayProxy extends TServerTwoWay, TClientOneWayProxy extends TClientOneWay, TClientTwoWayProxy extends TClientTwoWay> extends IBuilder<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy> {
    createServerProxy(client: T): Partial<TServerOneWayProxy & TServerTwoWayProxy>;
}
export interface IServerBuilder<T, TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy extends TServerOneWay, TServerTwoWayProxy extends TServerTwoWay, TClientOneWayProxy extends TClientOneWay, TClientTwoWayProxy extends TClientTwoWay> extends IBuilder<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy> {
    createServer(client: T, impl: TServerOneWay & TServerTwoWay): Partial<TServerOneWay & TServerTwoWay & {
        proxy: (TConnection: any) => TClientOneWayProxy & TClientTwoWayProxy;
    }>;
}
export interface IClientProxyBuilder<T, TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy extends TServerOneWay, TServerTwoWayProxy extends TServerTwoWay, TClientOneWayProxy extends TClientOneWay, TClientTwoWayProxy extends TClientTwoWay> extends IBuilder<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy> {
    createClientProxy(client: T): Partial<TClientOneWayProxy & TClientTwoWayProxy>;
}
export interface IClientBuilder<T, TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy extends TServerOneWay, TServerTwoWayProxy extends TServerTwoWay, TClientOneWayProxy extends TClientOneWay, TClientTwoWayProxy extends TClientTwoWay> extends IBuilder<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy> {
    createClient(client: T, clientImpl: TClientOneWay & TClientTwoWay, ...dummy: any[]): TClientOneWay & TClientTwoWay & {
        $proxy(): Partial<TServerOneWayProxy & TServerTwoWayProxy>;
    };
}
export declare class Api<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy> {
    constructor();
    serverOneWayConfig: Partial<{
        [k in keyof (TServerOneWay | TServerOneWayProxy)]: TConfig;
    }>;
    serverTwoWayConfig: Partial<{
        [k in keyof (TServerTwoWay | TServerTwoWayProxy)]: TConfig;
    }>;
    clientOneWayConfig: Partial<{
        [k in keyof (TClientOneWay | TClientOneWayProxy)]: TConfig;
    }>;
    clientTwoWayConfig: Partial<{
        [k in keyof (TClientTwoWay | TClientTwoWayProxy)]: TConfig;
    }>;
    connection<TConnectionNew extends TConnection>(): Api<TConnectionNew, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy>;
    clientToServerOneWay<TIn>(): <TImpl extends TConfig>(impl: TImpl) => Api<TConnection, TServerOneWay & Proxy<TImpl, (this: TServerOneWay & TServerTwoWay & {
        $proxy(socket: TConnection): Partial<TClientOneWayProxy & TClientTwoWayProxy>;
    }, p: TIn, connection?: TConnection) => PromiseLike<void> | void>, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy & Proxy<TImpl, (p: TIn) => PromiseLike<void>>, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy>;
    clientToServer<TIn, TOut>(): <TImpl extends TConfig>(impl: TImpl) => Api<TConnection, TServerOneWay, TServerTwoWay & Proxy<TImpl, (this: TServerOneWay & TServerTwoWay & {
        $proxy(socket: TConnection): Partial<TClientOneWayProxy & TClientTwoWayProxy>;
    }, p: TIn, connection?: TConnection) => TOut | PromiseLike<TOut>>, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy & Proxy<TImpl, (p: TIn) => PromiseLike<TOut>>, TClientOneWayProxy, TClientTwoWayProxy>;
    serverToClientOneWay<TIn>(): <TImpl extends TConfig>(impl: TImpl) => Api<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay & Proxy<TImpl, (p: TIn) => PromiseLike<void> | void>, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy & Proxy<TImpl, (p: TIn) => PromiseLike<void>>, TClientTwoWayProxy>;
    serverToClient<TIn, TOut>(): <TImpl>(impl: TImpl) => Api<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay & Proxy<TImpl, (p: TIn) => TOut | PromiseLike<TOut>>, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy & Proxy<TImpl, (p: TIn) => PromiseLike<TOut>>>;
}
export declare class DualApi<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy extends TServerOneWay, TServerTwoWayProxy extends TServerTwoWay, TClientOneWayProxy extends TClientOneWay, TClientTwoWayProxy extends TClientTwoWay, TOConnection, TOServerOneWay, TOServerTwoWay, TOClientOneWay, TOClientTwoWay, TOServerOneWayProxy extends TOServerOneWay, TOServerTwoWayProxy extends TOServerTwoWay, TOClientOneWayProxy extends TOClientOneWay, TOClientTwoWayProxy extends TOClientTwoWay> extends Api<TConnection & TOConnection, TServerOneWay & TOServerOneWay, TServerTwoWay & TOServerTwoWay, TClientOneWay & TOClientOneWay, TClientTwoWay & TOClientTwoWay, TServerOneWayProxy & TOServerOneWayProxy, TServerTwoWayProxy & TOServerTwoWayProxy, TClientOneWayProxy & TOClientOneWayProxy, TClientTwoWayProxy & TOClientTwoWayProxy> {
    constructor(meta1: Api<TConnection, TServerOneWay, TServerTwoWay, TClientOneWay, TClientTwoWay, TServerOneWayProxy, TServerTwoWayProxy, TClientOneWayProxy, TClientTwoWayProxy>, meta2: Api<TOConnection, TOServerOneWay, TOServerTwoWay, TOClientOneWay, TOClientTwoWay, TOServerOneWayProxy, TOServerTwoWayProxy, TOClientOneWayProxy, TOClientTwoWayProxy>);
}
export declare type ServerWithoutProxy<T extends Api<any, any, any, any, any, any, any, any, any>> = T extends Api<any, infer OW, infer TW, any, any, any, any, any, any> ? OW & TW : any;
export declare type Server<T extends Api<any, any, any, any, any, any, any, any, any>> = ServerWithoutProxy<T> & {
    $proxy(client: any): ClientProxy<T>;
};
export declare type ClientWithoutProxy<T extends Api<any, any, any, any, any, any, any, any, any>> = T extends Api<any, any, any, infer OW, infer TW, any, any, any, any> ? OW & TW : any;
export declare type Client<T extends Api<any, any, any, any, any, any, any, any, any>> = ClientWithoutProxy<T> & {
    $proxy(): ServerProxy<T>;
};
export declare type ServerProxy<T extends Api<any, any, any, any, any, any, any, any, any>> = T extends Api<any, any, any, any, any, infer OW, infer TW, any, any> ? OW & TW : any;
export declare type ClientProxy<T extends Api<any, any, any, any, any, any, any, any, any>> = T extends Api<any, any, any, any, any, any, any, infer OW, infer TW> ? OW & TW : any;
