interfaces.d.ts
291 lines
| 12.0 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r15 | import { ActivationItem } from "../ts/ActivationError"; | |
| import { key } from "../ts/traits"; | |||
| export interface IDestroyable { | |||
| destroy(): void; | |||
| } | |||
| /** | |||
| * @template S Карта доступных зависимостей | |||
| */ | |||
| export interface Resolver<S> { | |||
| /** | |||
| * Функция для разрешения зависимостей, поддерживает создание фабричных методов, | |||
| * отложенную активацию и значение по-умолчанию для сервисов | |||
| * @template K Ключ сервиса из {@linkcode S} | |||
| * @template O Тип параметра {@linkcode opts} используется для выведения типа | |||
| * возвращаемого значения. | |||
| * @param name Ключ сервиса, который будет разрешен. | |||
| * @param {boolean=} opts.lazy Признак того, что требуется отложенная активация, | |||
| * будет возвращен фабричный метод для получения зависимости. Если не указан, | |||
| * то считается `false`. | |||
| * @param {any=} opts.default Значение по умолчанию, если в контейнере указанный | |||
| * сервис не зарегистрирован | |||
| * @returns Либо фабричный метод для получения зависимости, либо значение зависимости | |||
| * @throws Error Если зависимость не найдена и не предоставлено значение по-умолчанию | |||
| */ | |||
| <K extends keyof S, O extends { lazy: true; }>(name: K, opts?: O): () => NonNullable<S[K]> | InferDefault<O>; | |||
| <K extends keyof S, O extends { lazy?: false; }>(name: K, opts?: O): NonNullable<S[K]> | InferDefault<O>; | |||
| } | |||
| export type DepsMap<S> = { | |||
| [k in key]: Refs<S> | keyof S; | |||
| }; | |||
| export type DescriptorDepsMap<S> = { | |||
| [k in key]: Refs<S>; | |||
| }; | |||
| export type Refs<S> = { | |||
| [k in keyof S]: Ref<k, S[k]>; | |||
| }[keyof S]; | |||
| export type Ref<K extends key, D> = { | |||
| /** The name of the service */ | |||
| name: K; | |||
| /** Make a lazy reference, the resolved dependency will be a function */ | |||
| lazy?: boolean; | |||
| /** The default value for the case where the service isn't defined. | |||
| * When specified the dependency becomes optional, the default value can be | |||
| * `null` or `undefined` | |||
| */ | |||
| default?: D; | |||
| }; | |||
| export type Lazy<T, L extends boolean> = L extends true ? () => T : T; | |||
| /** Возвращает тип свойства `default` в типе {@link T} */ | |||
| export type InferDefault<T> = T extends { default: infer D } ? D : never; | |||
| export type IsLazy<R> = R extends { lazy: infer L } ? | |||
| L extends true ? true : false : | |||
| false; | |||
| export type Resolve<S, R> = | |||
| R extends keyof S ? NonNullable<S[R]> : | |||
| R extends Ref<infer K, unknown> ? | |||
| K extends keyof S ? | |||
| Lazy<NonNullable<S[K]> | InferDefault<R>, IsLazy<R>> : | |||
| never : | |||
| never; | |||
| /** | |||
| * Интерфейс для конфигурирования сервиса в контейнере. Конфигурирование сервиса | |||
| * состоит из настройки различных параметров вызовами методов {@linkcode wants}, | |||
| * {@linkcode lifetime}, {@linkcode override}, {@linkcode cleanup}. Завершение настройки | |||
| * сервиса осуществляется вызовом одного из методов {@linkcode factory} либо | |||
| * {@linkcode value}. | |||
| * | |||
| * @template S Карта сервисов контейнера, доступных при описании дескриптора | |||
| * @template T Тип сервиса | |||
| * @template R Карта зависимостей, которая передается параметром фабрике | |||
| * @template U Имена пользовательских сервисов, доступных для переопределения | |||
| */ | |||
| export interface IDescriptorBuilder<S, T, R, U extends keyof S> { | |||
| /** Указывает фабрика для создания экземпляра сервиса, фабрика передается | |||
| * в виде параметра. При вызове фабрике будет передан объект с зависимостями, | |||
| * которые были предварительно указаны вызовами метода `wants(...)` | |||
| * | |||
| * Вызов данного метода завершает конфигурирование сервиса. | |||
| * | |||
| * @param f Фабрика для создания экземпляра сервиса. | |||
| */ | |||
| factory(f: (refs: R) => NonNullable<T>): void; | |||
| /** | |||
| * Используется для указания зависимостей, которые потребуются фабричному | |||
| * методу при создании нового экземпляра сервиса. Данный метод может быть | |||
| * вызван несколько раз подряд, при этом вызовы этого метода имеют | |||
| * кумулятивный эффект. | |||
| * | |||
| * @template X Тип объекта с зависимостями, которые требуется получить при | |||
| * создании экземпляра фабрики при помощи фабричного метода. | |||
| * @param refs Объект с описанием зависимостей | |||
| * @returns Возвращает дескриптор сервиса, в котором указаны необходимые | |||
| * зависимости | |||
| */ | |||
| wants<X extends DepsMap<S> & Record<keyof R & keyof X, never>>(refs: X): | |||
| IDescriptorBuilder<S, T, R & { | |||
| [k in keyof X]: Resolve<S, X[k]>; | |||
| }, U> | |||
| override<K extends U>(name: K, builder: BuildDescriptorFn<S, S[K], U>): this; | |||
| override<X extends ConfigurationMapConstraint<S, U, keyof X>>(services: X): this; | |||
| lifetime(lifetime: "singleton", typeId: string | number | object): this; | |||
| lifetime(lifetime: ILifetime<T> | Exclude<ActivationType, "singleton">): this; | |||
| /** Указывает функцию для освобождения экземпляра сервиса для случаев, когда | |||
| * время жизни привязано к контейнеру. | |||
| */ | |||
| cleanup(cb: (item: T) => void): this; | |||
| /** | |||
| * Регистрирует в контейнере постоянное значение в качестве реализации сервиса. | |||
| * | |||
| * @param v Экземпляр реализации сервиса. | |||
| */ | |||
| value(v: NonNullable<T>): void; | |||
| } | |||
| export type BuildDescriptorFn<S, T, U extends keyof S> = (d: IDescriptorBuilder<S, T, Record<never, never>, U>) => void; | |||
| /** | |||
| * Конфигурация контейнера, состоит из набора функций, которые выполняют конфигурацию. | |||
| * | |||
| * Все параметры конфигурации являются обязательными, если требуется ввести | |||
| * необязательные параметры, то нужно ограничить параметр типа {@linkcode K} | |||
| * | |||
| * @template S Сервисы доступные в контейнере | |||
| * @template K Сервисы участвующие в конфигурации | |||
| */ | |||
| export type ConfigurationMap<S, K extends keyof S, U extends keyof S> = { | |||
| [k in K]-?: BuildDescriptorFn<S, S[k], U> | |||
| }; | |||
| export type ConfigurationMapConstraint<S, U extends keyof S, X extends string | number | symbol> = { | |||
| [k in X]-?: k extends U ? BuildDescriptorFn<S, S[k], U> : never; | |||
| }; | |||
| /** | |||
| * The type constraint useful to restrict type parameters to prevent defining | |||
| * the services with the {@link ContainerKeys} names. | |||
| * | |||
| * The constraint doesn't exclude using this keys but declares them as `never` | |||
| * which effectively will lead using this keys to the error. | |||
| */ | |||
| export type ContainerServicesConstraint<S> = { | |||
| [k in keyof S]: k extends ContainerKeys ? never : S[k]; | |||
| }; | |||
| export interface Descriptor<S, T> { | |||
| /** This flags indicates that this registration can be replaced or overridden. */ | |||
| readonly configurable?: boolean; | |||
| activate(context: IActivationContext<S>, stack: ActivationItem[]): NonNullable<T>; | |||
| } | |||
| /** The context used to initialize lifetime instance {@linkcode ILifetime} */ | |||
| export interface ILifetimeContext { | |||
| contextSlot<T>(slotId: string | number): ILifetimeSlot<T>; | |||
| /** | |||
| * | |||
| * @param slotId | |||
| */ | |||
| scopeSlot<T>(level: number, slotId: string | number): ILifetimeSlot<T>; | |||
| hierarchySlot<T>(slotId: string | number): ILifetimeSlot<T>; | |||
| } | |||
| export interface IActivationContext<S> extends ILifetimeContext { | |||
| /** | |||
| * @param overrides | |||
| * @param action | |||
| * @throws | |||
| */ | |||
| withOverrides<X>(overrides: DescriptorMap<S>, action: () => X): X; | |||
| selfContainer(): ServiceLocator<S>; | |||
| createChildContainer(): IContainerBuilder<S, keyof S>; | |||
| resolve<K extends keyof S>(name: K, stack: ActivationItem[]): NonNullable<S[K]>; | |||
| resolve<K extends keyof S, T>(name: K, stack: ActivationItem[], def: T): NonNullable<S[K]> | T; | |||
| } | |||
| /** | |||
| * Descriptors map for the specified services {@linkcode S}. All entries are | |||
| * optional regardless the required or optional services in the original map. | |||
| * | |||
| * @template S Сервисы контекста активации | |||
| * @template U Карта сервисов которые создаются дескрипторами | |||
| */ | |||
| export type DescriptorMap<S> = { | |||
| [k in keyof S]?: Descriptor<S, S[k]>; | |||
| }; | |||
| export type ContainerKeys = keyof ContainerProvided<object>; | |||
| export type ContainerProvided<S, U extends keyof S = keyof S> = { | |||
| container: ServiceLocator<ContainerProvided<S>>; | |||
| childContainer: IContainerBuilder<S, U>; | |||
| }; | |||
| /** | |||
| * Таблица сервисов, которые предоставляет контейнер. | |||
| * | |||
| * Сервисы, предоставляемые контейнером не могут быть null или undefined. | |||
| */ | |||
| export type ContainerServices<S> = { | |||
| [k in (keyof S) | ContainerKeys]: | |||
| k extends ContainerKeys ? ContainerProvided<S>[k] : | |||
| k extends keyof S ? S[k] : never | |||
| }; | |||
| /** | |||
| * Returns the service declared in the type map {@link S}. | |||
| * | |||
| * | |||
| */ | |||
| export interface ServiceLocator<S> { | |||
| resolve<K extends keyof S>(name: K): NonNullable<S[K]>; | |||
| resolve<K extends keyof S, T>(name: K, def: T): NonNullable<S[K]> | T; | |||
| } | |||
| export interface IContainerBuilder<S, U extends keyof S> { | |||
| createServiceBuilder<K extends U>(name: K): | |||
| IDescriptorBuilder<S, S[K], Record<never, never>, U>; | |||
| build(): ServiceLocator<S>; | |||
| } | |||
| export type ActivationType = "singleton" | "container" | "hierarchy" | "context" | "call"; | |||
| /** | |||
| * Интерфейс для управления жизнью экземпляра объекта. Каждая регистрация имеет | |||
| * свой собственный объект `ILifetime`, который создается при первой активации | |||
| */ | |||
| export type ILifetime<T> = (context: ILifetimeContext) => ILifetimeSlot<T>; | |||
| export interface ILifetimeSlot<T> { | |||
| has(): boolean; | |||
| get(): NonNullable<T>; | |||
| /** | |||
| * Initializes the slot, if the slot is already initialized returns false, | |||
| * otherwise returns true. This method is used to detect cyclic references. | |||
| */ | |||
| initialize(): boolean; | |||
| store(item: NonNullable<T>, cleanup?: (item: NonNullable<T>) => void): void; | |||
| /** | |||
| * Removes the slot from the lifetime manager. The inner value will not be | |||
| * disposed. If the slot is cleaned up calling this method has no effect. | |||
| */ | |||
| remove(): void; | |||
| /** | |||
| * Disposed inner value of this slot. | |||
| */ | |||
| cleanup(): void; | |||
| } | |||
| export interface ILifetimeManager extends IDestroyable { | |||
| slot<T>(id: string | number): ILifetimeSlot<T>; | |||
| } | |||
| export type ExtractRequired<T, K extends keyof T = keyof T> = { [p in K as (undefined extends T[p] ? never : p)]-?: T[p] }; | |||
| export type ExtractRequiredKeys<T, K extends keyof T = keyof T> = { [p in K]-?: undefined extends T[p] ? never : p }[K]; |
