@kaokei/di 4.0.0 → 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 CHANGED
@@ -17,50 +17,28 @@
17
17
  - [入门指南](./docs/guide/index.md)
18
18
  - [API 文档](./docs/api/index.md)
19
19
  - [博客文章](./docs/note/01.什么是Token.md)
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
20
44
 
21
- ## CodeSandbox 在线示例
22
-
23
- 以下示例托管在 GitHub 仓库的 `examples/` 目录中,可通过 CodeSandbox 直接在线运行。
24
-
25
- URL 格式:`https://codesandbox.io/p/github/kaokei/di/main?file=/examples/<示例目录>/src/index.ts`
26
-
27
- | 示例 | 说明 | 在线运行 |
28
- | ------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
29
- | 01-basic-usage | 基础用法:创建容器、绑定服务、属性注入、单例验证 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/01-basic-usage/src/index.ts) |
30
- | 02-token-usage | Token 用法:Token 实例作为标识符,三种绑定方式 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/02-token-usage/src/index.ts) |
31
- | 03-optional-inject | Optional 注入:依赖不存在时返回 undefined | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/03-optional-inject/src/index.ts) |
32
- | 04-hierarchical-di | 层级容器:父子容器创建与依赖查找 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/04-hierarchical-di/src/index.ts) |
33
- | 05-self-skipself | Self 和 SkipSelf:控制依赖查找范围 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/05-self-skipself/src/index.ts) |
34
- | 06-lifecycle-activation | 激活生命周期:onActivation 钩子与执行顺序 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/06-lifecycle-activation/src/index.ts) |
35
- | 07-lifecycle-deactivation | 销毁生命周期:onDeactivation 钩子与执行顺序 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/07-lifecycle-deactivation/src/index.ts) |
36
- | 08-post-construct | PostConstruct:同步/异步初始化与继承行为 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/08-post-construct/src/index.ts) |
37
- | 09-pre-destroy | PreDestroy:服务销毁前的清理钩子 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/09-pre-destroy/src/index.ts) |
38
- | 10-circular-dependency | 循环依赖:属性注入原生支持循环依赖 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/10-circular-dependency/src/index.ts) |
39
- | 11-lazy-inject | LazyInject:延迟注入,首次访问时才从容器解析 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/11-lazy-inject/src/index.ts) |
40
- | 12-inheritance | 继承:子类继承父类的属性注入与 PostConstruct 规则 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/12-inheritance/src/index.ts) |
41
- | 13-to-service | toService 别名:接口 token 映射到实现类 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/13-to-service/src/index.ts) |
42
- | 14-dynamic-value | 动态值:toDynamicValue 工厂函数与条件注入 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/14-dynamic-value/src/index.ts) |
43
- | 15-error-handling | 错误处理:各种错误类型的触发场景与捕获方式 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/15-error-handling/src/index.ts) |
44
- | 16-javascript-usage | JavaScript 用法:使用 decorate 函数手动应用装饰器 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/16-javascript-usage/src/index.js) |
45
- | 17-container-destroy | 容器销毁:destroy 递归销毁子容器与 getContainerOf | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/17-container-destroy/src/index.ts) |
46
- | 18-deep-circular-dependency | 深层循环依赖:属性注入支持深层循环链,以及循环依赖检测 | [打开](https://codesandbox.io/p/github/kaokei/di/main?file=/examples/18-deep-circular-dependency/src/index.ts) |
47
-
48
- 每个示例目录包含独立的 `package.json`(依赖已发布的 `@kaokei/di` 版本)和 `tsconfig.json`,与主包构建流程完全隔离,可直接在 CodeSandbox 中运行。
49
-
50
- ## 项目特点
51
-
52
- 本项目只有单例模式,没有inversify中其他模式。
53
-
54
- 本项目中@LazyInject 和 @PostConstruct 只支持class服务。
55
-
56
- inversify中执行顺序是:
57
- postConstruct --> binding handler --> container handlers
58
- container handlers --> binding handler --> preDestroy
59
- 本项目执行顺序:
60
- binding handler --> container handlers --> postConstruct
61
- container handlers --> binding handler --> preDestroy
62
-
63
- @postConstruct装饰器在inversify中,如果A类继承了B类。
64
- 此时如果A类和B类都有 @postConstruct,那么B类不会执行,只有A类会执行。
65
- 如果A类没有@postConstruct,那么会执行B类的。
66
- 如果A继承B继承C,并且A,B都没有@postConstruct,那么会执行C类的。
@@ -1,25 +1,40 @@
1
1
  import { CommonToken, PostConstructParam } from './interfaces';
2
- import { KEYS } from './constants';
3
- export interface MetadataMap {
4
- [KEYS.INJECTED_PROPS]: Record<string, Record<string, unknown>>;
5
- [KEYS.POST_CONSTRUCT]: {
6
- key: string;
7
- value?: PostConstructParam;
8
- };
9
- [KEYS.PRE_DESTROY]: {
10
- key: string;
11
- };
12
- }
13
- export declare function defineMetadata<K extends keyof MetadataMap>(metadataKey: K, metadataValue: MetadataMap[K], target: CommonToken): void;
14
- export declare function defineMetadata(metadataKey: string, metadataValue: unknown, target: CommonToken): void;
15
- export declare function getOwnMetadata<K extends keyof MetadataMap>(metadataKey: K, target: CommonToken): MetadataMap[K] | undefined;
16
- export declare function getOwnMetadata(metadataKey: string, target: CommonToken): unknown | undefined;
17
2
  /**
18
- * 使用 hasParentClass 判断当前 target 有没有父类
19
- * 如果没有父类直接使用 getOwnMetadata 获取数据
20
- * 如果有父类,那么需要合并 getOwnMetadata(target) 和 getMetadata(target 的父类)
21
- * 统一使用展开运算符合并,返回外层新对象、内层原始引用
22
- * 不支持 META_KEY_INJECTED_PARAMS 作为 metadataKey
3
+ * 关联 target metadata 对象
4
+ * @Injectable 类装饰器调用,直接存储 context.metadata
23
5
  */
24
- export declare function getMetadata<K extends keyof MetadataMap>(metadataKey: K, target: CommonToken): MetadataMap[K] | undefined;
25
- export declare function getMetadata(metadataKey: string, target: CommonToken): unknown | undefined;
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;
@@ -1,25 +1,40 @@
1
1
  import { CommonToken, PostConstructParam } from './interfaces';
2
- import { KEYS } from './constants';
3
- export interface MetadataMap {
4
- [KEYS.INJECTED_PROPS]: Record<string, Record<string, unknown>>;
5
- [KEYS.POST_CONSTRUCT]: {
6
- key: string;
7
- value?: PostConstructParam;
8
- };
9
- [KEYS.PRE_DESTROY]: {
10
- key: string;
11
- };
12
- }
13
- export declare function defineMetadata<K extends keyof MetadataMap>(metadataKey: K, metadataValue: MetadataMap[K], target: CommonToken): void;
14
- export declare function defineMetadata(metadataKey: string, metadataValue: unknown, target: CommonToken): void;
15
- export declare function getOwnMetadata<K extends keyof MetadataMap>(metadataKey: K, target: CommonToken): MetadataMap[K] | undefined;
16
- export declare function getOwnMetadata(metadataKey: string, target: CommonToken): unknown | undefined;
17
2
  /**
18
- * 使用 hasParentClass 判断当前 target 有没有父类
19
- * 如果没有父类直接使用 getOwnMetadata 获取数据
20
- * 如果有父类,那么需要合并 getOwnMetadata(target) 和 getMetadata(target 的父类)
21
- * 统一使用展开运算符合并,返回外层新对象、内层原始引用
22
- * 不支持 META_KEY_INJECTED_PARAMS 作为 metadataKey
3
+ * 关联 target metadata 对象
4
+ * @Injectable 类装饰器调用,直接存储 context.metadata
23
5
  */
24
- export declare function getMetadata<K extends keyof MetadataMap>(metadataKey: K, target: CommonToken): MetadataMap[K] | undefined;
25
- export declare function getMetadata(metadataKey: string, target: CommonToken): unknown | undefined;
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;
@@ -3,8 +3,8 @@ import { InjectFunction, GenericToken } from './interfaces';
3
3
  /**
4
4
  * 创建属性装饰器的高阶函数(Stage 3 Field Decorator)
5
5
  *
6
- * 通过 context.addInitializer 在实例化时获取构造函数引用,
7
- * 并将装饰器元数据存储到 CacheMap 的 INJECTED_PROPS 分区。
6
+ * 直接在装饰器执行阶段将元数据写入 context.metadata,
7
+ * 不再使用 context.addInitializer,消除实例化时的重复回调。
8
8
  *
9
9
  * @param decoratorKey 装饰器名称(如 'inject'、'self' 等)
10
10
  * @param defaultValue 装饰器的默认参数值
@@ -17,6 +17,16 @@ export declare const SkipSelf: (decoratorValue?: any) => (_value: undefined, con
17
17
  export declare const Optional: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
18
18
  export declare const PostConstruct: (metaValue?: any) => (_value: Function, context: ClassMethodDecoratorContext) => void;
19
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;
20
30
  /**
21
31
  * 延迟注入装饰器,Stage 3 Field Decorator 签名。
22
32
  * 通过 context.addInitializer 在实例上定义 getter/setter,
@@ -3,8 +3,8 @@ import { InjectFunction, GenericToken } from './interfaces';
3
3
  /**
4
4
  * 创建属性装饰器的高阶函数(Stage 3 Field Decorator)
5
5
  *
6
- * 通过 context.addInitializer 在实例化时获取构造函数引用,
7
- * 并将装饰器元数据存储到 CacheMap 的 INJECTED_PROPS 分区。
6
+ * 直接在装饰器执行阶段将元数据写入 context.metadata,
7
+ * 不再使用 context.addInitializer,消除实例化时的重复回调。
8
8
  *
9
9
  * @param decoratorKey 装饰器名称(如 'inject'、'self' 等)
10
10
  * @param defaultValue 装饰器的默认参数值
@@ -17,6 +17,16 @@ export declare const SkipSelf: (decoratorValue?: any) => (_value: undefined, con
17
17
  export declare const Optional: (decoratorValue?: any) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
18
18
  export declare const PostConstruct: (metaValue?: any) => (_value: Function, context: ClassMethodDecoratorContext) => void;
19
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;
20
30
  /**
21
31
  * 延迟注入装饰器,Stage 3 Field Decorator 签名。
22
32
  * 通过 context.addInitializer 在实例上定义 getter/setter,
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var F=Object.defineProperty;var x=(n,t,e)=>t in n?F(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var r=(n,t,e)=>x(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l={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 O(n,t){return Object.prototype.hasOwnProperty.call(n,t)}const N=Symbol("UNINITIALIZED"),A=new WeakMap;function U(n){return typeof n=="function"&&Object.getPrototypeOf(n)!==Function.prototype}function V(n,t,e){const i=A.get(e)||{};i[n]=t,A.set(e,i)}function w(n,t){return(A.get(t)||{})[n]}function y(n,t){const e=w(n,t);if(!U(t))return e;const i=y(n,Object.getPrototypeOf(t));if(i||e)return{...i||{},...e||{}}}class J{constructor(t){r(this,"name");this.name=t}}class R{constructor(t){r(this,"_callback");this._callback=t}resolve(){return this._callback()}}function b(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 m 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 j extends I{constructor(t){super("Invalid binding: ",t)}}class L extends m{constructor(t){super(t),this.name="CircularDependencyError inside @PostConstruct"}}const E=class E{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",N);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 m(t);if(f.ACTIVATED===this.status)return this.cache;const e=E._resolvers[this.type];if(e)return this[e](t);throw new j(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}=y(l.POST_CONSTRUCT,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===N)throw new L({token:c.token,parent:t});const u=a.map(c=>c.postConstructResult);this.postConstructResult=Promise.all(u).then(()=>this._execute(i))}else this.postConstructResult=this._execute(i);else this.postConstructResult=void 0}}preDestroy(){if(d.Instance===this.type){const{key:t}=y(l.PRE_DESTROY,this.classValue)||{};t&&this._execute(t)}_._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=N,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(){_._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=y(l.INJECTED_PROPS,this.classValue)||{},i=Object.keys(e),s=Object.create(null),o=[];for(let a=0;a<i.length;a++){const u=i[a],c=e[u],{inject:p,...v}=c;v.parent=t;const h=this.container.get(b(p),v);h===void 0&&c.optional||(s[u]=h),o.push(v.binding)}return{properties:s,bindings:o}}};r(E,"_resolvers",{[d.Instance]:"_resolveInstanceValue",[d.ConstantValue]:"_resolveConstantValue",[d.DynamicValue]:"_resolveDynamicValue"});let C=E;class k extends I{constructor(t){super("No matching binding found for token: ",t)}}class B 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 B(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 C(t,this)}_getBinding(t){return this._bindings.get(t)}_checkBindingNotFoundError(t,e){if(!e.optional)throw new k(t)}};r(g,"_instanceContainerMap",new WeakMap);let _=g;class H 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 D(n,t){return function(e){return function(i,s){s.addInitializer(function(){const o=this.constructor,a=s.name,u=w(l.INJECTED_PROPS,o)||{},c=u[a]||{};c[n]=e===void 0?t:e,u[a]=c,V(l.INJECTED_PROPS,u,o)})}}}function M(n,t){return e=>(i,s)=>{const o=s.name,a=s.metadata;if(O(a,n))throw new Error(t);a[n]=!0,s.addInitializer(function(){const u=this.constructor;V(n,{key:o,value:e},u)})}}const Y=D(l.INJECT),G=D(l.SELF,!0),K=D(l.SKIP_SELF,!0),$=D(l.OPTIONAL,!0),Z=M(l.POST_CONSTRUCT,T.POST_CONSTRUCT),q=M(l.PRE_DESTROY,T.PRE_DESTROY);function W(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(!O(n,s)){const o=i||_.getContainerOf(n),a=n.constructor;if(!o)throw new H(b(e),a);n[s]=o.get(b(e),{parent:{token:a}})}return n[s]},set(o){n[s]=o}})}function z(n,t){return function(e,i){const s=i.name;i.addInitializer(function(){W(this,s,n,t)})}}function Q(n){return function(t){return z(t,n)}}const S=Symbol("decorate.metadata");function X(n,t,e){const i=Array.isArray(n)?n:[n],s=t.prototype,o=typeof s[e]=="function",a=[];O(t,S)||(t[S]={});const u=t[S],c={kind:o?"method":"field",name:e,static:!1,private:!1,addInitializer(h){a.push(h)},metadata:u};let p=o?s[e]:void 0;for(let h=i.length-1;h>=0;h--){const P=i[h](p,c);o&&typeof P=="function"&&(p=P)}o&&p!==s[e]&&(s[e]=p);const v=Object.create(s);for(const h of a)h.call(v)}exports.BaseError=I;exports.Binding=C;exports.BindingNotFoundError=k;exports.BindingNotValidError=j;exports.CircularDependencyError=m;exports.Container=_;exports.ContainerNotFoundError=H;exports.DuplicateBindingError=B;exports.Inject=Y;exports.LazyInject=z;exports.LazyToken=R;exports.Optional=$;exports.PostConstruct=Z;exports.PostConstructError=L;exports.PreDestroy=q;exports.Self=G;exports.SkipSelf=K;exports.Token=J;exports.createLazyInject=Q;exports.decorate=X;
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;
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@ export type { Newable, InjectFunction, CommonToken, TokenType, GenericToken, Laz
2
2
  export { Container } from './container';
3
3
  export { Binding } from './binding';
4
4
  export { Token, LazyToken } from './token';
5
- export { Inject, Self, SkipSelf, Optional, PostConstruct, PreDestroy, decorate, LazyInject, createLazyInject, } from './decorator';
5
+ export { Inject, Self, SkipSelf, Optional, PostConstruct, PreDestroy, Injectable, decorate, LazyInject, createLazyInject, } from './decorator';
6
6
  export { BaseError } from './errors/BaseError';
7
7
  export { BindingNotFoundError } from './errors/BindingNotFoundError';
8
8
  export { BindingNotValidError } from './errors/BindingNotValidError';
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export type { Newable, InjectFunction, CommonToken, TokenType, GenericToken, Laz
2
2
  export { Container } from './container';
3
3
  export { Binding } from './binding';
4
4
  export { Token, LazyToken } from './token';
5
- export { Inject, Self, SkipSelf, Optional, PostConstruct, PreDestroy, decorate, LazyInject, createLazyInject, } from './decorator';
5
+ export { Inject, Self, SkipSelf, Optional, PostConstruct, PreDestroy, Injectable, decorate, LazyInject, createLazyInject, } from './decorator';
6
6
  export { BaseError } from './errors/BaseError';
7
7
  export { BindingNotFoundError } from './errors/BindingNotFoundError';
8
8
  export { BindingNotValidError } from './errors/BindingNotValidError';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var L = Object.defineProperty;
2
- var j = (n, t, e) => t in n ? L(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
- var r = (n, t, e) => j(n, typeof t != "symbol" ? t + "" : t, e);
4
- const l = {
2
+ var k = (n, t, e) => t in n ? L(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
+ var r = (n, t, e) => k(n, typeof t != "symbol" ? t + "" : t, e);
4
+ const u = {
5
5
  // 记录实例属性装饰器对应的数据的键
6
6
  INJECTED_PROPS: "injected:props",
7
7
  // Inject 装饰器的键
@@ -25,7 +25,7 @@ const l = {
25
25
  Instance: "Instance",
26
26
  ConstantValue: "ConstantValue",
27
27
  DynamicValue: "DynamicValue"
28
- }, C = {
28
+ }, E = {
29
29
  // 用于 decorator.ts 的 createMetaDecorator —— 重复装饰器检测
30
30
  POST_CONSTRUCT: "Multiple @PostConstruct decorators are not allowed in a single class.",
31
31
  PRE_DESTROY: "Multiple @PreDestroy decorators are not allowed in a single class.",
@@ -34,35 +34,42 @@ const l = {
34
34
  // 用于 decorator.ts 的 defineLazyProperty —— 无效 token
35
35
  LAZY_INJECT_INVALID_TOKEN: "@LazyInject requires a valid token, but received null or undefined."
36
36
  };
37
- function m(n, t) {
37
+ function g(n, t) {
38
38
  return Object.prototype.hasOwnProperty.call(n, t);
39
39
  }
40
- const D = Symbol("UNINITIALIZED"), A = /* @__PURE__ */ new WeakMap();
41
- function k(n) {
40
+ const m = Symbol("UNINITIALIZED"), C = /* @__PURE__ */ new WeakMap();
41
+ function O(n) {
42
42
  return typeof n == "function" && Object.getPrototypeOf(n) !== Function.prototype;
43
43
  }
44
- function V(n, t, e) {
45
- const i = A.get(e) || {};
46
- i[n] = t, A.set(e, i);
47
- }
48
44
  function P(n, t) {
49
- return (A.get(t) || {})[n];
45
+ C.set(n, t);
46
+ }
47
+ function S(n) {
48
+ const t = C.get(n);
49
+ if (t)
50
+ return t[u.POST_CONSTRUCT];
51
+ if (O(n))
52
+ return S(Object.getPrototypeOf(n));
53
+ }
54
+ function V(n) {
55
+ const t = C.get(n);
56
+ if (t)
57
+ return t[u.PRE_DESTROY];
58
+ if (O(n))
59
+ return V(Object.getPrototypeOf(n));
50
60
  }
51
- function T(n, t) {
52
- const e = P(n, t);
53
- if (!k(t))
61
+ function w(n) {
62
+ const t = C.get(n), e = t && g(t, u.INJECTED_PROPS) ? t[u.INJECTED_PROPS] : void 0;
63
+ if (!O(n))
54
64
  return e;
55
- const i = T(
56
- n,
57
- Object.getPrototypeOf(t)
58
- );
65
+ const i = w(Object.getPrototypeOf(n));
59
66
  if (i || e)
60
67
  return {
61
68
  ...i || {},
62
69
  ...e || {}
63
70
  };
64
71
  }
65
- class G {
72
+ class Y {
66
73
  constructor(t) {
67
74
  // 仅类型层面存在,无运行时开销
68
75
  r(this, "name");
@@ -78,12 +85,12 @@ class B {
78
85
  return this._callback();
79
86
  }
80
87
  }
81
- function S(n) {
88
+ function b(n) {
82
89
  if (!n)
83
- throw new Error(C.INVALID_TOKEN);
90
+ throw new Error(E.INVALID_TOKEN);
84
91
  return n instanceof B ? n.resolve() : n;
85
92
  }
86
- class g extends Error {
93
+ class y extends Error {
87
94
  constructor(e, i) {
88
95
  const s = (i == null ? void 0 : i.name) || "<unknown token>";
89
96
  super(`${e}${s}`);
@@ -91,28 +98,28 @@ class g extends Error {
91
98
  this.name = this.constructor.name, this.token = i;
92
99
  }
93
100
  }
94
- class w extends g {
101
+ class R extends y {
95
102
  constructor(t) {
96
103
  super("");
97
104
  const e = [];
98
105
  let i = t;
99
106
  for (; i && i.token; )
100
107
  e.push(i.token), i = i.parent;
101
- const s = e.reverse().map((a) => a.name || "<anonymous>").join(" --> ");
108
+ const s = e.reverse().map((o) => o.name || "<anonymous>").join(" --> ");
102
109
  this.message = `Circular dependency found: ${s}`;
103
110
  }
104
111
  }
105
- class H extends g {
112
+ class H extends y {
106
113
  constructor(t) {
107
114
  super("Invalid binding: ", t);
108
115
  }
109
116
  }
110
- class M extends w {
117
+ class x extends R {
111
118
  constructor(t) {
112
119
  super(t), this.name = "CircularDependencyError inside @PostConstruct";
113
120
  }
114
121
  }
115
- const y = class y {
122
+ const T = class T {
116
123
  constructor(t, e) {
117
124
  r(this, "container");
118
125
  r(this, "context");
@@ -123,7 +130,7 @@ const y = class y {
123
130
  r(this, "constantValue");
124
131
  r(this, "dynamicValue");
125
132
  r(this, "cache");
126
- r(this, "postConstructResult", D);
133
+ r(this, "postConstructResult", m);
127
134
  r(this, "onActivationHandler");
128
135
  r(this, "onDeactivationHandler");
129
136
  this.container = e, this.context = { container: this.container }, this.token = t;
@@ -160,10 +167,10 @@ const y = class y {
160
167
  }
161
168
  get(t) {
162
169
  if (f.INITING === this.status)
163
- throw new w(t);
170
+ throw new R(t);
164
171
  if (f.ACTIVATED === this.status)
165
172
  return this.cache;
166
- const e = y._resolvers[this.type];
173
+ const e = T._resolvers[this.type];
167
174
  if (e)
168
175
  return this[e](t);
169
176
  throw new H(this.token);
@@ -186,20 +193,20 @@ const y = class y {
186
193
  */
187
194
  _postConstruct(t, e) {
188
195
  if (d.Instance === this.type) {
189
- const { key: i, value: s } = T(l.POST_CONSTRUCT, this.classValue) || {};
196
+ const { key: i, value: s } = S(this.classValue) || {};
190
197
  if (i)
191
198
  if (s) {
192
- const a = e.filter(
199
+ const o = e.filter(
193
200
  (c) => d.Instance === (c == null ? void 0 : c.type)
194
- ), o = this._getAwaitBindings(a, s);
195
- for (const c of o)
196
- if (c && c.postConstructResult === D)
197
- throw new M({
201
+ ), a = this._getAwaitBindings(o, s);
202
+ for (const c of a)
203
+ if (c && c.postConstructResult === m)
204
+ throw new x({
198
205
  token: c.token,
199
206
  parent: t
200
207
  });
201
- const u = o.map((c) => c.postConstructResult);
202
- this.postConstructResult = Promise.all(u).then(
208
+ const l = a.map((c) => c.postConstructResult);
209
+ this.postConstructResult = Promise.all(l).then(
203
210
  () => this._execute(i)
204
211
  );
205
212
  } else
@@ -210,10 +217,10 @@ const y = class y {
210
217
  }
211
218
  preDestroy() {
212
219
  if (d.Instance === this.type) {
213
- const { key: t } = T(l.PRE_DESTROY, this.classValue) || {};
220
+ const { key: t } = V(this.classValue) || {};
214
221
  t && this._execute(t);
215
222
  }
216
- I._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 = D, this.onActivationHandler = void 0, this.onDeactivationHandler = void 0;
223
+ I._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;
217
224
  }
218
225
  _execute(t) {
219
226
  const e = this.cache[t];
@@ -248,32 +255,32 @@ const y = class y {
248
255
  return this.cache = this.activate(t), this.status = f.ACTIVATED, this.cache;
249
256
  }
250
257
  _getInjectProperties(t) {
251
- const e = T(l.INJECTED_PROPS, this.classValue) || {}, i = Object.keys(e), s = /* @__PURE__ */ Object.create(null), a = [];
252
- for (let o = 0; o < i.length; o++) {
253
- const u = i[o], c = e[u], { inject: p, ..._ } = c;
254
- _.parent = t;
255
- const h = this.container.get(
256
- S(p),
257
- _
258
+ const e = w(this.classValue) || {}, i = Object.keys(e), s = /* @__PURE__ */ Object.create(null), o = [];
259
+ for (let a = 0; a < i.length; a++) {
260
+ const l = i[a], c = e[l], { inject: _, ...h } = c;
261
+ h.parent = t;
262
+ const p = this.container.get(
263
+ b(_),
264
+ h
258
265
  );
259
- h === void 0 && c.optional || (s[u] = h), a.push(_.binding);
266
+ p === void 0 && c.optional || (s[l] = p), o.push(h.binding);
260
267
  }
261
- return { properties: s, bindings: a };
268
+ return { properties: s, bindings: o };
262
269
  }
263
270
  };
264
271
  // 类型到解析方法的静态映射表,用于替代 get 方法中的 if-else 链
265
- r(y, "_resolvers", {
272
+ r(T, "_resolvers", {
266
273
  [d.Instance]: "_resolveInstanceValue",
267
274
  [d.ConstantValue]: "_resolveConstantValue",
268
275
  [d.DynamicValue]: "_resolveDynamicValue"
269
276
  });
270
- let b = y;
271
- class x extends g {
277
+ let A = T;
278
+ class M extends y {
272
279
  constructor(t) {
273
280
  super("No matching binding found for token: ", t);
274
281
  }
275
282
  }
276
- class F extends g {
283
+ class F extends y {
277
284
  constructor(t) {
278
285
  super("Cannot bind token multiple times: ", t);
279
286
  }
@@ -356,14 +363,14 @@ const v = class v {
356
363
  this._onDeactivationHandler && this._onDeactivationHandler(t.cache, t.token);
357
364
  }
358
365
  _buildBinding(t) {
359
- return new b(t, this);
366
+ return new A(t, this);
360
367
  }
361
368
  _getBinding(t) {
362
369
  return this._bindings.get(t);
363
370
  }
364
371
  _checkBindingNotFoundError(t, e) {
365
372
  if (!e.optional)
366
- throw new x(t);
373
+ throw new M(t);
367
374
  }
368
375
  };
369
376
  // 实例到容器的映射表,用于 @LazyInject 查找实例所属容器
@@ -374,7 +381,7 @@ const v = class v {
374
381
  // 由于 Instance 类型每次都通过 new ClassName() 创建新实例,不存在同一实例被多个容器注册的覆盖风险
375
382
  r(v, "_instanceContainerMap", /* @__PURE__ */ new WeakMap());
376
383
  let I = v;
377
- class z extends g {
384
+ class z extends y {
378
385
  constructor(t, e) {
379
386
  super(
380
387
  `@LazyInject(${t == null ? void 0 : t.name}) in class ${e.name} requires a registered container but none was found. Token: `,
@@ -382,113 +389,116 @@ class z extends g {
382
389
  );
383
390
  }
384
391
  }
385
- function E(n, t) {
392
+ function D(n, t) {
386
393
  return function(e) {
387
394
  return function(i, s) {
388
- s.addInitializer(function() {
389
- const a = this.constructor, o = s.name, u = P(l.INJECTED_PROPS, a) || {}, c = u[o] || {};
390
- c[n] = e === void 0 ? t : e, u[o] = c, V(l.INJECTED_PROPS, u, a);
391
- });
395
+ const o = s.name, a = s.metadata;
396
+ g(a, u.INJECTED_PROPS) || (a[u.INJECTED_PROPS] = {});
397
+ const l = a[u.INJECTED_PROPS];
398
+ l[o] || (l[o] = {}), l[o][n] = e === void 0 ? t : e;
392
399
  };
393
400
  };
394
401
  }
395
- function R(n, t) {
402
+ function j(n, t) {
396
403
  return (e) => (i, s) => {
397
- const a = s.name, o = s.metadata;
398
- if (m(o, n))
404
+ const o = s.name, a = s.metadata;
405
+ if (g(a, n))
399
406
  throw new Error(t);
400
- o[n] = !0, s.addInitializer(function() {
401
- const u = this.constructor;
402
- V(n, { key: a, value: e }, u);
403
- });
407
+ a[n] = { key: o, value: e };
404
408
  };
405
409
  }
406
- const K = E(l.INJECT), $ = E(l.SELF, !0), Z = E(l.SKIP_SELF, !0), q = E(l.OPTIONAL, !0), W = R(
407
- l.POST_CONSTRUCT,
408
- C.POST_CONSTRUCT
409
- ), Q = R(
410
- l.PRE_DESTROY,
411
- C.PRE_DESTROY
410
+ const G = D(u.INJECT), $ = D(u.SELF, !0), Z = D(u.SKIP_SELF, !0), q = D(u.OPTIONAL, !0), W = j(
411
+ u.POST_CONSTRUCT,
412
+ E.POST_CONSTRUCT
413
+ ), Q = j(
414
+ u.PRE_DESTROY,
415
+ E.PRE_DESTROY
412
416
  );
413
- function U(n, t, e, i) {
417
+ function X(n, t) {
418
+ const e = t.metadata;
419
+ P(n, e);
420
+ }
421
+ function J(n, t, e, i) {
414
422
  if (e == null)
415
- throw new Error(C.LAZY_INJECT_INVALID_TOKEN);
423
+ throw new Error(E.LAZY_INJECT_INVALID_TOKEN);
416
424
  const s = Symbol.for(t);
417
425
  Object.defineProperty(n, t, {
418
426
  configurable: !0,
419
427
  enumerable: !0,
420
428
  get() {
421
- if (!m(n, s)) {
422
- const a = i || I.getContainerOf(n), o = n.constructor;
423
- if (!a)
424
- throw new z(S(e), o);
425
- n[s] = a.get(S(e), {
426
- parent: { token: o }
429
+ if (!g(n, s)) {
430
+ const o = i || I.getContainerOf(n), a = n.constructor;
431
+ if (!o)
432
+ throw new z(b(e), a);
433
+ n[s] = o.get(b(e), {
434
+ parent: { token: a }
427
435
  });
428
436
  }
429
437
  return n[s];
430
438
  },
431
- set(a) {
432
- n[s] = a;
439
+ set(o) {
440
+ n[s] = o;
433
441
  }
434
442
  });
435
443
  }
436
- function J(n, t) {
444
+ function U(n, t) {
437
445
  return function(e, i) {
438
446
  const s = i.name;
439
447
  i.addInitializer(function() {
440
- U(this, s, n, t);
448
+ J(this, s, n, t);
441
449
  });
442
450
  };
443
451
  }
444
- function X(n) {
452
+ function tt(n) {
445
453
  return function(t) {
446
- return J(t, n);
454
+ return U(t, n);
447
455
  };
448
456
  }
449
457
  const N = Symbol("decorate.metadata");
450
- function tt(n, t, e) {
451
- const i = Array.isArray(n) ? n : [n], s = t.prototype, a = typeof s[e] == "function", o = [];
452
- m(t, N) || (t[N] = {});
453
- const u = t[N], c = {
454
- kind: a ? "method" : "field",
458
+ function et(n, t, e) {
459
+ const i = Array.isArray(n) ? n : [n], s = t.prototype, o = typeof s[e] == "function", a = [];
460
+ g(t, N) || (t[N] = {});
461
+ const l = t[N], c = {
462
+ kind: o ? "method" : "field",
455
463
  name: e,
456
464
  static: !1,
457
465
  private: !1,
458
466
  addInitializer(h) {
459
- o.push(h);
467
+ a.push(h);
460
468
  },
461
- metadata: u
469
+ metadata: l
462
470
  };
463
- let p = a ? s[e] : void 0;
471
+ let _ = o ? s[e] : void 0;
464
472
  for (let h = i.length - 1; h >= 0; h--) {
465
- const O = i[h](p, c);
466
- a && typeof O == "function" && (p = O);
473
+ const p = i[h](_, c);
474
+ o && typeof p == "function" && (_ = p);
475
+ }
476
+ if (o && _ !== s[e] && (s[e] = _), P(t, l), a.length > 0) {
477
+ const h = Object.create(s);
478
+ for (const p of a)
479
+ p.call(h);
467
480
  }
468
- a && p !== s[e] && (s[e] = p);
469
- const _ = Object.create(s);
470
- for (const h of o)
471
- h.call(_);
472
481
  }
473
482
  export {
474
- g as BaseError,
475
- b as Binding,
476
- x as BindingNotFoundError,
483
+ y as BaseError,
484
+ A as Binding,
485
+ M as BindingNotFoundError,
477
486
  H as BindingNotValidError,
478
- w as CircularDependencyError,
487
+ R as CircularDependencyError,
479
488
  I as Container,
480
489
  z as ContainerNotFoundError,
481
490
  F as DuplicateBindingError,
482
- K as Inject,
483
- J as LazyInject,
491
+ G as Inject,
492
+ X as Injectable,
493
+ U as LazyInject,
484
494
  B as LazyToken,
485
495
  q as Optional,
486
496
  W as PostConstruct,
487
- M as PostConstructError,
497
+ x as PostConstructError,
488
498
  Q as PreDestroy,
489
499
  $ as Self,
490
500
  Z as SkipSelf,
491
- G as Token,
492
- X as createLazyInject,
493
- tt as decorate
501
+ Y as Token,
502
+ tt as createLazyInject,
503
+ et as decorate
494
504
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaokei/di",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "type": "module",
5
5
  "description": "Tiny di library depends on typescript decorator.",
6
6
  "main": "./dist/index.cjs",
@@ -62,7 +62,7 @@
62
62
  "reflect-metadata": "^0.2.2",
63
63
  "standard-version": "^9.5.0",
64
64
  "typescript": "~5.6.3",
65
- "vite": "^5.4.14",
65
+ "vite": "^6.0.0",
66
66
  "vite-plugin-dts": "^4.5.0",
67
67
  "vitepress": "^1.6.3",
68
68
  "vitest": "^3.1.1",