import { RedisOptions } from 'ioredis';
export { Cluster, Redis } from 'ioredis';
import { IClientOptions } from 'mqtt';

/**
 * @boringnode/bus
 *
 * @license MIT
 * @copyright BoringNode
 */

type TransportFactory = () => Transport;
/**
 * A Duration can be a number in milliseconds or a string formatted as a duration
 *
 * Formats accepted are :
 * - Simple number in milliseconds
 * - String formatted as a duration. Uses https://github.com/lukeed/ms under the hood
 */
type Duration = number | string;
interface ManagerConfig<KnownTransports extends Record<string, TransportConfig>> {
    default?: keyof KnownTransports;
    transports: KnownTransports;
}
interface TransportConfig {
    transport: TransportFactory;
    retryQueue?: RetryQueueOptions;
}
interface RedisTransportConfig extends RedisOptions {
    /**
     * If true, we will use `messageBuffer` event instead of `message` event
     * that is emitted by ioredis. `messageBuffer` will returns a buffer instead
     * of a string and this is useful when you are dealing with binary data.
     */
    useMessageBuffer?: boolean;
}
interface RedisTransportOptions {
    /**
     * If true, we will use `messageBuffer` event instead of `message` event
     * that is emitted by ioredis. `messageBuffer` will returns a buffer instead
     * of a string and this is useful when you are dealing with binary data.
     */
    useMessageBuffer?: boolean;
}
declare enum MqttProtocol {
    MQTT = "mqtt",
    MQTTS = "mqtts",
    TCP = "tcp",
    TLS = "tls",
    WS = "ws",
    WSS = "wss",
    WXS = "wxs",
    ALIS = "alis"
}
interface MqttTransportConfig {
    host: string;
    port?: number;
    protocol?: MqttProtocol;
    options?: IClientOptions;
}
interface Transport {
    setId: (id: string) => Transport;
    onReconnect: (callback: () => void) => void;
    publish: (channel: string, message: Serializable) => Promise<void>;
    subscribe: <T extends Serializable>(channel: string, handler: SubscribeHandler<T>) => Promise<void>;
    unsubscribe: (channel: string) => Promise<void>;
    disconnect: () => Promise<void>;
}
interface TransportMessage<T extends Serializable = any> {
    busId: string;
    payload: T;
}
interface TransportEncoder {
    encode: (message: TransportMessage) => string | Buffer;
    decode: <T>(data: string | Buffer) => {
        busId: string;
        payload: T;
    };
}
interface RetryQueueOptions {
    enabled?: boolean;
    removeDuplicates?: boolean;
    maxSize?: number | null;
    retryInterval?: Duration | false;
}
type SubscribeHandler<T extends Serializable> = (payload: T) => void | Promise<void>;
type Serializable = string | number | boolean | null | Serializable[] | {
    [key: string]: Serializable;
};

export { type Duration, type ManagerConfig, MqttProtocol, type MqttTransportConfig, type RedisTransportConfig, type RedisTransportOptions, type RetryQueueOptions, type Serializable, type SubscribeHandler, type Transport, type TransportConfig, type TransportEncoder, type TransportFactory, type TransportMessage };
