import envHelper from './env';
import { type Plug } from './plug';
type MaybePromise<T> = T | Promise<T>;
type UnpackPromise<T> = T extends Promise<infer R> ? R : T;
type UnpackAsyncFunction<T> = T extends (...args: any) => infer R ? UnpackPromise<R> : T;
type UnpackAsyncMap<Map extends {}> = {
    [K in keyof Map]: UnpackAsyncFunction<Map[K]>;
};
export interface FrogeContext<ServiceMap extends {}> {
    services: ServiceMap;
    envs: typeof envHelper;
    log: (...items: any) => void;
    plug: <T extends NonNullable<unknown>>() => Plug<T>;
}
type PlugCallback<T extends keyof ServiceMap, ServiceMap extends {}> = ServiceMap[T] extends Plug<infer S> ? (ctx: FrogeContext<ServiceMap>) => MaybePromise<() => S> : never;
export interface FrogeConfig {
    /** Start services which don't depend on each other in parallel */
    parallelStartGroups: boolean;
    /** Stop services which don't depend on each other in parallel */
    parallelStopGroups: boolean;
    /** Kill the process if shutdown took longer than expected */
    gracefulShutdownTimeoutMs?: number;
    /** Force exit the current process after shutdown is completed */
    forceExitAfterShutdown: boolean;
    /** Print info logs */
    verbose: boolean;
}
declare class FrogeServer<ServiceMap extends Record<string, any>, ServiceGroups extends Record<string, Record<string, any>>> {
    private map;
    private groups;
    private config;
    configure(config: Partial<FrogeConfig>): this;
    readonly services: ServiceMap;
    up<NewServices extends ({
        [T in keyof ServiceMap]?: PlugCallback<T, ServiceMap>;
    } & Record<string, (ctx: FrogeContext<ServiceMap>) => any>), GroupKey extends string | undefined>(services: NewServices, group?: GroupKey): FrogeServer<ServiceMap & UnpackAsyncMap<NewServices>, ServiceGroups & (GroupKey extends string ? (GroupKey extends keyof ServiceGroups ? never : Record<GroupKey, ServiceMap & UnpackAsyncMap<NewServices>>) : {})>;
    down<NewDestroyers extends {
        [T in keyof ServiceMap]?: (service: ServiceMap[T]) => MaybePromise<void>;
    }>(destroyers: NewDestroyers): this;
    use<ServiceMap2 extends {
        [T in keyof ServiceMap]?: never;
    } & Record<string, any>, ServiceGroups2 extends {
        [T in keyof ServiceGroups]?: never;
    } & Record<string, Record<string, any>>>(other: FrogeServer<ServiceMap2, ServiceGroups2>): FrogeServer<ServiceMap & ServiceMap2, ServiceGroups & ServiceGroups2>;
    private startInternal;
    only<K extends keyof ServiceMap & string>(key: K): Promise<ServiceMap[K]>;
    start(): Promise<this>;
    stop(reasonText?: string): Promise<void>;
    launch(): Promise<this>;
    shutdown(reasonText?: string): Promise<void>;
}
export type { FrogeServer };
export { envHelper as envs };
export type { Plug } from './plug';
export type InferContext<S extends FrogeServer<any, any>, K> = S extends FrogeServer<any, infer G> ? K extends keyof G ? FrogeContext<G[K]> : never : never;
export default function froge(): FrogeServer<{}, {}>;
