@kaokei/di 5.0.0 → 5.0.2
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 +0 -24
- package/dist/binding.d.cts +2 -0
- package/dist/binding.d.ts +2 -0
- package/dist/constants.d.cts +4 -4
- package/dist/constants.d.ts +4 -4
- package/dist/container.d.cts +7 -0
- package/dist/container.d.ts +7 -0
- package/dist/decorator.d.cts +15 -2
- package/dist/decorator.d.ts +15 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +115 -94
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -18,27 +18,3 @@
|
|
|
18
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
|
@@ -17,6 +17,7 @@ export declare class Binding<T = unknown> {
|
|
|
17
17
|
dynamicValue?: DynamicValue<T>;
|
|
18
18
|
cache?: T;
|
|
19
19
|
postConstructResult: Promise<void> | symbol | undefined;
|
|
20
|
+
transient: boolean;
|
|
20
21
|
onActivationHandler?: ActivationHandler<T>;
|
|
21
22
|
onDeactivationHandler?: DeactivationHandler<T>;
|
|
22
23
|
constructor(token: CommonToken<T>, container: Container);
|
|
@@ -28,6 +29,7 @@ export declare class Binding<T = unknown> {
|
|
|
28
29
|
toSelf(): this;
|
|
29
30
|
toConstantValue(value: T): this;
|
|
30
31
|
toDynamicValue(func: DynamicValue<T>): this;
|
|
32
|
+
inTransientScope(): this;
|
|
31
33
|
toService(token: CommonToken<T>): this;
|
|
32
34
|
get(options: Options<T>): any;
|
|
33
35
|
_getAwaitBindings(bindings: Binding[], filter: PostConstructParam): Binding[];
|
package/dist/binding.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare class Binding<T = unknown> {
|
|
|
17
17
|
dynamicValue?: DynamicValue<T>;
|
|
18
18
|
cache?: T;
|
|
19
19
|
postConstructResult: Promise<void> | symbol | undefined;
|
|
20
|
+
transient: boolean;
|
|
20
21
|
onActivationHandler?: ActivationHandler<T>;
|
|
21
22
|
onDeactivationHandler?: DeactivationHandler<T>;
|
|
22
23
|
constructor(token: CommonToken<T>, container: Container);
|
|
@@ -28,6 +29,7 @@ export declare class Binding<T = unknown> {
|
|
|
28
29
|
toSelf(): this;
|
|
29
30
|
toConstantValue(value: T): this;
|
|
30
31
|
toDynamicValue(func: DynamicValue<T>): this;
|
|
32
|
+
inTransientScope(): this;
|
|
31
33
|
toService(token: CommonToken<T>): this;
|
|
32
34
|
get(options: Options<T>): any;
|
|
33
35
|
_getAwaitBindings(bindings: Binding[], filter: PostConstructParam): Binding[];
|
package/dist/constants.d.cts
CHANGED
|
@@ -13,10 +13,10 @@ export declare const STATUS: {
|
|
|
13
13
|
readonly ACTIVATED: "activated";
|
|
14
14
|
};
|
|
15
15
|
export declare const BINDING: {
|
|
16
|
-
readonly
|
|
17
|
-
readonly
|
|
18
|
-
readonly
|
|
19
|
-
readonly
|
|
16
|
+
readonly INVALID: "Invalid";
|
|
17
|
+
readonly INSTANCE: "Instance";
|
|
18
|
+
readonly CONSTANT: "ConstantValue";
|
|
19
|
+
readonly DYNAMIC: "DynamicValue";
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* 错误消息模板
|
package/dist/constants.d.ts
CHANGED
|
@@ -13,10 +13,10 @@ export declare const STATUS: {
|
|
|
13
13
|
readonly ACTIVATED: "activated";
|
|
14
14
|
};
|
|
15
15
|
export declare const BINDING: {
|
|
16
|
-
readonly
|
|
17
|
-
readonly
|
|
18
|
-
readonly
|
|
19
|
-
readonly
|
|
16
|
+
readonly INVALID: "Invalid";
|
|
17
|
+
readonly INSTANCE: "Instance";
|
|
18
|
+
readonly CONSTANT: "ConstantValue";
|
|
19
|
+
readonly DYNAMIC: "DynamicValue";
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* 错误消息模板
|
package/dist/container.d.cts
CHANGED
|
@@ -22,6 +22,13 @@ export declare class Container {
|
|
|
22
22
|
optional?: false;
|
|
23
23
|
}): T;
|
|
24
24
|
get<T>(token: CommonToken<T>, options?: Options<T>): T | void;
|
|
25
|
+
getAsync<T>(token: CommonToken<T>, options: Options<T> & {
|
|
26
|
+
optional: true;
|
|
27
|
+
}): Promise<T | void>;
|
|
28
|
+
getAsync<T>(token: CommonToken<T>, options?: Options<T> & {
|
|
29
|
+
optional?: false;
|
|
30
|
+
}): Promise<T>;
|
|
31
|
+
getAsync<T>(token: CommonToken<T>, options?: Options<T>): Promise<T | void>;
|
|
25
32
|
_resolveSkipSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
26
33
|
_resolveSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
27
34
|
_resolveDefault<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
package/dist/container.d.ts
CHANGED
|
@@ -22,6 +22,13 @@ export declare class Container {
|
|
|
22
22
|
optional?: false;
|
|
23
23
|
}): T;
|
|
24
24
|
get<T>(token: CommonToken<T>, options?: Options<T>): T | void;
|
|
25
|
+
getAsync<T>(token: CommonToken<T>, options: Options<T> & {
|
|
26
|
+
optional: true;
|
|
27
|
+
}): Promise<T | void>;
|
|
28
|
+
getAsync<T>(token: CommonToken<T>, options?: Options<T> & {
|
|
29
|
+
optional?: false;
|
|
30
|
+
}): Promise<T>;
|
|
31
|
+
getAsync<T>(token: CommonToken<T>, options?: Options<T>): Promise<T | void>;
|
|
25
32
|
_resolveSkipSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
26
33
|
_resolveSelf<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
|
27
34
|
_resolveDefault<T>(token: CommonToken<T>, options: Options<T>): T | void;
|
package/dist/decorator.d.cts
CHANGED
|
@@ -24,9 +24,9 @@ export declare const PreDestroy: (metaValue?: any) => (_value: Function, context
|
|
|
24
24
|
* @Injectable 读取 context.metadata 并通过 defineMetadata 写入 CacheMap,
|
|
25
25
|
* 建立 target → metadata 的映射关系。
|
|
26
26
|
*
|
|
27
|
-
* 使用方式:@Injectable
|
|
27
|
+
* 使用方式:@Injectable()(需要调用,与其他装饰器保持一致)
|
|
28
28
|
*/
|
|
29
|
-
export declare function Injectable(Ctor: Function, context: ClassDecoratorContext)
|
|
29
|
+
export declare function Injectable(): (Ctor: Function, context: ClassDecoratorContext) => void;
|
|
30
30
|
/**
|
|
31
31
|
* 延迟注入装饰器,Stage 3 Field Decorator 签名。
|
|
32
32
|
* 通过 context.addInitializer 在实例上定义 getter/setter,
|
|
@@ -41,5 +41,18 @@ export declare function LazyInject<T>(token: GenericToken<T>, container?: Contai
|
|
|
41
41
|
* 创建绑定到指定容器的延迟注入装饰器工厂。
|
|
42
42
|
*/
|
|
43
43
|
export declare function createLazyInject(container: Container): <T>(token: GenericToken<T>) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
44
|
+
/**
|
|
45
|
+
* 方法装饰器:自动绑定方法的 this 到实例(Stage 3 Method Decorator)
|
|
46
|
+
*
|
|
47
|
+
* 解决方法作为回调传递时丢失 this 的问题,例如:
|
|
48
|
+
* - Vue 模板中 `@click="service.method"` 丢失 this
|
|
49
|
+
* - `promise.then(service.method)` 丢失 this
|
|
50
|
+
*
|
|
51
|
+
* 通过 context.addInitializer 在实例创建时执行 bind,
|
|
52
|
+
* 每个实例都会拥有自己的绑定版本,互不影响。
|
|
53
|
+
*
|
|
54
|
+
* 使用方式:@autobind(无参数,直接作为装饰器使用)
|
|
55
|
+
*/
|
|
56
|
+
export declare function autobind<T extends (...args: any[]) => any>(value: T, context: ClassMethodDecoratorContext): void;
|
|
44
57
|
export declare function decorate(decorator: any, target: any, key: string): void;
|
|
45
58
|
export {};
|
package/dist/decorator.d.ts
CHANGED
|
@@ -24,9 +24,9 @@ export declare const PreDestroy: (metaValue?: any) => (_value: Function, context
|
|
|
24
24
|
* @Injectable 读取 context.metadata 并通过 defineMetadata 写入 CacheMap,
|
|
25
25
|
* 建立 target → metadata 的映射关系。
|
|
26
26
|
*
|
|
27
|
-
* 使用方式:@Injectable
|
|
27
|
+
* 使用方式:@Injectable()(需要调用,与其他装饰器保持一致)
|
|
28
28
|
*/
|
|
29
|
-
export declare function Injectable(Ctor: Function, context: ClassDecoratorContext)
|
|
29
|
+
export declare function Injectable(): (Ctor: Function, context: ClassDecoratorContext) => void;
|
|
30
30
|
/**
|
|
31
31
|
* 延迟注入装饰器,Stage 3 Field Decorator 签名。
|
|
32
32
|
* 通过 context.addInitializer 在实例上定义 getter/setter,
|
|
@@ -41,5 +41,18 @@ export declare function LazyInject<T>(token: GenericToken<T>, container?: Contai
|
|
|
41
41
|
* 创建绑定到指定容器的延迟注入装饰器工厂。
|
|
42
42
|
*/
|
|
43
43
|
export declare function createLazyInject(container: Container): <T>(token: GenericToken<T>) => (_value: undefined, context: ClassFieldDecoratorContext) => void;
|
|
44
|
+
/**
|
|
45
|
+
* 方法装饰器:自动绑定方法的 this 到实例(Stage 3 Method Decorator)
|
|
46
|
+
*
|
|
47
|
+
* 解决方法作为回调传递时丢失 this 的问题,例如:
|
|
48
|
+
* - Vue 模板中 `@click="service.method"` 丢失 this
|
|
49
|
+
* - `promise.then(service.method)` 丢失 this
|
|
50
|
+
*
|
|
51
|
+
* 通过 context.addInitializer 在实例创建时执行 bind,
|
|
52
|
+
* 每个实例都会拥有自己的绑定版本,互不影响。
|
|
53
|
+
*
|
|
54
|
+
* 使用方式:@autobind(无参数,直接作为装饰器使用)
|
|
55
|
+
*/
|
|
56
|
+
export declare function autobind<T extends (...args: any[]) => any>(value: T, context: ClassMethodDecoratorContext): void;
|
|
44
57
|
export declare function decorate(decorator: any, target: any, key: string): void;
|
|
45
58
|
export {};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
"use strict";var z=Object.defineProperty;var U=(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)=>U(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"},d={DEFAULT:"default",INITING:"initing",ACTIVATED:"activated"},f={INVALID:"Invalid",INSTANCE:"Instance",CONSTANT:"ConstantValue",DYNAMIC:"DynamicValue"},g={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 N(n,t){return Object.prototype.hasOwnProperty.call(n,t)}const D=Symbol("UNINITIALIZED"),y=new WeakMap;function m(n){return typeof n=="function"&&Object.getPrototypeOf(n)!==Function.prototype}function P(n,t){y.set(n,t)}function V(n){const t=y.get(n);if(t)return t[u.POST_CONSTRUCT];if(m(n))return V(Object.getPrototypeOf(n))}function w(n){const t=y.get(n);if(t)return t[u.PRE_DESTROY];if(m(n))return w(Object.getPrototypeOf(n))}function R(n){const t=y.get(n),e=t&&N(t,u.INJECTED_PROPS)?t[u.INJECTED_PROPS]:void 0;if(!m(n))return e;const i=R(Object.getPrototypeOf(n));if(i||e)return{...i||{},...e||{}}}class Y{constructor(t){r(this,"name");this.name=t}}class j{constructor(t){r(this,"_callback");this._callback=t}resolve(){return this._callback()}}function b(n){if(!n)throw new Error(g.INVALID_TOKEN);return n instanceof j?n.resolve():n}class v 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 v{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 v{constructor(t){super("Invalid binding: ",t)}}class k extends O{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",f.INVALID);r(this,"status",d.DEFAULT);r(this,"classValue");r(this,"constantValue");r(this,"dynamicValue");r(this,"cache");r(this,"postConstructResult",D);r(this,"transient",!1);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=f.INSTANCE,this.classValue=t,this}toSelf(){return this.to(this.token)}toConstantValue(t){return this.type=f.CONSTANT,this.constantValue=t,this}toDynamicValue(t){return this.type=f.DYNAMIC,this.dynamicValue=t,this}inTransientScope(){return this.transient=!0,this}toService(t){return this.toDynamicValue(e=>e.container.get(t,{parent:{token:this.token}}))}get(t){if(d.INITING===this.status)throw new O(t);if(d.ACTIVATED===this.status)if(this.transient)this.status=d.DEFAULT;else return this.cache;const e=E._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(f.INSTANCE===this.type){const{key:i,value:s}=V(this.classValue)||{};if(i)if(s){const o=e.filter(c=>f.INSTANCE===(c==null?void 0:c.type)),a=this._getAwaitBindings(o,s);for(const c of a)if(c&&c.postConstructResult===D)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(f.INSTANCE===this.type){const{key:t}=w(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=D,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=d.INITING;const e=this._createInstance();this.cache=this.activate(e),this.status=d.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=d.INITING,this.cache=this.activate(this.constantValue),this.status=d.ACTIVATED,this.cache}_resolveDynamicValue(){this.status=d.INITING;const t=this.dynamicValue(this.context);return this.cache=this.activate(t),this.status=d.ACTIVATED,this.cache}_getInjectProperties(t){const e=R(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:I,...h}=c;h.parent=t;const p=this.container.get(b(I),h);p===void 0&&c.optional||(s[l]=p),o.push(h.binding)}return{properties:s,bindings:o}}};r(E,"_resolvers",{[f.INSTANCE]:"_resolveInstanceValue",[f.CONSTANT]:"_resolveConstantValue",[f.DYNAMIC]:"_resolveDynamicValue"});let C=E;class B extends v{constructor(t){super("No matching binding found for token: ",t)}}class H extends v{constructor(t){super("Cannot bind token multiple times: ",t)}}const T=class T{constructor(){r(this,"parent");r(this,"children");r(this,"_bindings",new Map);r(this,"_onActivationHandler");r(this,"_onDeactivationHandler")}static getContainerOf(t){return T._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 T;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)}async getAsync(t,e={}){const i=this.get(t,e),s=e.binding;return(s==null?void 0:s.postConstructResult)instanceof Promise&&await s.postConstructResult,i}_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 B(t)}};r(T,"_instanceContainerMap",new WeakMap);let _=T;class M extends v{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 A(n,t){return function(e){return function(i,s){const o=s.name,a=s.metadata;N(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(N(a,n))throw new Error(t);a[n]={key:o,value:e}}}const J=A(u.INJECT),K=A(u.SELF,!0),G=A(u.SKIP_SELF,!0),$=A(u.OPTIONAL,!0),Z=F(u.POST_CONSTRUCT,g.POST_CONSTRUCT),q=F(u.PRE_DESTROY,g.PRE_DESTROY);function W(){return function(n,t){const e=t.metadata;P(n,e)}}function Q(n,t,e,i){if(e==null)throw new Error(g.LAZY_INJECT_INVALID_TOKEN);const s=Symbol.for(t);Object.defineProperty(n,t,{configurable:!0,enumerable:!0,get(){if(!N(n,s)){const o=i||_.getContainerOf(n),a=n.constructor;if(!o)throw new M(b(e),a);n[s]=o.get(b(e),{parent:{token:a}})}return n[s]},set(o){n[s]=o}})}function x(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 x(t,n)}}function tt(n,t){const e=t.name;t.addInitializer(function(){this[e]=n.bind(this)})}const S=Symbol("decorate.metadata");function et(n,t,e){const i=Array.isArray(n)?n:[n],s=t.prototype,o=typeof s[e]=="function",a=[];N(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 I=o?s[e]:void 0;for(let h=i.length-1;h>=0;h--){const p=i[h](I,c);o&&typeof p=="function"&&(I=p)}if(o&&I!==s[e]&&(s[e]=I),P(t,l),a.length>0){const h=Object.create(s);for(const p of a)p.call(h)}}exports.BaseError=v;exports.Binding=C;exports.BindingNotFoundError=B;exports.BindingNotValidError=L;exports.CircularDependencyError=O;exports.Container=_;exports.ContainerNotFoundError=M;exports.DuplicateBindingError=H;exports.Inject=J;exports.Injectable=W;exports.LazyInject=x;exports.LazyToken=j;exports.Optional=$;exports.PostConstruct=Z;exports.PostConstructError=k;exports.PreDestroy=q;exports.Self=K;exports.SkipSelf=G;exports.Token=Y;exports.autobind=tt;exports.createLazyInject=X;exports.decorate=et;
|
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, Injectable, decorate, LazyInject, createLazyInject, } from './decorator';
|
|
5
|
+
export { Inject, Self, SkipSelf, Optional, PostConstruct, PreDestroy, Injectable, decorate, LazyInject, createLazyInject, autobind, } 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, Injectable, decorate, LazyInject, createLazyInject, } from './decorator';
|
|
5
|
+
export { Inject, Self, SkipSelf, Optional, PostConstruct, PreDestroy, Injectable, decorate, LazyInject, createLazyInject, autobind, } 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
|
@@ -16,16 +16,16 @@ const u = {
|
|
|
16
16
|
POST_CONSTRUCT: "postConstruct",
|
|
17
17
|
// PreDestroy 装饰器的键
|
|
18
18
|
PRE_DESTROY: "preDestroy"
|
|
19
|
-
},
|
|
19
|
+
}, d = {
|
|
20
20
|
DEFAULT: "default",
|
|
21
21
|
INITING: "initing",
|
|
22
22
|
ACTIVATED: "activated"
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
23
|
+
}, f = {
|
|
24
|
+
INVALID: "Invalid",
|
|
25
|
+
INSTANCE: "Instance",
|
|
26
|
+
CONSTANT: "ConstantValue",
|
|
27
|
+
DYNAMIC: "DynamicValue"
|
|
28
|
+
}, g = {
|
|
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,32 +34,32 @@ const u = {
|
|
|
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
|
|
37
|
+
function T(n, t) {
|
|
38
38
|
return Object.prototype.hasOwnProperty.call(n, t);
|
|
39
39
|
}
|
|
40
|
-
const
|
|
40
|
+
const y = Symbol("UNINITIALIZED"), E = /* @__PURE__ */ new WeakMap();
|
|
41
41
|
function O(n) {
|
|
42
42
|
return typeof n == "function" && Object.getPrototypeOf(n) !== Function.prototype;
|
|
43
43
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
44
|
+
function b(n, t) {
|
|
45
|
+
E.set(n, t);
|
|
46
46
|
}
|
|
47
|
-
function
|
|
48
|
-
const t =
|
|
47
|
+
function P(n) {
|
|
48
|
+
const t = E.get(n);
|
|
49
49
|
if (t)
|
|
50
50
|
return t[u.POST_CONSTRUCT];
|
|
51
51
|
if (O(n))
|
|
52
|
-
return
|
|
52
|
+
return P(Object.getPrototypeOf(n));
|
|
53
53
|
}
|
|
54
54
|
function V(n) {
|
|
55
|
-
const t =
|
|
55
|
+
const t = E.get(n);
|
|
56
56
|
if (t)
|
|
57
57
|
return t[u.PRE_DESTROY];
|
|
58
58
|
if (O(n))
|
|
59
59
|
return V(Object.getPrototypeOf(n));
|
|
60
60
|
}
|
|
61
61
|
function w(n) {
|
|
62
|
-
const t =
|
|
62
|
+
const t = E.get(n), e = t && T(t, u.INJECTED_PROPS) ? t[u.INJECTED_PROPS] : void 0;
|
|
63
63
|
if (!O(n))
|
|
64
64
|
return e;
|
|
65
65
|
const i = w(Object.getPrototypeOf(n));
|
|
@@ -69,7 +69,7 @@ function w(n) {
|
|
|
69
69
|
...e || {}
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
-
class
|
|
72
|
+
class K {
|
|
73
73
|
constructor(t) {
|
|
74
74
|
// 仅类型层面存在,无运行时开销
|
|
75
75
|
r(this, "name");
|
|
@@ -85,12 +85,12 @@ class B {
|
|
|
85
85
|
return this._callback();
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
function
|
|
88
|
+
function S(n) {
|
|
89
89
|
if (!n)
|
|
90
|
-
throw new Error(
|
|
90
|
+
throw new Error(g.INVALID_TOKEN);
|
|
91
91
|
return n instanceof B ? n.resolve() : n;
|
|
92
92
|
}
|
|
93
|
-
class
|
|
93
|
+
class N extends Error {
|
|
94
94
|
constructor(e, i) {
|
|
95
95
|
const s = (i == null ? void 0 : i.name) || "<unknown token>";
|
|
96
96
|
super(`${e}${s}`);
|
|
@@ -98,7 +98,7 @@ class y extends Error {
|
|
|
98
98
|
this.name = this.constructor.name, this.token = i;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
class R extends
|
|
101
|
+
class R extends N {
|
|
102
102
|
constructor(t) {
|
|
103
103
|
super("");
|
|
104
104
|
const e = [];
|
|
@@ -109,28 +109,30 @@ class R extends y {
|
|
|
109
109
|
this.message = `Circular dependency found: ${s}`;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
class H extends
|
|
112
|
+
class H extends N {
|
|
113
113
|
constructor(t) {
|
|
114
114
|
super("Invalid binding: ", t);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
class
|
|
117
|
+
class M extends R {
|
|
118
118
|
constructor(t) {
|
|
119
119
|
super(t), this.name = "CircularDependencyError inside @PostConstruct";
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
const
|
|
122
|
+
const C = class C {
|
|
123
123
|
constructor(t, e) {
|
|
124
124
|
r(this, "container");
|
|
125
125
|
r(this, "context");
|
|
126
126
|
r(this, "token");
|
|
127
|
-
r(this, "type",
|
|
128
|
-
r(this, "status",
|
|
127
|
+
r(this, "type", f.INVALID);
|
|
128
|
+
r(this, "status", d.DEFAULT);
|
|
129
129
|
r(this, "classValue");
|
|
130
130
|
r(this, "constantValue");
|
|
131
131
|
r(this, "dynamicValue");
|
|
132
132
|
r(this, "cache");
|
|
133
|
-
r(this, "postConstructResult",
|
|
133
|
+
r(this, "postConstructResult", y);
|
|
134
|
+
// 是否为瞬态作用域,默认 false(单例)
|
|
135
|
+
r(this, "transient", !1);
|
|
134
136
|
r(this, "onActivationHandler");
|
|
135
137
|
r(this, "onDeactivationHandler");
|
|
136
138
|
this.container = e, this.context = { container: this.container }, this.token = t;
|
|
@@ -149,16 +151,19 @@ const T = class T {
|
|
|
149
151
|
this.onDeactivationHandler && this.onDeactivationHandler(this.cache);
|
|
150
152
|
}
|
|
151
153
|
to(t) {
|
|
152
|
-
return this.type =
|
|
154
|
+
return this.type = f.INSTANCE, this.classValue = t, this;
|
|
153
155
|
}
|
|
154
156
|
toSelf() {
|
|
155
157
|
return this.to(this.token);
|
|
156
158
|
}
|
|
157
159
|
toConstantValue(t) {
|
|
158
|
-
return this.type =
|
|
160
|
+
return this.type = f.CONSTANT, this.constantValue = t, this;
|
|
159
161
|
}
|
|
160
162
|
toDynamicValue(t) {
|
|
161
|
-
return this.type =
|
|
163
|
+
return this.type = f.DYNAMIC, this.dynamicValue = t, this;
|
|
164
|
+
}
|
|
165
|
+
inTransientScope() {
|
|
166
|
+
return this.transient = !0, this;
|
|
162
167
|
}
|
|
163
168
|
toService(t) {
|
|
164
169
|
return this.toDynamicValue(
|
|
@@ -166,11 +171,14 @@ const T = class T {
|
|
|
166
171
|
);
|
|
167
172
|
}
|
|
168
173
|
get(t) {
|
|
169
|
-
if (
|
|
174
|
+
if (d.INITING === this.status)
|
|
170
175
|
throw new R(t);
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
if (d.ACTIVATED === this.status)
|
|
177
|
+
if (this.transient)
|
|
178
|
+
this.status = d.DEFAULT;
|
|
179
|
+
else
|
|
180
|
+
return this.cache;
|
|
181
|
+
const e = C._resolvers[this.type];
|
|
174
182
|
if (e)
|
|
175
183
|
return this[e](t);
|
|
176
184
|
throw new H(this.token);
|
|
@@ -192,16 +200,16 @@ const T = class T {
|
|
|
192
200
|
* - 如果前置服务初始化失败,rejected promise 自然传播,当前服务的 PostConstruct 不执行
|
|
193
201
|
*/
|
|
194
202
|
_postConstruct(t, e) {
|
|
195
|
-
if (
|
|
196
|
-
const { key: i, value: s } =
|
|
203
|
+
if (f.INSTANCE === this.type) {
|
|
204
|
+
const { key: i, value: s } = P(this.classValue) || {};
|
|
197
205
|
if (i)
|
|
198
206
|
if (s) {
|
|
199
207
|
const o = e.filter(
|
|
200
|
-
(c) =>
|
|
208
|
+
(c) => f.INSTANCE === (c == null ? void 0 : c.type)
|
|
201
209
|
), a = this._getAwaitBindings(o, s);
|
|
202
210
|
for (const c of a)
|
|
203
|
-
if (c && c.postConstructResult ===
|
|
204
|
-
throw new
|
|
211
|
+
if (c && c.postConstructResult === y)
|
|
212
|
+
throw new M({
|
|
205
213
|
token: c.token,
|
|
206
214
|
parent: t
|
|
207
215
|
});
|
|
@@ -216,20 +224,20 @@ const T = class T {
|
|
|
216
224
|
}
|
|
217
225
|
}
|
|
218
226
|
preDestroy() {
|
|
219
|
-
if (
|
|
227
|
+
if (f.INSTANCE === this.type) {
|
|
220
228
|
const { key: t } = V(this.classValue) || {};
|
|
221
229
|
t && this._execute(t);
|
|
222
230
|
}
|
|
223
|
-
|
|
231
|
+
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 = y, this.onActivationHandler = void 0, this.onDeactivationHandler = void 0;
|
|
224
232
|
}
|
|
225
233
|
_execute(t) {
|
|
226
234
|
const e = this.cache[t];
|
|
227
235
|
return e == null ? void 0 : e.call(this.cache);
|
|
228
236
|
}
|
|
229
237
|
_resolveInstanceValue(t) {
|
|
230
|
-
this.status =
|
|
238
|
+
this.status = d.INITING;
|
|
231
239
|
const e = this._createInstance();
|
|
232
|
-
this.cache = this.activate(e), this.status =
|
|
240
|
+
this.cache = this.activate(e), this.status = d.ACTIVATED, this._registerInstance();
|
|
233
241
|
const { properties: i, bindings: s } = this._getInjectProperties(t);
|
|
234
242
|
return this._injectProperties(i), this._postConstruct(t, s), this.cache;
|
|
235
243
|
}
|
|
@@ -240,19 +248,19 @@ const T = class T {
|
|
|
240
248
|
}
|
|
241
249
|
// 注册实例与容器的映射关系
|
|
242
250
|
_registerInstance() {
|
|
243
|
-
|
|
251
|
+
v._instanceContainerMap.set(this.cache, this.container);
|
|
244
252
|
}
|
|
245
253
|
// 将解析后的属性注入到实例上
|
|
246
254
|
_injectProperties(t) {
|
|
247
255
|
Object.assign(this.cache, t);
|
|
248
256
|
}
|
|
249
257
|
_resolveConstantValue() {
|
|
250
|
-
return this.status =
|
|
258
|
+
return this.status = d.INITING, this.cache = this.activate(this.constantValue), this.status = d.ACTIVATED, this.cache;
|
|
251
259
|
}
|
|
252
260
|
_resolveDynamicValue() {
|
|
253
|
-
this.status =
|
|
261
|
+
this.status = d.INITING;
|
|
254
262
|
const t = this.dynamicValue(this.context);
|
|
255
|
-
return this.cache = this.activate(t), this.status =
|
|
263
|
+
return this.cache = this.activate(t), this.status = d.ACTIVATED, this.cache;
|
|
256
264
|
}
|
|
257
265
|
_getInjectProperties(t) {
|
|
258
266
|
const e = w(this.classValue) || {}, i = Object.keys(e), s = /* @__PURE__ */ Object.create(null), o = [];
|
|
@@ -260,7 +268,7 @@ const T = class T {
|
|
|
260
268
|
const l = i[a], c = e[l], { inject: _, ...h } = c;
|
|
261
269
|
h.parent = t;
|
|
262
270
|
const p = this.container.get(
|
|
263
|
-
|
|
271
|
+
S(_),
|
|
264
272
|
h
|
|
265
273
|
);
|
|
266
274
|
p === void 0 && c.optional || (s[l] = p), o.push(h.binding);
|
|
@@ -269,23 +277,23 @@ const T = class T {
|
|
|
269
277
|
}
|
|
270
278
|
};
|
|
271
279
|
// 类型到解析方法的静态映射表,用于替代 get 方法中的 if-else 链
|
|
272
|
-
r(
|
|
273
|
-
[
|
|
274
|
-
[
|
|
275
|
-
[
|
|
280
|
+
r(C, "_resolvers", {
|
|
281
|
+
[f.INSTANCE]: "_resolveInstanceValue",
|
|
282
|
+
[f.CONSTANT]: "_resolveConstantValue",
|
|
283
|
+
[f.DYNAMIC]: "_resolveDynamicValue"
|
|
276
284
|
});
|
|
277
|
-
let
|
|
278
|
-
class
|
|
285
|
+
let m = C;
|
|
286
|
+
class x extends N {
|
|
279
287
|
constructor(t) {
|
|
280
288
|
super("No matching binding found for token: ", t);
|
|
281
289
|
}
|
|
282
290
|
}
|
|
283
|
-
class F extends
|
|
291
|
+
class F extends N {
|
|
284
292
|
constructor(t) {
|
|
285
293
|
super("Cannot bind token multiple times: ", t);
|
|
286
294
|
}
|
|
287
295
|
}
|
|
288
|
-
const
|
|
296
|
+
const I = class I {
|
|
289
297
|
constructor() {
|
|
290
298
|
r(this, "parent");
|
|
291
299
|
r(this, "children");
|
|
@@ -295,7 +303,7 @@ const v = class v {
|
|
|
295
303
|
}
|
|
296
304
|
// 查询实例所属的容器
|
|
297
305
|
static getContainerOf(t) {
|
|
298
|
-
return
|
|
306
|
+
return I._instanceContainerMap.get(t);
|
|
299
307
|
}
|
|
300
308
|
bind(t) {
|
|
301
309
|
if (this._bindings.has(t))
|
|
@@ -321,7 +329,7 @@ const v = class v {
|
|
|
321
329
|
return this.isCurrentBound(t) || !!this.parent && this.parent.isBound(t);
|
|
322
330
|
}
|
|
323
331
|
createChild() {
|
|
324
|
-
const t = new
|
|
332
|
+
const t = new I();
|
|
325
333
|
return t.parent = this, this.children || (this.children = /* @__PURE__ */ new Set()), this.children.add(t), t;
|
|
326
334
|
}
|
|
327
335
|
destroy() {
|
|
@@ -336,6 +344,10 @@ const v = class v {
|
|
|
336
344
|
get(t, e = {}) {
|
|
337
345
|
return e.skipSelf ? this._resolveSkipSelf(t, e) : e.self ? this._resolveSelf(t, e) : this._resolveDefault(t, e);
|
|
338
346
|
}
|
|
347
|
+
async getAsync(t, e = {}) {
|
|
348
|
+
const i = this.get(t, e), s = e.binding;
|
|
349
|
+
return (s == null ? void 0 : s.postConstructResult) instanceof Promise && await s.postConstructResult, i;
|
|
350
|
+
}
|
|
339
351
|
// 处理 skipSelf 选项:跳过当前容器,委托父容器解析
|
|
340
352
|
_resolveSkipSelf(t, e) {
|
|
341
353
|
return this.parent ? (e.skipSelf = !1, this.parent.get(t, e)) : this._checkBindingNotFoundError(t, e);
|
|
@@ -363,14 +375,14 @@ const v = class v {
|
|
|
363
375
|
this._onDeactivationHandler && this._onDeactivationHandler(t.cache, t.token);
|
|
364
376
|
}
|
|
365
377
|
_buildBinding(t) {
|
|
366
|
-
return new
|
|
378
|
+
return new m(t, this);
|
|
367
379
|
}
|
|
368
380
|
_getBinding(t) {
|
|
369
381
|
return this._bindings.get(t);
|
|
370
382
|
}
|
|
371
383
|
_checkBindingNotFoundError(t, e) {
|
|
372
384
|
if (!e.optional)
|
|
373
|
-
throw new
|
|
385
|
+
throw new x(t);
|
|
374
386
|
}
|
|
375
387
|
};
|
|
376
388
|
// 实例到容器的映射表,用于 @LazyInject 查找实例所属容器
|
|
@@ -379,9 +391,9 @@ const v = class v {
|
|
|
379
391
|
// 同一对象可能通过 toConstantValue 被绑定到多个容器,WeakMap 只能保留最后一次映射,
|
|
380
392
|
// 会导致 @LazyInject 从错误的容器解析依赖。
|
|
381
393
|
// 由于 Instance 类型每次都通过 new ClassName() 创建新实例,不存在同一实例被多个容器注册的覆盖风险
|
|
382
|
-
r(
|
|
383
|
-
let
|
|
384
|
-
class z extends
|
|
394
|
+
r(I, "_instanceContainerMap", /* @__PURE__ */ new WeakMap());
|
|
395
|
+
let v = I;
|
|
396
|
+
class z extends N {
|
|
385
397
|
constructor(t, e) {
|
|
386
398
|
super(
|
|
387
399
|
`@LazyInject(${t == null ? void 0 : t.name}) in class ${e.name} requires a registered container but none was found. Token: `,
|
|
@@ -389,11 +401,11 @@ class z extends y {
|
|
|
389
401
|
);
|
|
390
402
|
}
|
|
391
403
|
}
|
|
392
|
-
function
|
|
404
|
+
function A(n, t) {
|
|
393
405
|
return function(e) {
|
|
394
406
|
return function(i, s) {
|
|
395
407
|
const o = s.name, a = s.metadata;
|
|
396
|
-
|
|
408
|
+
T(a, u.INJECTED_PROPS) || (a[u.INJECTED_PROPS] = {});
|
|
397
409
|
const l = a[u.INJECTED_PROPS];
|
|
398
410
|
l[o] || (l[o] = {}), l[o][n] = e === void 0 ? t : e;
|
|
399
411
|
};
|
|
@@ -402,35 +414,37 @@ function D(n, t) {
|
|
|
402
414
|
function j(n, t) {
|
|
403
415
|
return (e) => (i, s) => {
|
|
404
416
|
const o = s.name, a = s.metadata;
|
|
405
|
-
if (
|
|
417
|
+
if (T(a, n))
|
|
406
418
|
throw new Error(t);
|
|
407
419
|
a[n] = { key: o, value: e };
|
|
408
420
|
};
|
|
409
421
|
}
|
|
410
|
-
const G =
|
|
422
|
+
const G = A(u.INJECT), $ = A(u.SELF, !0), Z = A(u.SKIP_SELF, !0), q = A(u.OPTIONAL, !0), W = j(
|
|
411
423
|
u.POST_CONSTRUCT,
|
|
412
|
-
|
|
424
|
+
g.POST_CONSTRUCT
|
|
413
425
|
), Q = j(
|
|
414
426
|
u.PRE_DESTROY,
|
|
415
|
-
|
|
427
|
+
g.PRE_DESTROY
|
|
416
428
|
);
|
|
417
|
-
function X(
|
|
418
|
-
|
|
419
|
-
|
|
429
|
+
function X() {
|
|
430
|
+
return function(n, t) {
|
|
431
|
+
const e = t.metadata;
|
|
432
|
+
b(n, e);
|
|
433
|
+
};
|
|
420
434
|
}
|
|
421
|
-
function
|
|
435
|
+
function U(n, t, e, i) {
|
|
422
436
|
if (e == null)
|
|
423
|
-
throw new Error(
|
|
437
|
+
throw new Error(g.LAZY_INJECT_INVALID_TOKEN);
|
|
424
438
|
const s = Symbol.for(t);
|
|
425
439
|
Object.defineProperty(n, t, {
|
|
426
440
|
configurable: !0,
|
|
427
441
|
enumerable: !0,
|
|
428
442
|
get() {
|
|
429
|
-
if (!
|
|
430
|
-
const o = i ||
|
|
443
|
+
if (!T(n, s)) {
|
|
444
|
+
const o = i || v.getContainerOf(n), a = n.constructor;
|
|
431
445
|
if (!o)
|
|
432
|
-
throw new z(
|
|
433
|
-
n[s] = o.get(
|
|
446
|
+
throw new z(S(e), a);
|
|
447
|
+
n[s] = o.get(S(e), {
|
|
434
448
|
parent: { token: a }
|
|
435
449
|
});
|
|
436
450
|
}
|
|
@@ -441,24 +455,30 @@ function J(n, t, e, i) {
|
|
|
441
455
|
}
|
|
442
456
|
});
|
|
443
457
|
}
|
|
444
|
-
function
|
|
458
|
+
function Y(n, t) {
|
|
445
459
|
return function(e, i) {
|
|
446
460
|
const s = i.name;
|
|
447
461
|
i.addInitializer(function() {
|
|
448
|
-
|
|
462
|
+
U(this, s, n, t);
|
|
449
463
|
});
|
|
450
464
|
};
|
|
451
465
|
}
|
|
452
466
|
function tt(n) {
|
|
453
467
|
return function(t) {
|
|
454
|
-
return
|
|
468
|
+
return Y(t, n);
|
|
455
469
|
};
|
|
456
470
|
}
|
|
457
|
-
|
|
458
|
-
|
|
471
|
+
function et(n, t) {
|
|
472
|
+
const e = t.name;
|
|
473
|
+
t.addInitializer(function() {
|
|
474
|
+
this[e] = n.bind(this);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
const D = Symbol("decorate.metadata");
|
|
478
|
+
function nt(n, t, e) {
|
|
459
479
|
const i = Array.isArray(n) ? n : [n], s = t.prototype, o = typeof s[e] == "function", a = [];
|
|
460
|
-
|
|
461
|
-
const l = t[
|
|
480
|
+
T(t, D) || (t[D] = {});
|
|
481
|
+
const l = t[D], c = {
|
|
462
482
|
kind: o ? "method" : "field",
|
|
463
483
|
name: e,
|
|
464
484
|
static: !1,
|
|
@@ -473,32 +493,33 @@ function et(n, t, e) {
|
|
|
473
493
|
const p = i[h](_, c);
|
|
474
494
|
o && typeof p == "function" && (_ = p);
|
|
475
495
|
}
|
|
476
|
-
if (o && _ !== s[e] && (s[e] = _),
|
|
496
|
+
if (o && _ !== s[e] && (s[e] = _), b(t, l), a.length > 0) {
|
|
477
497
|
const h = Object.create(s);
|
|
478
498
|
for (const p of a)
|
|
479
499
|
p.call(h);
|
|
480
500
|
}
|
|
481
501
|
}
|
|
482
502
|
export {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
503
|
+
N as BaseError,
|
|
504
|
+
m as Binding,
|
|
505
|
+
x as BindingNotFoundError,
|
|
486
506
|
H as BindingNotValidError,
|
|
487
507
|
R as CircularDependencyError,
|
|
488
|
-
|
|
508
|
+
v as Container,
|
|
489
509
|
z as ContainerNotFoundError,
|
|
490
510
|
F as DuplicateBindingError,
|
|
491
511
|
G as Inject,
|
|
492
512
|
X as Injectable,
|
|
493
|
-
|
|
513
|
+
Y as LazyInject,
|
|
494
514
|
B as LazyToken,
|
|
495
515
|
q as Optional,
|
|
496
516
|
W as PostConstruct,
|
|
497
|
-
|
|
517
|
+
M as PostConstructError,
|
|
498
518
|
Q as PreDestroy,
|
|
499
519
|
$ as Self,
|
|
500
520
|
Z as SkipSelf,
|
|
501
|
-
|
|
521
|
+
K as Token,
|
|
522
|
+
et as autobind,
|
|
502
523
|
tt as createLazyInject,
|
|
503
|
-
|
|
524
|
+
nt as decorate
|
|
504
525
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaokei/di",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Tiny di library depends on typescript decorator.",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
],
|
|
38
38
|
"scripts": {
|
|
39
39
|
"test": "vitest",
|
|
40
|
+
"test:inversify": "vitest run --config vite.config.inversify.ts",
|
|
40
41
|
"coverage": "vitest run --coverage",
|
|
41
42
|
"build": "tsc && vite build",
|
|
42
43
|
"clean": "rm -rf dist/*",
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
"docs:preview": "vitepress preview docs"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
54
|
+
"@swc/core": "^1.15.21",
|
|
53
55
|
"@types/fs-extra": "^11.0.4",
|
|
54
56
|
"@types/node": "^22.13.4",
|
|
55
57
|
"@vitejs/plugin-vue": "^5.2.1",
|
|
@@ -62,7 +64,8 @@
|
|
|
62
64
|
"reflect-metadata": "^0.2.2",
|
|
63
65
|
"standard-version": "^9.5.0",
|
|
64
66
|
"typescript": "~5.6.3",
|
|
65
|
-
"
|
|
67
|
+
"unplugin-swc": "^1.5.9",
|
|
68
|
+
"vite": "5.3.0",
|
|
66
69
|
"vite-plugin-dts": "^4.5.0",
|
|
67
70
|
"vitepress": "^1.6.3",
|
|
68
71
|
"vitest": "^3.1.1",
|