interfaces.ts
183 lines
| 7.9 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r4 | import { key } from "./traits"; | ||
|
|
r1 | |||
|
|
r0 | export interface IDestroyable { | ||
| destroy(): void; | ||||
| } | ||||
|
|
r1 | /** | ||
| * @template S Карта доступных зависимостей | ||||
| */ | ||||
|
|
r8 | export interface Resolver<S> { | ||
|
|
r1 | /** | ||
| * Функция для разрешения зависимостей, поддерживает создание фабричных методов, | ||||
| * отложенную активацию и значение по-умолчанию для сервисов | ||||
| * @template K Ключ сервиса из {@link S} | ||||
| * @template O Тип параметра {@link opts} используется для выведения типа | ||||
| * возвращаемого значения. | ||||
| * @param name Ключ сервиса, который будет разрешен. | ||||
| * @param {boolean=} opts.lazy Признак того, что требуется отложенная активация, | ||||
| * будет возвращен фабричный метод для получения зависимости. Если не указан, | ||||
| * то считается `false`. | ||||
| * @param {any=} opts.default Значение по умолчанию, если в контейнере указанный | ||||
| * сервис не зарегистрирован | ||||
| * @returns Либо фабричный метод для получения зависимости, либо значение зависимости | ||||
| * @throws Error Если зависимость не найдена и не предоставлено значение по-умолчанию | ||||
| */ | ||||
| <K extends keyof S, O extends { lazy: true; default?: unknown }>(name: K, opts?: O): () => (O extends { default: infer T } ? T : never) | NonNullable<S[K]>; | ||||
| <K extends keyof S, O extends { lazy?: false; default?: unknown }>(name: K, opts?: O): (O extends { default: infer T } ? T : never) | NonNullable<S[K]>; | ||||
|
|
r0 | } | ||
|
|
r8 | export type DepsMap<S> = { | ||
| [k in key]: Refs<S> | keyof S; | ||||
|
|
r7 | }; | ||
|
|
r8 | export type Refs<S> = { | ||
|
|
r7 | [k in keyof S]: Ref<k, boolean, S[k]>; | ||
|
|
r8 | }[keyof S]; | ||
|
|
r7 | |||
| export type Ref<K extends key, L extends boolean, D> = { name: K, lazy?: L, default?: D | null }; | ||||
|
|
r4 | |||
|
|
r7 | export type Lazy<T, L extends boolean> = L extends true ? () => T : T; | ||
| export type InferDefault<T> = T extends { default: infer D } ? D : never; | ||||
|
|
r4 | |||
|
|
r8 | export type Resolve<S, R> = | ||
|
|
r7 | R extends keyof S ? NonNullable<S[R]> : | ||
|
|
r8 | R extends Ref<infer K, infer L, unknown> ? | ||
| K extends keyof S ? Lazy<NonNullable<S[K]> | InferDefault<R>, L> : | ||||
| never : | ||||
|
|
r7 | never; | ||
|
|
r4 | |||
|
|
r8 | /** | ||
| * Интерфейс для конфигурирования сервиса в контейнере | ||||
| */ | ||||
| export interface IDescriptorBuilder<S, T, R, O extends keyof S> { | ||||
|
|
r1 | |||
|
|
r8 | /** Указывает фабрика для создания экземпляра сервиса, фабрика передается | ||
| * в виде параметра. При вызове фабрике будет передан объект с зависимостями, | ||||
| * которые были предварительно указаны вызовами метода `wants(...)` | ||||
|
|
r1 | * | ||
|
|
r8 | * Вызов данного метода завершает конфигурирование сервиса. | ||
| * | ||||
| * @param f Фабрика для создания экземпляра сервиса | ||||
|
|
r1 | */ | ||
|
|
r4 | factory(f: (refs: R) => T): void; | ||
|
|
r8 | /** | ||
| * Используется для указания зависимостей, которые потребуются фабричному | ||||
| * методу при создании нового экземпляра сервиса. Данный метод может быть | ||||
| * вызван несколько раз подряд, при этом вызовы этого метода имеют | ||||
| * кумулятивный эффект. | ||||
| * | ||||
| * @template X Тип объекта с зависимостями, которые требуется получить при | ||||
| * создании экземпляра фабрики при помощи фабричного метода. | ||||
| * @param refs Объект с описанием зависимостей | ||||
| * @returns Возвращает дескриптор сервиса, в котором указаны необходимые | ||||
| * зависимости | ||||
| */ | ||||
|
|
r7 | wants<X extends DepsMap<S> & Record<keyof R & keyof X, never>>(refs: X): | ||
|
|
r4 | IDescriptorBuilder<S, T, R & { | ||
|
|
r7 | [k in keyof X]: Resolve<S, X[k]>; | ||
|
|
r6 | }, O> | ||
|
|
r0 | |||
|
|
r6 | override<K extends O>(name: K, builder: RegistrationBuilder<S, NonNullable<S[K]>>): this; | ||
| override<K extends O>(services: { [name in K]: RegistrationBuilder<S, NonNullable<S[K]>> }): this; | ||||
|
|
r0 | |||
|
|
r1 | lifetime(lifetime: "singleton", typeId: string | number | object): this; | ||
| lifetime(lifetime: ILifetime<T> | Exclude<ActivationType, "singleton">): this; | ||||
|
|
r0 | |||
|
|
r8 | /** Указывает функцию для освобождения экземпляра сервиса для случаев, когда | ||
| * время жизни привязано к контейнеру. | ||||
| */ | ||||
|
|
r0 | cleanup(cb: (item: T) => void): this; | ||
|
|
r8 | /** | ||
| * Регистрирует в контейнере постоянное значение в качестве реализации сервиса. | ||||
| * | ||||
| * @param v Экземпляр реализации сервиса. | ||||
| */ | ||||
|
|
r0 | value(v: T): void; | ||
| } | ||||
|
|
r8 | export type RegistrationBuilder<S, T> = (d: IDescriptorBuilder<S, T, object, ConfigurableKeys<S>>) => void; | ||
|
|
r0 | |||
|
|
r6 | export type RegistrationBuildersMap<S extends Configurable<S>, K extends keyof S = keyof S> = { | ||
|
|
r5 | [k in K]-?: RegistrationBuilder<ContainerServices<S>, NonNullable<S[k]>> | ||
|
|
r1 | }; | ||
|
|
r0 | |||
|
|
r8 | export interface Descriptor<S, T> { | ||
|
|
r5 | activate(context: IActivationContext<S>): T; | ||
|
|
r0 | } | ||
|
|
r8 | export interface IActivationContext<S> extends ServiceLocator<S> { | ||
|
|
r5 | createLifetime<T>(): ILifetime<T>; | ||
| createContainerLifetime<T>(): ILifetime<T>; | ||||
| } | ||||
|
|
r8 | export type RegistrationMap<S, K extends keyof S = keyof S> = { | ||
|
|
r1 | [k in K]-?: Descriptor<S, S[k]>; | ||
|
|
r0 | }; | ||
|
|
r8 | export interface ContainerProvided<S> { | ||
|
|
r1 | container: ServiceLocator<ContainerServices<S>>; | ||
|
|
r5 | childContainer: IContainerBuilder<S>; | ||
|
|
r1 | } | ||
|
|
r8 | export type Configurable<S> = { [k in keyof S]: k extends ProvidedKeys ? never : S[k]; }; | ||
|
|
r1 | |||
|
|
r5 | export type ProvidedKeys = keyof ContainerProvided<never>; | ||
|
|
r1 | |||
|
|
r8 | export type ContainerServices<S> = | ||
| { [k in keyof S as k extends ProvidedKeys ? never: k]: S[k] } & | ||||
| ContainerProvided<S>; | ||||
|
|
r1 | |||
|
|
r8 | export type ConfigurableKeys<S> = Exclude<keyof S, ProvidedKeys>; | ||
|
|
r1 | |||
|
|
r8 | export type ConfigurableServices<S> = Pick<S, ConfigurableKeys<S>>; | ||
|
|
r0 | |||
|
|
r8 | export type ContainerKeys<S> = keyof S | ProvidedKeys; | ||
|
|
r5 | |||
|
|
r8 | export interface ServiceLocator<S> { | ||
|
|
r1 | resolve<K extends keyof S>(name: K): NonNullable<S[K]>; | ||
| resolve<K extends keyof S, T>(name: K, def: T): NonNullable<S[K]> | T; | ||||
|
|
r0 | } | ||
|
|
r1 | export interface LifetimeContainer { | ||
| createLifetime<T>(): ILifetime<T>; | ||||
| } | ||||
|
|
r8 | export interface ServiceContainer<S> extends | ||
|
|
r5 | ServiceLocator<ContainerServices<S>>, | ||
| IDestroyable { | ||||
|
|
r1 | |||
|
|
r5 | createChildContainer(): IContainerBuilder<S>; | ||
| } | ||||
|
|
r0 | |||
|
|
r8 | export interface IContainerBuilder<S> { | ||
|
|
r6 | createServiceBuilder<K extends keyof S>(name: K): IDescriptorBuilder<S, NonNullable<S[K]>, object, keyof S>; | ||
|
|
r5 | |||
| build(): ServiceContainer<S>; | ||||
|
|
r0 | } | ||
| export type ActivationType = "singleton" | "container" | "hierarchy" | "context" | "call"; | ||||
| /** | ||||
| * Интерфейс для управления жизнью экземпляра объекта. Каждая регистрация имеет | ||||
| * свой собственный объект `ILifetime`, который создается при первой активации | ||||
| */ | ||||
|
|
r1 | export interface ILifetime<T> { | ||
|
|
r0 | /** Проверяет, что уже создан экземпляр объекта */ | ||
| has(): boolean; | ||||
|
|
r1 | get(): T; | ||
|
|
r5 | initialize(context: IActivationContext<object>): void; | ||
|
|
r0 | |||
|
|
r1 | store(item: T, cleanup?: (item: T) => void): void; | ||
| } | ||||
|
|
r0 | |||
|
|
r2 | export type ExtractRequired<T, K extends keyof T = keyof T> = { [p in K as (undefined extends T[p] ? never : p)]-?: T[p] }; | ||
|
|
r1 | |||
