ts-ioc-container 60.3.0 → 62.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 +111 -65
- package/cjm/container/Container.js +16 -26
- package/cjm/container/EmptyContainer.js +3 -6
- package/cjm/hooks/HooksRunner.js +30 -22
- package/cjm/hooks/onConstruct.js +3 -11
- package/cjm/hooks/onResolved.js +8 -4
- package/cjm/hooks/onScopeDisposed.js +22 -0
- package/cjm/hooks/resolveHooks.js +3 -14
- package/cjm/index.js +8 -19
- package/cjm/injector/IInjector.js +12 -0
- package/cjm/provider/Provider.js +6 -6
- package/cjm/registration/IRegistration.js +1 -1
- package/esm/container/Container.js +16 -26
- package/esm/container/EmptyContainer.js +3 -6
- package/esm/hooks/HooksRunner.js +28 -21
- package/esm/hooks/onConstruct.js +4 -12
- package/esm/hooks/onResolved.js +8 -4
- package/esm/hooks/onScopeDisposed.js +17 -0
- package/esm/hooks/resolveHooks.js +2 -12
- package/esm/index.js +3 -6
- package/esm/injector/IInjector.js +12 -0
- package/esm/provider/Provider.js +6 -6
- package/esm/registration/IRegistration.js +2 -2
- package/package.json +1 -1
- package/typings/container/Container.d.ts +5 -8
- package/typings/container/EmptyContainer.d.ts +3 -5
- package/typings/container/IContainer.d.ts +3 -7
- package/typings/hooks/HooksRunner.d.ts +4 -2
- package/typings/hooks/onConstruct.d.ts +4 -6
- package/typings/hooks/onResolved.d.ts +4 -2
- package/typings/hooks/onScopeDisposed.d.ts +10 -0
- package/typings/hooks/resolveHooks.d.ts +6 -7
- package/typings/index.d.ts +7 -10
- package/typings/injector/IInjector.d.ts +9 -1
- package/typings/provider/IProvider.d.ts +3 -2
- package/typings/provider/Provider.d.ts +4 -4
- package/typings/registration/IRegistration.d.ts +3 -3
- package/cjm/errors/UnexpectedHookResultError.js +0 -12
- package/cjm/hooks/onConstructAsync.js +0 -28
- package/cjm/hooks/onContainerDisposed.js +0 -18
- package/cjm/hooks/onResolvedAsync.js +0 -24
- package/cjm/utils/promise.js +0 -5
- package/esm/errors/UnexpectedHookResultError.js +0 -8
- package/esm/hooks/onConstructAsync.js +0 -23
- package/esm/hooks/onContainerDisposed.js +0 -13
- package/esm/hooks/onResolvedAsync.js +0 -19
- package/esm/utils/promise.js +0 -1
- package/typings/errors/UnexpectedHookResultError.d.ts +0 -5
- package/typings/hooks/onConstructAsync.d.ts +0 -11
- package/typings/hooks/onContainerDisposed.d.ts +0 -9
- package/typings/hooks/onResolvedAsync.d.ts +0 -12
- package/typings/utils/promise.d.ts +0 -1
package/cjm/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createHookContextFactory = exports.HookContext = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnsupportedTokenTypeError = exports.CannonSingletonApplyTwiceError = exports.
|
|
4
|
-
exports.
|
|
5
|
-
exports.Is = exports.unwrapProxy = exports.ProxyRegistry = exports.pipe = exports.select = exports.once = exports.shallowCache = exports.debounce =
|
|
3
|
+
exports.createHookContext = exports.createHookContextFactory = exports.HookContext = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnsupportedTokenTypeError = exports.CannonSingletonApplyTwiceError = 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.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.runHooks = exports.HooksRunner = exports.invokeMethod = exports.resolved = exports.OnResolvedModule = exports.onceResolved = exports.onResolved = exports.onResolvedHooksRunner = exports.OnDisposeModule = exports.onScopeDisposed = exports.onScopeDisposedHooksRunner = exports.OnConstructModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = void 0;
|
|
5
|
+
exports.Is = exports.unwrapProxy = exports.ProxyRegistry = exports.pipe = exports.select = exports.once = exports.shallowCache = exports.debounce = 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");
|
|
@@ -59,8 +59,6 @@ var ContainerDisposedError_1 = require("./errors/ContainerDisposedError");
|
|
|
59
59
|
Object.defineProperty(exports, "ContainerDisposedError", { enumerable: true, get: function () { return ContainerDisposedError_1.ContainerDisposedError; } });
|
|
60
60
|
var ProviderDisposedError_1 = require("./errors/ProviderDisposedError");
|
|
61
61
|
Object.defineProperty(exports, "ProviderDisposedError", { enumerable: true, get: function () { return ProviderDisposedError_1.ProviderDisposedError; } });
|
|
62
|
-
var UnexpectedHookResultError_1 = require("./errors/UnexpectedHookResultError");
|
|
63
|
-
Object.defineProperty(exports, "UnexpectedHookResultError", { enumerable: true, get: function () { return UnexpectedHookResultError_1.UnexpectedHookResultError; } });
|
|
64
62
|
var CannonSingletonApplyTwiceError_1 = require("./errors/CannonSingletonApplyTwiceError");
|
|
65
63
|
Object.defineProperty(exports, "CannonSingletonApplyTwiceError", { enumerable: true, get: function () { return CannonSingletonApplyTwiceError_1.CannonSingletonApplyTwiceError; } });
|
|
66
64
|
var UnsupportedTokenTypeError_1 = require("./errors/UnsupportedTokenTypeError");
|
|
@@ -83,30 +81,21 @@ var onConstruct_1 = require("./hooks/onConstruct");
|
|
|
83
81
|
Object.defineProperty(exports, "onConstructHooksRunner", { enumerable: true, get: function () { return onConstruct_1.onConstructHooksRunner; } });
|
|
84
82
|
Object.defineProperty(exports, "onConstruct", { enumerable: true, get: function () { return onConstruct_1.onConstruct; } });
|
|
85
83
|
Object.defineProperty(exports, "OnConstructModule", { enumerable: true, get: function () { return onConstruct_1.OnConstructModule; } });
|
|
86
|
-
var
|
|
87
|
-
Object.defineProperty(exports, "
|
|
88
|
-
Object.defineProperty(exports, "
|
|
89
|
-
Object.defineProperty(exports, "
|
|
90
|
-
var onContainerDisposed_1 = require("./hooks/onContainerDisposed");
|
|
91
|
-
Object.defineProperty(exports, "onContainerDisposedHooksRunner", { enumerable: true, get: function () { return onContainerDisposed_1.onContainerDisposedHooksRunner; } });
|
|
92
|
-
Object.defineProperty(exports, "onContainerDisposed", { enumerable: true, get: function () { return onContainerDisposed_1.onContainerDisposed; } });
|
|
93
|
-
Object.defineProperty(exports, "OnDisposeModule", { enumerable: true, get: function () { return onContainerDisposed_1.OnDisposeModule; } });
|
|
84
|
+
var onScopeDisposed_1 = require("./hooks/onScopeDisposed");
|
|
85
|
+
Object.defineProperty(exports, "onScopeDisposedHooksRunner", { enumerable: true, get: function () { return onScopeDisposed_1.onScopeDisposedHooksRunner; } });
|
|
86
|
+
Object.defineProperty(exports, "onScopeDisposed", { enumerable: true, get: function () { return onScopeDisposed_1.onScopeDisposed; } });
|
|
87
|
+
Object.defineProperty(exports, "OnDisposeModule", { enumerable: true, get: function () { return onScopeDisposed_1.OnDisposeModule; } });
|
|
94
88
|
var onResolved_1 = require("./hooks/onResolved");
|
|
95
89
|
Object.defineProperty(exports, "onResolvedHooksRunner", { enumerable: true, get: function () { return onResolved_1.onResolvedHooksRunner; } });
|
|
96
90
|
Object.defineProperty(exports, "onResolved", { enumerable: true, get: function () { return onResolved_1.onResolved; } });
|
|
97
91
|
Object.defineProperty(exports, "onceResolved", { enumerable: true, get: function () { return onResolved_1.onceResolved; } });
|
|
98
92
|
Object.defineProperty(exports, "OnResolvedModule", { enumerable: true, get: function () { return onResolved_1.OnResolvedModule; } });
|
|
99
93
|
Object.defineProperty(exports, "resolved", { enumerable: true, get: function () { return onResolved_1.resolved; } });
|
|
100
|
-
var onResolvedAsync_1 = require("./hooks/onResolvedAsync");
|
|
101
|
-
Object.defineProperty(exports, "onResolvedAsyncHooksRunner", { enumerable: true, get: function () { return onResolvedAsync_1.onResolvedAsyncHooksRunner; } });
|
|
102
|
-
Object.defineProperty(exports, "onResolvedAsync", { enumerable: true, get: function () { return onResolvedAsync_1.onResolvedAsync; } });
|
|
103
|
-
Object.defineProperty(exports, "onceResolvedAsync", { enumerable: true, get: function () { return onResolvedAsync_1.onceResolvedAsync; } });
|
|
104
|
-
Object.defineProperty(exports, "OnResolvedAsyncModule", { enumerable: true, get: function () { return onResolvedAsync_1.OnResolvedAsyncModule; } });
|
|
105
|
-
Object.defineProperty(exports, "resolvedAsync", { enumerable: true, get: function () { return onResolvedAsync_1.resolvedAsync; } });
|
|
106
94
|
var resolveHooks_1 = require("./hooks/resolveHooks");
|
|
107
95
|
Object.defineProperty(exports, "invokeMethod", { enumerable: true, get: function () { return resolveHooks_1.invokeMethod; } });
|
|
108
96
|
var HooksRunner_1 = require("./hooks/HooksRunner");
|
|
109
97
|
Object.defineProperty(exports, "HooksRunner", { enumerable: true, get: function () { return HooksRunner_1.HooksRunner; } });
|
|
98
|
+
Object.defineProperty(exports, "runHooks", { enumerable: true, get: function () { return HooksRunner_1.runHooks; } });
|
|
110
99
|
var InjectionToken_1 = require("./token/InjectionToken");
|
|
111
100
|
Object.defineProperty(exports, "InjectionToken", { enumerable: true, get: function () { return InjectionToken_1.InjectionToken; } });
|
|
112
101
|
var toToken_1 = require("./token/toToken");
|
|
@@ -4,6 +4,7 @@ exports.Injector = void 0;
|
|
|
4
4
|
const ProxyRegistry_1 = require("../utils/ProxyRegistry");
|
|
5
5
|
class Injector {
|
|
6
6
|
proxyRegistry;
|
|
7
|
+
onConstructedHookList = [];
|
|
7
8
|
constructor(proxyRegistry = ProxyRegistry_1.ProxyRegistry.getInstance()) {
|
|
8
9
|
this.proxyRegistry = proxyRegistry;
|
|
9
10
|
}
|
|
@@ -11,8 +12,19 @@ class Injector {
|
|
|
11
12
|
return this.proxyRegistry.toLazyIf(() => {
|
|
12
13
|
const instance = this.createInstance(scope, Target, { args });
|
|
13
14
|
scope.addInstance(instance);
|
|
15
|
+
for (const onConstructed of this.onConstructedHookList) {
|
|
16
|
+
onConstructed(instance, scope);
|
|
17
|
+
}
|
|
14
18
|
return instance;
|
|
15
19
|
}, lazy);
|
|
16
20
|
}
|
|
21
|
+
onConstructed(...hooks) {
|
|
22
|
+
this.onConstructedHookList.push(...hooks);
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
useModule(module) {
|
|
26
|
+
module.applyTo(this);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
17
29
|
}
|
|
18
30
|
exports.Injector = Injector;
|
package/cjm/provider/Provider.js
CHANGED
|
@@ -22,7 +22,7 @@ class Provider {
|
|
|
22
22
|
cache = new Map();
|
|
23
23
|
getKey;
|
|
24
24
|
isDisposed = false;
|
|
25
|
-
|
|
25
|
+
onResolvedHookList = [];
|
|
26
26
|
constructor(resolveDependency) {
|
|
27
27
|
this.resolveDependency = resolveDependency;
|
|
28
28
|
}
|
|
@@ -43,8 +43,8 @@ class Provider {
|
|
|
43
43
|
lazy: lazy ?? this.isLazy,
|
|
44
44
|
});
|
|
45
45
|
dependency = this.mappers.reduce((acc, current) => current(acc, scope), dependency);
|
|
46
|
-
for (const
|
|
47
|
-
|
|
46
|
+
for (const onResolved of this.onResolvedHookList) {
|
|
47
|
+
onResolved(dependency, scope);
|
|
48
48
|
}
|
|
49
49
|
return dependency;
|
|
50
50
|
}
|
|
@@ -81,8 +81,8 @@ class Provider {
|
|
|
81
81
|
this.getKey = getCacheKey;
|
|
82
82
|
return this;
|
|
83
83
|
}
|
|
84
|
-
|
|
85
|
-
this.
|
|
84
|
+
onResolved(...hooks) {
|
|
85
|
+
this.onResolvedHookList.push(...hooks);
|
|
86
86
|
return this;
|
|
87
87
|
}
|
|
88
88
|
dispose() {
|
|
@@ -94,7 +94,7 @@ class Provider {
|
|
|
94
94
|
this.accessRules.splice(0, this.accessRules.length);
|
|
95
95
|
this.mappers.splice(0, this.mappers.length);
|
|
96
96
|
this.argsFnList.splice(0, this.argsFnList.length);
|
|
97
|
-
this.
|
|
97
|
+
this.onResolvedHookList.splice(0, this.onResolvedHookList.length);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
exports.Provider = Provider;
|
|
@@ -54,5 +54,5 @@ const decorate = (...fns) => (0, exports.registerPipe)((p) => p.map(...fns));
|
|
|
54
54
|
exports.decorate = decorate;
|
|
55
55
|
const singleton = (getCacheKey) => (0, exports.registerPipe)((p) => p.singleton(getCacheKey));
|
|
56
56
|
exports.singleton = singleton;
|
|
57
|
-
const onResolve = (...hooks) => (0, exports.registerPipe)((p) => p.
|
|
57
|
+
const onResolve = (...hooks) => (0, exports.registerPipe)((p) => p.onResolved(...hooks));
|
|
58
58
|
exports.onResolve = onResolve;
|
|
@@ -16,10 +16,9 @@ export class Container {
|
|
|
16
16
|
providers = new Map();
|
|
17
17
|
aliases = new AliasMap();
|
|
18
18
|
injector;
|
|
19
|
-
onConstructHookList = [];
|
|
20
|
-
onDisposeHookList = [];
|
|
21
19
|
onScopeCreatedHookList = [];
|
|
22
|
-
|
|
20
|
+
onScopeDisposedHookList = [];
|
|
21
|
+
onRegisteredHookList = [];
|
|
23
22
|
constructor(options = {}) {
|
|
24
23
|
this.injector = options.injector ?? new MetadataInjector();
|
|
25
24
|
this.parent = options.parent ?? new EmptyContainer();
|
|
@@ -29,8 +28,8 @@ export class Container {
|
|
|
29
28
|
this.validateContainer();
|
|
30
29
|
this.providers.set(key, provider);
|
|
31
30
|
this.aliases.setAliasesByKey(key, aliases);
|
|
32
|
-
for (const
|
|
33
|
-
|
|
31
|
+
for (const onRegistered of this.onRegisteredHookList) {
|
|
32
|
+
onRegistered(provider, key, this);
|
|
34
33
|
}
|
|
35
34
|
return this;
|
|
36
35
|
}
|
|
@@ -75,10 +74,9 @@ export class Container {
|
|
|
75
74
|
createScope({ tags } = {}) {
|
|
76
75
|
this.validateContainer();
|
|
77
76
|
const scope = new Container({ injector: this.injector, parent: this, tags })
|
|
78
|
-
.onConstruct(...this.onConstructHookList)
|
|
79
|
-
.onInstanceDisposed(...this.onDisposeHookList)
|
|
80
77
|
.onScopeCreated(...this.onScopeCreatedHookList)
|
|
81
|
-
.
|
|
78
|
+
.onScopeDisposed(...this.onScopeDisposedHookList)
|
|
79
|
+
.onRegistered(...this.onRegisteredHookList);
|
|
82
80
|
for (const registration of this.getRegistrations()) {
|
|
83
81
|
registration.applyTo(scope);
|
|
84
82
|
}
|
|
@@ -100,8 +98,8 @@ export class Container {
|
|
|
100
98
|
dispose() {
|
|
101
99
|
this.validateContainer();
|
|
102
100
|
this.isDisposed = true;
|
|
103
|
-
for (const
|
|
104
|
-
|
|
101
|
+
for (const onScopeDisposed of this.onScopeDisposedHookList) {
|
|
102
|
+
onScopeDisposed(this);
|
|
105
103
|
}
|
|
106
104
|
this.parent.removeScope(this);
|
|
107
105
|
this.parent = new EmptyContainer();
|
|
@@ -112,10 +110,9 @@ export class Container {
|
|
|
112
110
|
this.aliases.destroy();
|
|
113
111
|
this.instances.clear();
|
|
114
112
|
this.registrations = [];
|
|
115
|
-
this.onConstructHookList.length = 0;
|
|
116
|
-
this.onDisposeHookList.length = 0;
|
|
117
113
|
this.onScopeCreatedHookList.length = 0;
|
|
118
|
-
this.
|
|
114
|
+
this.onScopeDisposedHookList.length = 0;
|
|
115
|
+
this.onRegisteredHookList.length = 0;
|
|
119
116
|
}
|
|
120
117
|
addRegistration(registration) {
|
|
121
118
|
this.registrations.push(registration);
|
|
@@ -128,27 +125,20 @@ export class Container {
|
|
|
128
125
|
hasRegistration(key) {
|
|
129
126
|
return this.registrations.some((r) => r.getKeyOrFail() === key) || this.parent.hasRegistration(key);
|
|
130
127
|
}
|
|
131
|
-
onConstruct(...hooks) {
|
|
132
|
-
this.onConstructHookList.push(...hooks);
|
|
133
|
-
return this;
|
|
134
|
-
}
|
|
135
|
-
onInstanceDisposed(...hooks) {
|
|
136
|
-
this.onDisposeHookList.push(...hooks);
|
|
137
|
-
return this;
|
|
138
|
-
}
|
|
139
128
|
onScopeCreated(...hooks) {
|
|
140
129
|
this.onScopeCreatedHookList.push(...hooks);
|
|
141
130
|
return this;
|
|
142
131
|
}
|
|
143
|
-
|
|
144
|
-
this.
|
|
132
|
+
onScopeDisposed(...hooks) {
|
|
133
|
+
this.onScopeDisposedHookList.push(...hooks);
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
onRegistered(...hooks) {
|
|
137
|
+
this.onRegisteredHookList.push(...hooks);
|
|
145
138
|
return this;
|
|
146
139
|
}
|
|
147
140
|
addInstance(instance) {
|
|
148
141
|
this.instances.add(instance);
|
|
149
|
-
for (const onConstruct of this.onConstructHookList) {
|
|
150
|
-
onConstruct(instance, this);
|
|
151
|
-
}
|
|
152
142
|
}
|
|
153
143
|
getScopes() {
|
|
154
144
|
return [...this.scopes];
|
|
@@ -57,16 +57,13 @@ export class EmptyContainer {
|
|
|
57
57
|
resolveOneByAlias(alias, options) {
|
|
58
58
|
throw new DependencyNotFoundError(`Cannot find alias ${alias.toString()}`);
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
throw new MethodNotImplementedError();
|
|
62
|
-
}
|
|
63
|
-
onConstruct(...hooks) {
|
|
60
|
+
onScopeCreated(...hooks) {
|
|
64
61
|
throw new MethodNotImplementedError();
|
|
65
62
|
}
|
|
66
|
-
|
|
63
|
+
onScopeDisposed(...hooks) {
|
|
67
64
|
throw new MethodNotImplementedError();
|
|
68
65
|
}
|
|
69
|
-
|
|
66
|
+
onRegistered(...hooks) {
|
|
70
67
|
throw new MethodNotImplementedError();
|
|
71
68
|
}
|
|
72
69
|
}
|
package/esm/hooks/HooksRunner.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { createHookContext } from './HookContext.js';
|
|
2
2
|
import { getHooks, hasHooks, toHookFn } from './hook.js';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const runFrom = (fns, index, context) => {
|
|
4
|
+
for (let i = index; i < fns.length; i++) {
|
|
5
|
+
const result = fns[i](context);
|
|
6
|
+
if (result instanceof Promise) {
|
|
7
|
+
return result.then(() => runFrom(fns, i + 1, context));
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
};
|
|
5
11
|
export class HooksRunner {
|
|
6
12
|
key;
|
|
7
13
|
constructor(key) {
|
|
@@ -12,27 +18,28 @@ export class HooksRunner {
|
|
|
12
18
|
}
|
|
13
19
|
execute(target, { scope, createContext = createHookContext, mapContext = (context) => context, predicate = () => true, }) {
|
|
14
20
|
const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
|
|
15
|
-
const
|
|
16
|
-
const context = mapContext(createContext(target, scope, methodName));
|
|
17
|
-
for (const execute of executions) {
|
|
18
|
-
const result = execute(context);
|
|
19
|
-
if (result instanceof Promise) {
|
|
20
|
-
throw new UnexpectedHookResultError(`Hook ${methodName} returned a promise, use runHooksAsync instead`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
};
|
|
21
|
+
const pending = [];
|
|
24
22
|
for (const [methodName, executions] of hooks) {
|
|
25
|
-
runMethodHooks(methodName, executions.map(toHookFn));
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
async executeAsync(target, { scope, createContext = createHookContext, mapContext = (context) => context, predicate = () => true, }) {
|
|
29
|
-
const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
|
|
30
|
-
const runMethodHooks = async (methodName, executions) => {
|
|
31
23
|
const context = mapContext(createContext(target, scope, methodName));
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
const result = runFrom(executions.map(toHookFn), 0, context);
|
|
25
|
+
if (result) {
|
|
26
|
+
pending.push(result);
|
|
34
27
|
}
|
|
35
|
-
}
|
|
36
|
-
return Promise.all(
|
|
28
|
+
}
|
|
29
|
+
return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
|
|
37
30
|
}
|
|
38
31
|
}
|
|
32
|
+
export const runHooks = (runner, target, scope, onException) => {
|
|
33
|
+
const report = (ex) => {
|
|
34
|
+
if (!onException) {
|
|
35
|
+
throw ex;
|
|
36
|
+
}
|
|
37
|
+
onException(ex, { scope });
|
|
38
|
+
};
|
|
39
|
+
try {
|
|
40
|
+
runner.execute(target, { scope })?.catch(report);
|
|
41
|
+
}
|
|
42
|
+
catch (ex) {
|
|
43
|
+
report(ex);
|
|
44
|
+
}
|
|
45
|
+
};
|
package/esm/hooks/onConstruct.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { hook, prependHooks } from './hook.js';
|
|
2
|
-
import { HooksRunner } from './HooksRunner.js';
|
|
2
|
+
import { HooksRunner, runHooks } from './HooksRunner.js';
|
|
3
3
|
export const onConstructHooksRunner = new HooksRunner('onConstruct');
|
|
4
4
|
export const onConstruct = (...fns) => hook('onConstruct', prependHooks(...fns));
|
|
5
5
|
export class OnConstructModule {
|
|
@@ -7,17 +7,9 @@ export class OnConstructModule {
|
|
|
7
7
|
constructor(onException) {
|
|
8
8
|
this.onException = onException;
|
|
9
9
|
}
|
|
10
|
-
applyTo(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
onConstructHooksRunner.execute(instance, { scope });
|
|
14
|
-
}
|
|
15
|
-
catch (ex) {
|
|
16
|
-
if (!this.onException) {
|
|
17
|
-
throw ex;
|
|
18
|
-
}
|
|
19
|
-
this.onException(ex, { scope });
|
|
20
|
-
}
|
|
10
|
+
applyTo(injector) {
|
|
11
|
+
injector.onConstructed((instance, scope) => {
|
|
12
|
+
runHooks(onConstructHooksRunner, instance, scope, this.onException);
|
|
21
13
|
});
|
|
22
14
|
}
|
|
23
15
|
}
|
package/esm/hooks/onResolved.js
CHANGED
|
@@ -4,12 +4,16 @@ import { executeHooks, forEachResolvedObject, onceResolvedHook, resolvedHook } f
|
|
|
4
4
|
export const onResolvedHooksRunner = new HooksRunner('onResolved');
|
|
5
5
|
export const onResolved = resolvedHook('onResolved');
|
|
6
6
|
export const onceResolved = onceResolvedHook('onResolved');
|
|
7
|
-
const runHooks = forEachResolvedObject(executeHooks(onResolvedHooksRunner));
|
|
7
|
+
const runHooks = (onException) => forEachResolvedObject(executeHooks(onResolvedHooksRunner, onException));
|
|
8
8
|
export class OnResolvedModule {
|
|
9
|
+
runHooks;
|
|
10
|
+
constructor(onException) {
|
|
11
|
+
this.runHooks = runHooks(onException);
|
|
12
|
+
}
|
|
9
13
|
applyTo(container) {
|
|
10
|
-
container.
|
|
11
|
-
provider.
|
|
14
|
+
container.onRegistered((provider) => {
|
|
15
|
+
provider.onResolved(this.runHooks);
|
|
12
16
|
});
|
|
13
17
|
}
|
|
14
18
|
}
|
|
15
|
-
export const resolved = () => registerPipe((p) => p.
|
|
19
|
+
export const resolved = (onException) => registerPipe((p) => p.onResolved(runHooks(onException)));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { hook, prependHooks } from './hook.js';
|
|
2
|
+
import { HooksRunner, runHooks } from './HooksRunner.js';
|
|
3
|
+
export const onScopeDisposedHooksRunner = new HooksRunner('onScopeDisposed');
|
|
4
|
+
export const onScopeDisposed = (...fns) => hook('onScopeDisposed', prependHooks(...fns));
|
|
5
|
+
export class OnDisposeModule {
|
|
6
|
+
onException;
|
|
7
|
+
constructor(onException) {
|
|
8
|
+
this.onException = onException;
|
|
9
|
+
}
|
|
10
|
+
applyTo(container) {
|
|
11
|
+
container.onScopeDisposed((scope) => {
|
|
12
|
+
for (const instance of scope.getInstances()) {
|
|
13
|
+
runHooks(onScopeDisposedHooksRunner, instance, scope, this.onException);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { runHooks } from './HooksRunner.js';
|
|
1
2
|
import { hook, prependHooks, toHookFn } from './hook.js';
|
|
2
3
|
import { Is } from '../utils/basic.js';
|
|
3
4
|
export const invokeMethod = (context) => {
|
|
@@ -21,15 +22,4 @@ export const forEachResolvedObject = (run) => (dependency, scope) => {
|
|
|
21
22
|
run(dependency, scope);
|
|
22
23
|
}
|
|
23
24
|
};
|
|
24
|
-
export const executeHooks = (runner) => (dependency, scope) => runner
|
|
25
|
-
export const executeHooksAsync = (runner, onException) => (dependency, scope) => {
|
|
26
|
-
if (!runner.hasHooks(dependency)) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
runner.executeAsync(dependency, { scope }).catch((ex) => {
|
|
30
|
-
if (!onException) {
|
|
31
|
-
throw ex;
|
|
32
|
-
}
|
|
33
|
-
onException(ex, { scope });
|
|
34
|
-
});
|
|
35
|
-
};
|
|
25
|
+
export const executeHooks = (runner, onException) => (dependency, scope) => runHooks(runner, dependency, scope, onException);
|
package/esm/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { 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';
|
|
5
|
-
export { Injector } from './injector/IInjector.js';
|
|
5
|
+
export { Injector, } from './injector/IInjector.js';
|
|
6
6
|
export { MetadataInjector, inject, arg, args, argsFn, resolveArgs } from './injector/MetadataInjector.js';
|
|
7
7
|
export { SimpleInjector } from './injector/SimpleInjector.js';
|
|
8
8
|
export { ProxyInjector } from './injector/ProxyInjector.js';
|
|
@@ -16,19 +16,16 @@ export { DependencyMissingKeyError } from './errors/DependencyMissingKeyError.js
|
|
|
16
16
|
export { MethodNotImplementedError } from './errors/MethodNotImplementedError.js';
|
|
17
17
|
export { ContainerDisposedError } from './errors/ContainerDisposedError.js';
|
|
18
18
|
export { ProviderDisposedError } from './errors/ProviderDisposedError.js';
|
|
19
|
-
export { UnexpectedHookResultError } from './errors/UnexpectedHookResultError.js';
|
|
20
19
|
export { CannonSingletonApplyTwiceError } from './errors/CannonSingletonApplyTwiceError.js';
|
|
21
20
|
export { UnsupportedTokenTypeError } from './errors/UnsupportedTokenTypeError.js';
|
|
22
21
|
export { getHooks, hook, hasHooks, appendHooks, prependHooks, append, prepend, } from './hooks/hook.js';
|
|
23
22
|
export { HookContext, createHookContextFactory, createHookContext } from './hooks/HookContext.js';
|
|
24
23
|
export { injectProp } from './hooks/injectProp.js';
|
|
25
24
|
export { onConstructHooksRunner, onConstruct, OnConstructModule } from './hooks/onConstruct.js';
|
|
26
|
-
export {
|
|
27
|
-
export { onContainerDisposedHooksRunner, onContainerDisposed, OnDisposeModule } from './hooks/onContainerDisposed.js';
|
|
25
|
+
export { onScopeDisposedHooksRunner, onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
|
|
28
26
|
export { onResolvedHooksRunner, onResolved, onceResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
|
|
29
|
-
export { onResolvedAsyncHooksRunner, onResolvedAsync, onceResolvedAsync, OnResolvedAsyncModule, resolvedAsync, } from './hooks/onResolvedAsync.js';
|
|
30
27
|
export { invokeMethod } from './hooks/resolveHooks.js';
|
|
31
|
-
export { HooksRunner } from './hooks/HooksRunner.js';
|
|
28
|
+
export { HooksRunner, runHooks, } from './hooks/HooksRunner.js';
|
|
32
29
|
export { InjectionToken } from './token/InjectionToken.js';
|
|
33
30
|
export { toToken, toMappedToken, argToToken } from './token/toToken.js';
|
|
34
31
|
export { GroupAliasToken, toGroupAlias } from './token/GroupAliasToken.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ProxyRegistry } from '../utils/ProxyRegistry.js';
|
|
2
2
|
export class Injector {
|
|
3
3
|
proxyRegistry;
|
|
4
|
+
onConstructedHookList = [];
|
|
4
5
|
constructor(proxyRegistry = ProxyRegistry.getInstance()) {
|
|
5
6
|
this.proxyRegistry = proxyRegistry;
|
|
6
7
|
}
|
|
@@ -8,7 +9,18 @@ export class Injector {
|
|
|
8
9
|
return this.proxyRegistry.toLazyIf(() => {
|
|
9
10
|
const instance = this.createInstance(scope, Target, { args });
|
|
10
11
|
scope.addInstance(instance);
|
|
12
|
+
for (const onConstructed of this.onConstructedHookList) {
|
|
13
|
+
onConstructed(instance, scope);
|
|
14
|
+
}
|
|
11
15
|
return instance;
|
|
12
16
|
}, lazy);
|
|
13
17
|
}
|
|
18
|
+
onConstructed(...hooks) {
|
|
19
|
+
this.onConstructedHookList.push(...hooks);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
useModule(module) {
|
|
23
|
+
module.applyTo(this);
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
14
26
|
}
|
package/esm/provider/Provider.js
CHANGED
|
@@ -19,7 +19,7 @@ export class Provider {
|
|
|
19
19
|
cache = new Map();
|
|
20
20
|
getKey;
|
|
21
21
|
isDisposed = false;
|
|
22
|
-
|
|
22
|
+
onResolvedHookList = [];
|
|
23
23
|
constructor(resolveDependency) {
|
|
24
24
|
this.resolveDependency = resolveDependency;
|
|
25
25
|
}
|
|
@@ -40,8 +40,8 @@ export class Provider {
|
|
|
40
40
|
lazy: lazy ?? this.isLazy,
|
|
41
41
|
});
|
|
42
42
|
dependency = this.mappers.reduce((acc, current) => current(acc, scope), dependency);
|
|
43
|
-
for (const
|
|
44
|
-
|
|
43
|
+
for (const onResolved of this.onResolvedHookList) {
|
|
44
|
+
onResolved(dependency, scope);
|
|
45
45
|
}
|
|
46
46
|
return dependency;
|
|
47
47
|
}
|
|
@@ -78,8 +78,8 @@ export class Provider {
|
|
|
78
78
|
this.getKey = getCacheKey;
|
|
79
79
|
return this;
|
|
80
80
|
}
|
|
81
|
-
|
|
82
|
-
this.
|
|
81
|
+
onResolved(...hooks) {
|
|
82
|
+
this.onResolvedHookList.push(...hooks);
|
|
83
83
|
return this;
|
|
84
84
|
}
|
|
85
85
|
dispose() {
|
|
@@ -91,6 +91,6 @@ export class Provider {
|
|
|
91
91
|
this.accessRules.splice(0, this.accessRules.length);
|
|
92
92
|
this.mappers.splice(0, this.mappers.length);
|
|
93
93
|
this.argsFnList.splice(0, this.argsFnList.length);
|
|
94
|
-
this.
|
|
94
|
+
this.onResolvedHookList.splice(0, this.onResolvedHookList.length);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isDependencyKey
|
|
1
|
+
import { isDependencyKey } from '../container/IContainer.js';
|
|
2
2
|
import { SingleToken } from '../token/SingleToken.js';
|
|
3
3
|
import { addClassMeta, getClassMeta } from '../metadata/class.js';
|
|
4
4
|
export const isProviderPipe = (obj) => obj !== null && typeof obj === 'object' && 'mapProvider' in obj;
|
|
@@ -35,4 +35,4 @@ export const lazy = () => registerPipe((p) => p.lazy());
|
|
|
35
35
|
export const autoResolve = () => registerPipe((p) => p.autoResolve());
|
|
36
36
|
export const decorate = (...fns) => registerPipe((p) => p.map(...fns));
|
|
37
37
|
export const singleton = (getCacheKey) => registerPipe((p) => p.singleton(getCacheKey));
|
|
38
|
-
export const onResolve = (...hooks) => registerPipe((p) => p.
|
|
38
|
+
export const onResolve = (...hooks) => registerPipe((p) => p.onResolved(...hooks));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "62.0.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,8 +1,7 @@
|
|
|
1
|
-
import { type AutoResolveOptions, type CreateScopeOptions, type DependencyKey, type IContainer, type IContainerModule, type
|
|
1
|
+
import { type AutoResolveOptions, type CreateScopeOptions, type DependencyKey, type IContainer, type IContainerModule, type RegisteredHook, 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';
|
|
5
|
-
import { OnDisposeHook } from '../hooks/onContainerDisposed.js';
|
|
6
5
|
import { constructor, Instance } from '../utils/basic.js';
|
|
7
6
|
export declare class Container implements IContainer {
|
|
8
7
|
isDisposed: boolean;
|
|
@@ -14,10 +13,9 @@ export declare class Container implements IContainer {
|
|
|
14
13
|
private readonly providers;
|
|
15
14
|
private readonly aliases;
|
|
16
15
|
private readonly injector;
|
|
17
|
-
private readonly onConstructHookList;
|
|
18
|
-
private readonly onDisposeHookList;
|
|
19
16
|
private readonly onScopeCreatedHookList;
|
|
20
|
-
private readonly
|
|
17
|
+
private readonly onScopeDisposedHookList;
|
|
18
|
+
private readonly onRegisteredHookList;
|
|
21
19
|
constructor(options?: {
|
|
22
20
|
injector?: IInjector;
|
|
23
21
|
parent?: IContainer;
|
|
@@ -33,10 +31,9 @@ export declare class Container implements IContainer {
|
|
|
33
31
|
addRegistration(registration: IRegistration): this;
|
|
34
32
|
getRegistrations(): IRegistration[];
|
|
35
33
|
hasRegistration(key: DependencyKey): boolean;
|
|
36
|
-
onConstruct(...hooks: InstanceHook[]): this;
|
|
37
|
-
onInstanceDisposed(...hooks: OnDisposeHook[]): this;
|
|
38
34
|
onScopeCreated(...hooks: ScopeHook[]): this;
|
|
39
|
-
|
|
35
|
+
onScopeDisposed(...hooks: ScopeHook[]): this;
|
|
36
|
+
onRegistered(...hooks: RegisteredHook[]): this;
|
|
40
37
|
addInstance(instance: Instance): void;
|
|
41
38
|
getScopes(): IContainer[];
|
|
42
39
|
hasInstance(instance: Instance): boolean;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { type AutoResolveOptions, type DependencyKey, type IContainer, type IContainerModule, type ScopeHook, type
|
|
1
|
+
import { type AutoResolveOptions, type DependencyKey, type IContainer, type IContainerModule, type ScopeHook, type RegisteredHook, type ResolveManyOptions, type ResolveOneOptions, type Tag } from './IContainer.js';
|
|
2
2
|
import { type IProvider } from '../provider/IProvider.js';
|
|
3
3
|
import { type IRegistration } from '../registration/IRegistration.js';
|
|
4
|
-
import { OnDisposeHook } from '../hooks/onContainerDisposed.js';
|
|
5
4
|
import { type constructor, type Instance } from '../utils/basic.js';
|
|
6
5
|
export declare class EmptyContainer implements IContainer {
|
|
7
6
|
get isDisposed(): boolean;
|
|
@@ -24,8 +23,7 @@ export declare class EmptyContainer implements IContainer {
|
|
|
24
23
|
resolve<T>(key: constructor<T> | DependencyKey, options?: ResolveOneOptions): T;
|
|
25
24
|
resolveByAlias<T>(alias: DependencyKey, options?: ResolveManyOptions): T[];
|
|
26
25
|
resolveOneByAlias<T>(alias: DependencyKey, options?: ResolveOneOptions): T;
|
|
27
|
-
onInstanceDisposed(...hooks: OnDisposeHook[]): this;
|
|
28
|
-
onConstruct(...hooks: InstanceHook[]): this;
|
|
29
26
|
onScopeCreated(...hooks: ScopeHook[]): this;
|
|
30
|
-
|
|
27
|
+
onScopeDisposed(...hooks: ScopeHook[]): this;
|
|
28
|
+
onRegistered(...hooks: RegisteredHook[]): this;
|
|
31
29
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type IProvider, ProviderOptions } from '../provider/IProvider.js';
|
|
2
2
|
import { type IRegistration } from '../registration/IRegistration.js';
|
|
3
|
-
import { OnDisposeHook } from '../hooks/onContainerDisposed.js';
|
|
4
3
|
import { type WithArgs } from '../injector/IInjector.js';
|
|
5
4
|
import { type constructor, Instance } from '../utils/basic.js';
|
|
6
5
|
export type DependencyKey = string | symbol;
|
|
@@ -33,15 +32,12 @@ export type RegisterOptions = {
|
|
|
33
32
|
aliases?: DependencyKey[];
|
|
34
33
|
};
|
|
35
34
|
export type ScopeHook = (scope: IContainer) => void;
|
|
36
|
-
export type
|
|
37
|
-
export type DependencyHook = (dependency: unknown, scope: IContainer) => void;
|
|
38
|
-
export type ProviderHook = (provider: IProvider, key: DependencyKey, scope: IContainer) => void;
|
|
35
|
+
export type RegisteredHook = (provider: IProvider, key: DependencyKey, scope: IContainer) => void;
|
|
39
36
|
export interface IContainer extends Tagged {
|
|
40
37
|
readonly isDisposed: boolean;
|
|
41
|
-
onConstruct(...hooks: InstanceHook[]): this;
|
|
42
|
-
onInstanceDisposed(...hooks: OnDisposeHook[]): this;
|
|
43
38
|
onScopeCreated(...hooks: ScopeHook[]): this;
|
|
44
|
-
|
|
39
|
+
onScopeDisposed(...hooks: ScopeHook[]): this;
|
|
40
|
+
onRegistered(...hooks: RegisteredHook[]): this;
|
|
45
41
|
register(key: DependencyKey, value: IProvider, options?: RegisterOptions): this;
|
|
46
42
|
addRegistration(registration: IRegistration): this;
|
|
47
43
|
getRegistrations(): IRegistration[];
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type CreateHookContext, type IHookContext } from './HookContext.js';
|
|
2
2
|
import type { IContainer } from '../container/IContainer.js';
|
|
3
3
|
import { type Instance } from '../utils/basic.js';
|
|
4
|
+
import type { ExecutionContext } from '../ExecutionContext.js';
|
|
4
5
|
export type MapHookContext = (context: IHookContext) => IHookContext;
|
|
6
|
+
export type OnExceptionHandler = (ex: unknown, context: ExecutionContext) => void;
|
|
5
7
|
export type HooksRunnerContext = {
|
|
6
8
|
scope: IContainer;
|
|
7
9
|
createContext?: CreateHookContext;
|
|
@@ -12,6 +14,6 @@ export declare class HooksRunner {
|
|
|
12
14
|
private readonly key;
|
|
13
15
|
constructor(key: string | symbol);
|
|
14
16
|
hasHooks(target: Instance): boolean;
|
|
15
|
-
execute(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): void
|
|
16
|
-
executeAsync(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): Promise<void[]>;
|
|
17
|
+
execute(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): void | Promise<void>;
|
|
17
18
|
}
|
|
19
|
+
export declare const runHooks: (runner: HooksRunner, target: Instance, scope: IContainer, onException?: OnExceptionHandler) => void;
|