##// END OF EJS Templates
WIP lifetime, service descriptors
WIP lifetime, service descriptors

File last commit:

r14:3f8a82c8ce73 default
r14:3f8a82c8ce73 default
Show More
interfaces.ts
272 lines | 11.5 KiB | video/mp2t | TypeScriptLexer
cin
WIP service descriptors
r13 import { ContainerBuilder } from "./ContainerBuilder";
cin
Removed ContextResolver, added DescriptoBuilder.wants(...), dependencies are declared statically
r4 import { key } from "./traits";
cin
working on fluent configuration
r1
cin
initial commit
r0 export interface IDestroyable {
destroy(): void;
}
cin
working on fluent configuration
r1 /**
* @template S Карта доступных зависимостей
*/
cin
working on typings
r8 export interface Resolver<S> {
cin
working on fluent configuration
r1 /**
* Функция для разрешения зависимостей, поддерживает создание фабричных методов,
* отложенную активацию и значение по-умолчанию для сервисов
cin
almost woking typings
r9 * @template K Ключ сервиса из {@linkcode S}
* @template O Тип параметра {@linkcode opts} используется для выведения типа
cin
working on fluent configuration
r1 * возвращаемого значения.
* @param name Ключ сервиса, который будет разрешен.
* @param {boolean=} opts.lazy Признак того, что требуется отложенная активация,
* будет возвращен фабричный метод для получения зависимости. Если не указан,
* то считается `false`.
* @param {any=} opts.default Значение по умолчанию, если в контейнере указанный
* сервис не зарегистрирован
* @returns Либо фабричный метод для получения зависимости, либо значение зависимости
* @throws Error Если зависимость не найдена и не предоставлено значение по-умолчанию
*/
cin
almost woking typings
r9 <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>;
cin
initial commit
r0 }
cin
working on typings
r8 export type DepsMap<S> = {
[k in key]: Refs<S> | keyof S;
cin
improved typings
r7 };
cin
working on typings
r8 export type Refs<S> = {
cin
almost woking typings
r9 [k in keyof S]: Ref<k, S[k]>;
cin
working on typings
r8 }[keyof S];
cin
improved typings
r7
cin
almost woking typings
r9 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 | null
};
cin
Removed ContextResolver, added DescriptoBuilder.wants(...), dependencies are declared statically
r4
cin
improved typings
r7 export type Lazy<T, L extends boolean> = L extends true ? () => T : T;
cin
almost woking typings
r9 /** Возвращает тип свойства `default` в типе {@link T} */
cin
improved typings
r7 export type InferDefault<T> = T extends { default: infer D } ? D : never;
cin
Removed ContextResolver, added DescriptoBuilder.wants(...), dependencies are declared statically
r4
cin
almost woking typings
r9 export type InferLazy<R> = R extends { lazy: infer L } ?
L extends true ? true : false :
false;
cin
working on typings
r8 export type Resolve<S, R> =
cin
improved typings
r7 R extends keyof S ? NonNullable<S[R]> :
cin
almost woking typings
r9 R extends Ref<infer K, unknown> ?
K extends keyof S ?
Lazy<NonNullable<S[K]> | InferDefault<R>, InferLazy<R>> :
cin
working on typings
r8 never :
cin
improved typings
r7 never;
cin
Removed ContextResolver, added DescriptoBuilder.wants(...), dependencies are declared statically
r4
cin
working on typings
r8 /**
cin
almost woking typings
r9 * Интерфейс для конфигурирования сервиса в контейнере. Конфигурирование сервиса
* состоит из настройки различных параметров вызовами методов {@linkcode wants},
* {@linkcode lifetime}, {@linkcode override}, {@linkcode cleanup}. Завершение настройки
* сервиса осуществляется вызовом одного из методов {@linkcode factory} либо
* {@linkcode value}.
*
* @template S Карта сервисов контейнера, доступных при описании дескриптора
* @template T Тип сервиса
* @template R Карта зависимостей, которая передается параметром фабрике
* @template U Имена пользовательских сервисов, доступных для переопределения
cin
working on typings
r8 */
cin
almost woking typings
r9 export interface IDescriptorBuilder<S, T, R, U extends keyof S> {
cin
working on fluent configuration
r1
cin
working on typings
r8 /** Указывает фабрика для создания экземпляра сервиса, фабрика передается
* в виде параметра. При вызове фабрике будет передан объект с зависимостями,
* которые были предварительно указаны вызовами метода `wants(...)`
cin
working on fluent configuration
r1 *
cin
working on typings
r8 * Вызов данного метода завершает конфигурирование сервиса.
*
cin
almost woking typings
r9 * @param f Фабрика для создания экземпляра сервиса.
cin
working on fluent configuration
r1 */
cin
almost woking typings
r9 factory(f: (refs: R) => NonNullable<T>): void;
cin
Removed ContextResolver, added DescriptoBuilder.wants(...), dependencies are declared statically
r4
cin
working on typings
r8 /**
* Используется для указания зависимостей, которые потребуются фабричному
* методу при создании нового экземпляра сервиса. Данный метод может быть
* вызван несколько раз подряд, при этом вызовы этого метода имеют
* кумулятивный эффект.
*
* @template X Тип объекта с зависимостями, которые требуется получить при
* создании экземпляра фабрики при помощи фабричного метода.
* @param refs Объект с описанием зависимостей
* @returns Возвращает дескриптор сервиса, в котором указаны необходимые
* зависимости
*/
cin
improved typings
r7 wants<X extends DepsMap<S> & Record<keyof R & keyof X, never>>(refs: X):
cin
Removed ContextResolver, added DescriptoBuilder.wants(...), dependencies are declared statically
r4 IDescriptorBuilder<S, T, R & {
cin
improved typings
r7 [k in keyof X]: Resolve<S, X[k]>;
cin
almost woking typings
r9 }, U>
cin
initial commit
r0
cin
almost woking typings
r9 override<K extends U>(name: K, builder: BuildDescriptorFn<S, S[K], U>): this;
override<X extends ConfigurationMapConstraint<S, U, keyof X>>(services: X): this;
cin
initial commit
r0
cin
working on fluent configuration
r1 lifetime(lifetime: "singleton", typeId: string | number | object): this;
lifetime(lifetime: ILifetime<T> | Exclude<ActivationType, "singleton">): this;
cin
initial commit
r0
cin
working on typings
r8 /** Указывает функцию для освобождения экземпляра сервиса для случаев, когда
* время жизни привязано к контейнеру.
*/
cin
initial commit
r0 cleanup(cb: (item: T) => void): this;
cin
working on typings
r8 /**
* Регистрирует в контейнере постоянное значение в качестве реализации сервиса.
*
* @param v Экземпляр реализации сервиса.
*/
cin
almost woking typings
r9 value(v: NonNullable<T>): void;
cin
initial commit
r0 }
cin
almost woking typings
r9 export type BuildDescriptorFn<S, T, U extends keyof S> = (d: IDescriptorBuilder<S, T, Record<never, never>, U>) => void;
cin
initial commit
r0
cin
almost woking typings
r9 /**
* Конфигурация контейнера, состоит из набора функций, которые выполняют конфигурацию.
*
* Все параметры конфигурации являются обязательными, если требуется ввести
* необязательные параметры, то нужно ограничить параметр типа {@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];
cin
working on fluent configuration
r1 };
cin
initial commit
r0
cin
working on typings
r8 export interface Descriptor<S, T> {
cin
almost woking typings
r9
/** This flags indicates that this registration can be replaced or overridden. */
readonly configurable?: boolean;
/** If specified signals the activation context that a new service scope
* should be created to isolate service overrides.
*/
readonly hasOverrides?: boolean;
activate(context: IActivationContext<S>): NonNullable<T>;
cin
initial commit
r0 }
cin
intoruced initial work on ILifetimeSlot
r10 /** The context used to initialize lifetime instance {@linkcode ILifetime} */
export interface ILifetimeContext {
cin
WIP service descriptors
r13
ownerSlot<T>(slotId: string | number): ILifetimeSlot<T>;
cin
WIP lifetime services
r12 contextSlot<T>(slotId: string | number): ILifetimeSlot<T>;
cin
Working on container builder
r5
cin
WIP lifetime services
r12 containerSlot<T>(slotId: string | number): ILifetimeSlot<T>;
cin
Working on container builder
r5
cin
intoruced initial work on ILifetimeSlot
r10 }
export interface IActivationContext<S> extends ILifetimeContext, ServiceLocator<S> {
cin
almost woking typings
r9 register<K extends keyof S>(name: K, service: DescriptorMap<S>[K]): void;
cin
WIP lifetime services, change target to ES2018
r11
fail(error: unknown): never;
cin
WIP service descriptors
r13
selfContainer(): ServiceLocator<S>;
createChildContainer(): IContainerBuilder<S, Exclude<keyof S, ContainerKeys>>;
cin
working on fluent configuration
r1 }
cin
almost woking typings
r9 /**
* 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]>;
};
cin
working on fluent configuration
r1
cin
almost woking typings
r9 type ContainerKeys = keyof ContainerProvided<object>;
cin
WIP service descriptors
r13 export type ContainerProvided<S, U extends keyof S = keyof S> = {
container: ServiceLocator<ContainerProvided<S>>;
cin
almost woking typings
r9
cin
WIP service descriptors
r13 childContainer: IContainerBuilder<S, U>;
cin
almost woking typings
r9 };
cin
working on fluent configuration
r1
cin
almost woking typings
r9 /**
* Таблица сервисов, которые предоставляет контейнер.
*
* Сервисы, предоставляемые контейнером не могут быть null или undefined.
*/
cin
WIP service descriptors
r13 export type ContainerServices<S> = {
[k in (keyof S) | ContainerKeys]:
cin
WIP lifetime services
r12 k extends ContainerKeys ? ContainerProvided<S>[k] :
k extends keyof S ? S[k] : never
cin
almost woking typings
r9 };
cin
working on fluent configuration
r1
cin
initial commit
r0
cin
almost woking typings
r9 /**
* Returns the service declared in the type map {@link S}.
*
*
*/
cin
working on typings
r8 export interface ServiceLocator<S> {
cin
working on fluent configuration
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;
cin
initial commit
r0 }
cin
working on fluent configuration
r1
cin
almost woking typings
r9 export interface IContainerBuilder<S, U extends keyof S> {
createServiceBuilder<K extends U>(name: K):
IDescriptorBuilder<S, S[K], Record<never, never>, U>;
cin
working on fluent configuration
r1
cin
almost woking typings
r9 build(): ServiceLocator<S>;
cin
initial commit
r0 }
export type ActivationType = "singleton" | "container" | "hierarchy" | "context" | "call";
/**
* Интерфейс для управления жизнью экземпляра объекта. Каждая регистрация имеет
* свой собственный объект `ILifetime`, который создается при первой активации
*/
cin
WIP lifetime, service descriptors
r14 export type ILifetime<T> = (context: ILifetimeContext) => ILifetimeSlot<T>;
cin
initial commit
r0
cin
WIP lifetime services
r12 export interface ILifetimeSlot<T> {
readonly has: () => boolean;
readonly get: () => T;
cin
almost woking typings
r9
cin
WIP lifetime services
r12 readonly initialize: () => void;
readonly store: (item: T, cleanup?: (item: T) => void) => void;
cin
almost woking typings
r9
cin
WIP lifetime services
r12 readonly remove: () => void;
cin
working on fluent configuration
r1
cin
WIP lifetime services
r12 readonly cleanup: () => void;
cin
almost woking typings
r9 }
cin
initial commit
r0
cin
almost woking typings
r9 export interface ILifetimeManager extends IDestroyable {
cin
WIP lifetime services
r12 slot<T>(id: string | number): ILifetimeSlot<T>;
cin
working on fluent configuration
r1 }
cin
initial commit
r0
cin
code comments
r2 export type ExtractRequired<T, K extends keyof T = keyof T> = { [p in K as (undefined extends T[p] ? never : p)]-?: T[p] };
cin
working on fluent configuration
r1
cin
almost woking typings
r9 export type ExtractRequiredKeys<T, K extends keyof T = keyof T> = { [p in K]-?: undefined extends T[p] ? never : p }[K];