/**
 * Event object
 */
export type Event<EventName extends string = string, Payload extends unknown = unknown> = {
    [Key in EventName]: Payload;
};
/**
 * Event handler function
 */
export type Handler<News> = undefined extends News ? (news?: News | undefined) => void : (news: News) => void;
/**
 * Event subscription object
 */
export interface Subscription<T extends Event, Key extends keyof T & string> {
    event: Key;
    handler: Handler<T[Key]>;
}
/**
 * Function to subscribe to an event
 */
export type Subscribe<T extends Event> = ReturnType<typeof createSubscribe<T>>;
/**
 * Function to unsubscribe to an event
 */
export type Unsubscribe<T extends Event> = ReturnType<typeof createUnsubscribe<T>>;
/**
 * Options for customizing the subscriber factory
 */
export interface CreateSubscribeOptions {
    /**
     * If `true` the event names are case insenseitive
     */
    caseInsensitive: boolean;
}
/**
 * Options for customizing the unsubscriber factory
 */
export interface CreateUnsubscribeOptions {
    /**
     * If `true` the event names are case insenseitive
     */
    caseInsensitive: boolean;
}
/**
 * Options for how to publish an event
 */
export type PublishOptions = {
    /**
     * If `true` event will *not* be broadcasted gloablly even if `isGlobal` is `true`.
     */
    isNoGlobalBroadcast: boolean;
    /**
     * If `true` event will *not* be broadcasted synchronously even if `async` is `false` globally.
     */
    async: boolean;
};
/**
 * Function to publish an event
 */
export type Publish<T extends Event> = <Key extends keyof T & string>(...args: undefined extends T[Key] ? [key: Key, news?: T[Key], options?: Partial<PublishOptions>] : [key: Key, news: T[Key], options?: Partial<PublishOptions>]) => void;
/**
 * Options for customizing the publisher factory
 */
export interface CreatePublishOptions {
    /**
     * If `true` event will be published globally.
     */
    isGlobal: boolean;
    /**
     * If `true` the event names are case insenseitive
     */
    caseInsensitive: boolean;
    /**
     * If `true` the pub-sub instance publishes events asynchronously (recommended)
     */
    async: boolean;
}
/**
 * Event listener object that stores the event hander and notification times
 */
export interface Listener<News> {
    handler: Handler<News>;
    times: number;
}
/**
 * Event stack object that stores all event listeners
 */
export type Stack<T extends Event> = Partial<{
    [Key in keyof T & string]: Listener<T[Key]>[];
}>;
/**
 * Remove all event listeners
 */
export type Clear = ReturnType<typeof createClear>;
/**
 * Options for customizing the pub-sub instance
 */
export interface PubSubOptions<T extends Event> {
    async: boolean;
    caseInsensitive: boolean;
    stack: Stack<T>;
}
/**
 * The pub-sub instance
 */
export interface PubSub<T extends Event = Event> {
    publish: Publish<T>;
    subscribe: Subscribe<T>;
    unsubscribe: Unsubscribe<T>;
    clear: Clear;
    stack: Stack<T>;
}
/**
 * Setup subscriber
 */
declare const createSubscribe: <T extends Event<string, unknown>>(stack: Stack<T>, options?: Partial<CreateSubscribeOptions>) => <Key extends keyof T & string>(event: Key, handler: Handler<T[Key]>, times?: number) => {
    event: Key;
    handler: Handler<T[Key]>;
};
/**
 * Factory function for creating `unsubscribe`
 */
declare function createUnsubscribe<T extends Event>(stack: Stack<T>, options?: Partial<CreateUnsubscribeOptions>): {
    <Key extends keyof T & string>(subscription: Subscription<T, Key>): void;
    <Key_1 extends keyof T & string>(event: Key_1, handler: Handler<T[Key_1]>): void;
};
/**
 * Factory function for creating `clear()`
 */
declare const createClear: <T extends Event<string, unknown>>(stack: Stack<T>) => () => void;
/**
 * Create a new pub-sub instance
 */
declare const createPubSub: <T extends Event<string, unknown> = Event<string, unknown>>(options?: Partial<PubSubOptions<T>>) => PubSub<T>;
/**
 * Global pub-sub instance
 */
declare const globalPubSub: PubSub;
export { globalPubSub, createPubSub };
export default createPubSub;
