ts-ioc-container 60.0.0 → 60.2.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/cjm/container/Container.js +13 -2
- package/cjm/container/EmptyContainer.js +3 -0
- package/cjm/hooks/HookContext.js +1 -1
- package/cjm/hooks/hook.js +3 -2
- package/cjm/index.js +5 -3
- package/cjm/injector/MetadataInjector.js +4 -4
- package/cjm/metadata/class.js +2 -2
- package/cjm/metadata/method.js +2 -2
- package/cjm/metadata/parameter.js +2 -2
- package/cjm/metadata/target.js +9 -0
- package/cjm/utils/ProxyRegistry.js +3 -1
- package/cjm/utils/basic.js +0 -4
- package/cjm/utils/errorHandler.js +3 -2
- package/esm/container/Container.js +13 -2
- package/esm/container/EmptyContainer.js +3 -0
- package/esm/hooks/HookContext.js +1 -1
- package/esm/hooks/hook.js +3 -2
- package/esm/index.js +3 -2
- package/esm/injector/MetadataInjector.js +4 -4
- package/esm/metadata/class.js +1 -1
- package/esm/metadata/method.js +1 -1
- package/esm/metadata/parameter.js +1 -1
- package/esm/metadata/target.js +6 -0
- package/esm/utils/ProxyRegistry.js +1 -0
- package/esm/utils/basic.js +0 -3
- package/esm/utils/errorHandler.js +3 -2
- package/package.json +1 -1
- package/typings/container/Container.d.ts +3 -1
- package/typings/container/EmptyContainer.d.ts +2 -1
- package/typings/container/IContainer.d.ts +2 -0
- package/typings/hooks/hook.d.ts +2 -2
- package/typings/index.d.ts +4 -3
- package/typings/injector/MetadataInjector.d.ts +2 -2
- package/typings/metadata/target.d.ts +2 -0
- package/typings/utils/ProxyRegistry.d.ts +1 -0
- package/typings/utils/basic.d.ts +0 -1
|
@@ -5,6 +5,7 @@ const EmptyContainer_1 = require("./EmptyContainer");
|
|
|
5
5
|
const ContainerDisposedError_1 = require("../errors/ContainerDisposedError");
|
|
6
6
|
const MetadataInjector_1 = require("../injector/MetadataInjector");
|
|
7
7
|
const AliasMap_1 = require("./AliasMap");
|
|
8
|
+
const ProxyRegistry_1 = require("../utils/ProxyRegistry");
|
|
8
9
|
const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
|
|
9
10
|
const basic_1 = require("../utils/basic");
|
|
10
11
|
const array_1 = require("../utils/array");
|
|
@@ -21,6 +22,7 @@ class Container {
|
|
|
21
22
|
onConstructHookList = [];
|
|
22
23
|
onDisposeHookList = [];
|
|
23
24
|
onScopeCreatedHookList = [];
|
|
25
|
+
onProviderRegisteredHookList = [];
|
|
24
26
|
constructor(options = {}) {
|
|
25
27
|
this.injector = options.injector ?? new MetadataInjector_1.MetadataInjector();
|
|
26
28
|
this.parent = options.parent ?? new EmptyContainer_1.EmptyContainer();
|
|
@@ -30,6 +32,9 @@ class Container {
|
|
|
30
32
|
this.validateContainer();
|
|
31
33
|
this.providers.set(key, provider);
|
|
32
34
|
this.aliases.setAliasesByKey(key, aliases);
|
|
35
|
+
for (const onProviderRegistered of this.onProviderRegisteredHookList) {
|
|
36
|
+
onProviderRegistered(provider, key, this);
|
|
37
|
+
}
|
|
33
38
|
return this;
|
|
34
39
|
}
|
|
35
40
|
resolve(target, { args = [], child = this, lazy } = {}) {
|
|
@@ -75,7 +80,8 @@ class Container {
|
|
|
75
80
|
const scope = new Container({ injector: this.injector, parent: this, tags })
|
|
76
81
|
.onConstruct(...this.onConstructHookList)
|
|
77
82
|
.onInstanceDisposed(...this.onDisposeHookList)
|
|
78
|
-
.onScopeCreated(...this.onScopeCreatedHookList)
|
|
83
|
+
.onScopeCreated(...this.onScopeCreatedHookList)
|
|
84
|
+
.onProviderRegistered(...this.onProviderRegisteredHookList);
|
|
79
85
|
for (const registration of this.getRegistrations()) {
|
|
80
86
|
registration.applyTo(scope);
|
|
81
87
|
}
|
|
@@ -112,6 +118,7 @@ class Container {
|
|
|
112
118
|
this.onConstructHookList.length = 0;
|
|
113
119
|
this.onDisposeHookList.length = 0;
|
|
114
120
|
this.onScopeCreatedHookList.length = 0;
|
|
121
|
+
this.onProviderRegisteredHookList.length = 0;
|
|
115
122
|
}
|
|
116
123
|
addRegistration(registration) {
|
|
117
124
|
this.registrations.push(registration);
|
|
@@ -136,6 +143,10 @@ class Container {
|
|
|
136
143
|
this.onScopeCreatedHookList.push(...hooks);
|
|
137
144
|
return this;
|
|
138
145
|
}
|
|
146
|
+
onProviderRegistered(...hooks) {
|
|
147
|
+
this.onProviderRegisteredHookList.push(...hooks);
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
139
150
|
addInstance(instance) {
|
|
140
151
|
this.instances.add(instance);
|
|
141
152
|
for (const onConstruct of this.onConstructHookList) {
|
|
@@ -146,7 +157,7 @@ class Container {
|
|
|
146
157
|
return [...this.scopes];
|
|
147
158
|
}
|
|
148
159
|
hasInstance(instance) {
|
|
149
|
-
return this.instances.has(instance);
|
|
160
|
+
return this.instances.has((0, ProxyRegistry_1.unwrapProxy)(instance));
|
|
150
161
|
}
|
|
151
162
|
removeScope(child) {
|
|
152
163
|
this.scopes = this.scopes.filter((s) => s !== child);
|
|
@@ -69,5 +69,8 @@ class EmptyContainer {
|
|
|
69
69
|
onScopeCreated(...hooks) {
|
|
70
70
|
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
71
71
|
}
|
|
72
|
+
onProviderRegistered(...hooks) {
|
|
73
|
+
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
74
|
+
}
|
|
72
75
|
}
|
|
73
76
|
exports.EmptyContainer = EmptyContainer;
|
package/cjm/hooks/HookContext.js
CHANGED
|
@@ -13,7 +13,7 @@ class HookContext {
|
|
|
13
13
|
this.methodName = methodName;
|
|
14
14
|
}
|
|
15
15
|
resolveArgs(...args) {
|
|
16
|
-
return (0, MetadataInjector_1.resolveArgs)(this.instance
|
|
16
|
+
return (0, MetadataInjector_1.resolveArgs)(this.instance, this.methodName)(this.scope, {
|
|
17
17
|
args: [...this.initialArgs, ...args],
|
|
18
18
|
});
|
|
19
19
|
}
|
package/cjm/hooks/hook.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.hook = exports.toHookFn = exports.prepend = exports.append = exports.pre
|
|
|
4
4
|
exports.getHooks = getHooks;
|
|
5
5
|
exports.hasHooks = hasHooks;
|
|
6
6
|
const basic_1 = require("../utils/basic");
|
|
7
|
+
const target_1 = require("../metadata/target");
|
|
7
8
|
const appendHooks = (...fns) => (...prev) => [...prev, ...fns];
|
|
8
9
|
exports.appendHooks = appendHooks;
|
|
9
10
|
const prependHooks = (...fns) => (...prev) => [...fns, ...prev];
|
|
@@ -26,7 +27,7 @@ const getConstructorChain = (ctor) => {
|
|
|
26
27
|
};
|
|
27
28
|
function getHooks(target, key) {
|
|
28
29
|
const merged = new Map();
|
|
29
|
-
for (const ctor of getConstructorChain(
|
|
30
|
+
for (const ctor of getConstructorChain((0, target_1.resolveConstructor)(target)).reverse()) {
|
|
30
31
|
const ownHooks = Reflect.getOwnMetadata(key, ctor);
|
|
31
32
|
if (ownHooks) {
|
|
32
33
|
for (const [methodName, fns] of ownHooks) {
|
|
@@ -37,7 +38,7 @@ function getHooks(target, key) {
|
|
|
37
38
|
return merged;
|
|
38
39
|
}
|
|
39
40
|
function hasHooks(target, key) {
|
|
40
|
-
return getConstructorChain(
|
|
41
|
+
return getConstructorChain((0, target_1.resolveConstructor)(target)).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
|
|
41
42
|
}
|
|
42
43
|
const hook = (key, mapFn) => (target, propertyKey) => {
|
|
43
44
|
const hooks = Reflect.hasOwnMetadata(key, target.constructor)
|
package/cjm/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createHookContextFactory = exports.HookContext = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnsupportedTokenTypeError = exports.CannonSingletonApplyTwiceError = exports.UnexpectedHookResultError = exports.ProviderDisposedError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.ContainerNotFoundError = exports.DependencyNotFoundError = exports.ContainerError = exports.Registration = exports.onResolve = exports.appendArgsFn = exports.appendArgs = exports.decorate = exports.singleton = exports.autoResolve = exports.lazy = exports.scopeAccess = exports.scope = exports.bindTo = exports.register = exports.toRegistrationFn = exports.toProviderFn = exports.toBindToken = exports.registerPipe = exports.isProviderPipe = exports.Provider = exports.ProxyInjector = exports.SimpleInjector = exports.resolveArgs = exports.argsFn = exports.args = exports.arg = exports.inject = exports.MetadataInjector = exports.Injector = exports.EmptyContainer = exports.AutoResolveModule = exports.Container = exports.isDependencyKey = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
4
|
+
exports.once = exports.shallowCache = exports.debounce = exports.throttle = exports.handleAsyncError = exports.handleError = exports.getMethodTags = exports.addMethodTag = exports.getMethodLabels = exports.addMethodLabel = exports.getMethodMeta = exports.addMethodMeta = exports.getParamTags = exports.addParamTag = exports.getParamLabels = exports.addParamLabel = exports.getParamMeta = exports.addParamMeta = exports.getClassTags = exports.addClassTag = exports.getClassLabels = exports.addClassLabel = exports.getClassMeta = exports.addClassMeta = exports.resolveConstructor = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken = exports.SingleToken = exports.ClassToken = exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.argToToken = exports.toMappedToken = exports.toToken = exports.InjectionToken = exports.HooksRunner = exports.OnDisposeModule = exports.onContainerDisposed = exports.onContainerDisposedHooksRunner = exports.OnConstructAsyncModule = exports.onConstructAsync = exports.onConstructAsyncHooksRunner = exports.OnConstructModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = exports.createHookContext = void 0;
|
|
5
|
+
exports.Is = exports.unwrapProxy = exports.ProxyRegistry = exports.pipe = exports.select = void 0;
|
|
6
6
|
var IContainer_1 = require("./container/IContainer");
|
|
7
7
|
Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
|
|
8
8
|
var Container_1 = require("./container/Container");
|
|
@@ -115,6 +115,8 @@ var ConstantToken_1 = require("./token/ConstantToken");
|
|
|
115
115
|
Object.defineProperty(exports, "ConstantToken", { enumerable: true, get: function () { return ConstantToken_1.ConstantToken; } });
|
|
116
116
|
var GroupInstanceToken_1 = require("./token/GroupInstanceToken");
|
|
117
117
|
Object.defineProperty(exports, "GroupInstanceToken", { enumerable: true, get: function () { return GroupInstanceToken_1.GroupInstanceToken; } });
|
|
118
|
+
var target_1 = require("./metadata/target");
|
|
119
|
+
Object.defineProperty(exports, "resolveConstructor", { enumerable: true, get: function () { return target_1.resolveConstructor; } });
|
|
118
120
|
var class_1 = require("./metadata/class");
|
|
119
121
|
Object.defineProperty(exports, "addClassMeta", { enumerable: true, get: function () { return class_1.addClassMeta; } });
|
|
120
122
|
Object.defineProperty(exports, "getClassMeta", { enumerable: true, get: function () { return class_1.getClassMeta; } });
|
|
@@ -153,6 +155,6 @@ var fp_1 = require("./utils/fp");
|
|
|
153
155
|
Object.defineProperty(exports, "pipe", { enumerable: true, get: function () { return fp_1.pipe; } });
|
|
154
156
|
var ProxyRegistry_1 = require("./utils/ProxyRegistry");
|
|
155
157
|
Object.defineProperty(exports, "ProxyRegistry", { enumerable: true, get: function () { return ProxyRegistry_1.ProxyRegistry; } });
|
|
158
|
+
Object.defineProperty(exports, "unwrapProxy", { enumerable: true, get: function () { return ProxyRegistry_1.unwrapProxy; } });
|
|
156
159
|
var basic_1 = require("./utils/basic");
|
|
157
160
|
Object.defineProperty(exports, "Is", { enumerable: true, get: function () { return basic_1.Is; } });
|
|
158
|
-
Object.defineProperty(exports, "resolveConstructor", { enumerable: true, get: function () { return basic_1.resolveConstructor; } });
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.resolveArgs = exports.args = exports.arg = exports.argsFn = exports.MetadataInjector = void 0;
|
|
4
4
|
exports.inject = inject;
|
|
5
5
|
const IInjector_1 = require("./IInjector");
|
|
6
|
-
const
|
|
6
|
+
const target_1 = require("../metadata/target");
|
|
7
7
|
const parameter_1 = require("../metadata/parameter");
|
|
8
8
|
const toToken_1 = require("../token/toToken");
|
|
9
9
|
class MetadataInjector extends IInjector_1.Injector {
|
|
@@ -16,7 +16,7 @@ exports.MetadataInjector = MetadataInjector;
|
|
|
16
16
|
const hookMetaKey = (methodName = 'constructor') => `inject:${methodName}`;
|
|
17
17
|
function inject(fn, ...mappers) {
|
|
18
18
|
return (target, propertyKey, parameterIndex) => {
|
|
19
|
-
(0, parameter_1.addParamMeta)(hookMetaKey(propertyKey), () => (0, toToken_1.toMappedToken)(fn, mappers))(
|
|
19
|
+
(0, parameter_1.addParamMeta)(hookMetaKey(propertyKey), () => (0, toToken_1.toMappedToken)(fn, mappers))((0, target_1.resolveConstructor)(target), propertyKey, parameterIndex);
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
const argsFn = (predicate) => (c, { args = [] }) => args.find((value, index) => predicate(value, index));
|
|
@@ -25,8 +25,8 @@ const arg = (index) => (0, exports.argsFn)((value, i) => i === index);
|
|
|
25
25
|
exports.arg = arg;
|
|
26
26
|
const args = (c, { args = [] }) => args;
|
|
27
27
|
exports.args = args;
|
|
28
|
-
const resolveArgs = (
|
|
29
|
-
const tokens = (0, parameter_1.getParamMeta)(hookMetaKey(methodName),
|
|
28
|
+
const resolveArgs = (target, methodName) => {
|
|
29
|
+
const tokens = (0, parameter_1.getParamMeta)(hookMetaKey(methodName), target);
|
|
30
30
|
return (scope, { args = [], lazy }) => tokens.map((fn) => fn.resolve(scope, { args: args.map(toToken_1.argToToken).map((t) => t.resolve(scope)), lazy }));
|
|
31
31
|
};
|
|
32
32
|
exports.resolveArgs = resolveArgs;
|
package/cjm/metadata/class.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getClassTags = exports.addClassTag = exports.getClassLabels = exports.addClassLabel = exports.addClassMeta = void 0;
|
|
4
4
|
exports.getClassMeta = getClassMeta;
|
|
5
|
-
const
|
|
5
|
+
const target_1 = require("./target");
|
|
6
6
|
const addClassMeta = (key, mapFn) => (target) => {
|
|
7
7
|
const value = Reflect.getOwnMetadata(key, target);
|
|
8
8
|
Reflect.defineMetadata(key, mapFn(value), target);
|
|
9
9
|
};
|
|
10
10
|
exports.addClassMeta = addClassMeta;
|
|
11
11
|
function getClassMeta(target, key) {
|
|
12
|
-
return Reflect.getOwnMetadata(key, (0,
|
|
12
|
+
return Reflect.getOwnMetadata(key, (0, target_1.resolveConstructor)(target));
|
|
13
13
|
}
|
|
14
14
|
const addClassLabel = (key, label) => (0, exports.addClassMeta)('label', (prev = new Map()) => prev.set(key, label));
|
|
15
15
|
exports.addClassLabel = addClassLabel;
|
package/cjm/metadata/method.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getMethodTags = exports.addMethodTag = exports.getMethodLabels = exports.addMethodLabel = exports.getMethodMeta = exports.addMethodMeta = void 0;
|
|
4
|
-
const
|
|
4
|
+
const target_1 = require("./target");
|
|
5
5
|
const addMethodMeta = (key, mapFn) => (target, propertyKey) => {
|
|
6
6
|
const metadata = Reflect.getMetadata(key, target.constructor, propertyKey);
|
|
7
7
|
Reflect.defineMetadata(key, mapFn(metadata), target.constructor, propertyKey);
|
|
8
8
|
};
|
|
9
9
|
exports.addMethodMeta = addMethodMeta;
|
|
10
|
-
const getMethodMeta = (key, target, propertyKey) => Reflect.getMetadata(key, (0,
|
|
10
|
+
const getMethodMeta = (key, target, propertyKey) => Reflect.getMetadata(key, (0, target_1.resolveConstructor)(target), propertyKey);
|
|
11
11
|
exports.getMethodMeta = getMethodMeta;
|
|
12
12
|
const addMethodLabel = (key, label) => (0, exports.addMethodMeta)('label', (prev = new Map()) => prev.set(key, label));
|
|
13
13
|
exports.addMethodLabel = addMethodLabel;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getParamTags = exports.addParamTag = exports.getParamLabels = exports.addParamLabel = exports.getParamMeta = exports.addParamMeta = void 0;
|
|
4
|
-
const
|
|
4
|
+
const target_1 = require("./target");
|
|
5
5
|
const addParamMeta = (key, mapFn) => (target, _, parameterIndex) => {
|
|
6
6
|
const metadata = Reflect.getOwnMetadata(key, target) ?? [];
|
|
7
7
|
metadata[parameterIndex] = mapFn(metadata[parameterIndex]);
|
|
@@ -9,7 +9,7 @@ const addParamMeta = (key, mapFn) => (target, _, parameterIndex) => {
|
|
|
9
9
|
};
|
|
10
10
|
exports.addParamMeta = addParamMeta;
|
|
11
11
|
const getParamMeta = (key, target) => {
|
|
12
|
-
return Reflect.getOwnMetadata(key, (0,
|
|
12
|
+
return Reflect.getOwnMetadata(key, (0, target_1.resolveConstructor)(target)) ?? [];
|
|
13
13
|
};
|
|
14
14
|
exports.getParamMeta = getParamMeta;
|
|
15
15
|
const addParamLabel = (key, label) => (0, exports.addParamMeta)('label', (prev) => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveConstructor = resolveConstructor;
|
|
4
|
+
const basic_1 = require("../utils/basic");
|
|
5
|
+
const ProxyRegistry_1 = require("../utils/ProxyRegistry");
|
|
6
|
+
function resolveConstructor(target) {
|
|
7
|
+
const value = (0, ProxyRegistry_1.unwrapProxy)(target);
|
|
8
|
+
return basic_1.Is.constructor(value) ? value : value.constructor;
|
|
9
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProxyRegistry = void 0;
|
|
3
|
+
exports.unwrapProxy = exports.ProxyRegistry = void 0;
|
|
4
4
|
class ProxyRegistry {
|
|
5
5
|
static instance;
|
|
6
6
|
states = new WeakMap();
|
|
@@ -53,3 +53,5 @@ class ProxyRegistry {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
exports.ProxyRegistry = ProxyRegistry;
|
|
56
|
+
const unwrapProxy = (value) => ProxyRegistry.getInstance().unwrap(value);
|
|
57
|
+
exports.unwrapProxy = unwrapProxy;
|
package/cjm/utils/basic.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Is = void 0;
|
|
4
|
-
exports.resolveConstructor = resolveConstructor;
|
|
5
4
|
exports.Is = {
|
|
6
5
|
nullish: (value) => value === undefined || value === null,
|
|
7
6
|
object: (target) => target !== null && typeof target === 'object',
|
|
8
7
|
instance: (target) => Object.prototype.hasOwnProperty.call(target, 'constructor'),
|
|
9
8
|
constructor: (target) => typeof target === 'function' && !!target.prototype,
|
|
10
9
|
};
|
|
11
|
-
function resolveConstructor(target) {
|
|
12
|
-
return exports.Is.constructor(target) ? target : target.constructor;
|
|
13
|
-
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleError = exports.handleAsyncError = void 0;
|
|
4
|
+
const target_1 = require("../metadata/target");
|
|
4
5
|
const handleAsyncError = (errorHandler) => (target, propertyKey, descriptor) => {
|
|
5
6
|
const originalMethod = descriptor.value;
|
|
6
7
|
descriptor.value = async function (...args) {
|
|
@@ -8,7 +9,7 @@ const handleAsyncError = (errorHandler) => (target, propertyKey, descriptor) =>
|
|
|
8
9
|
return await originalMethod.apply(this, args);
|
|
9
10
|
}
|
|
10
11
|
catch (e) {
|
|
11
|
-
errorHandler(e, { target: target.
|
|
12
|
+
errorHandler(e, { target: (0, target_1.resolveConstructor)(target).name, method: propertyKey });
|
|
12
13
|
}
|
|
13
14
|
};
|
|
14
15
|
return descriptor;
|
|
@@ -21,7 +22,7 @@ const handleError = (errorHandler) => (target, propertyKey, descriptor) => {
|
|
|
21
22
|
return originalMethod.apply(this, args);
|
|
22
23
|
}
|
|
23
24
|
catch (e) {
|
|
24
|
-
errorHandler(e, { target: target.
|
|
25
|
+
errorHandler(e, { target: (0, target_1.resolveConstructor)(target).name, method: propertyKey });
|
|
25
26
|
}
|
|
26
27
|
};
|
|
27
28
|
return descriptor;
|
|
@@ -2,6 +2,7 @@ import { EmptyContainer } from './EmptyContainer.js';
|
|
|
2
2
|
import { ContainerDisposedError } from '../errors/ContainerDisposedError.js';
|
|
3
3
|
import { MetadataInjector } from '../injector/MetadataInjector.js';
|
|
4
4
|
import { AliasMap } from './AliasMap.js';
|
|
5
|
+
import { unwrapProxy } from '../utils/ProxyRegistry.js';
|
|
5
6
|
import { DependencyNotFoundError } from '../errors/DependencyNotFoundError.js';
|
|
6
7
|
import { Is } from '../utils/basic.js';
|
|
7
8
|
import { Filter as F } from '../utils/array.js';
|
|
@@ -18,6 +19,7 @@ export class Container {
|
|
|
18
19
|
onConstructHookList = [];
|
|
19
20
|
onDisposeHookList = [];
|
|
20
21
|
onScopeCreatedHookList = [];
|
|
22
|
+
onProviderRegisteredHookList = [];
|
|
21
23
|
constructor(options = {}) {
|
|
22
24
|
this.injector = options.injector ?? new MetadataInjector();
|
|
23
25
|
this.parent = options.parent ?? new EmptyContainer();
|
|
@@ -27,6 +29,9 @@ export class Container {
|
|
|
27
29
|
this.validateContainer();
|
|
28
30
|
this.providers.set(key, provider);
|
|
29
31
|
this.aliases.setAliasesByKey(key, aliases);
|
|
32
|
+
for (const onProviderRegistered of this.onProviderRegisteredHookList) {
|
|
33
|
+
onProviderRegistered(provider, key, this);
|
|
34
|
+
}
|
|
30
35
|
return this;
|
|
31
36
|
}
|
|
32
37
|
resolve(target, { args = [], child = this, lazy } = {}) {
|
|
@@ -72,7 +77,8 @@ export class Container {
|
|
|
72
77
|
const scope = new Container({ injector: this.injector, parent: this, tags })
|
|
73
78
|
.onConstruct(...this.onConstructHookList)
|
|
74
79
|
.onInstanceDisposed(...this.onDisposeHookList)
|
|
75
|
-
.onScopeCreated(...this.onScopeCreatedHookList)
|
|
80
|
+
.onScopeCreated(...this.onScopeCreatedHookList)
|
|
81
|
+
.onProviderRegistered(...this.onProviderRegisteredHookList);
|
|
76
82
|
for (const registration of this.getRegistrations()) {
|
|
77
83
|
registration.applyTo(scope);
|
|
78
84
|
}
|
|
@@ -109,6 +115,7 @@ export class Container {
|
|
|
109
115
|
this.onConstructHookList.length = 0;
|
|
110
116
|
this.onDisposeHookList.length = 0;
|
|
111
117
|
this.onScopeCreatedHookList.length = 0;
|
|
118
|
+
this.onProviderRegisteredHookList.length = 0;
|
|
112
119
|
}
|
|
113
120
|
addRegistration(registration) {
|
|
114
121
|
this.registrations.push(registration);
|
|
@@ -133,6 +140,10 @@ export class Container {
|
|
|
133
140
|
this.onScopeCreatedHookList.push(...hooks);
|
|
134
141
|
return this;
|
|
135
142
|
}
|
|
143
|
+
onProviderRegistered(...hooks) {
|
|
144
|
+
this.onProviderRegisteredHookList.push(...hooks);
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
136
147
|
addInstance(instance) {
|
|
137
148
|
this.instances.add(instance);
|
|
138
149
|
for (const onConstruct of this.onConstructHookList) {
|
|
@@ -143,7 +154,7 @@ export class Container {
|
|
|
143
154
|
return [...this.scopes];
|
|
144
155
|
}
|
|
145
156
|
hasInstance(instance) {
|
|
146
|
-
return this.instances.has(instance);
|
|
157
|
+
return this.instances.has(unwrapProxy(instance));
|
|
147
158
|
}
|
|
148
159
|
removeScope(child) {
|
|
149
160
|
this.scopes = this.scopes.filter((s) => s !== child);
|
package/esm/hooks/HookContext.js
CHANGED
|
@@ -10,7 +10,7 @@ export class HookContext {
|
|
|
10
10
|
this.methodName = methodName;
|
|
11
11
|
}
|
|
12
12
|
resolveArgs(...args) {
|
|
13
|
-
return resolveArgs(this.instance
|
|
13
|
+
return resolveArgs(this.instance, this.methodName)(this.scope, {
|
|
14
14
|
args: [...this.initialArgs, ...args],
|
|
15
15
|
});
|
|
16
16
|
}
|
package/esm/hooks/hook.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Is } from '../utils/basic.js';
|
|
2
|
+
import { resolveConstructor } from '../metadata/target.js';
|
|
2
3
|
export const appendHooks = (...fns) => (...prev) => [...prev, ...fns];
|
|
3
4
|
export const prependHooks = (...fns) => (...prev) => [...fns, ...prev];
|
|
4
5
|
export const append = appendHooks;
|
|
@@ -18,7 +19,7 @@ const getConstructorChain = (ctor) => {
|
|
|
18
19
|
};
|
|
19
20
|
export function getHooks(target, key) {
|
|
20
21
|
const merged = new Map();
|
|
21
|
-
for (const ctor of getConstructorChain(target
|
|
22
|
+
for (const ctor of getConstructorChain(resolveConstructor(target)).reverse()) {
|
|
22
23
|
const ownHooks = Reflect.getOwnMetadata(key, ctor);
|
|
23
24
|
if (ownHooks) {
|
|
24
25
|
for (const [methodName, fns] of ownHooks) {
|
|
@@ -29,7 +30,7 @@ export function getHooks(target, key) {
|
|
|
29
30
|
return merged;
|
|
30
31
|
}
|
|
31
32
|
export function hasHooks(target, key) {
|
|
32
|
-
return getConstructorChain(target
|
|
33
|
+
return getConstructorChain(resolveConstructor(target)).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
|
|
33
34
|
}
|
|
34
35
|
export const hook = (key, mapFn) => (target, propertyKey) => {
|
|
35
36
|
const hooks = Reflect.hasOwnMetadata(key, target.constructor)
|
package/esm/index.js
CHANGED
|
@@ -35,6 +35,7 @@ export { SingleToken } from './token/SingleToken.js';
|
|
|
35
35
|
export { FunctionToken } from './token/FunctionToken.js';
|
|
36
36
|
export { ConstantToken } from './token/ConstantToken.js';
|
|
37
37
|
export { GroupInstanceToken } from './token/GroupInstanceToken.js';
|
|
38
|
+
export { resolveConstructor } from './metadata/target.js';
|
|
38
39
|
export { addClassMeta, getClassMeta, addClassLabel, getClassLabels, addClassTag, getClassTags } from './metadata/class.js';
|
|
39
40
|
export { addParamMeta, getParamMeta, addParamLabel, getParamLabels, addParamTag, getParamTags, } from './metadata/parameter.js';
|
|
40
41
|
export { addMethodMeta, getMethodMeta, addMethodLabel, getMethodLabels, addMethodTag, getMethodTags, } from './metadata/method.js';
|
|
@@ -45,5 +46,5 @@ export { shallowCache } from './utils/shallowCache.js';
|
|
|
45
46
|
export { once } from './utils/once.js';
|
|
46
47
|
export { select } from './select.js';
|
|
47
48
|
export { pipe } from './utils/fp.js';
|
|
48
|
-
export { ProxyRegistry } from './utils/ProxyRegistry.js';
|
|
49
|
-
export { Is
|
|
49
|
+
export { ProxyRegistry, unwrapProxy } from './utils/ProxyRegistry.js';
|
|
50
|
+
export { Is } from './utils/basic.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Injector } from './IInjector.js';
|
|
2
|
-
import {
|
|
2
|
+
import { resolveConstructor } from '../metadata/target.js';
|
|
3
3
|
import { getParamMeta, addParamMeta } from '../metadata/parameter.js';
|
|
4
4
|
import { argToToken, toMappedToken } from '../token/toToken.js';
|
|
5
5
|
export class MetadataInjector extends Injector {
|
|
@@ -11,13 +11,13 @@ export class MetadataInjector extends Injector {
|
|
|
11
11
|
const hookMetaKey = (methodName = 'constructor') => `inject:${methodName}`;
|
|
12
12
|
export function inject(fn, ...mappers) {
|
|
13
13
|
return (target, propertyKey, parameterIndex) => {
|
|
14
|
-
addParamMeta(hookMetaKey(propertyKey), () => toMappedToken(fn, mappers))(
|
|
14
|
+
addParamMeta(hookMetaKey(propertyKey), () => toMappedToken(fn, mappers))(resolveConstructor(target), propertyKey, parameterIndex);
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
export const argsFn = (predicate) => (c, { args = [] }) => args.find((value, index) => predicate(value, index));
|
|
18
18
|
export const arg = (index) => argsFn((value, i) => i === index);
|
|
19
19
|
export const args = (c, { args = [] }) => args;
|
|
20
|
-
export const resolveArgs = (
|
|
21
|
-
const tokens = getParamMeta(hookMetaKey(methodName),
|
|
20
|
+
export const resolveArgs = (target, methodName) => {
|
|
21
|
+
const tokens = getParamMeta(hookMetaKey(methodName), target);
|
|
22
22
|
return (scope, { args = [], lazy }) => tokens.map((fn) => fn.resolve(scope, { args: args.map(argToToken).map((t) => t.resolve(scope)), lazy }));
|
|
23
23
|
};
|
package/esm/metadata/class.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveConstructor } from '
|
|
1
|
+
import { resolveConstructor } from './target.js';
|
|
2
2
|
export const addClassMeta = (key, mapFn) => (target) => {
|
|
3
3
|
const value = Reflect.getOwnMetadata(key, target);
|
|
4
4
|
Reflect.defineMetadata(key, mapFn(value), target);
|
package/esm/metadata/method.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveConstructor } from '
|
|
1
|
+
import { resolveConstructor } from './target.js';
|
|
2
2
|
export const addMethodMeta = (key, mapFn) => (target, propertyKey) => {
|
|
3
3
|
const metadata = Reflect.getMetadata(key, target.constructor, propertyKey);
|
|
4
4
|
Reflect.defineMetadata(key, mapFn(metadata), target.constructor, propertyKey);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveConstructor } from '
|
|
1
|
+
import { resolveConstructor } from './target.js';
|
|
2
2
|
export const addParamMeta = (key, mapFn) => (target, _, parameterIndex) => {
|
|
3
3
|
const metadata = Reflect.getOwnMetadata(key, target) ?? [];
|
|
4
4
|
metadata[parameterIndex] = mapFn(metadata[parameterIndex]);
|
package/esm/utils/basic.js
CHANGED
|
@@ -4,6 +4,3 @@ export const Is = {
|
|
|
4
4
|
instance: (target) => Object.prototype.hasOwnProperty.call(target, 'constructor'),
|
|
5
5
|
constructor: (target) => typeof target === 'function' && !!target.prototype,
|
|
6
6
|
};
|
|
7
|
-
export function resolveConstructor(target) {
|
|
8
|
-
return Is.constructor(target) ? target : target.constructor;
|
|
9
|
-
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveConstructor } from '../metadata/target.js';
|
|
1
2
|
export const handleAsyncError = (errorHandler) => (target, propertyKey, descriptor) => {
|
|
2
3
|
const originalMethod = descriptor.value;
|
|
3
4
|
descriptor.value = async function (...args) {
|
|
@@ -5,7 +6,7 @@ export const handleAsyncError = (errorHandler) => (target, propertyKey, descript
|
|
|
5
6
|
return await originalMethod.apply(this, args);
|
|
6
7
|
}
|
|
7
8
|
catch (e) {
|
|
8
|
-
errorHandler(e, { target: target.
|
|
9
|
+
errorHandler(e, { target: resolveConstructor(target).name, method: propertyKey });
|
|
9
10
|
}
|
|
10
11
|
};
|
|
11
12
|
return descriptor;
|
|
@@ -17,7 +18,7 @@ export const handleError = (errorHandler) => (target, propertyKey, descriptor) =
|
|
|
17
18
|
return originalMethod.apply(this, args);
|
|
18
19
|
}
|
|
19
20
|
catch (e) {
|
|
20
|
-
errorHandler(e, { target: target.
|
|
21
|
+
errorHandler(e, { target: resolveConstructor(target).name, method: propertyKey });
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
24
|
return descriptor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "60.
|
|
3
|
+
"version": "60.2.0",
|
|
4
4
|
"description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AutoResolveOptions, type CreateScopeOptions, type DependencyKey, type IContainer, type IContainerModule, type InstanceHook, type RegisterOptions, ResolveManyOptions, type ResolveOneOptions, type ScopeHook, type Tag } from './IContainer.js';
|
|
1
|
+
import { type AutoResolveOptions, type CreateScopeOptions, type DependencyKey, type IContainer, type IContainerModule, type InstanceHook, type ProviderHook, type RegisterOptions, ResolveManyOptions, type ResolveOneOptions, type ScopeHook, type Tag } from './IContainer.js';
|
|
2
2
|
import { type IInjector } from '../injector/IInjector.js';
|
|
3
3
|
import { type IProvider } from '../provider/IProvider.js';
|
|
4
4
|
import { type IRegistration } from '../registration/IRegistration.js';
|
|
@@ -17,6 +17,7 @@ export declare class Container implements IContainer {
|
|
|
17
17
|
private readonly onConstructHookList;
|
|
18
18
|
private readonly onDisposeHookList;
|
|
19
19
|
private readonly onScopeCreatedHookList;
|
|
20
|
+
private readonly onProviderRegisteredHookList;
|
|
20
21
|
constructor(options?: {
|
|
21
22
|
injector?: IInjector;
|
|
22
23
|
parent?: IContainer;
|
|
@@ -35,6 +36,7 @@ export declare class Container implements IContainer {
|
|
|
35
36
|
onConstruct(...hooks: InstanceHook[]): this;
|
|
36
37
|
onInstanceDisposed(...hooks: OnDisposeHook[]): this;
|
|
37
38
|
onScopeCreated(...hooks: ScopeHook[]): this;
|
|
39
|
+
onProviderRegistered(...hooks: ProviderHook[]): this;
|
|
38
40
|
addInstance(instance: Instance): void;
|
|
39
41
|
getScopes(): IContainer[];
|
|
40
42
|
hasInstance(instance: Instance): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AutoResolveOptions, type DependencyKey, type IContainer, type IContainerModule, type ScopeHook, type ResolveManyOptions, type ResolveOneOptions, type Tag, type InstanceHook } from './IContainer.js';
|
|
1
|
+
import { type AutoResolveOptions, type DependencyKey, type IContainer, type IContainerModule, type ScopeHook, type ProviderHook, type ResolveManyOptions, type ResolveOneOptions, type Tag, type InstanceHook } from './IContainer.js';
|
|
2
2
|
import { type IProvider } from '../provider/IProvider.js';
|
|
3
3
|
import { type IRegistration } from '../registration/IRegistration.js';
|
|
4
4
|
import { OnDisposeHook } from '../hooks/onContainerDisposed.js';
|
|
@@ -27,4 +27,5 @@ export declare class EmptyContainer implements IContainer {
|
|
|
27
27
|
onInstanceDisposed(...hooks: OnDisposeHook[]): this;
|
|
28
28
|
onConstruct(...hooks: InstanceHook[]): this;
|
|
29
29
|
onScopeCreated(...hooks: ScopeHook[]): this;
|
|
30
|
+
onProviderRegistered(...hooks: ProviderHook[]): this;
|
|
30
31
|
}
|
|
@@ -35,11 +35,13 @@ export type RegisterOptions = {
|
|
|
35
35
|
export type ScopeHook = (scope: IContainer) => void;
|
|
36
36
|
export type InstanceHook = (instance: Instance, scope: IContainer) => void;
|
|
37
37
|
export type DependencyHook = (dependency: unknown, scope: IContainer) => void;
|
|
38
|
+
export type ProviderHook = (provider: IProvider, key: DependencyKey, scope: IContainer) => void;
|
|
38
39
|
export interface IContainer extends Tagged {
|
|
39
40
|
readonly isDisposed: boolean;
|
|
40
41
|
onConstruct(...hooks: InstanceHook[]): this;
|
|
41
42
|
onInstanceDisposed(...hooks: OnDisposeHook[]): this;
|
|
42
43
|
onScopeCreated(...hooks: ScopeHook[]): this;
|
|
44
|
+
onProviderRegistered(...hooks: ProviderHook[]): this;
|
|
43
45
|
register(key: DependencyKey, value: IProvider, options?: RegisterOptions): this;
|
|
44
46
|
addRegistration(registration: IRegistration): this;
|
|
45
47
|
getRegistrations(): IRegistration[];
|
package/typings/hooks/hook.d.ts
CHANGED
|
@@ -15,6 +15,6 @@ export declare const prependHooks: (...fns: HookType[]) => MapHooksFn;
|
|
|
15
15
|
export declare const append: (...fns: HookType[]) => MapHooksFn;
|
|
16
16
|
export declare const prepend: (...fns: HookType[]) => MapHooksFn;
|
|
17
17
|
export declare const toHookFn: <C extends IHookContext>(execute: HookFn<C> | constructor<HookClass<C>>) => HookFn<C>;
|
|
18
|
-
export declare function getHooks(target: Instance
|
|
19
|
-
export declare function hasHooks(target: Instance
|
|
18
|
+
export declare function getHooks(target: Instance | constructor<unknown>, key: string | symbol): HooksOfClass;
|
|
19
|
+
export declare function hasHooks(target: Instance | constructor<unknown>, key: string | symbol): boolean;
|
|
20
20
|
export declare const hook: (key: string | symbol, mapFn: MapHooksFn) => (target: object, propertyKey: string | symbol) => void;
|
package/typings/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { type IContainer, type Resolvable, type IContainerModule, type DependencyKey, type Tag, type Tagged, type ResolveOneOptions, type ResolveManyOptions, type ScopeHook, type InstanceHook, type DependencyHook, type AutoResolveOptions, isDependencyKey, } from './container/IContainer.js';
|
|
1
|
+
export { type IContainer, type Resolvable, type IContainerModule, type DependencyKey, type Tag, type Tagged, type ResolveOneOptions, type ResolveManyOptions, type ScopeHook, type InstanceHook, type DependencyHook, type ProviderHook, type AutoResolveOptions, isDependencyKey, } from './container/IContainer.js';
|
|
2
2
|
export { Container } from './container/Container.js';
|
|
3
3
|
export { AutoResolveModule } from './container/AutoResolveModule.js';
|
|
4
4
|
export { EmptyContainer } from './container/EmptyContainer.js';
|
|
@@ -36,6 +36,7 @@ export { SingleToken } from './token/SingleToken.js';
|
|
|
36
36
|
export { FunctionToken } from './token/FunctionToken.js';
|
|
37
37
|
export { ConstantToken } from './token/ConstantToken.js';
|
|
38
38
|
export { type InstancePredicate, GroupInstanceToken } from './token/GroupInstanceToken.js';
|
|
39
|
+
export { resolveConstructor } from './metadata/target.js';
|
|
39
40
|
export { addClassMeta, getClassMeta, addClassLabel, getClassLabels, addClassTag, getClassTags } from './metadata/class.js';
|
|
40
41
|
export { addParamMeta, getParamMeta, addParamLabel, getParamLabels, addParamTag, getParamTags, } from './metadata/parameter.js';
|
|
41
42
|
export { addMethodMeta, getMethodMeta, addMethodLabel, getMethodLabels, addMethodTag, getMethodTags, } from './metadata/method.js';
|
|
@@ -47,5 +48,5 @@ export { once } from './utils/once.js';
|
|
|
47
48
|
export { type ExecutionContext } from './ExecutionContext.js';
|
|
48
49
|
export { select } from './select.js';
|
|
49
50
|
export { pipe, type MapFn } from './utils/fp.js';
|
|
50
|
-
export { ProxyRegistry, type IProxyRegistry } from './utils/ProxyRegistry.js';
|
|
51
|
-
export { type Branded, type constructor, type Instance, Is
|
|
51
|
+
export { ProxyRegistry, unwrapProxy, type IProxyRegistry } from './utils/ProxyRegistry.js';
|
|
52
|
+
export { type Branded, type constructor, type Instance, Is } from './utils/basic.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IInjector, InjectOptions, Injector } from './IInjector.js';
|
|
2
2
|
import type { IContainer } from '../container/IContainer.js';
|
|
3
|
-
import { type constructor } from '../utils/basic.js';
|
|
3
|
+
import { type constructor, type Instance } from '../utils/basic.js';
|
|
4
4
|
import { ProviderOptions } from '../provider/IProvider.js';
|
|
5
5
|
import { type Injectable } from '../token/toToken.js';
|
|
6
6
|
import { InjectFn } from '../hooks/hook.js';
|
|
@@ -22,4 +22,4 @@ export declare function inject<T>(fn: Injectable<T>, ...mappers: MapFn<T>[]): Pa
|
|
|
22
22
|
export declare const argsFn: <T = unknown>(predicate: (value: unknown, index: number) => boolean) => InjectFn<T>;
|
|
23
23
|
export declare const arg: <T = unknown>(index: number) => InjectFn<T>;
|
|
24
24
|
export declare const args: InjectFn<unknown[]>;
|
|
25
|
-
export declare const resolveArgs: (
|
|
25
|
+
export declare const resolveArgs: (target: constructor<unknown> | Instance, methodName?: string) => (scope: IContainer, { args, lazy }: ProviderOptions) => unknown[];
|
package/typings/utils/basic.d.ts
CHANGED