export type primitive = number | string | null | undefined | symbol; export interface IDestroyable { destroy(): void; } export interface DependencyOptions { optional?: boolean; default?: any; } export interface LazyDependencyOptions extends DependencyOptions { lazy: true; } export type ExtractService = K extends keyof S ? S[K] : never; export type ExtractDependency = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService : ExtractService : D extends { $type: new (...args: any[]) => infer I } ? I : D extends { $factory: (...args: any[]) => infer R } ? R : WalkDependencies; export type WalkDependencies = D extends primitive ? D : { [K in keyof D]: ExtractDependency }; export type InferReferenceType, O> = O extends { default: infer X } ? (TypeOfService | X) : O extends { optional: true } ? (TypeOfService | undefined) : TypeOfService; export interface Resolver { , O extends LazyDependencyOptions>(this: void, name: K, opts: O): () => InferReferenceType; , O extends DependencyOptions>(this: void, name: K, opts?: O): InferReferenceType; } export interface DescriptorBuilder { factory(f: (resolve: Resolver) => T): void; build(): DescriptorBuilder; override(name: K, builder: RegistrationBuilder): this; override(services: { [name in K]: RegistrationBuilder }): this; lifetime(lifetime: "singleton", typeId: any): this; lifetime(lifetime: ILifetime | Exclude): this; cleanup(cb: (item: T) => void): this; value(v: T): void; } export type RegistrationBuilder = (d: DescriptorBuilder, ct?: ICancellation) => void | Promise; export type FluentRegistrations = { [k in K]: RegistrationBuilder }; export interface Descriptor { activate(context: ActivationContext): T; } export type ServiceMap = { [k in keyof S]: Descriptor; }; export type ContainerKeys = keyof S | keyof ContainerProvided; export type TypeOfService = K extends keyof ContainerProvided ? ContainerProvided[K] : K extends keyof S ? S[K] : never; export type ContainerServiceMap = { [K in ContainerKeys]: Descriptor>; }; export type PartialServiceMap = { [k in keyof S]?: Descriptor; }; export interface ServiceLocator { resolve>(name: K, def?: TypeOfService): TypeOfService; resolve>(name: K, def?: undefined): TypeOfService | undefined; } export interface ServiceContainer extends ServiceLocator, IDestroyable { getLifetimeManager(): LifetimeManager; register(name: K, service: Descriptor): this; register(services: PartialServiceMap): this; createChildContainer(): ServiceContainer; } export interface ContainerProvided { container: ServiceLocator; childContainer: ServiceContainer; } export type ContainerRegistered = /*{ [K in Exclude>]: S[K]; };*/ Exclude>; export type ActivationType = "singleton" | "container" | "hierarchy" | "context" | "call"; /** * Интерфейс для управления жизнью экземпляра объекта. Каждая регистрация имеет * свой собственный объект `ILifetime`, который создается при первой активации */ export interface ILifetime { /** Проверяет, что уже создан экземпляр объекта */ has(): boolean; get(): any; initialize(context: ActivationContext): void; store(item: any, cleanup?: (item: any) => void): void; }