ts-ioc-container 43.5.2 → 44.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 +47 -34
- package/cjm/container/AliasMap.js +5 -6
- package/cjm/container/Container.js +58 -56
- package/cjm/hooks/{runner/SyncHooksRunner.js → HooksRunner.js} +17 -6
- package/cjm/hooks/onConstruct.js +2 -2
- package/cjm/hooks/onDispose.js +4 -5
- package/cjm/index.js +5 -6
- package/cjm/injector/IInjector.js +7 -4
- package/cjm/provider/Provider.js +3 -2
- package/cjm/token/InstanceListToken.js +1 -9
- package/esm/container/AliasMap.js +5 -6
- package/esm/container/Container.js +59 -57
- package/esm/hooks/{runner/SyncHooksRunner.js → HooksRunner.js} +15 -4
- package/esm/hooks/onConstruct.js +2 -2
- package/esm/hooks/onDispose.js +3 -5
- package/esm/index.js +2 -2
- package/esm/injector/IInjector.js +7 -4
- package/esm/provider/Provider.js +4 -3
- package/esm/token/InstanceListToken.js +1 -9
- package/package.json +1 -1
- package/typings/container/AliasMap.d.ts +0 -1
- package/typings/container/Container.d.ts +11 -11
- package/typings/container/IContainer.d.ts +1 -1
- package/typings/hooks/HooksRunner.d.ts +17 -0
- package/typings/hooks/hook.d.ts +1 -1
- package/typings/hooks/onConstruct.d.ts +5 -5
- package/typings/hooks/onDispose.d.ts +5 -3
- package/typings/index.d.ts +2 -5
- package/typings/injector/IInjector.d.ts +3 -2
- package/typings/provider/IProvider.d.ts +1 -1
- package/cjm/hooks/runner/AsyncHooksRunner.js +0 -23
- package/cjm/hooks/runner/HooksRunner.js +0 -2
- package/esm/hooks/runner/AsyncHooksRunner.js +0 -19
- package/esm/hooks/runner/HooksRunner.js +0 -1
- package/typings/hooks/runner/AsyncHooksRunner.d.ts +0 -11
- package/typings/hooks/runner/HooksRunner.d.ts +0 -7
- package/typings/hooks/runner/SyncHooksRunner.d.ts +0 -6
package/README.md
CHANGED
|
@@ -1394,28 +1394,18 @@ Sometimes you need to invoke methods after construct or dispose of class. This i
|
|
|
1394
1394
|
```typescript
|
|
1395
1395
|
import {
|
|
1396
1396
|
bindTo,
|
|
1397
|
-
type constructor,
|
|
1398
1397
|
Container,
|
|
1399
1398
|
hook,
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1399
|
+
HookContext,
|
|
1400
|
+
HookFn,
|
|
1401
|
+
HooksRunner,
|
|
1402
|
+
inject,
|
|
1403
|
+
onConstruct,
|
|
1404
1404
|
register,
|
|
1405
1405
|
Registration as R,
|
|
1406
|
-
SyncHooksRunner,
|
|
1407
1406
|
} from 'ts-ioc-container';
|
|
1408
1407
|
|
|
1409
|
-
const onConstructHooksRunner = new
|
|
1410
|
-
class MyInjector implements IInjector {
|
|
1411
|
-
private injector = new MetadataInjector();
|
|
1412
|
-
|
|
1413
|
-
resolve<T>(container: IContainer, value: constructor<T>, options: InjectOptions): T {
|
|
1414
|
-
const instance = this.injector.resolve(container, value, options);
|
|
1415
|
-
onConstructHooksRunner.execute(instance as object, { scope: container });
|
|
1416
|
-
return instance;
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1408
|
+
const onConstructHooksRunner = new HooksRunner('onConstruct');
|
|
1419
1409
|
|
|
1420
1410
|
@register(bindTo('logger'))
|
|
1421
1411
|
class Logger {
|
|
@@ -1435,31 +1425,54 @@ class Logger {
|
|
|
1435
1425
|
|
|
1436
1426
|
describe('onConstruct', function () {
|
|
1437
1427
|
it('should make logger be ready on resolve', function () {
|
|
1438
|
-
const container = new Container(
|
|
1428
|
+
const container = new Container()
|
|
1429
|
+
.addOnConstructHook((instance, scope) => {
|
|
1430
|
+
onConstructHooksRunner.execute(instance as object, { scope });
|
|
1431
|
+
})
|
|
1432
|
+
.addRegistration(R.fromClass(Logger));
|
|
1439
1433
|
|
|
1440
1434
|
const logger = container.resolve<Logger>('logger');
|
|
1441
1435
|
|
|
1442
1436
|
expect(logger.isReady).toBe(true);
|
|
1443
1437
|
});
|
|
1438
|
+
|
|
1439
|
+
it('should run methods and resolve arguments from container', function () {
|
|
1440
|
+
const execute: HookFn = (ctx: HookContext) => {
|
|
1441
|
+
ctx.invokeMethod({ args: ctx.resolveArgs() });
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
class Car {
|
|
1445
|
+
private engine!: string;
|
|
1446
|
+
|
|
1447
|
+
@onConstruct(execute)
|
|
1448
|
+
setEngine(@inject('engine') engine: string) {
|
|
1449
|
+
this.engine = engine;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
getEngine() {
|
|
1453
|
+
return this.engine;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
const root = new Container()
|
|
1458
|
+
.addOnConstructHook((instance, scope) => {
|
|
1459
|
+
onConstructHooksRunner.execute(instance as object, { scope });
|
|
1460
|
+
})
|
|
1461
|
+
.addRegistration(R.fromValue('bmw').bindTo('engine'));
|
|
1462
|
+
|
|
1463
|
+
const car = root.resolve(Car);
|
|
1464
|
+
|
|
1465
|
+
expect(car.getEngine()).toBe('bmw');
|
|
1466
|
+
});
|
|
1444
1467
|
});
|
|
1445
1468
|
|
|
1446
1469
|
```
|
|
1447
1470
|
|
|
1448
1471
|
### OnDispose
|
|
1449
1472
|
```typescript
|
|
1450
|
-
import {
|
|
1451
|
-
bindTo,
|
|
1452
|
-
Container,
|
|
1453
|
-
hook,
|
|
1454
|
-
inject,
|
|
1455
|
-
register,
|
|
1456
|
-
Registration as R,
|
|
1457
|
-
select,
|
|
1458
|
-
singleton,
|
|
1459
|
-
SyncHooksRunner,
|
|
1460
|
-
} from 'ts-ioc-container';
|
|
1473
|
+
import { bindTo, Container, hook, HooksRunner, inject, register, Registration as R, select, singleton } from 'ts-ioc-container';
|
|
1461
1474
|
|
|
1462
|
-
const onDisposeHookRunner = new
|
|
1475
|
+
const onDisposeHookRunner = new HooksRunner('onDispose');
|
|
1463
1476
|
@register(bindTo('logsRepo'), singleton())
|
|
1464
1477
|
class LogsRepo {
|
|
1465
1478
|
savedLogs: string[] = [];
|
|
@@ -1515,9 +1528,9 @@ describe('onDispose', function () {
|
|
|
1515
1528
|
### Inject property
|
|
1516
1529
|
|
|
1517
1530
|
```typescript
|
|
1518
|
-
import { Container, hook, injectProp, Registration
|
|
1531
|
+
import { Container, hook, HooksRunner, injectProp, Registration } from 'ts-ioc-container';
|
|
1519
1532
|
|
|
1520
|
-
const onInitHookRunner = new
|
|
1533
|
+
const onInitHookRunner = new HooksRunner('onInit');
|
|
1521
1534
|
describe('inject property', () => {
|
|
1522
1535
|
it('should inject property', () => {
|
|
1523
1536
|
class App {
|
|
@@ -1526,9 +1539,9 @@ describe('inject property', () => {
|
|
|
1526
1539
|
}
|
|
1527
1540
|
const expected = 'Hello world!';
|
|
1528
1541
|
|
|
1529
|
-
const
|
|
1530
|
-
const app =
|
|
1531
|
-
onInitHookRunner.execute(app
|
|
1542
|
+
const scope = new Container().addRegistration(Registration.fromValue(expected).bindToKey('greeting'));
|
|
1543
|
+
const app = scope.resolve(App);
|
|
1544
|
+
onInitHookRunner.execute(app, { scope });
|
|
1532
1545
|
|
|
1533
1546
|
expect(app.greeting).toBe(expected);
|
|
1534
1547
|
});
|
|
@@ -3,18 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AliasMap = void 0;
|
|
4
4
|
class AliasMap {
|
|
5
5
|
aliasToKeySet = new Map();
|
|
6
|
-
|
|
6
|
+
getKeysByAlias(alias) {
|
|
7
|
+
return [...(this.aliasToKeySet.get(alias) ?? [])];
|
|
8
|
+
}
|
|
9
|
+
setAliasesByKey(key, aliases) {
|
|
10
|
+
// reset existing key's aliases
|
|
7
11
|
for (const [alias, keySet] of this.aliasToKeySet) {
|
|
8
12
|
keySet.delete(key);
|
|
9
13
|
if (keySet.size === 0) {
|
|
10
14
|
this.aliasToKeySet.delete(alias);
|
|
11
15
|
}
|
|
12
16
|
}
|
|
13
|
-
}
|
|
14
|
-
getKeysByAlias(alias) {
|
|
15
|
-
return [...(this.aliasToKeySet.get(alias) ?? [])];
|
|
16
|
-
}
|
|
17
|
-
setAliasesByKey(key, aliases) {
|
|
18
17
|
for (const alias of aliases) {
|
|
19
18
|
const dependencyKeySet = this.aliasToKeySet.get(alias) ?? new Set();
|
|
20
19
|
this.aliasToKeySet.set(alias, dependencyKeySet.add(key));
|
|
@@ -10,12 +10,12 @@ const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
|
|
|
10
10
|
class Container {
|
|
11
11
|
isDisposed = false;
|
|
12
12
|
parent;
|
|
13
|
-
scopes =
|
|
14
|
-
instances =
|
|
13
|
+
scopes = [];
|
|
14
|
+
instances = [];
|
|
15
|
+
registrations = [];
|
|
15
16
|
tags;
|
|
16
17
|
providers = new Map();
|
|
17
18
|
aliases = new AliasMap_1.AliasMap();
|
|
18
|
-
registrations = new Set();
|
|
19
19
|
injector;
|
|
20
20
|
onConstructHookList = [];
|
|
21
21
|
onDisposeHookList = [];
|
|
@@ -24,45 +24,21 @@ class Container {
|
|
|
24
24
|
this.parent = options.parent ?? new EmptyContainer_1.EmptyContainer();
|
|
25
25
|
this.tags = new Set(options.tags ?? []);
|
|
26
26
|
}
|
|
27
|
-
addOnConstructHook(...hooks) {
|
|
28
|
-
this.onConstructHookList.push(...hooks);
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
addOnDisposeHook(...hooks) {
|
|
32
|
-
this.onDisposeHookList.push(...hooks);
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
|
-
addInstance(instance) {
|
|
36
|
-
this.instances.add(instance);
|
|
37
|
-
// Execute onConstruct hooks
|
|
38
|
-
for (const onConstruct of this.onConstructHookList) {
|
|
39
|
-
onConstruct(instance, this);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
27
|
register(key, provider, { aliases = [] } = {}) {
|
|
43
28
|
this.validateContainer();
|
|
44
29
|
this.providers.set(key, provider);
|
|
45
|
-
this.aliases.deleteAliasesByKey(key);
|
|
46
30
|
this.aliases.setAliasesByKey(key, aliases);
|
|
47
31
|
return this;
|
|
48
32
|
}
|
|
49
|
-
|
|
50
|
-
this.registrations.add(registration);
|
|
51
|
-
registration.applyTo(this);
|
|
52
|
-
return this;
|
|
53
|
-
}
|
|
54
|
-
getRegistrations() {
|
|
55
|
-
return [...this.parent.getRegistrations(), ...this.registrations];
|
|
56
|
-
}
|
|
57
|
-
resolve(keyOrAlias, { args = [], child = this, lazy } = {}) {
|
|
33
|
+
resolve(key, { args = [], child = this, lazy } = {}) {
|
|
58
34
|
this.validateContainer();
|
|
59
|
-
if (utils_1.Is.constructor(
|
|
60
|
-
return
|
|
35
|
+
if (utils_1.Is.constructor(key)) {
|
|
36
|
+
return this.injector.resolve(this, key, { args, lazy });
|
|
61
37
|
}
|
|
62
|
-
const provider = this.providers.get(
|
|
38
|
+
const provider = this.providers.get(key);
|
|
63
39
|
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
64
40
|
? provider.resolve(this, { args, lazy })
|
|
65
|
-
: this.parent.resolve(
|
|
41
|
+
: this.parent.resolve(key, { args, child, lazy });
|
|
66
42
|
}
|
|
67
43
|
resolveByAlias(alias, { args = [], child = this, lazy, excludedKeys = [] } = {}) {
|
|
68
44
|
this.validateContainer();
|
|
@@ -87,7 +63,7 @@ class Container {
|
|
|
87
63
|
resolveOneByAlias(alias, { args = [], child = this, lazy } = {}) {
|
|
88
64
|
this.validateContainer();
|
|
89
65
|
const [key, ..._] = this.aliases.getKeysByAlias(alias);
|
|
90
|
-
const provider = key
|
|
66
|
+
const provider = key ? this.findProviderByKeyOrFail(key) : undefined;
|
|
91
67
|
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
92
68
|
? provider.resolve(this, { args, lazy })
|
|
93
69
|
: this.parent.resolveOneByAlias(key, { args, child, lazy });
|
|
@@ -100,14 +76,56 @@ class Container {
|
|
|
100
76
|
for (const registration of this.getRegistrations()) {
|
|
101
77
|
registration.applyTo(scope);
|
|
102
78
|
}
|
|
103
|
-
this.scopes.
|
|
79
|
+
this.scopes.push(scope);
|
|
104
80
|
return scope;
|
|
105
81
|
}
|
|
82
|
+
dispose() {
|
|
83
|
+
this.validateContainer();
|
|
84
|
+
this.isDisposed = true;
|
|
85
|
+
// Execute onDispose hooks
|
|
86
|
+
while (this.onDisposeHookList.length) {
|
|
87
|
+
const onDispose = this.onDisposeHookList.shift();
|
|
88
|
+
onDispose(this);
|
|
89
|
+
}
|
|
90
|
+
// Detach from parent
|
|
91
|
+
this.parent.removeScope(this);
|
|
92
|
+
this.parent = new EmptyContainer_1.EmptyContainer();
|
|
93
|
+
// Reset the state
|
|
94
|
+
this.providers.clear();
|
|
95
|
+
this.aliases.destroy();
|
|
96
|
+
this.instances = [];
|
|
97
|
+
this.registrations = [];
|
|
98
|
+
// Clear hooks
|
|
99
|
+
this.onConstructHookList.splice(0, this.onConstructHookList.length);
|
|
100
|
+
}
|
|
101
|
+
addRegistration(registration) {
|
|
102
|
+
this.registrations.push(registration);
|
|
103
|
+
registration.applyTo(this);
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
getRegistrations() {
|
|
107
|
+
return [...this.parent.getRegistrations(), ...this.registrations];
|
|
108
|
+
}
|
|
109
|
+
addOnConstructHook(...hooks) {
|
|
110
|
+
this.onConstructHookList.push(...hooks);
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
addOnDisposeHook(...hooks) {
|
|
114
|
+
this.onDisposeHookList.push(...hooks);
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
addInstance(instance) {
|
|
118
|
+
this.instances.push(instance);
|
|
119
|
+
// Execute onConstruct hooks
|
|
120
|
+
for (const onConstruct of this.onConstructHookList) {
|
|
121
|
+
onConstruct(instance, this);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
106
124
|
getScopes() {
|
|
107
125
|
return [...this.scopes];
|
|
108
126
|
}
|
|
109
127
|
removeScope(child) {
|
|
110
|
-
this.scopes.
|
|
128
|
+
this.scopes = this.scopes.filter((s) => s !== child);
|
|
111
129
|
}
|
|
112
130
|
useModule(module) {
|
|
113
131
|
module.applyTo(this);
|
|
@@ -116,31 +134,15 @@ class Container {
|
|
|
116
134
|
getParent() {
|
|
117
135
|
return this.parent;
|
|
118
136
|
}
|
|
119
|
-
getInstances() {
|
|
120
|
-
|
|
137
|
+
getInstances(cascade = false) {
|
|
138
|
+
if (!cascade) {
|
|
139
|
+
return [...this.instances];
|
|
140
|
+
}
|
|
141
|
+
return [...this.instances, ...this.scopes.flatMap((s) => s.getInstances(true))];
|
|
121
142
|
}
|
|
122
143
|
hasTag(tag) {
|
|
123
144
|
return this.tags.has(tag);
|
|
124
145
|
}
|
|
125
|
-
dispose() {
|
|
126
|
-
this.validateContainer();
|
|
127
|
-
this.isDisposed = true;
|
|
128
|
-
// Detach from parent
|
|
129
|
-
this.parent.removeScope(this);
|
|
130
|
-
this.parent = new EmptyContainer_1.EmptyContainer();
|
|
131
|
-
// Reset the state
|
|
132
|
-
this.providers.clear();
|
|
133
|
-
this.aliases.destroy();
|
|
134
|
-
this.instances.clear();
|
|
135
|
-
this.registrations.clear();
|
|
136
|
-
// Clear hooks
|
|
137
|
-
this.onConstructHookList.splice(0, this.onConstructHookList.length);
|
|
138
|
-
// Execute onDispose hooks
|
|
139
|
-
while (this.onDisposeHookList.length) {
|
|
140
|
-
const onDispose = this.onDisposeHookList.shift();
|
|
141
|
-
onDispose(this);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
146
|
validateContainer() {
|
|
145
147
|
if (this.isDisposed) {
|
|
146
148
|
throw new ContainerDisposedError_1.ContainerDisposedError('Container is already disposed');
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const HookContext_1 = require("
|
|
5
|
-
const hook_1 = require("
|
|
6
|
-
const UnexpectedHookResultError_1 = require("
|
|
7
|
-
|
|
3
|
+
exports.HooksRunner = void 0;
|
|
4
|
+
const HookContext_1 = require("./HookContext");
|
|
5
|
+
const hook_1 = require("./hook");
|
|
6
|
+
const UnexpectedHookResultError_1 = require("../errors/UnexpectedHookResultError");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
class HooksRunner {
|
|
8
9
|
key;
|
|
9
10
|
constructor(key) {
|
|
10
11
|
this.key = key;
|
|
@@ -24,5 +25,15 @@ class SyncHooksRunner {
|
|
|
24
25
|
runMethodHooks(methodName, executions.map(hook_1.toHookFn));
|
|
25
26
|
}
|
|
26
27
|
}
|
|
28
|
+
async executeAsync(target, { scope, createContext = HookContext_1.createHookContext, predicate = () => true, }) {
|
|
29
|
+
const hooks = Array.from((0, hook_1.getHooks)(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
|
|
30
|
+
const runMethodHooks = async (methodName, executions) => {
|
|
31
|
+
const context = createContext(target, scope, methodName);
|
|
32
|
+
for (const execute of executions) {
|
|
33
|
+
await (0, utils_1.promisify)(execute(context));
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(hook_1.toHookFn))));
|
|
37
|
+
}
|
|
27
38
|
}
|
|
28
|
-
exports.
|
|
39
|
+
exports.HooksRunner = HooksRunner;
|
package/cjm/hooks/onConstruct.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.onConstruct = exports.onConstructHooksRunner = void 0;
|
|
4
4
|
const hook_1 = require("./hook");
|
|
5
|
-
const
|
|
6
|
-
exports.onConstructHooksRunner = new
|
|
5
|
+
const HooksRunner_1 = require("./HooksRunner");
|
|
6
|
+
exports.onConstructHooksRunner = new HooksRunner_1.HooksRunner('onConstruct');
|
|
7
7
|
const onConstruct = (fn) => (0, hook_1.hook)('onConstruct', fn);
|
|
8
8
|
exports.onConstruct = onConstruct;
|
package/cjm/hooks/onDispose.js
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.onDispose = exports.onDisposeHooksRunner = void 0;
|
|
4
4
|
const hook_1 = require("./hook");
|
|
5
|
-
const
|
|
6
|
-
exports.onDisposeHooksRunner = new
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
});
|
|
5
|
+
const HooksRunner_1 = require("./HooksRunner");
|
|
6
|
+
exports.onDisposeHooksRunner = new HooksRunner_1.HooksRunner('onDispose');
|
|
7
|
+
const onDispose = (fn) => (0, hook_1.hook)('onDispose', fn);
|
|
8
|
+
exports.onDispose = onDispose;
|
package/cjm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AliasUniqToken = exports.toAlias = exports.AliasToken = exports.InjectionToken = exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.
|
|
4
|
-
exports.Is = exports.select = exports.toToken = exports.InstanceListToken = exports.ConstantToken = exports.FunctionToken = exports.IDToken = exports.ClassToken =
|
|
3
|
+
exports.toAliasUniq = exports.AliasUniqToken = exports.toAlias = exports.AliasToken = exports.InjectionToken = exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.HooksRunner = exports.onDispose = exports.onDisposeHooksRunner = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = exports.HookContext = exports.hasHooks = exports.hook = exports.getHooks = exports.UnexpectedHookResultError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.DependencyNotFoundError = exports.Registration = exports.bindTo = exports.register = exports.scope = exports.decorate = exports.MultiCache = exports.multiCache = exports.SingletonProvider = exports.singleton = exports.Provider = exports.resolveByArgs = exports.ProviderDecorator = exports.args = exports.argsFn = exports.lazy = exports.scopeAccess = exports.ProxyInjector = exports.SimpleInjector = exports.MetadataInjector = exports.resolveArgs = exports.inject = exports.EmptyContainer = exports.Container = exports.isDependencyKey = void 0;
|
|
4
|
+
exports.Is = exports.select = exports.toToken = exports.InstanceListToken = exports.ConstantToken = exports.FunctionToken = exports.IDToken = exports.ClassToken = void 0;
|
|
5
5
|
// Containers
|
|
6
6
|
var IContainer_1 = require("./container/IContainer");
|
|
7
7
|
Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
|
|
@@ -70,10 +70,9 @@ Object.defineProperty(exports, "onConstruct", { enumerable: true, get: function
|
|
|
70
70
|
var onDispose_1 = require("./hooks/onDispose");
|
|
71
71
|
Object.defineProperty(exports, "onDisposeHooksRunner", { enumerable: true, get: function () { return onDispose_1.onDisposeHooksRunner; } });
|
|
72
72
|
Object.defineProperty(exports, "onDispose", { enumerable: true, get: function () { return onDispose_1.onDispose; } });
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
Object.defineProperty(exports, "SyncHooksRunner", { enumerable: true, get: function () { return SyncHooksRunner_1.SyncHooksRunner; } });
|
|
73
|
+
// Hooks runner
|
|
74
|
+
var HooksRunner_1 = require("./hooks/HooksRunner");
|
|
75
|
+
Object.defineProperty(exports, "HooksRunner", { enumerable: true, get: function () { return HooksRunner_1.HooksRunner; } });
|
|
77
76
|
// Metadata
|
|
78
77
|
var metadata_1 = require("./metadata");
|
|
79
78
|
Object.defineProperty(exports, "setMetadata", { enumerable: true, get: function () { return metadata_1.setMetadata; } });
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Injector = void 0;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
4
5
|
class Injector {
|
|
5
|
-
resolve(scope, Target,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
resolve(scope, Target, { args, lazy } = {}) {
|
|
7
|
+
return (0, utils_1.toLazyIf)(() => {
|
|
8
|
+
const instance = this.createInstance(scope, Target, { args });
|
|
9
|
+
scope.addInstance(instance);
|
|
10
|
+
return instance;
|
|
11
|
+
}, lazy);
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
exports.Injector = Injector;
|
package/cjm/provider/Provider.js
CHANGED
|
@@ -25,9 +25,10 @@ class Provider {
|
|
|
25
25
|
return (0, utils_1.pipe)(...fns)(this);
|
|
26
26
|
}
|
|
27
27
|
resolve(container, { args = [], lazy } = {}) {
|
|
28
|
-
return
|
|
28
|
+
return this.resolveDependency(container, {
|
|
29
29
|
args: [...this.argsFn(container, ...args), ...args],
|
|
30
|
-
|
|
30
|
+
lazy: lazy ?? this.isLazy,
|
|
31
|
+
});
|
|
31
32
|
}
|
|
32
33
|
setAccessPredicate(predicate) {
|
|
33
34
|
this.checkAccess = predicate;
|
|
@@ -24,15 +24,7 @@ class InstanceListToken extends InjectionToken_1.InjectionToken {
|
|
|
24
24
|
return this;
|
|
25
25
|
}
|
|
26
26
|
resolve(c) {
|
|
27
|
-
|
|
28
|
-
if (this.isCascade) {
|
|
29
|
-
for (const s of c.getScopes()) {
|
|
30
|
-
for (const instance of s.getInstances().filter(this.predicate)) {
|
|
31
|
-
result.add(instance);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return [...result];
|
|
27
|
+
return c.getInstances(this.isCascade).filter(this.predicate);
|
|
36
28
|
}
|
|
37
29
|
}
|
|
38
30
|
exports.InstanceListToken = InstanceListToken;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
export class AliasMap {
|
|
2
2
|
aliasToKeySet = new Map();
|
|
3
|
-
|
|
3
|
+
getKeysByAlias(alias) {
|
|
4
|
+
return [...(this.aliasToKeySet.get(alias) ?? [])];
|
|
5
|
+
}
|
|
6
|
+
setAliasesByKey(key, aliases) {
|
|
7
|
+
// reset existing key's aliases
|
|
4
8
|
for (const [alias, keySet] of this.aliasToKeySet) {
|
|
5
9
|
keySet.delete(key);
|
|
6
10
|
if (keySet.size === 0) {
|
|
7
11
|
this.aliasToKeySet.delete(alias);
|
|
8
12
|
}
|
|
9
13
|
}
|
|
10
|
-
}
|
|
11
|
-
getKeysByAlias(alias) {
|
|
12
|
-
return [...(this.aliasToKeySet.get(alias) ?? [])];
|
|
13
|
-
}
|
|
14
|
-
setAliasesByKey(key, aliases) {
|
|
15
14
|
for (const alias of aliases) {
|
|
16
15
|
const dependencyKeySet = this.aliasToKeySet.get(alias) ?? new Set();
|
|
17
16
|
this.aliasToKeySet.set(alias, dependencyKeySet.add(key));
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { EmptyContainer } from './EmptyContainer';
|
|
2
2
|
import { ContainerDisposedError } from '../errors/ContainerDisposedError';
|
|
3
3
|
import { MetadataInjector } from '../injector/MetadataInjector';
|
|
4
|
-
import { Filter as F, Is
|
|
4
|
+
import { Filter as F, Is } from '../utils';
|
|
5
5
|
import { AliasMap } from './AliasMap';
|
|
6
6
|
import { DependencyNotFoundError } from '../errors/DependencyNotFoundError';
|
|
7
7
|
export class Container {
|
|
8
8
|
isDisposed = false;
|
|
9
9
|
parent;
|
|
10
|
-
scopes =
|
|
11
|
-
instances =
|
|
10
|
+
scopes = [];
|
|
11
|
+
instances = [];
|
|
12
|
+
registrations = [];
|
|
12
13
|
tags;
|
|
13
14
|
providers = new Map();
|
|
14
15
|
aliases = new AliasMap();
|
|
15
|
-
registrations = new Set();
|
|
16
16
|
injector;
|
|
17
17
|
onConstructHookList = [];
|
|
18
18
|
onDisposeHookList = [];
|
|
@@ -21,45 +21,21 @@ export class Container {
|
|
|
21
21
|
this.parent = options.parent ?? new EmptyContainer();
|
|
22
22
|
this.tags = new Set(options.tags ?? []);
|
|
23
23
|
}
|
|
24
|
-
addOnConstructHook(...hooks) {
|
|
25
|
-
this.onConstructHookList.push(...hooks);
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
addOnDisposeHook(...hooks) {
|
|
29
|
-
this.onDisposeHookList.push(...hooks);
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
addInstance(instance) {
|
|
33
|
-
this.instances.add(instance);
|
|
34
|
-
// Execute onConstruct hooks
|
|
35
|
-
for (const onConstruct of this.onConstructHookList) {
|
|
36
|
-
onConstruct(instance, this);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
24
|
register(key, provider, { aliases = [] } = {}) {
|
|
40
25
|
this.validateContainer();
|
|
41
26
|
this.providers.set(key, provider);
|
|
42
|
-
this.aliases.deleteAliasesByKey(key);
|
|
43
27
|
this.aliases.setAliasesByKey(key, aliases);
|
|
44
28
|
return this;
|
|
45
29
|
}
|
|
46
|
-
|
|
47
|
-
this.registrations.add(registration);
|
|
48
|
-
registration.applyTo(this);
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
getRegistrations() {
|
|
52
|
-
return [...this.parent.getRegistrations(), ...this.registrations];
|
|
53
|
-
}
|
|
54
|
-
resolve(keyOrAlias, { args = [], child = this, lazy } = {}) {
|
|
30
|
+
resolve(key, { args = [], child = this, lazy } = {}) {
|
|
55
31
|
this.validateContainer();
|
|
56
|
-
if (Is.constructor(
|
|
57
|
-
return
|
|
32
|
+
if (Is.constructor(key)) {
|
|
33
|
+
return this.injector.resolve(this, key, { args, lazy });
|
|
58
34
|
}
|
|
59
|
-
const provider = this.providers.get(
|
|
35
|
+
const provider = this.providers.get(key);
|
|
60
36
|
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
61
37
|
? provider.resolve(this, { args, lazy })
|
|
62
|
-
: this.parent.resolve(
|
|
38
|
+
: this.parent.resolve(key, { args, child, lazy });
|
|
63
39
|
}
|
|
64
40
|
resolveByAlias(alias, { args = [], child = this, lazy, excludedKeys = [] } = {}) {
|
|
65
41
|
this.validateContainer();
|
|
@@ -84,7 +60,7 @@ export class Container {
|
|
|
84
60
|
resolveOneByAlias(alias, { args = [], child = this, lazy } = {}) {
|
|
85
61
|
this.validateContainer();
|
|
86
62
|
const [key, ..._] = this.aliases.getKeysByAlias(alias);
|
|
87
|
-
const provider = key
|
|
63
|
+
const provider = key ? this.findProviderByKeyOrFail(key) : undefined;
|
|
88
64
|
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
89
65
|
? provider.resolve(this, { args, lazy })
|
|
90
66
|
: this.parent.resolveOneByAlias(key, { args, child, lazy });
|
|
@@ -97,14 +73,56 @@ export class Container {
|
|
|
97
73
|
for (const registration of this.getRegistrations()) {
|
|
98
74
|
registration.applyTo(scope);
|
|
99
75
|
}
|
|
100
|
-
this.scopes.
|
|
76
|
+
this.scopes.push(scope);
|
|
101
77
|
return scope;
|
|
102
78
|
}
|
|
79
|
+
dispose() {
|
|
80
|
+
this.validateContainer();
|
|
81
|
+
this.isDisposed = true;
|
|
82
|
+
// Execute onDispose hooks
|
|
83
|
+
while (this.onDisposeHookList.length) {
|
|
84
|
+
const onDispose = this.onDisposeHookList.shift();
|
|
85
|
+
onDispose(this);
|
|
86
|
+
}
|
|
87
|
+
// Detach from parent
|
|
88
|
+
this.parent.removeScope(this);
|
|
89
|
+
this.parent = new EmptyContainer();
|
|
90
|
+
// Reset the state
|
|
91
|
+
this.providers.clear();
|
|
92
|
+
this.aliases.destroy();
|
|
93
|
+
this.instances = [];
|
|
94
|
+
this.registrations = [];
|
|
95
|
+
// Clear hooks
|
|
96
|
+
this.onConstructHookList.splice(0, this.onConstructHookList.length);
|
|
97
|
+
}
|
|
98
|
+
addRegistration(registration) {
|
|
99
|
+
this.registrations.push(registration);
|
|
100
|
+
registration.applyTo(this);
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
getRegistrations() {
|
|
104
|
+
return [...this.parent.getRegistrations(), ...this.registrations];
|
|
105
|
+
}
|
|
106
|
+
addOnConstructHook(...hooks) {
|
|
107
|
+
this.onConstructHookList.push(...hooks);
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
addOnDisposeHook(...hooks) {
|
|
111
|
+
this.onDisposeHookList.push(...hooks);
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
addInstance(instance) {
|
|
115
|
+
this.instances.push(instance);
|
|
116
|
+
// Execute onConstruct hooks
|
|
117
|
+
for (const onConstruct of this.onConstructHookList) {
|
|
118
|
+
onConstruct(instance, this);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
103
121
|
getScopes() {
|
|
104
122
|
return [...this.scopes];
|
|
105
123
|
}
|
|
106
124
|
removeScope(child) {
|
|
107
|
-
this.scopes.
|
|
125
|
+
this.scopes = this.scopes.filter((s) => s !== child);
|
|
108
126
|
}
|
|
109
127
|
useModule(module) {
|
|
110
128
|
module.applyTo(this);
|
|
@@ -113,31 +131,15 @@ export class Container {
|
|
|
113
131
|
getParent() {
|
|
114
132
|
return this.parent;
|
|
115
133
|
}
|
|
116
|
-
getInstances() {
|
|
117
|
-
|
|
134
|
+
getInstances(cascade = false) {
|
|
135
|
+
if (!cascade) {
|
|
136
|
+
return [...this.instances];
|
|
137
|
+
}
|
|
138
|
+
return [...this.instances, ...this.scopes.flatMap((s) => s.getInstances(true))];
|
|
118
139
|
}
|
|
119
140
|
hasTag(tag) {
|
|
120
141
|
return this.tags.has(tag);
|
|
121
142
|
}
|
|
122
|
-
dispose() {
|
|
123
|
-
this.validateContainer();
|
|
124
|
-
this.isDisposed = true;
|
|
125
|
-
// Detach from parent
|
|
126
|
-
this.parent.removeScope(this);
|
|
127
|
-
this.parent = new EmptyContainer();
|
|
128
|
-
// Reset the state
|
|
129
|
-
this.providers.clear();
|
|
130
|
-
this.aliases.destroy();
|
|
131
|
-
this.instances.clear();
|
|
132
|
-
this.registrations.clear();
|
|
133
|
-
// Clear hooks
|
|
134
|
-
this.onConstructHookList.splice(0, this.onConstructHookList.length);
|
|
135
|
-
// Execute onDispose hooks
|
|
136
|
-
while (this.onDisposeHookList.length) {
|
|
137
|
-
const onDispose = this.onDisposeHookList.shift();
|
|
138
|
-
onDispose(this);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
143
|
validateContainer() {
|
|
142
144
|
if (this.isDisposed) {
|
|
143
145
|
throw new ContainerDisposedError('Container is already disposed');
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { createHookContext } from '
|
|
2
|
-
import { getHooks, toHookFn } from '
|
|
3
|
-
import { UnexpectedHookResultError } from '
|
|
4
|
-
|
|
1
|
+
import { createHookContext } from './HookContext';
|
|
2
|
+
import { getHooks, toHookFn } from './hook';
|
|
3
|
+
import { UnexpectedHookResultError } from '../errors/UnexpectedHookResultError';
|
|
4
|
+
import { promisify } from '../utils';
|
|
5
|
+
export class HooksRunner {
|
|
5
6
|
key;
|
|
6
7
|
constructor(key) {
|
|
7
8
|
this.key = key;
|
|
@@ -21,4 +22,14 @@ export class SyncHooksRunner {
|
|
|
21
22
|
runMethodHooks(methodName, executions.map(toHookFn));
|
|
22
23
|
}
|
|
23
24
|
}
|
|
25
|
+
async executeAsync(target, { scope, createContext = createHookContext, predicate = () => true, }) {
|
|
26
|
+
const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
|
|
27
|
+
const runMethodHooks = async (methodName, executions) => {
|
|
28
|
+
const context = createContext(target, scope, methodName);
|
|
29
|
+
for (const execute of executions) {
|
|
30
|
+
await promisify(execute(context));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(toHookFn))));
|
|
34
|
+
}
|
|
24
35
|
}
|
package/esm/hooks/onConstruct.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { hook } from './hook';
|
|
2
|
-
import {
|
|
3
|
-
export const onConstructHooksRunner = new
|
|
2
|
+
import { HooksRunner } from './HooksRunner';
|
|
3
|
+
export const onConstructHooksRunner = new HooksRunner('onConstruct');
|
|
4
4
|
export const onConstruct = (fn) => hook('onConstruct', fn);
|
package/esm/hooks/onDispose.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { hook } from './hook';
|
|
2
|
-
import {
|
|
3
|
-
export const onDisposeHooksRunner = new
|
|
4
|
-
export const onDispose = hook('onDispose',
|
|
5
|
-
context.invokeMethod({});
|
|
6
|
-
});
|
|
2
|
+
import { HooksRunner } from './HooksRunner';
|
|
3
|
+
export const onDisposeHooksRunner = new HooksRunner('onDispose');
|
|
4
|
+
export const onDispose = (fn) => hook('onDispose', fn);
|
package/esm/index.js
CHANGED
|
@@ -28,8 +28,8 @@ export { HookContext } from './hooks/HookContext';
|
|
|
28
28
|
export { injectProp } from './hooks/injectProp';
|
|
29
29
|
export { onConstructHooksRunner, onConstruct } from './hooks/onConstruct';
|
|
30
30
|
export { onDisposeHooksRunner, onDispose } from './hooks/onDispose';
|
|
31
|
-
|
|
32
|
-
export {
|
|
31
|
+
// Hooks runner
|
|
32
|
+
export { HooksRunner } from './hooks/HooksRunner';
|
|
33
33
|
// Metadata
|
|
34
34
|
export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
|
|
35
35
|
// InjectionToken
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { toLazyIf } from '../utils';
|
|
1
2
|
export class Injector {
|
|
2
|
-
resolve(scope, Target,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
resolve(scope, Target, { args, lazy } = {}) {
|
|
4
|
+
return toLazyIf(() => {
|
|
5
|
+
const instance = this.createInstance(scope, Target, { args });
|
|
6
|
+
scope.addInstance(instance);
|
|
7
|
+
return instance;
|
|
8
|
+
}, lazy);
|
|
6
9
|
}
|
|
7
10
|
}
|
package/esm/provider/Provider.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pipe
|
|
1
|
+
import { pipe } from '../utils';
|
|
2
2
|
import { isProviderPipe } from './ProviderPipe';
|
|
3
3
|
export class Provider {
|
|
4
4
|
resolveDependency;
|
|
@@ -22,9 +22,10 @@ export class Provider {
|
|
|
22
22
|
return pipe(...fns)(this);
|
|
23
23
|
}
|
|
24
24
|
resolve(container, { args = [], lazy } = {}) {
|
|
25
|
-
return
|
|
25
|
+
return this.resolveDependency(container, {
|
|
26
26
|
args: [...this.argsFn(container, ...args), ...args],
|
|
27
|
-
|
|
27
|
+
lazy: lazy ?? this.isLazy,
|
|
28
|
+
});
|
|
28
29
|
}
|
|
29
30
|
setAccessPredicate(predicate) {
|
|
30
31
|
this.checkAccess = predicate;
|
|
@@ -21,14 +21,6 @@ export class InstanceListToken extends InjectionToken {
|
|
|
21
21
|
return this;
|
|
22
22
|
}
|
|
23
23
|
resolve(c) {
|
|
24
|
-
|
|
25
|
-
if (this.isCascade) {
|
|
26
|
-
for (const s of c.getScopes()) {
|
|
27
|
-
for (const instance of s.getInstances().filter(this.predicate)) {
|
|
28
|
-
result.add(instance);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return [...result];
|
|
24
|
+
return c.getInstances(this.isCascade).filter(this.predicate);
|
|
33
25
|
}
|
|
34
26
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,6 @@ import { type DependencyKey } from './IContainer';
|
|
|
2
2
|
export type Alias = DependencyKey;
|
|
3
3
|
export declare class AliasMap {
|
|
4
4
|
private readonly aliasToKeySet;
|
|
5
|
-
deleteAliasesByKey(key: DependencyKey): void;
|
|
6
5
|
getKeysByAlias(alias: DependencyKey): DependencyKey[];
|
|
7
6
|
setAliasesByKey(key: DependencyKey, aliases: DependencyKey[]): void;
|
|
8
7
|
destroy(): void;
|
|
@@ -8,12 +8,12 @@ import { constructor, Instance } from '../types';
|
|
|
8
8
|
export declare class Container implements IContainer {
|
|
9
9
|
isDisposed: boolean;
|
|
10
10
|
private parent;
|
|
11
|
-
private
|
|
12
|
-
private
|
|
11
|
+
private scopes;
|
|
12
|
+
private instances;
|
|
13
|
+
private registrations;
|
|
13
14
|
private readonly tags;
|
|
14
15
|
private readonly providers;
|
|
15
16
|
private readonly aliases;
|
|
16
|
-
private readonly registrations;
|
|
17
17
|
private readonly injector;
|
|
18
18
|
private readonly onConstructHookList;
|
|
19
19
|
private readonly onDisposeHookList;
|
|
@@ -22,23 +22,23 @@ export declare class Container implements IContainer {
|
|
|
22
22
|
parent?: IContainer;
|
|
23
23
|
tags?: Tag[];
|
|
24
24
|
});
|
|
25
|
-
addOnConstructHook(...hooks: OnConstructHook[]): this;
|
|
26
|
-
addOnDisposeHook(...hooks: OnDisposeHook[]): this;
|
|
27
|
-
addInstance(instance: Instance): void;
|
|
28
25
|
register(key: DependencyKey, provider: IProvider, { aliases }?: RegisterOptions): this;
|
|
29
|
-
|
|
30
|
-
getRegistrations(): IRegistration[];
|
|
31
|
-
resolve<T>(keyOrAlias: constructor<T> | DependencyKey, { args, child, lazy }?: ResolveOneOptions): T;
|
|
26
|
+
resolve<T>(key: constructor<T> | DependencyKey, { args, child, lazy }?: ResolveOneOptions): T;
|
|
32
27
|
resolveByAlias<T>(alias: DependencyKey, { args, child, lazy, excludedKeys }?: ResolveManyOptions): T[];
|
|
33
28
|
resolveOneByAlias<T>(alias: DependencyKey, { args, child, lazy }?: ResolveOneOptions): T;
|
|
34
29
|
createScope({ tags }?: CreateScopeOptions): IContainer;
|
|
30
|
+
dispose(): void;
|
|
31
|
+
addRegistration(registration: IRegistration): this;
|
|
32
|
+
getRegistrations(): IRegistration[];
|
|
33
|
+
addOnConstructHook(...hooks: OnConstructHook[]): this;
|
|
34
|
+
addOnDisposeHook(...hooks: OnDisposeHook[]): this;
|
|
35
|
+
addInstance(instance: Instance): void;
|
|
35
36
|
getScopes(): IContainer[];
|
|
36
37
|
removeScope(child: IContainer): void;
|
|
37
38
|
useModule(module: IContainerModule): this;
|
|
38
39
|
getParent(): IContainer;
|
|
39
|
-
getInstances(): Instance<unknown>[];
|
|
40
|
+
getInstances(cascade?: boolean): Instance<unknown>[];
|
|
40
41
|
hasTag(tag: Tag): boolean;
|
|
41
|
-
dispose(): void;
|
|
42
42
|
private validateContainer;
|
|
43
43
|
private findProviderByKeyOrFail;
|
|
44
44
|
}
|
|
@@ -41,7 +41,7 @@ export interface IContainer extends Tagged {
|
|
|
41
41
|
removeScope(child: IContainer): void;
|
|
42
42
|
useModule(module: IContainerModule): this;
|
|
43
43
|
getParent(): IContainer | undefined;
|
|
44
|
-
getInstances(): Instance[];
|
|
44
|
+
getInstances(cascade?: boolean): Instance[];
|
|
45
45
|
dispose(): void;
|
|
46
46
|
addInstance(instance: Instance): void;
|
|
47
47
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createHookContext, type CreateHookContext } from './HookContext';
|
|
2
|
+
import type { IContainer } from '../container/IContainer';
|
|
3
|
+
export type HooksRunnerContext = {
|
|
4
|
+
scope: IContainer;
|
|
5
|
+
createContext?: CreateHookContext;
|
|
6
|
+
predicate?: (methodName: string) => boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare class HooksRunner {
|
|
9
|
+
private readonly key;
|
|
10
|
+
constructor(key: string | symbol);
|
|
11
|
+
execute(target: object, { scope, createContext, predicate }: HooksRunnerContext): void;
|
|
12
|
+
executeAsync(target: object, { scope, createContext, predicate, }: {
|
|
13
|
+
scope: IContainer;
|
|
14
|
+
createContext?: typeof createHookContext;
|
|
15
|
+
predicate?: (methodName: string) => boolean;
|
|
16
|
+
}): Promise<void[]>;
|
|
17
|
+
}
|
package/typings/hooks/hook.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export type HookFn<T extends IHookContext = IHookContext> = (context: T) => void
|
|
|
6
6
|
export interface HookClass<T extends IHookContext = IHookContext> {
|
|
7
7
|
execute(context: Omit<T, 'scope'>): void | Promise<void>;
|
|
8
8
|
}
|
|
9
|
-
export declare const toHookFn: <C extends IHookContext>(execute: HookFn<C> | constructor<HookClass<C>>) => HookFn<C>;
|
|
10
9
|
type HooksOfClass = Map<string, (HookFn | constructor<HookClass>)[]>;
|
|
10
|
+
export declare const toHookFn: <C extends IHookContext>(execute: HookFn<C> | constructor<HookClass<C>>) => HookFn<C>;
|
|
11
11
|
export declare function getHooks(target: object, key: string | symbol): HooksOfClass;
|
|
12
12
|
export declare function hasHooks(target: object, key: string | symbol): boolean;
|
|
13
13
|
export declare const hook: (key: string | symbol, ...fns: (HookFn | constructor<HookClass>)[]) => (target: object, propertyKey: string | symbol) => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { HookFn } from './hook';
|
|
2
|
-
import { SyncHooksRunner } from './runner/SyncHooksRunner';
|
|
1
|
+
import { HookClass, HookFn } from './hook';
|
|
3
2
|
import type { IContainer } from '../container/IContainer';
|
|
4
|
-
import { Instance } from '../types';
|
|
5
|
-
|
|
6
|
-
export declare const
|
|
3
|
+
import { constructor, Instance } from '../types';
|
|
4
|
+
import { HooksRunner } from './HooksRunner';
|
|
5
|
+
export declare const onConstructHooksRunner: HooksRunner;
|
|
6
|
+
export declare const onConstruct: (fn: HookFn | constructor<HookClass>) => (target: object, propertyKey: string | symbol) => void;
|
|
7
7
|
export type OnConstructHook = (instance: Instance, scope: IContainer) => void;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HookClass, HookFn } from './hook';
|
|
2
2
|
import type { IContainer } from '../container/IContainer';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { constructor } from '../types';
|
|
4
|
+
import { HooksRunner } from './HooksRunner';
|
|
5
|
+
export declare const onDisposeHooksRunner: HooksRunner;
|
|
6
|
+
export declare const onDispose: (fn: HookFn | constructor<HookClass>) => (target: object, propertyKey: string | symbol) => void;
|
|
5
7
|
export type OnDisposeHook = (scope: IContainer) => void;
|
package/typings/index.d.ts
CHANGED
|
@@ -24,9 +24,7 @@ export { HookContext, type IHookContext } from './hooks/HookContext';
|
|
|
24
24
|
export { injectProp } from './hooks/injectProp';
|
|
25
25
|
export { onConstructHooksRunner, onConstruct } from './hooks/onConstruct';
|
|
26
26
|
export { onDisposeHooksRunner, onDispose } from './hooks/onDispose';
|
|
27
|
-
export { HooksRunnerContext } from './hooks/
|
|
28
|
-
export { AsyncHooksRunner } from './hooks/runner/AsyncHooksRunner';
|
|
29
|
-
export { SyncHooksRunner } from './hooks/runner/SyncHooksRunner';
|
|
27
|
+
export { HooksRunnerContext, HooksRunner } from './hooks/HooksRunner';
|
|
30
28
|
export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
|
|
31
29
|
export { InjectionToken } from './token/InjectionToken';
|
|
32
30
|
export { AliasToken, toAlias } from './token/AliasToken';
|
|
@@ -40,5 +38,4 @@ export { toToken } from './token/toToken';
|
|
|
40
38
|
export { select } from './select';
|
|
41
39
|
export { Is } from './utils';
|
|
42
40
|
export { InjectFn } from './hooks/hook';
|
|
43
|
-
export { Instance } from './types';
|
|
44
|
-
export { constructor } from './types';
|
|
41
|
+
export { Instance, constructor } from './types';
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { type IContainer, ResolveOneOptions } from '../container/IContainer';
|
|
2
2
|
import { constructor } from '../types';
|
|
3
|
+
import { ProviderOptions } from '../provider/IProvider';
|
|
3
4
|
type WithArgs = {
|
|
4
5
|
args: unknown[];
|
|
5
6
|
};
|
|
6
7
|
export type InjectOptions = Partial<WithArgs>;
|
|
7
8
|
export interface IInjector {
|
|
8
|
-
resolve<T>(container: IContainer, value: constructor<T>, options?:
|
|
9
|
+
resolve<T>(container: IContainer, value: constructor<T>, options?: ProviderOptions): T;
|
|
9
10
|
}
|
|
10
11
|
export interface IInjectFnResolver<T> {
|
|
11
12
|
resolve(s: IContainer, options?: ResolveOneOptions): T;
|
|
12
13
|
}
|
|
13
14
|
export declare abstract class Injector {
|
|
14
|
-
resolve<T>(scope: IContainer, Target: constructor<T>,
|
|
15
|
+
resolve<T>(scope: IContainer, Target: constructor<T>, { args, lazy }?: ProviderOptions): T;
|
|
15
16
|
protected abstract createInstance<T>(scope: IContainer, Target: constructor<T>, options?: InjectOptions): T;
|
|
16
17
|
}
|
|
17
18
|
export {};
|
|
@@ -6,7 +6,7 @@ export type WithLazy = {
|
|
|
6
6
|
lazy: boolean;
|
|
7
7
|
};
|
|
8
8
|
export type ProviderOptions = InjectOptions & Partial<WithLazy>;
|
|
9
|
-
export type ResolveDependency<T = unknown> = (container: IContainer, options:
|
|
9
|
+
export type ResolveDependency<T = unknown> = (container: IContainer, options: ProviderOptions) => T;
|
|
10
10
|
export type ScopeAccessOptions = {
|
|
11
11
|
invocationScope: Tagged;
|
|
12
12
|
providerScope: Tagged;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AsyncHooksRunner = void 0;
|
|
4
|
-
const HookContext_1 = require("../HookContext");
|
|
5
|
-
const hook_1 = require("../hook");
|
|
6
|
-
const utils_1 = require("../../utils");
|
|
7
|
-
class AsyncHooksRunner {
|
|
8
|
-
key;
|
|
9
|
-
constructor(key) {
|
|
10
|
-
this.key = key;
|
|
11
|
-
}
|
|
12
|
-
async execute(target, { scope, createContext = HookContext_1.createHookContext, predicate = () => true, }) {
|
|
13
|
-
const hooks = Array.from((0, hook_1.getHooks)(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
|
|
14
|
-
const runMethodHooks = async (methodName, executions) => {
|
|
15
|
-
const context = createContext(target, scope, methodName);
|
|
16
|
-
for (const execute of executions) {
|
|
17
|
-
await (0, utils_1.promisify)(execute(context));
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(hook_1.toHookFn))));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.AsyncHooksRunner = AsyncHooksRunner;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { createHookContext } from '../HookContext';
|
|
2
|
-
import { getHooks, toHookFn } from '../hook';
|
|
3
|
-
import { promisify } from '../../utils';
|
|
4
|
-
export class AsyncHooksRunner {
|
|
5
|
-
key;
|
|
6
|
-
constructor(key) {
|
|
7
|
-
this.key = key;
|
|
8
|
-
}
|
|
9
|
-
async execute(target, { scope, createContext = createHookContext, predicate = () => true, }) {
|
|
10
|
-
const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
|
|
11
|
-
const runMethodHooks = async (methodName, executions) => {
|
|
12
|
-
const context = createContext(target, scope, methodName);
|
|
13
|
-
for (const execute of executions) {
|
|
14
|
-
await promisify(execute(context));
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(toHookFn))));
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { createHookContext } from '../HookContext';
|
|
2
|
-
import type { IContainer } from '../../container/IContainer';
|
|
3
|
-
export declare class AsyncHooksRunner {
|
|
4
|
-
private readonly key;
|
|
5
|
-
constructor(key: string | symbol);
|
|
6
|
-
execute(target: object, { scope, createContext, predicate, }: {
|
|
7
|
-
scope: IContainer;
|
|
8
|
-
createContext?: typeof createHookContext;
|
|
9
|
-
predicate?: (methodName: string) => boolean;
|
|
10
|
-
}): Promise<void[]>;
|
|
11
|
-
}
|