@kaokei/di 3.0.9 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -3
- package/dist/binding.d.cts +41 -17
- package/dist/binding.d.ts +41 -17
- package/dist/cachemap.d.cts +38 -8
- package/dist/cachemap.d.ts +38 -8
- package/dist/constants.d.cts +19 -6
- package/dist/constants.d.ts +19 -6
- package/dist/container.d.cts +11 -7
- package/dist/container.d.ts +11 -7
- package/dist/decorator.d.cts +40 -13
- package/dist/decorator.d.ts +40 -13
- package/dist/errors/BaseError.d.cts +1 -0
- package/dist/errors/BaseError.d.ts +1 -0
- package/dist/errors/ContainerNotFoundError.d.cts +5 -0
- package/dist/errors/ContainerNotFoundError.d.ts +5 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +337 -239
- package/dist/interfaces.d.cts +1 -1
- package/dist/interfaces.d.ts +1 -1
- package/dist/token.d.cts +1 -1
- package/dist/token.d.ts +1 -1
- package/package.json +8 -3
- package/dist/lazyinject.d.cts +0 -4
- package/dist/lazyinject.d.ts +0 -4
package/README.md
CHANGED
|
@@ -14,7 +14,31 @@
|
|
|
14
14
|
|
|
15
15
|
本库主要特点是参考借鉴了`InversifyJS`和`Angular`的优秀 API 设计,不依赖`reflect-metadata`,支持属性注入的循环依赖。
|
|
16
16
|
|
|
17
|
-
- [入门指南](./docs/guide/
|
|
18
|
-
- [API 文档](./docs/api/
|
|
17
|
+
- [入门指南](./docs/guide/index.md)
|
|
18
|
+
- [API 文档](./docs/api/index.md)
|
|
19
19
|
- [博客文章](./docs/note/01.什么是Token.md)
|
|
20
|
-
- [
|
|
20
|
+
- [CodeSandbox 在线示例](./docs/guide/EXAMPLES.md)
|
|
21
|
+
|
|
22
|
+
## Todo
|
|
23
|
+
|
|
24
|
+
- 完善docs中todo项目
|
|
25
|
+
- 最低需要typescript@5.0.0版本,esbuild@0.24.0版本,vite@6.0.0版本,
|
|
26
|
+
这里主要是vite依赖了esbuild,但是低版本esbuild在stage3装饰器的翻译上存在bug,所以esbuild最低版本需要0.24.0,而对应的vite最低版本则是6.0.0
|
|
27
|
+
当然如果明确使用 useDefineForClassFields: true,低版本esbuild也是可以正常工作的。
|
|
28
|
+
https://chatgpt.com/share/69ca7982-2fd0-8321-8e6b-31867f5839e5
|
|
29
|
+
- 需要重构当前的实现方案,应该通过context.metadata来收集依赖注入信息,然后通过类装饰器建立类和context.metadata的关联关系。
|
|
30
|
+
addInitializer → this.constructor → class
|
|
31
|
+
metadata → class decorator → WeakMap
|
|
32
|
+
|
|
33
|
+
- stage3 装饰器执行顺序
|
|
34
|
+
enter method decorator -->
|
|
35
|
+
enter field decorator -->
|
|
36
|
+
enter class decorator -->
|
|
37
|
+
class decorator addInitializer callback -->
|
|
38
|
+
method decorator addInitializer callback -->
|
|
39
|
+
field decorator addInitializer callback -->
|
|
40
|
+
class constructor
|
|
41
|
+
|
|
42
|
+
- 5.0.4,5.1.6并不支持context.metadata
|
|
43
|
+
- 5.2.2 开始支持context.metadata
|
|
44
|
+
|
package/dist/binding.d.cts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
import { BindingType, StatusType } from './constants';
|
|
1
2
|
import { Container } from './container';
|
|
2
|
-
import { Newable, Context, Options, CommonToken, DynamicValue, ActivationHandler, DeactivationHandler } from './interfaces';
|
|
3
|
+
import { Newable, Context, Options, CommonToken, RecordObject, DynamicValue, PostConstructParam, ActivationHandler, DeactivationHandler } from './interfaces';
|
|
4
|
+
export interface InjectPropertiesResult {
|
|
5
|
+
properties: RecordObject;
|
|
6
|
+
bindings: Binding[];
|
|
7
|
+
}
|
|
3
8
|
export declare class Binding<T = unknown> {
|
|
9
|
+
static _resolvers: Record<string, string>;
|
|
4
10
|
container: Container;
|
|
5
11
|
context: Context;
|
|
6
12
|
token: CommonToken<T>;
|
|
7
|
-
type:
|
|
8
|
-
status:
|
|
9
|
-
classValue
|
|
10
|
-
constantValue
|
|
11
|
-
dynamicValue
|
|
12
|
-
cache
|
|
13
|
-
postConstructResult
|
|
13
|
+
type: BindingType;
|
|
14
|
+
status: StatusType;
|
|
15
|
+
classValue?: Newable<T>;
|
|
16
|
+
constantValue?: T;
|
|
17
|
+
dynamicValue?: DynamicValue<T>;
|
|
18
|
+
cache?: T;
|
|
19
|
+
postConstructResult: Promise<void> | symbol | undefined;
|
|
14
20
|
onActivationHandler?: ActivationHandler<T>;
|
|
15
21
|
onDeactivationHandler?: DeactivationHandler<T>;
|
|
16
22
|
constructor(token: CommonToken<T>, container: Container);
|
|
@@ -23,14 +29,32 @@ export declare class Binding<T = unknown> {
|
|
|
23
29
|
toConstantValue(value: T): this;
|
|
24
30
|
toDynamicValue(func: DynamicValue<T>): this;
|
|
25
31
|
toService(token: CommonToken<T>): this;
|
|
26
|
-
get(options: Options<T>):
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
get(options: Options<T>): any;
|
|
33
|
+
_getAwaitBindings(bindings: Binding[], filter: PostConstructParam): Binding[];
|
|
34
|
+
/**
|
|
35
|
+
* PostConstruct 生命周期处理
|
|
36
|
+
*
|
|
37
|
+
* postConstructResult 的三种状态:
|
|
38
|
+
* - UNINITIALIZED(Symbol):PostConstruct 尚未执行,用于循环依赖检测
|
|
39
|
+
* - undefined:没有使用 @PostConstruct 装饰器,或 @PostConstruct() 无参数时同步执行完毕
|
|
40
|
+
* - Promise<void>:@PostConstruct(value) 有参数时,等待前置服务初始化后异步执行
|
|
41
|
+
*
|
|
42
|
+
* @PostConstruct() 无参数时:同步执行,不等待任何前置服务
|
|
43
|
+
* @PostConstruct(value) 有参数时:等待指定的前置服务初始化完成后再执行
|
|
44
|
+
* - 如果前置服务初始化成功,执行当前服务的 PostConstruct 方法
|
|
45
|
+
* - 如果前置服务初始化失败,rejected promise 自然传播,当前服务的 PostConstruct 不执行
|
|
46
|
+
*/
|
|
47
|
+
_postConstruct(options: Options<T>, propertyBindings: Binding[]): void;
|
|
29
48
|
preDestroy(): void;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
_execute(key: string): any;
|
|
50
|
+
_resolveInstanceValue(options: Options<T>): T;
|
|
51
|
+
_createInstance(): T;
|
|
52
|
+
_registerInstance(): void;
|
|
53
|
+
_injectProperties(properties: RecordObject): void;
|
|
54
|
+
_resolveConstantValue(): T;
|
|
55
|
+
_resolveDynamicValue(): T;
|
|
56
|
+
_getInjectProperties(options: Options<T>): {
|
|
57
|
+
properties: RecordObject;
|
|
58
|
+
bindings: Binding<unknown>[];
|
|
59
|
+
};
|
|
36
60
|
}
|
package/dist/binding.d.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
import { BindingType, StatusType } from './constants';
|
|
1
2
|
import { Container } from './container';
|
|
2
|
-
import { Newable, Context, Options, CommonToken, DynamicValue, ActivationHandler, DeactivationHandler } from './interfaces';
|
|
3
|
+
import { Newable, Context, Options, CommonToken, RecordObject, DynamicValue, PostConstructParam, ActivationHandler, DeactivationHandler } from './interfaces';
|
|
4
|
+
export interface InjectPropertiesResult {
|
|
5
|
+
properties: RecordObject;
|
|
6
|
+
bindings: Binding[];
|
|
7
|
+
}
|
|
3
8
|
export declare class Binding<T = unknown> {
|
|
9
|
+
static _resolvers: Record<string, string>;
|
|
4
10
|
container: Container;
|
|
5
11
|
context: Context;
|
|
6
12
|
token: CommonToken<T>;
|
|
7
|
-
type:
|
|
8
|
-
status:
|
|
9
|
-
classValue
|
|
10
|
-
constantValue
|
|
11
|
-
dynamicValue
|
|
12
|
-
cache
|
|
13
|
-
postConstructResult
|
|
13
|
+
type: BindingType;
|
|
14
|
+
status: StatusType;
|
|
15
|
+
classValue?: Newable<T>;
|
|
16
|
+
constantValue?: T;
|
|
17
|
+
dynamicValue?: DynamicValue<T>;
|
|
18
|
+
cache?: T;
|
|
19
|
+
postConstructResult: Promise<void> | symbol | undefined;
|
|
14
20
|
onActivationHandler?: ActivationHandler<T>;
|
|
15
21
|
onDeactivationHandler?: DeactivationHandler<T>;
|
|
16
22
|
constructor(token: CommonToken<T>, container: Container);
|
|
@@ -23,14 +29,32 @@ export declare class Binding<T = unknown> {
|
|
|
23
29
|
toConstantValue(value: T): this;
|
|
24
30
|
toDynamicValue(func: DynamicValue<T>): this;
|
|
25
31
|
toService(token: CommonToken<T>): this;
|
|
26
|
-
get(options: Options<T>):
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
get(options: Options<T>): any;
|
|
33
|
+
_getAwaitBindings(bindings: Binding[], filter: PostConstructParam): Binding[];
|
|
34
|
+
/**
|
|
35
|
+
* PostConstruct 生命周期处理
|
|
36
|
+
*
|
|
37
|
+
* postConstructResult 的三种状态:
|
|
38
|
+
* - UNINITIALIZED(Symbol):PostConstruct 尚未执行,用于循环依赖检测
|
|
39
|
+
* - undefined:没有使用 @PostConstruct 装饰器,或 @PostConstruct() 无参数时同步执行完毕
|
|
40
|
+
* - Promise<void>:@PostConstruct(value) 有参数时,等待前置服务初始化后异步执行
|
|
41
|
+
*
|
|
42
|
+
* @PostConstruct() 无参数时:同步执行,不等待任何前置服务
|
|
43
|
+
* @PostConstruct(value) 有参数时:等待指定的前置服务初始化完成后再执行
|
|
44
|
+
* - 如果前置服务初始化成功,执行当前服务的 PostConstruct 方法
|
|
45
|
+
* - 如果前置服务初始化失败,rejected promise 自然传播,当前服务的 PostConstruct 不执行
|
|
46
|
+
*/
|
|
47
|
+
_postConstruct(options: Options<T>, propertyBindings: Binding[]): void;
|
|
29
48
|
preDestroy(): void;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
_execute(key: string): any;
|
|
50
|
+
_resolveInstanceValue(options: Options<T>): T;
|
|
51
|
+
_createInstance(): T;
|
|
52
|
+
_registerInstance(): void;
|
|
53
|
+
_injectProperties(properties: RecordObject): void;
|
|
54
|
+
_resolveConstantValue(): T;
|
|
55
|
+
_resolveDynamicValue(): T;
|
|
56
|
+
_getInjectProperties(options: Options<T>): {
|
|
57
|
+
properties: RecordObject;
|
|
58
|
+
bindings: Binding<unknown>[];
|
|
59
|
+
};
|
|
36
60
|
}
|
package/dist/cachemap.d.cts
CHANGED
|
@@ -1,10 +1,40 @@
|
|
|
1
|
-
import { CommonToken } from './interfaces';
|
|
2
|
-
export declare function defineMetadata(metadataKey: string, metadataValue: any, target: CommonToken): void;
|
|
3
|
-
export declare function getOwnMetadata(metadataKey: string, target: CommonToken): any | undefined;
|
|
1
|
+
import { CommonToken, PostConstructParam } from './interfaces';
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 如果有父类,那么需要合并getOwnMetadata(target)和getMetadata(target的父类)
|
|
8
|
-
* 不支持META_KEY_INJECTED_PARAMS作为metadataKey
|
|
3
|
+
* 关联 target 和 metadata 对象
|
|
4
|
+
* 由 @Injectable 类装饰器调用,直接存储 context.metadata
|
|
9
5
|
*/
|
|
10
|
-
export declare function
|
|
6
|
+
export declare function defineMetadata(target: CommonToken, metadata: Record<string, unknown>): void;
|
|
7
|
+
/**
|
|
8
|
+
* 获取 PostConstruct 元数据
|
|
9
|
+
*
|
|
10
|
+
* 如果 target 在 map 中注册了(使用了 @Injectable),
|
|
11
|
+
* 直接读取 metadata[key],原型链自动处理继承。
|
|
12
|
+
* 如果 target 未注册但有父类,递归向上查找。
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPostConstruct(target: CommonToken): {
|
|
15
|
+
key: string;
|
|
16
|
+
value?: PostConstructParam;
|
|
17
|
+
} | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* 获取 PreDestroy 元数据
|
|
20
|
+
*
|
|
21
|
+
* 与 getPostConstruct 同理。
|
|
22
|
+
*/
|
|
23
|
+
export declare function getPreDestroy(target: CommonToken): {
|
|
24
|
+
key: string;
|
|
25
|
+
} | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* 获取属性注入元数据(需要手动处理继承链中嵌套对象的合并)
|
|
28
|
+
*
|
|
29
|
+
* context.metadata 的原型链继承只对第一层属性有效。
|
|
30
|
+
* INJECTED_PROPS 对应的值是一个嵌套对象 { propName: { inject, self, ... } },
|
|
31
|
+
* 原型链无法自动合并嵌套属性。
|
|
32
|
+
*
|
|
33
|
+
* 例如:父类有 { a: {...}, b: {...} },子类有 { a: {...} }
|
|
34
|
+
* 通过原型链读取子类的 INJECTED_PROPS 只能拿到子类自己的 { a: {...} },
|
|
35
|
+
* 无法自动合并父类的 b 属性。
|
|
36
|
+
*
|
|
37
|
+
* 所以需要手动递归处理:合并当前类和父类的 INJECTED_PROPS,
|
|
38
|
+
* 子类同名属性覆盖父类。
|
|
39
|
+
*/
|
|
40
|
+
export declare function getInjectedProps(target: CommonToken): Record<string, Record<string, unknown>> | undefined;
|
package/dist/cachemap.d.ts
CHANGED
|
@@ -1,10 +1,40 @@
|
|
|
1
|
-
import { CommonToken } from './interfaces';
|
|
2
|
-
export declare function defineMetadata(metadataKey: string, metadataValue: any, target: CommonToken): void;
|
|
3
|
-
export declare function getOwnMetadata(metadataKey: string, target: CommonToken): any | undefined;
|
|
1
|
+
import { CommonToken, PostConstructParam } from './interfaces';
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 如果有父类,那么需要合并getOwnMetadata(target)和getMetadata(target的父类)
|
|
8
|
-
* 不支持META_KEY_INJECTED_PARAMS作为metadataKey
|
|
3
|
+
* 关联 target 和 metadata 对象
|
|
4
|
+
* 由 @Injectable 类装饰器调用,直接存储 context.metadata
|
|
9
5
|
*/
|
|
10
|
-
export declare function
|
|
6
|
+
export declare function defineMetadata(target: CommonToken, metadata: Record<string, unknown>): void;
|
|
7
|
+
/**
|
|
8
|
+
* 获取 PostConstruct 元数据
|
|
9
|
+
*
|
|
10
|
+
* 如果 target 在 map 中注册了(使用了 @Injectable),
|
|
11
|
+
* 直接读取 metadata[key],原型链自动处理继承。
|
|
12
|
+
* 如果 target 未注册但有父类,递归向上查找。
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPostConstruct(target: CommonToken): {
|
|
15
|
+
key: string;
|
|
16
|
+
value?: PostConstructParam;
|
|
17
|
+
} | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* 获取 PreDestroy 元数据
|
|
20
|
+
*
|
|
21
|
+
* 与 getPostConstruct 同理。
|
|
22
|
+
*/
|
|
23
|
+
export declare function getPreDestroy(target: CommonToken): {
|
|
24
|
+
key: string;
|
|
25
|
+
} | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* 获取属性注入元数据(需要手动处理继承链中嵌套对象的合并)
|
|
28
|
+
*
|
|
29
|
+
* context.metadata 的原型链继承只对第一层属性有效。
|
|
30
|
+
* INJECTED_PROPS 对应的值是一个嵌套对象 { propName: { inject, self, ... } },
|
|
31
|
+
* 原型链无法自动合并嵌套属性。
|
|
32
|
+
*
|
|
33
|
+
* 例如:父类有 { a: {...}, b: {...} },子类有 { a: {...} }
|
|
34
|
+
* 通过原型链读取子类的 INJECTED_PROPS 只能拿到子类自己的 { a: {...} },
|
|
35
|
+
* 无法自动合并父类的 b 属性。
|
|
36
|
+
*
|
|
37
|
+
* 所以需要手动递归处理:合并当前类和父类的 INJECTED_PROPS,
|
|
38
|
+
* 子类同名属性覆盖父类。
|
|
39
|
+
*/
|
|
40
|
+
export declare function getInjectedProps(target: CommonToken): Record<string, Record<string, unknown>> | undefined;
|
package/dist/constants.d.cts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare const KEYS: {
|
|
2
|
-
readonly INJECTED_PARAMS: "injected:params";
|
|
3
2
|
readonly INJECTED_PROPS: "injected:props";
|
|
4
3
|
readonly INJECT: "inject";
|
|
5
4
|
readonly SELF: "self";
|
|
@@ -19,10 +18,24 @@ export declare const BINDING: {
|
|
|
19
18
|
readonly ConstantValue: "ConstantValue";
|
|
20
19
|
readonly DynamicValue: "DynamicValue";
|
|
21
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* 错误消息模板
|
|
23
|
+
*
|
|
24
|
+
* 这些消息用于装饰器和 token 模块中的运行时错误检测,
|
|
25
|
+
* 与 errors/ 目录下的错误类无关(错误类有自己的消息前缀)。
|
|
26
|
+
*/
|
|
22
27
|
export declare const ERRORS: {
|
|
23
|
-
readonly POST_CONSTRUCT: "
|
|
24
|
-
readonly PRE_DESTROY: "
|
|
25
|
-
readonly
|
|
26
|
-
readonly
|
|
28
|
+
readonly POST_CONSTRUCT: "Multiple @PostConstruct decorators are not allowed in a single class.";
|
|
29
|
+
readonly PRE_DESTROY: "Multiple @PreDestroy decorators are not allowed in a single class.";
|
|
30
|
+
readonly INVALID_TOKEN: "@Inject or @LazyInject requires a valid token, but received null or undefined.";
|
|
31
|
+
readonly LAZY_INJECT_INVALID_TOKEN: "@LazyInject requires a valid token, but received null or undefined.";
|
|
27
32
|
};
|
|
28
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Object.hasOwn 的兼容性替代函数
|
|
35
|
+
* Object.hasOwn 在部分旧版浏览器和运行时中不可用(ES2022+),
|
|
36
|
+
* 此函数使用 Object.prototype.hasOwnProperty.call 实现相同语义。
|
|
37
|
+
*/
|
|
38
|
+
export declare function hasOwn(obj: object, key: PropertyKey): boolean;
|
|
39
|
+
export declare const UNINITIALIZED: unique symbol;
|
|
40
|
+
export type BindingType = (typeof BINDING)[keyof typeof BINDING];
|
|
41
|
+
export type StatusType = (typeof STATUS)[keyof typeof STATUS];
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare const KEYS: {
|
|
2
|
-
readonly INJECTED_PARAMS: "injected:params";
|
|
3
2
|
readonly INJECTED_PROPS: "injected:props";
|
|
4
3
|
readonly INJECT: "inject";
|
|
5
4
|
readonly SELF: "self";
|
|
@@ -19,10 +18,24 @@ export declare const BINDING: {
|
|
|
19
18
|
readonly ConstantValue: "ConstantValue";
|
|
20
19
|
readonly DynamicValue: "DynamicValue";
|
|
21
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* 错误消息模板
|
|
23
|
+
*
|
|
24
|
+
* 这些消息用于装饰器和 token 模块中的运行时错误检测,
|
|
25
|
+
* 与 errors/ 目录下的错误类无关(错误类有自己的消息前缀)。
|
|
26
|
+
*/
|
|
22
27
|
export declare const ERRORS: {
|
|
23
|
-
readonly POST_CONSTRUCT: "
|
|
24
|
-
readonly PRE_DESTROY: "
|
|
25
|
-
readonly
|
|
26
|
-
readonly
|
|
28
|
+
readonly POST_CONSTRUCT: "Multiple @PostConstruct decorators are not allowed in a single class.";
|
|
29
|
+
readonly PRE_DESTROY: "Multiple @PreDestroy decorators are not allowed in a single class.";
|
|
30
|
+
readonly INVALID_TOKEN: "@Inject or @LazyInject requires a valid token, but received null or undefined.";
|
|
31
|
+
readonly LAZY_INJECT_INVALID_TOKEN: "@LazyInject requires a valid token, but received null or undefined.";
|
|
27
32
|
};
|
|
28
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Object.hasOwn 的兼容性替代函数
|
|
35
|
+
* Object.hasOwn 在部分旧版浏览器和运行时中不可用(ES2022+),
|
|
36
|
+
* 此函数使用 Object.prototype.hasOwnProperty.call 实现相同语义。
|
|
37
|
+
*/
|
|
38
|
+
export declare function hasOwn(obj: object, key: PropertyKey): boolean;
|
|
39
|
+
export declare const UNINITIALIZED: unique symbol;
|
|
40
|
+
export type BindingType = (typeof BINDING)[keyof typeof BINDING];
|
|
41
|
+
export type StatusType = (typeof STATUS)[keyof typeof STATUS];
|
package/dist/container.d.cts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Binding } from './binding';
|
|
2
2
|
import { Options, CommonToken, ActivationHandler, DeactivationHandler } from './interfaces';
|
|
3
3
|
export declare class Container {
|
|
4
|
-
static
|
|
4
|
+
static _instanceContainerMap: WeakMap<object, Container>;
|
|
5
|
+
static getContainerOf(instance: object): Container | undefined;
|
|
5
6
|
parent?: Container;
|
|
6
7
|
children?: Set<Container>;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
_bindings: Map<CommonToken, Binding>;
|
|
9
|
+
_onActivationHandler?: ActivationHandler;
|
|
10
|
+
_onDeactivationHandler?: DeactivationHandler;
|
|
10
11
|
bind<T>(token: CommonToken<T>): Binding<T>;
|
|
11
12
|
unbind<T>(token: CommonToken<T>): void;
|
|
12
13
|
unbindAll(): void;
|
|
@@ -21,11 +22,14 @@ export declare class Container {
|
|
|
21
22
|
optional?: false;
|
|
22
23
|
}): T;
|
|
23
24
|
get<T>(token: CommonToken<T>, options?: Options<T>): T | void;
|
|
25
|
+
_resolveSkipSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
26
|
+
_resolveSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
27
|
+
_resolveDefault<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
24
28
|
onActivation(handler: ActivationHandler): void;
|
|
25
29
|
onDeactivation(handler: DeactivationHandler): void;
|
|
26
30
|
activate<T>(input: T, token: CommonToken<T>): T;
|
|
27
31
|
deactivate<T>(binding: Binding<T>): void;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
_buildBinding<T>(token: CommonToken<T>): Binding<T>;
|
|
33
|
+
_getBinding<T>(token: CommonToken<T>): Binding<T>;
|
|
34
|
+
_checkBindingNotFoundError<T>(token: CommonToken, options: Options<T>): void;
|
|
31
35
|
}
|
package/dist/container.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Binding } from './binding';
|
|
2
2
|
import { Options, CommonToken, ActivationHandler, DeactivationHandler } from './interfaces';
|
|
3
3
|
export declare class Container {
|
|
4
|
-
static
|
|
4
|
+
static _instanceContainerMap: WeakMap<object, Container>;
|
|
5
|
+
static getContainerOf(instance: object): Container | undefined;
|
|
5
6
|
parent?: Container;
|
|
6
7
|
children?: Set<Container>;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
_bindings: Map<CommonToken, Binding>;
|
|
9
|
+
_onActivationHandler?: ActivationHandler;
|
|
10
|
+
_onDeactivationHandler?: DeactivationHandler;
|
|
10
11
|
bind<T>(token: CommonToken<T>): Binding<T>;
|
|
11
12
|
unbind<T>(token: CommonToken<T>): void;
|
|
12
13
|
unbindAll(): void;
|
|
@@ -21,11 +22,14 @@ export declare class Container {
|
|
|
21
22
|
optional?: false;
|
|
22
23
|
}): T;
|
|
23
24
|
get<T>(token: CommonToken<T>, options?: Options<T>): T | void;
|
|
25
|
+
_resolveSkipSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
26
|
+
_resolveSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
27
|
+
_resolveDefault<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
24
28
|
onActivation(handler: ActivationHandler): void;
|
|
25
29
|
onDeactivation(handler: DeactivationHandler): void;
|
|
26
30
|
activate<T>(input: T, token: CommonToken<T>): T;
|
|
27
31
|
deactivate<T>(binding: Binding<T>): void;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
_buildBinding<T>(token: CommonToken<T>): Binding<T>;
|
|
33
|
+
_getBinding<T>(token: CommonToken<T>): Binding<T>;
|
|
34
|
+
_checkBindingNotFoundError<T>(token: CommonToken, options: Options<T>): void;
|
|
31
35
|
}
|
package/dist/decorator.d.cts
CHANGED
|
@@ -1,18 +1,45 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Container } from './container';
|
|
2
|
+
import { InjectFunction, GenericToken } from './interfaces';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
-
* 装饰器的通用逻辑就是通过cachemap记录到全局的WeakMap中
|
|
4
|
+
* 创建属性装饰器的高阶函数(Stage 3 Field Decorator)
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* 直接在装饰器执行阶段将元数据写入 context.metadata,
|
|
7
|
+
* 不再使用 context.addInitializer,消除实例化时的重复回调。
|
|
8
|
+
*
|
|
9
|
+
* @param decoratorKey 装饰器名称(如 'inject'、'self' 等)
|
|
10
|
+
* @param defaultValue 装饰器的默认参数值
|
|
11
|
+
* @returns 装饰器函数
|
|
9
12
|
*/
|
|
10
|
-
declare function createDecorator(decoratorKey: string, defaultValue?: any): (decoratorValue?: any) => (
|
|
13
|
+
declare function createDecorator(decoratorKey: string, defaultValue?: any): (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
11
14
|
export declare const Inject: InjectFunction<ReturnType<typeof createDecorator>>;
|
|
12
|
-
export declare const Self: (decoratorValue?: any) => (
|
|
13
|
-
export declare const SkipSelf: (decoratorValue?: any) => (
|
|
14
|
-
export declare const Optional: (decoratorValue?: any) => (
|
|
15
|
-
export declare const PostConstruct: (metaValue?: any) => (
|
|
16
|
-
export declare const PreDestroy: (metaValue?: any) => (
|
|
17
|
-
|
|
15
|
+
export declare const Self: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
16
|
+
export declare const SkipSelf: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
17
|
+
export declare const Optional: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
18
|
+
export declare const PostConstruct: (metaValue?: any) => (_value: Function, context: ClassMethodDecoratorContext) => void;
|
|
19
|
+
export declare const PreDestroy: (metaValue?: any) => (_value: Function, context: ClassMethodDecoratorContext) => void;
|
|
20
|
+
/**
|
|
21
|
+
* 类装饰器:在类定义阶段关联 target(类构造函数)和 context.metadata
|
|
22
|
+
*
|
|
23
|
+
* 当所有成员装饰器(@Inject、@PostConstruct 等)执行完毕后,
|
|
24
|
+
* @Injectable 读取 context.metadata 并通过 defineMetadata 写入 CacheMap,
|
|
25
|
+
* 建立 target → metadata 的映射关系。
|
|
26
|
+
*
|
|
27
|
+
* 使用方式:@Injectable(无参数,直接作为装饰器使用)
|
|
28
|
+
*/
|
|
29
|
+
export declare function Injectable(Ctor: Function, context: ClassDecoratorContext): void;
|
|
30
|
+
/**
|
|
31
|
+
* 延迟注入装饰器,Stage 3 Field Decorator 签名。
|
|
32
|
+
* 通过 context.addInitializer 在实例上定义 getter/setter,
|
|
33
|
+
* 首次访问属性时才从容器中解析依赖。
|
|
34
|
+
*
|
|
35
|
+
* @param token 要解析的服务 Token
|
|
36
|
+
* @param container 可选,显式指定容器。未传入时通过 Container.getContainerOf 查找,
|
|
37
|
+
* 仅支持 Instance 类型绑定。toConstantValue / toDynamicValue 场景需显式传入。
|
|
38
|
+
*/
|
|
39
|
+
export declare function LazyInject<T>(token: GenericToken<T>, container?: Container): (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
40
|
+
/**
|
|
41
|
+
* 创建绑定到指定容器的延迟注入装饰器工厂。
|
|
42
|
+
*/
|
|
43
|
+
export declare function createLazyInject(container: Container): <T>(token: GenericToken<T>) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
44
|
+
export declare function decorate(decorator: any, target: any, key: string): void;
|
|
18
45
|
export {};
|
package/dist/decorator.d.ts
CHANGED
|
@@ -1,18 +1,45 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Container } from './container';
|
|
2
|
+
import { InjectFunction, GenericToken } from './interfaces';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
-
* 装饰器的通用逻辑就是通过cachemap记录到全局的WeakMap中
|
|
4
|
+
* 创建属性装饰器的高阶函数(Stage 3 Field Decorator)
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* 直接在装饰器执行阶段将元数据写入 context.metadata,
|
|
7
|
+
* 不再使用 context.addInitializer,消除实例化时的重复回调。
|
|
8
|
+
*
|
|
9
|
+
* @param decoratorKey 装饰器名称(如 'inject'、'self' 等)
|
|
10
|
+
* @param defaultValue 装饰器的默认参数值
|
|
11
|
+
* @returns 装饰器函数
|
|
9
12
|
*/
|
|
10
|
-
declare function createDecorator(decoratorKey: string, defaultValue?: any): (decoratorValue?: any) => (
|
|
13
|
+
declare function createDecorator(decoratorKey: string, defaultValue?: any): (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
11
14
|
export declare const Inject: InjectFunction<ReturnType<typeof createDecorator>>;
|
|
12
|
-
export declare const Self: (decoratorValue?: any) => (
|
|
13
|
-
export declare const SkipSelf: (decoratorValue?: any) => (
|
|
14
|
-
export declare const Optional: (decoratorValue?: any) => (
|
|
15
|
-
export declare const PostConstruct: (metaValue?: any) => (
|
|
16
|
-
export declare const PreDestroy: (metaValue?: any) => (
|
|
17
|
-
|
|
15
|
+
export declare const Self: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
16
|
+
export declare const SkipSelf: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
17
|
+
export declare const Optional: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
18
|
+
export declare const PostConstruct: (metaValue?: any) => (_value: Function, context: ClassMethodDecoratorContext) => void;
|
|
19
|
+
export declare const PreDestroy: (metaValue?: any) => (_value: Function, context: ClassMethodDecoratorContext) => void;
|
|
20
|
+
/**
|
|
21
|
+
* 类装饰器:在类定义阶段关联 target(类构造函数)和 context.metadata
|
|
22
|
+
*
|
|
23
|
+
* 当所有成员装饰器(@Inject、@PostConstruct 等)执行完毕后,
|
|
24
|
+
* @Injectable 读取 context.metadata 并通过 defineMetadata 写入 CacheMap,
|
|
25
|
+
* 建立 target → metadata 的映射关系。
|
|
26
|
+
*
|
|
27
|
+
* 使用方式:@Injectable(无参数,直接作为装饰器使用)
|
|
28
|
+
*/
|
|
29
|
+
export declare function Injectable(Ctor: Function, context: ClassDecoratorContext): void;
|
|
30
|
+
/**
|
|
31
|
+
* 延迟注入装饰器,Stage 3 Field Decorator 签名。
|
|
32
|
+
* 通过 context.addInitializer 在实例上定义 getter/setter,
|
|
33
|
+
* 首次访问属性时才从容器中解析依赖。
|
|
34
|
+
*
|
|
35
|
+
* @param token 要解析的服务 Token
|
|
36
|
+
* @param container 可选,显式指定容器。未传入时通过 Container.getContainerOf 查找,
|
|
37
|
+
* 仅支持 Instance 类型绑定。toConstantValue / toDynamicValue 场景需显式传入。
|
|
38
|
+
*/
|
|
39
|
+
export declare function LazyInject<T>(token: GenericToken<T>, container?: Container): (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
40
|
+
/**
|
|
41
|
+
* 创建绑定到指定容器的延迟注入装饰器工厂。
|
|
42
|
+
*/
|
|
43
|
+
export declare function createLazyInject(container: Container): <T>(token: GenericToken<T>) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
44
|
+
export declare function decorate(decorator: any, target: any, key: string): void;
|
|
18
45
|
export {};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var w=Object.defineProperty;var j=(n,t,e)=>t in n?w(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var r=(n,t,e)=>j(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h={INJECTED_PARAMS:"injected:params",INJECTED_PROPS:"injected:props",INJECT:"inject",SELF:"self",SKIP_SELF:"skipSelf",OPTIONAL:"optional",POST_CONSTRUCT:"postConstruct",PRE_DESTROY:"preDestroy"},p={DEFAULT:"default",INITING:"initing",ACTIVATED:"activated"},d={Invalid:"Invalid",Instance:"Instance",ConstantValue:"ConstantValue",DynamicValue:"DynamicValue"},v={POST_CONSTRUCT:"Cannot apply @PostConstruct decorator multiple times in the same class.",PRE_DESTROY:"Cannot apply @PreDestroy decorator multiple times in the same class.",MISS_INJECT:"Expected a @Inject decorator to explicitly specify the token.",MISS_CONTAINER:"@LazyInject decorator cannot find the corresponding container."},m=Symbol(),D=new WeakMap;function B(n){return typeof n=="function"&&Object.getPrototypeOf(n)!==Function.prototype}function b(n,t,e){const s=D.get(e)||{};s[n]=t,D.set(e,s)}function T(n,t){return(D.get(t)||{})[n]}function I(n,t){const e=T(n,t);if(!B(t))return e;const s=I(n,Object.getPrototypeOf(t));if(s||e)return{...s||{},...e||{}}}class _{constructor(t){r(this,"_","");r(this,"name");this.name=t}}class O{constructor(t){r(this,"callback");this.callback=t}resolve(){return this.callback()}}function A(n){if(!n)throw new Error(v.MISS_INJECT);return n instanceof O?n.resolve():n}class E extends Error{constructor(t,e){super(),this.name=this.constructor.name,this.message=`${t}${e==null?void 0:e.name}`}}class V extends E{constructor(t){super("");const e=[];let s=t;for(;s&&s.token;)e.push(s.token),s=s.parent;const i=e.reverse().map(o=>o.name).join(" --> ");this.message=`Circular dependency found: ${i}`}}class k extends E{constructor(t){super("Invalid binding: ",t)}}class H extends V{constructor(t){super(t),this.name="CircularDependencyError inside @PostConstruct"}}class L{constructor(t,e){r(this,"container");r(this,"context");r(this,"token");r(this,"type",d.Invalid);r(this,"status",p.DEFAULT);r(this,"classValue");r(this,"constantValue");r(this,"dynamicValue");r(this,"cache");r(this,"postConstructResult",m);r(this,"onActivationHandler");r(this,"onDeactivationHandler");this.container=e,this.context={container:this.container},this.token=t}onActivation(t){this.onActivationHandler=t}onDeactivation(t){this.onDeactivationHandler=t}activate(t){const e=this.onActivationHandler?this.onActivationHandler(this.context,t):t;return this.container.activate(e,this.token)}deactivate(){this.onDeactivationHandler&&this.onDeactivationHandler(this.cache)}to(t){return this.type=d.Instance,this.classValue=t,this}toSelf(){return this.to(this.token)}toConstantValue(t){return this.type=d.ConstantValue,this.constantValue=t,this}toDynamicValue(t){return this.type=d.DynamicValue,this.dynamicValue=t,this}toService(t){return this.toDynamicValue(e=>e.container.get(t,{parent:{token:this.token}}))}get(t){if(p.INITING===this.status)throw new V(t);if(p.ACTIVATED===this.status)return this.cache;if(d.Instance===this.type)return this.resolveInstanceValue(t);if(d.ConstantValue===this.type)return this.resolveConstantValue();if(d.DynamicValue===this.type)return this.resolveDynamicValue();throw new k(this.token)}getAwaitBindings(t,e){return e===!0?t:Array.isArray(e)?t.filter(s=>e.includes(s.token)):typeof e=="function"?t.filter(e):[]}postConstruct(t,e,s){if(d.Instance===this.type){const{key:i,value:o}=I(h.POST_CONSTRUCT,this.classValue)||{};if(i)if(o){const a=[...e,...s].filter(u=>d.Instance===(u==null?void 0:u.type)),c=this.getAwaitBindings(a,o);for(const u of c)if(u&&u.postConstructResult===m)throw new H({token:u.token,parent:t});const l=c.map(u=>u.postConstructResult);this.postConstructResult=Promise.all(l).then(()=>this.execute(i))}else this.postConstructResult=this.execute(i);else this.postConstructResult=void 0}}preDestroy(){if(d.Instance===this.type){const{key:t}=I(h.PRE_DESTROY,this.classValue)||{};t&&this.execute(t)}y.map.delete(this.cache),this.container=null,this.context=null,this.classValue=null,this.constantValue=null,this.dynamicValue=null,this.cache=null,this.postConstructResult=m,this.onActivationHandler=void 0,this.onDeactivationHandler=void 0}execute(t){const e=this.cache[t];return e==null?void 0:e.call(this.cache)}resolveInstanceValue(t){this.status=p.INITING;const e=this.classValue,[s,i]=this.getConstructorParameters(t),o=new e(...s);this.cache=this.activate(o),this.status=p.ACTIVATED,y.map.set(this.cache,this.container);const[a,c]=this.getInjectProperties(t);return Object.assign(this.cache,a),this.postConstruct(t,i,c),this.cache}resolveConstantValue(){return this.status=p.INITING,this.cache=this.activate(this.constantValue),this.status=p.ACTIVATED,this.cache}resolveDynamicValue(){this.status=p.INITING;const t=this.dynamicValue.call(this,this.context);return this.cache=this.activate(t),this.status=p.ACTIVATED,this.cache}getConstructorParameters(t){const e=T(h.INJECTED_PARAMS,this.classValue)||[],s=[],i=[];for(let o=0;o<e.length;o++){const a=e[o],{inject:c,...l}=a;l.parent=t;const u=this.container.get(A(c),l);s.push(u),i.push(l.binding)}return[s,i]}getInjectProperties(t){const e=I(h.INJECTED_PROPS,this.classValue)||{},s=Object.keys(e),i=Object.create(null),o=[];for(let a=0;a<s.length;a++){const c=s[a],l=e[c],{inject:u,...f}=l;f.parent=t;const g=this.container.get(A(u),f);g===void 0&&l.optional||(i[c]=g),o.push(f.binding)}return[i,o]}}class M extends E{constructor(t){super("No matching binding found for token: ",t)}}class x extends E{constructor(t){super("Cannot bind token multiple times: ",t)}}const C=class C{constructor(){r(this,"parent");r(this,"children");r(this,"bindings",new Map);r(this,"onActivationHandler");r(this,"onDeactivationHandler")}bind(t){if(this.bindings.has(t))throw new x(t);const e=this.buildBinding(t);return this.bindings.set(t,e),e}unbind(t){if(this.bindings.has(t)){const e=this.getBinding(t);this.deactivate(e),e.deactivate(),e.preDestroy(),this.bindings.delete(t)}}unbindAll(){this.bindings.forEach(t=>{this.unbind(t.token)})}isCurrentBound(t){return this.bindings.has(t)}isBound(t){return this.isCurrentBound(t)||!!this.parent&&this.parent.isBound(t)}createChild(){const t=new C;return t.parent=this,this.children||(this.children=new Set),this.children.add(t),t}destroy(){var t,e,s;this.unbindAll(),this.bindings.clear(),(e=(t=this.parent)==null?void 0:t.children)==null||e.delete(this),this.parent=void 0,(s=this.children)==null||s.clear(),this.children=void 0,this.onActivationHandler=void 0,this.onDeactivationHandler=void 0}get(t,e={}){const s=this.getBinding(t);if(e.skipSelf){if(this.parent)return e.skipSelf=!1,this.parent.get(t,e)}else if(e.self||s){if(s)return e.token=t,e.binding=s,s.get(e)}else if(this.parent)return this.parent.get(t,e);return this.checkBindingNotFoundError(t,e)}onActivation(t){this.onActivationHandler=t}onDeactivation(t){this.onDeactivationHandler=t}activate(t,e){return this.onActivationHandler?this.onActivationHandler({container:this},t,e):t}deactivate(t){this.onDeactivationHandler&&this.onDeactivationHandler(t.cache,t.token)}buildBinding(t){return new L(t,this)}getBinding(t){return this.bindings.get(t)}checkBindingNotFoundError(t,e){if(!e.optional)throw new M(t)}};r(C,"map",new WeakMap);let y=C;function S(n,t){return function(e){return function(s,i,o){const a=typeof o=="number",c=a?s:s.constructor,l=a?o:i,u=a?h.INJECTED_PARAMS:h.INJECTED_PROPS,f=a?T(u,c)||[]:I(u,c)||{},g=f[l]||{};g[n]=e===void 0?t:e,f[l]=g,b(u,f,c)}}}function N(n,t){return e=>(s,i)=>{if(T(n,s.constructor))throw new Error(t);b(n,{key:i,value:e},s.constructor)}}const F=S(h.INJECT),J=S(h.SELF,!0),U=S(h.SKIP_SELF,!0),z=S(h.OPTIONAL,!0),G=N(h.POST_CONSTRUCT,v.POST_CONSTRUCT),Y=N(h.PRE_DESTROY,v.PRE_DESTROY);function P(n,t,e,s){for(let i=n.length-1;i>=0;i--)n[i](t,e,s)}function K(n,t,e){n=Array.isArray(n)?n:[n],typeof e=="number"?P(n,t,void 0,e):typeof e=="string"&&P(n,t.prototype,e)}function $(n,t,e,s){function i(){const a=Symbol.for(t);if(!this.hasOwnProperty(a)){const c=s||y.map.get(this),l=this.constructor;if(!c)throw new Error(`${v.MISS_CONTAINER} ${l.name}`);this[a]=c.get(A(e),{parent:{token:l}})}return this[a]}function o(a){const c=Symbol.for(t);this[c]=a}Object.defineProperty(n,t,{configurable:!0,enumerable:!0,get:i,set:o})}function R(n,t){return function(e,s){$(e,s,n,t)}}function W(n){return function(t){return R(t,n)}}exports.Container=y;exports.Inject=F;exports.LazyInject=R;exports.LazyToken=O;exports.Optional=z;exports.PostConstruct=G;exports.PreDestroy=Y;exports.Self=J;exports.SkipSelf=U;exports.Token=_;exports.createLazyInject=W;exports.decorate=K;
|
|
1
|
+
"use strict";var z=Object.defineProperty;var J=(n,t,e)=>t in n?z(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var r=(n,t,e)=>J(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u={INJECTED_PROPS:"injected:props",INJECT:"inject",SELF:"self",SKIP_SELF:"skipSelf",OPTIONAL:"optional",POST_CONSTRUCT:"postConstruct",PRE_DESTROY:"preDestroy"},f={DEFAULT:"default",INITING:"initing",ACTIVATED:"activated"},d={Invalid:"Invalid",Instance:"Instance",ConstantValue:"ConstantValue",DynamicValue:"DynamicValue"},T={POST_CONSTRUCT:"Multiple @PostConstruct decorators are not allowed in a single class.",PRE_DESTROY:"Multiple @PreDestroy decorators are not allowed in a single class.",INVALID_TOKEN:"@Inject or @LazyInject requires a valid token, but received null or undefined.",LAZY_INJECT_INVALID_TOKEN:"@LazyInject requires a valid token, but received null or undefined."};function y(n,t){return Object.prototype.hasOwnProperty.call(n,t)}const m=Symbol("UNINITIALIZED"),D=new WeakMap;function b(n){return typeof n=="function"&&Object.getPrototypeOf(n)!==Function.prototype}function A(n,t){D.set(n,t)}function V(n){const t=D.get(n);if(t)return t[u.POST_CONSTRUCT];if(b(n))return V(Object.getPrototypeOf(n))}function w(n){const t=D.get(n);if(t)return t[u.PRE_DESTROY];if(b(n))return w(Object.getPrototypeOf(n))}function j(n){const t=D.get(n),e=t&&y(t,u.INJECTED_PROPS)?t[u.INJECTED_PROPS]:void 0;if(!b(n))return e;const i=j(Object.getPrototypeOf(n));if(i||e)return{...i||{},...e||{}}}class U{constructor(t){r(this,"name");this.name=t}}class R{constructor(t){r(this,"_callback");this._callback=t}resolve(){return this._callback()}}function P(n){if(!n)throw new Error(T.INVALID_TOKEN);return n instanceof R?n.resolve():n}class I extends Error{constructor(e,i){const s=(i==null?void 0:i.name)||"<unknown token>";super(`${e}${s}`);r(this,"token");this.name=this.constructor.name,this.token=i}}class O extends I{constructor(t){super("");const e=[];let i=t;for(;i&&i.token;)e.push(i.token),i=i.parent;const s=e.reverse().map(o=>o.name||"<anonymous>").join(" --> ");this.message=`Circular dependency found: ${s}`}}class L extends I{constructor(t){super("Invalid binding: ",t)}}class k extends O{constructor(t){super(t),this.name="CircularDependencyError inside @PostConstruct"}}const C=class C{constructor(t,e){r(this,"container");r(this,"context");r(this,"token");r(this,"type",d.Invalid);r(this,"status",f.DEFAULT);r(this,"classValue");r(this,"constantValue");r(this,"dynamicValue");r(this,"cache");r(this,"postConstructResult",m);r(this,"onActivationHandler");r(this,"onDeactivationHandler");this.container=e,this.context={container:this.container},this.token=t}onActivation(t){this.onActivationHandler=t}onDeactivation(t){this.onDeactivationHandler=t}activate(t){const e=this.onActivationHandler?this.onActivationHandler(this.context,t):t;return this.container.activate(e,this.token)}deactivate(){this.onDeactivationHandler&&this.onDeactivationHandler(this.cache)}to(t){return this.type=d.Instance,this.classValue=t,this}toSelf(){return this.to(this.token)}toConstantValue(t){return this.type=d.ConstantValue,this.constantValue=t,this}toDynamicValue(t){return this.type=d.DynamicValue,this.dynamicValue=t,this}toService(t){return this.toDynamicValue(e=>e.container.get(t,{parent:{token:this.token}}))}get(t){if(f.INITING===this.status)throw new O(t);if(f.ACTIVATED===this.status)return this.cache;const e=C._resolvers[this.type];if(e)return this[e](t);throw new L(this.token)}_getAwaitBindings(t,e){return e===!0?t:Array.isArray(e)?t.filter(i=>e.includes(i.token)):typeof e=="function"?t.filter(e):[]}_postConstruct(t,e){if(d.Instance===this.type){const{key:i,value:s}=V(this.classValue)||{};if(i)if(s){const o=e.filter(c=>d.Instance===(c==null?void 0:c.type)),a=this._getAwaitBindings(o,s);for(const c of a)if(c&&c.postConstructResult===m)throw new k({token:c.token,parent:t});const l=a.map(c=>c.postConstructResult);this.postConstructResult=Promise.all(l).then(()=>this._execute(i))}else this.postConstructResult=this._execute(i);else this.postConstructResult=void 0}}preDestroy(){if(d.Instance===this.type){const{key:t}=w(this.classValue)||{};t&&this._execute(t)}v._instanceContainerMap.delete(this.cache),this.container=null,this.context=null,this.classValue=void 0,this.constantValue=void 0,this.dynamicValue=void 0,this.cache=void 0,this.postConstructResult=m,this.onActivationHandler=void 0,this.onDeactivationHandler=void 0}_execute(t){const e=this.cache[t];return e==null?void 0:e.call(this.cache)}_resolveInstanceValue(t){this.status=f.INITING;const e=this._createInstance();this.cache=this.activate(e),this.status=f.ACTIVATED,this._registerInstance();const{properties:i,bindings:s}=this._getInjectProperties(t);return this._injectProperties(i),this._postConstruct(t,s),this.cache}_createInstance(){const t=this.classValue;return new t}_registerInstance(){v._instanceContainerMap.set(this.cache,this.container)}_injectProperties(t){Object.assign(this.cache,t)}_resolveConstantValue(){return this.status=f.INITING,this.cache=this.activate(this.constantValue),this.status=f.ACTIVATED,this.cache}_resolveDynamicValue(){this.status=f.INITING;const t=this.dynamicValue(this.context);return this.cache=this.activate(t),this.status=f.ACTIVATED,this.cache}_getInjectProperties(t){const e=j(this.classValue)||{},i=Object.keys(e),s=Object.create(null),o=[];for(let a=0;a<i.length;a++){const l=i[a],c=e[l],{inject:_,...h}=c;h.parent=t;const p=this.container.get(P(_),h);p===void 0&&c.optional||(s[l]=p),o.push(h.binding)}return{properties:s,bindings:o}}};r(C,"_resolvers",{[d.Instance]:"_resolveInstanceValue",[d.ConstantValue]:"_resolveConstantValue",[d.DynamicValue]:"_resolveDynamicValue"});let E=C;class B extends I{constructor(t){super("No matching binding found for token: ",t)}}class H extends I{constructor(t){super("Cannot bind token multiple times: ",t)}}const g=class g{constructor(){r(this,"parent");r(this,"children");r(this,"_bindings",new Map);r(this,"_onActivationHandler");r(this,"_onDeactivationHandler")}static getContainerOf(t){return g._instanceContainerMap.get(t)}bind(t){if(this._bindings.has(t))throw new H(t);const e=this._buildBinding(t);return this._bindings.set(t,e),e}unbind(t){if(this._bindings.has(t)){const e=this._getBinding(t);this.deactivate(e),e.deactivate(),e.preDestroy(),this._bindings.delete(t)}}unbindAll(){const t=Array.from(this._bindings.keys());for(const e of t)this.unbind(e)}isCurrentBound(t){return this._bindings.has(t)}isBound(t){return this.isCurrentBound(t)||!!this.parent&&this.parent.isBound(t)}createChild(){const t=new g;return t.parent=this,this.children||(this.children=new Set),this.children.add(t),t}destroy(){var t,e;if(this.children){const i=Array.from(this.children);for(const s of i)s.destroy()}this.unbindAll(),this._bindings.clear(),(e=(t=this.parent)==null?void 0:t.children)==null||e.delete(this),this.parent=void 0,this.children=void 0,this._onActivationHandler=void 0,this._onDeactivationHandler=void 0}get(t,e={}){return e.skipSelf?this._resolveSkipSelf(t,e):e.self?this._resolveSelf(t,e):this._resolveDefault(t,e)}_resolveSkipSelf(t,e){return this.parent?(e.skipSelf=!1,this.parent.get(t,e)):this._checkBindingNotFoundError(t,e)}_resolveSelf(t,e){const i=this._getBinding(t);return i?(e.token=t,e.binding=i,i.get(e)):this._checkBindingNotFoundError(t,e)}_resolveDefault(t,e){const i=this._getBinding(t);return i?(e.token=t,e.binding=i,i.get(e)):this.parent?this.parent.get(t,e):this._checkBindingNotFoundError(t,e)}onActivation(t){this._onActivationHandler=t}onDeactivation(t){this._onDeactivationHandler=t}activate(t,e){return this._onActivationHandler?this._onActivationHandler({container:this},t,e):t}deactivate(t){this._onDeactivationHandler&&this._onDeactivationHandler(t.cache,t.token)}_buildBinding(t){return new E(t,this)}_getBinding(t){return this._bindings.get(t)}_checkBindingNotFoundError(t,e){if(!e.optional)throw new B(t)}};r(g,"_instanceContainerMap",new WeakMap);let v=g;class x extends I{constructor(t,e){super(`@LazyInject(${t==null?void 0:t.name}) in class ${e.name} requires a registered container but none was found. Token: `,t)}}function N(n,t){return function(e){return function(i,s){const o=s.name,a=s.metadata;y(a,u.INJECTED_PROPS)||(a[u.INJECTED_PROPS]={});const l=a[u.INJECTED_PROPS];l[o]||(l[o]={}),l[o][n]=e===void 0?t:e}}}function F(n,t){return e=>(i,s)=>{const o=s.name,a=s.metadata;if(y(a,n))throw new Error(t);a[n]={key:o,value:e}}}const K=N(u.INJECT),Y=N(u.SELF,!0),G=N(u.SKIP_SELF,!0),$=N(u.OPTIONAL,!0),Z=F(u.POST_CONSTRUCT,T.POST_CONSTRUCT),q=F(u.PRE_DESTROY,T.PRE_DESTROY);function W(n,t){const e=t.metadata;A(n,e)}function Q(n,t,e,i){if(e==null)throw new Error(T.LAZY_INJECT_INVALID_TOKEN);const s=Symbol.for(t);Object.defineProperty(n,t,{configurable:!0,enumerable:!0,get(){if(!y(n,s)){const o=i||v.getContainerOf(n),a=n.constructor;if(!o)throw new x(P(e),a);n[s]=o.get(P(e),{parent:{token:a}})}return n[s]},set(o){n[s]=o}})}function M(n,t){return function(e,i){const s=i.name;i.addInitializer(function(){Q(this,s,n,t)})}}function X(n){return function(t){return M(t,n)}}const S=Symbol("decorate.metadata");function tt(n,t,e){const i=Array.isArray(n)?n:[n],s=t.prototype,o=typeof s[e]=="function",a=[];y(t,S)||(t[S]={});const l=t[S],c={kind:o?"method":"field",name:e,static:!1,private:!1,addInitializer(h){a.push(h)},metadata:l};let _=o?s[e]:void 0;for(let h=i.length-1;h>=0;h--){const p=i[h](_,c);o&&typeof p=="function"&&(_=p)}if(o&&_!==s[e]&&(s[e]=_),A(t,l),a.length>0){const h=Object.create(s);for(const p of a)p.call(h)}}exports.BaseError=I;exports.Binding=E;exports.BindingNotFoundError=B;exports.BindingNotValidError=L;exports.CircularDependencyError=O;exports.Container=v;exports.ContainerNotFoundError=x;exports.DuplicateBindingError=H;exports.Inject=K;exports.Injectable=W;exports.LazyInject=M;exports.LazyToken=R;exports.Optional=$;exports.PostConstruct=Z;exports.PostConstructError=k;exports.PreDestroy=q;exports.Self=Y;exports.SkipSelf=G;exports.Token=U;exports.createLazyInject=X;exports.decorate=tt;
|