froge
Version:
Jump-start your NodeJS/Bun/... services with dependency & lifecycle management and handy helper methods
57 lines (56 loc) • 3.01 kB
TypeScript
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<{}, {}>;