import type { EmptyObject } from '../../../framework-types/BaseTypes';
import type { BaseContext } from '../../../framework-types/Types';
export type EventBase = {
    timestamp: number;
    type: string;
};
export type EventListener<Event extends object> = (event: Event & EventBase) => void;
export type EventBusContext = BaseContext;
export type EventMap = {
    [key: string]: object;
};
export type EventBus<Events extends EventMap, Type extends Record<string, string> = EmptyObject> = {
    on<Name extends keyof Events & string>(name: Name | `${Name}`, listener: EventListener<Events[Name]>): void;
    off<Name extends keyof Events & string>(name: Name | `${Name}`, listener: EventListener<Events[Name]>): void;
    dispatch<Name extends keyof Events & string>(context: EventBusContext, name: Name | `${Name}`, event: Omit<Events[Name], 'type' | 'timestamp'> & Partial<EventBase>): void;
    readonly Type: Type;
};
type EventMaps<Apis extends object[]> = {
    [key in keyof Apis]: Apis[key] extends {
        events: EventBus<infer Events extends EventMap, Record<string, string>>;
    } ? Events : EmptyObject;
};
type ApiEventTypes<Apis extends object[]> = {
    [key in keyof Apis]: Apis[key] extends {
        events: {
            readonly Type: infer T extends Record<string, string>;
        };
    } ? T : EmptyObject;
};
type WithoutEventBuses<Apis extends object[]> = {
    [key in keyof Apis]: Omit<Apis[key], 'events'>;
};
type MergeEventMaps<EventMaps extends EventMap[]> = EventMaps extends [infer Events extends EventMap] ? Events : EventMaps extends [infer Events extends EventMap, ...infer OtherMaps extends EventMap[]] ? Events & MergeEventMaps<OtherMaps> : EmptyObject;
type MergeRecords<Records extends Record<string, string>[]> = Records extends [infer R extends Record<string, string>] ? R : Records extends [infer R extends Record<string, string>, ...infer Rest extends Record<string, string>[]] ? R & MergeRecords<Rest> : EmptyObject;
type MergeApis<Apis extends object[]> = Apis extends [infer Api] ? Api : Apis extends [infer Api, ...infer RemainingApis extends object[]] ? Api & MergeApis<RemainingApis> : EmptyObject;
export type MergeApisAndEventBuses<Apis extends object[]> = MergeApis<WithoutEventBuses<Apis>> & {
    events: EventBus<MergeEventMaps<EventMaps<Apis>>, MergeRecords<ApiEventTypes<Apis>>>;
};
export declare enum EventBusExportNames {
    CreateEventBus = "create-event-bus",
    ExtendEventBusTypes = "extend-event-bus-types"
}
export {};
