ts-ioc-container 65.0.0 → 67.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 +51 -28
- package/cjm/hooks/HookExecutionStrategy.js +4 -24
- package/cjm/hooks/ParallelAsync.js +4 -10
- package/cjm/hooks/SequentialAsync.js +5 -9
- package/cjm/hooks/SequentialSync.js +2 -4
- package/cjm/hooks/combinators.js +27 -0
- package/cjm/hooks/hook.js +5 -11
- package/cjm/hooks/onConstruct.js +1 -1
- package/cjm/hooks/onResolved.js +1 -1
- package/cjm/hooks/onScopeDisposed.js +1 -1
- package/cjm/index.js +10 -10
- package/cjm/utils/task.js +23 -0
- package/esm/hooks/HookExecutionStrategy.js +3 -21
- package/esm/hooks/ParallelAsync.js +4 -10
- package/esm/hooks/SequentialAsync.js +5 -9
- package/esm/hooks/SequentialSync.js +2 -4
- package/esm/hooks/combinators.js +21 -0
- package/esm/hooks/hook.js +4 -8
- package/esm/hooks/onConstruct.js +2 -2
- package/esm/hooks/onResolved.js +2 -2
- package/esm/hooks/onScopeDisposed.js +2 -2
- package/esm/index.js +3 -3
- package/esm/utils/task.js +18 -0
- package/package.json +1 -1
- package/typings/hooks/HookExecutionStrategy.d.ts +3 -5
- package/typings/hooks/ParallelAsync.d.ts +3 -4
- package/typings/hooks/SequentialAsync.d.ts +3 -4
- package/typings/hooks/SequentialSync.d.ts +2 -2
- package/typings/hooks/{resolveHooks.d.ts → combinators.d.ts} +2 -0
- package/typings/hooks/hook.d.ts +2 -7
- package/typings/hooks/onConstruct.d.ts +1 -1
- package/typings/hooks/onResolved.d.ts +1 -1
- package/typings/hooks/onScopeDisposed.d.ts +1 -1
- package/typings/index.d.ts +4 -4
- package/typings/utils/task.d.ts +3 -0
- package/cjm/hooks/AsyncHookExecutionStrategy.js +0 -15
- package/cjm/hooks/resolveHooks.js +0 -15
- package/esm/hooks/AsyncHookExecutionStrategy.js +0 -11
- package/esm/hooks/resolveHooks.js +0 -11
- package/typings/hooks/AsyncHookExecutionStrategy.d.ts +0 -10
package/README.md
CHANGED
|
@@ -162,7 +162,7 @@ describe('Quickstart', function () {
|
|
|
162
162
|
- Lazy token: `select.token('Service').lazy()`
|
|
163
163
|
- Inject decorator: `@inject('Key')`
|
|
164
164
|
- Map an injected value: `@inject('Key', sanitize(), validate())`
|
|
165
|
-
- Property inject: `@hook('onInit',
|
|
165
|
+
- Property inject: `@hook('onInit', injectProp('Key'))`
|
|
166
166
|
|
|
167
167
|
> [!TIP]
|
|
168
168
|
> For classes, prefer the `@register(bindTo('Key'))` decorator over the fluent
|
|
@@ -2385,6 +2385,8 @@ Sometimes you don't want to change the dependency, only to react to it. Use the
|
|
|
2385
2385
|
|
|
2386
2386
|
Hooks run after the whole `decorate(...)` chain, so they always observe the fully decorated dependency, and their return value is ignored — `onResolve` can never swap the dependency out. They fire per resolution, which means a `singleton()` provider runs them only on the resolve that fills the cache.
|
|
2387
2387
|
|
|
2388
|
+
This — or the `@onResolved` decorator over the same provider event — is the recommended way to react to a dependency; see [OnConstruct](#onconstruct) for why `@onConstruct` is the narrower tool.
|
|
2389
|
+
|
|
2388
2390
|
```typescript
|
|
2389
2391
|
import 'reflect-metadata';
|
|
2390
2392
|
import { Container, type IContainer, onResolve, register, Registration as R, singleton } from 'ts-ioc-container';
|
|
@@ -2809,41 +2811,51 @@ describe('Container Modules', function () {
|
|
|
2809
2811
|
|
|
2810
2812
|
Sometimes you need to invoke methods after construct or dispose of class. This is what hooks are for.
|
|
2811
2813
|
|
|
2812
|
-
|
|
2813
|
-
`
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
the existing ones:
|
|
2814
|
+
Every hook decorator — the generic `@hook(key, hook)` and `@onConstruct`,
|
|
2815
|
+
`@onScopeDisposed`, `@onResolved` — takes **one** hook for the decorated member.
|
|
2816
|
+
Several hooks are combined at the declaration site, by the combinator that says
|
|
2817
|
+
how they relate:
|
|
2817
2818
|
|
|
2818
2819
|
```typescript
|
|
2819
2820
|
class OrderService {
|
|
2820
|
-
@hook('actions',
|
|
2821
|
-
@hook('actions', prepend(authorize))
|
|
2821
|
+
@hook('actions', sequential(authorize, validate, persist))
|
|
2822
2822
|
submit() {}
|
|
2823
|
+
|
|
2824
|
+
@onScopeDisposed(parallel(flushMetrics, closeSocket))
|
|
2825
|
+
destroy() {}
|
|
2823
2826
|
}
|
|
2824
2827
|
```
|
|
2825
2828
|
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
`(...
|
|
2829
|
-
|
|
2829
|
+
- `sequential(...hooks)` runs them in declaration order, awaiting each one that
|
|
2830
|
+
goes async before the next.
|
|
2831
|
+
- `parallel(...hooks)` starts them all at once and settles when every one has.
|
|
2832
|
+
- `oncePerInstance(hook)` runs its hook a single time per instance, however
|
|
2833
|
+
often the event fires.
|
|
2830
2834
|
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2835
|
+
They compose, because each returns an ordinary `HookFn`:
|
|
2836
|
+
`oncePerInstance(sequential(connect, warmUp))`, or a `parallel(...)` nested
|
|
2837
|
+
inside a `sequential(...)`. A hook class (`HookType`) may be passed anywhere a
|
|
2838
|
+
hook function can. Writing your own combinator needs nothing from the library
|
|
2839
|
+
beyond `toHookFn`.
|
|
2840
|
+
|
|
2841
|
+
A member carries exactly one hook per key, so decorating the same member twice
|
|
2842
|
+
under one key replaces the earlier hook rather than adding to it — decorators
|
|
2843
|
+
are applied bottom-up, so the topmost one is the one that stays.
|
|
2834
2844
|
|
|
2835
2845
|
Every hook may be sync or async — one decorator and one module take both, so
|
|
2836
2846
|
there is no separate async form to reach for. *How* the hooks run is a separate
|
|
2837
2847
|
choice: each module takes a `HookExecutionStrategy`, keyed to the hooks it runs
|
|
2838
|
-
(`onConstruct`, `onScopeDisposed`, `onResolved`, or a custom key)
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
|
2845
|
-
|
|
|
2846
|
-
| `
|
|
2848
|
+
(`onConstruct`, `onScopeDisposed`, `onResolved`, or a custom key). A strategy
|
|
2849
|
+
decides how the **members** — the decorated methods — relate to each other,
|
|
2850
|
+
what is awaited, and where a failure goes
|
|
2851
|
+
([ADR 0015](../../adr/0015-one-hook-per-member.md)); how the hooks *within* one
|
|
2852
|
+
member relate is the combinator's job, not the strategy's:
|
|
2853
|
+
|
|
2854
|
+
| Strategy | Members (decorated methods) | Awaits |
|
|
2855
|
+
| ----------------- | --------------------------- | ------ |
|
|
2856
|
+
| `SequentialSync` | one after another | no |
|
|
2857
|
+
| `SequentialAsync` | one after another | yes |
|
|
2858
|
+
| `ParallelAsync` | all at once | yes |
|
|
2847
2859
|
|
|
2848
2860
|
```typescript
|
|
2849
2861
|
const container = new Container()
|
|
@@ -2915,15 +2927,26 @@ and `OnResolvedModule` reaches every provider through `registered`.
|
|
|
2915
2927
|
|
|
2916
2928
|
### OnConstruct
|
|
2917
2929
|
|
|
2930
|
+
> **Prefer `@onResolved` — or the [`onResolve`](#on-resolve) pipe — over
|
|
2931
|
+
> `@onConstruct`.** Construction is the *injector's* event, so `@onConstruct`
|
|
2932
|
+
> fires only for dependencies the injector builds: a `fromValue` constant or a
|
|
2933
|
+
> factory registration never triggers it. It also observes the instance before
|
|
2934
|
+
> the provider's `decorate(...)` chain wraps it, so a hook sees the bare
|
|
2935
|
+
> instance rather than what the caller receives. `@onResolved` runs on every
|
|
2936
|
+
> dependency leaving a provider, after the whole decorate chain — the same
|
|
2937
|
+
> ordering, awaiting and error handling, on what the caller actually gets.
|
|
2938
|
+
> Reach for `@onConstruct` only when you mean "this class was just constructed"
|
|
2939
|
+
> specifically.
|
|
2940
|
+
|
|
2918
2941
|
```typescript
|
|
2919
2942
|
import 'reflect-metadata';
|
|
2920
2943
|
import {
|
|
2921
|
-
OnConstructModule,
|
|
2922
2944
|
Container,
|
|
2923
2945
|
type HookFn,
|
|
2924
2946
|
type IContainer,
|
|
2925
2947
|
inject,
|
|
2926
2948
|
onConstruct,
|
|
2949
|
+
OnConstructModule,
|
|
2927
2950
|
Registration as R,
|
|
2928
2951
|
SequentialAsync,
|
|
2929
2952
|
SequentialSync,
|
|
@@ -3154,7 +3177,7 @@ describe('onScopeDisposed', function () {
|
|
|
3154
3177
|
|
|
3155
3178
|
```typescript
|
|
3156
3179
|
import 'reflect-metadata';
|
|
3157
|
-
import {
|
|
3180
|
+
import { Container, hook, injectProp, Registration, sequential, SequentialSync } from 'ts-ioc-container';
|
|
3158
3181
|
|
|
3159
3182
|
/**
|
|
3160
3183
|
* UI Components - Property Injection
|
|
@@ -3174,7 +3197,7 @@ describe('inject property', () => {
|
|
|
3174
3197
|
|
|
3175
3198
|
class UserViewModel {
|
|
3176
3199
|
// Inject 'GreetingService' into 'greeting' property during 'onInit'
|
|
3177
|
-
@hook('onInit',
|
|
3200
|
+
@hook('onInit', injectProp('GreetingService'))
|
|
3178
3201
|
greetingService!: string;
|
|
3179
3202
|
|
|
3180
3203
|
display(): string {
|
|
@@ -3202,7 +3225,7 @@ describe('inject property', () => {
|
|
|
3202
3225
|
class UserViewModel {
|
|
3203
3226
|
@hook(
|
|
3204
3227
|
'onInit',
|
|
3205
|
-
|
|
3228
|
+
sequential(injectProp('GreetingService'), (context) => {
|
|
3206
3229
|
injectedValue = context.getProperty();
|
|
3207
3230
|
}),
|
|
3208
3231
|
)
|
|
@@ -1,29 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HookExecutionStrategy =
|
|
3
|
+
exports.HookExecutionStrategy = void 0;
|
|
4
4
|
const target_1 = require("../metadata/target");
|
|
5
5
|
const hook_1 = require("./hook");
|
|
6
6
|
const HookContext_1 = require("./HookContext");
|
|
7
|
-
const runInOrder = (hooks, context, from = 0) => {
|
|
8
|
-
for (let i = from; i < hooks.length; i++) {
|
|
9
|
-
const result = hooks[i](context);
|
|
10
|
-
if (result instanceof Promise) {
|
|
11
|
-
return result.then(() => (0, exports.runInOrder)(hooks, context, i + 1));
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
exports.runInOrder = runInOrder;
|
|
16
|
-
const runAtOnce = (hooks, context) => {
|
|
17
|
-
const pending = [];
|
|
18
|
-
for (const hook of hooks) {
|
|
19
|
-
const result = hook(context);
|
|
20
|
-
if (result instanceof Promise) {
|
|
21
|
-
pending.push(result);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
|
|
25
|
-
};
|
|
26
|
-
exports.runAtOnce = runAtOnce;
|
|
27
7
|
class HookExecutionStrategy {
|
|
28
8
|
key;
|
|
29
9
|
onError;
|
|
@@ -48,9 +28,9 @@ class HookExecutionStrategy {
|
|
|
48
28
|
}
|
|
49
29
|
collect(target, scope, { createExecutionContext = this.options.createExecutionContext, mapExecutionContext = this.options.mapExecutionContext, predicate = this.options.predicate, }) {
|
|
50
30
|
const members = [];
|
|
51
|
-
for (const { methodName,
|
|
31
|
+
for (const { methodName, hook } of this.hooksOf(target)) {
|
|
52
32
|
if (predicate(methodName)) {
|
|
53
|
-
members.push({
|
|
33
|
+
members.push({ hook, context: mapExecutionContext(createExecutionContext(target, scope, methodName)) });
|
|
54
34
|
}
|
|
55
35
|
}
|
|
56
36
|
return members;
|
|
@@ -59,7 +39,7 @@ class HookExecutionStrategy {
|
|
|
59
39
|
const Target = (0, target_1.resolveConstructor)(target);
|
|
60
40
|
let hooks = this.hooksByClass.get(Target);
|
|
61
41
|
if (!hooks) {
|
|
62
|
-
hooks = Array.from((0, hook_1.getHooks)(Target, this.key), ([methodName,
|
|
42
|
+
hooks = Array.from((0, hook_1.getHooks)(Target, this.key), ([methodName, fn]) => ({ methodName, hook: (0, hook_1.toHookFn)(fn) }));
|
|
63
43
|
this.hooksByClass.set(Target, hooks);
|
|
64
44
|
}
|
|
65
45
|
return hooks;
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ParallelAsync = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
4
|
+
const HookExecutionStrategy_1 = require("./HookExecutionStrategy");
|
|
5
|
+
const task_1 = require("../utils/task");
|
|
6
|
+
class ParallelAsync extends HookExecutionStrategy_1.HookExecutionStrategy {
|
|
6
7
|
processHooks(members) {
|
|
7
|
-
|
|
8
|
-
for (const member of members) {
|
|
9
|
-
const result = this.runMember(member);
|
|
10
|
-
if (result) {
|
|
11
|
-
pending.push(result);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
|
|
8
|
+
return (0, task_1.runAtOnce)(members.map(({ hook, context }) => () => hook(context)));
|
|
15
9
|
}
|
|
16
10
|
}
|
|
17
11
|
exports.ParallelAsync = ParallelAsync;
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SequentialAsync = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (result) {
|
|
10
|
-
return result.then(() => this.processHooks(members, i + 1));
|
|
11
|
-
}
|
|
12
|
-
}
|
|
4
|
+
const HookExecutionStrategy_1 = require("./HookExecutionStrategy");
|
|
5
|
+
const task_1 = require("../utils/task");
|
|
6
|
+
class SequentialAsync extends HookExecutionStrategy_1.HookExecutionStrategy {
|
|
7
|
+
processHooks(members) {
|
|
8
|
+
return (0, task_1.runInOrder)(members.map(({ hook, context }) => () => hook(context)));
|
|
13
9
|
}
|
|
14
10
|
}
|
|
15
11
|
exports.SequentialAsync = SequentialAsync;
|
|
@@ -4,10 +4,8 @@ exports.SequentialSync = void 0;
|
|
|
4
4
|
const HookExecutionStrategy_1 = require("./HookExecutionStrategy");
|
|
5
5
|
class SequentialSync extends HookExecutionStrategy_1.HookExecutionStrategy {
|
|
6
6
|
processHooks(members) {
|
|
7
|
-
for (const {
|
|
8
|
-
|
|
9
|
-
hook(context);
|
|
10
|
-
}
|
|
7
|
+
for (const { hook, context } of members) {
|
|
8
|
+
hook(context);
|
|
11
9
|
}
|
|
12
10
|
}
|
|
13
11
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.oncePerInstance = exports.parallel = exports.sequential = void 0;
|
|
4
|
+
const task_1 = require("../utils/task");
|
|
5
|
+
const hook_1 = require("./hook");
|
|
6
|
+
const sequential = (...hooks) => {
|
|
7
|
+
const fns = hooks.map(hook_1.toHookFn);
|
|
8
|
+
return (context) => (0, task_1.runInOrder)(fns.map((fn) => () => fn(context)));
|
|
9
|
+
};
|
|
10
|
+
exports.sequential = sequential;
|
|
11
|
+
const parallel = (...hooks) => {
|
|
12
|
+
const fns = hooks.map(hook_1.toHookFn);
|
|
13
|
+
return (context) => (0, task_1.runAtOnce)(fns.map((fn) => () => fn(context)));
|
|
14
|
+
};
|
|
15
|
+
exports.parallel = parallel;
|
|
16
|
+
const oncePerInstance = (execute) => {
|
|
17
|
+
const invokedInstances = new WeakSet();
|
|
18
|
+
const fn = (0, hook_1.toHookFn)(execute);
|
|
19
|
+
return (context) => {
|
|
20
|
+
if (invokedInstances.has(context.instance)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
invokedInstances.add(context.instance);
|
|
24
|
+
return fn(context);
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.oncePerInstance = oncePerInstance;
|
package/cjm/hooks/hook.js
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.hook = exports.toHookFn =
|
|
3
|
+
exports.hook = exports.toHookFn = void 0;
|
|
4
4
|
exports.getHooks = getHooks;
|
|
5
5
|
exports.hasHooks = hasHooks;
|
|
6
6
|
const basic_1 = require("../utils/basic");
|
|
7
7
|
const target_1 = require("../metadata/target");
|
|
8
|
-
const appendHooks = (...fns) => (...prev) => [...prev, ...fns];
|
|
9
|
-
exports.appendHooks = appendHooks;
|
|
10
|
-
const prependHooks = (...fns) => (...prev) => [...fns, ...prev];
|
|
11
|
-
exports.prependHooks = prependHooks;
|
|
12
|
-
exports.append = exports.appendHooks;
|
|
13
|
-
exports.prepend = exports.prependHooks;
|
|
14
8
|
const isHookClassConstructor = (execute) => {
|
|
15
9
|
return basic_1.Is.constructor(execute) && execute.prototype.execute;
|
|
16
10
|
};
|
|
@@ -30,8 +24,8 @@ function getHooks(target, key) {
|
|
|
30
24
|
for (const ctor of getConstructorChain((0, target_1.resolveConstructor)(target)).reverse()) {
|
|
31
25
|
const ownHooks = Reflect.getOwnMetadata(key, ctor);
|
|
32
26
|
if (ownHooks) {
|
|
33
|
-
for (const [methodName,
|
|
34
|
-
merged.set(methodName,
|
|
27
|
+
for (const [methodName, fn] of ownHooks) {
|
|
28
|
+
merged.set(methodName, fn);
|
|
35
29
|
}
|
|
36
30
|
}
|
|
37
31
|
}
|
|
@@ -40,11 +34,11 @@ function getHooks(target, key) {
|
|
|
40
34
|
function hasHooks(target, key) {
|
|
41
35
|
return getConstructorChain((0, target_1.resolveConstructor)(target)).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
|
|
42
36
|
}
|
|
43
|
-
const hook = (key,
|
|
37
|
+
const hook = (key, fn) => (target, propertyKey) => {
|
|
44
38
|
const hooks = Reflect.hasOwnMetadata(key, target.constructor)
|
|
45
39
|
? Reflect.getOwnMetadata(key, target.constructor)
|
|
46
40
|
: new Map();
|
|
47
|
-
hooks.set(propertyKey,
|
|
41
|
+
hooks.set(propertyKey, fn);
|
|
48
42
|
Reflect.defineMetadata(key, hooks, target.constructor);
|
|
49
43
|
};
|
|
50
44
|
exports.hook = hook;
|
package/cjm/hooks/onConstruct.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OnConstructModule = exports.onConstruct = void 0;
|
|
4
4
|
const hook_1 = require("./hook");
|
|
5
|
-
const onConstruct = (
|
|
5
|
+
const onConstruct = (fn) => (0, hook_1.hook)('onConstruct', fn);
|
|
6
6
|
exports.onConstruct = onConstruct;
|
|
7
7
|
class OnConstructModule {
|
|
8
8
|
strategy;
|
package/cjm/hooks/onResolved.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.resolved = exports.OnResolvedModule = exports.onResolved = void 0;
|
|
|
4
4
|
const IRegistration_1 = require("../registration/IRegistration");
|
|
5
5
|
const basic_1 = require("../utils/basic");
|
|
6
6
|
const hook_1 = require("./hook");
|
|
7
|
-
const onResolved = (
|
|
7
|
+
const onResolved = (fn) => (0, hook_1.hook)('onResolved', fn);
|
|
8
8
|
exports.onResolved = onResolved;
|
|
9
9
|
const runHooks = (strategy) => (dependency, scope) => {
|
|
10
10
|
if (basic_1.Is.object(dependency)) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OnDisposeModule = exports.onScopeDisposed = void 0;
|
|
4
4
|
const hook_1 = require("./hook");
|
|
5
|
-
const onScopeDisposed = (
|
|
5
|
+
const onScopeDisposed = (fn) => (0, hook_1.hook)('onScopeDisposed', fn);
|
|
6
6
|
exports.onScopeDisposed = onScopeDisposed;
|
|
7
7
|
class OnDisposeModule {
|
|
8
8
|
strategy;
|
package/cjm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
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.ParallelAsync = exports.SequentialAsync = exports.SequentialSync = exports.
|
|
3
|
+
exports.onConstruct = exports.injectProp = exports.createHookExecutionContext = exports.createHookContextFactory = exports.HookContext = exports.toHookFn = exports.hasHooks = exports.hook = exports.getHooks = exports.TypedEventDisposedError = 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.runAtOnce = exports.runInOrder = 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.ParallelAsync = exports.SequentialAsync = exports.SequentialSync = exports.HookExecutionStrategy = exports.oncePerInstance = exports.parallel = exports.sequential = exports.resolved = exports.OnResolvedModule = exports.onResolved = exports.OnDisposeModule = exports.onScopeDisposed = exports.OnConstructModule = void 0;
|
|
5
5
|
exports.Is = exports.unwrapProxy = exports.ProxyRegistry = exports.pipe = exports.select = exports.TypedEvent = 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; } });
|
|
@@ -69,10 +69,7 @@ var hook_1 = require("./hooks/hook");
|
|
|
69
69
|
Object.defineProperty(exports, "getHooks", { enumerable: true, get: function () { return hook_1.getHooks; } });
|
|
70
70
|
Object.defineProperty(exports, "hook", { enumerable: true, get: function () { return hook_1.hook; } });
|
|
71
71
|
Object.defineProperty(exports, "hasHooks", { enumerable: true, get: function () { return hook_1.hasHooks; } });
|
|
72
|
-
Object.defineProperty(exports, "
|
|
73
|
-
Object.defineProperty(exports, "prependHooks", { enumerable: true, get: function () { return hook_1.prependHooks; } });
|
|
74
|
-
Object.defineProperty(exports, "append", { enumerable: true, get: function () { return hook_1.append; } });
|
|
75
|
-
Object.defineProperty(exports, "prepend", { enumerable: true, get: function () { return hook_1.prepend; } });
|
|
72
|
+
Object.defineProperty(exports, "toHookFn", { enumerable: true, get: function () { return hook_1.toHookFn; } });
|
|
76
73
|
var HookContext_1 = require("./hooks/HookContext");
|
|
77
74
|
Object.defineProperty(exports, "HookContext", { enumerable: true, get: function () { return HookContext_1.HookContext; } });
|
|
78
75
|
Object.defineProperty(exports, "createHookContextFactory", { enumerable: true, get: function () { return HookContext_1.createHookContextFactory; } });
|
|
@@ -89,12 +86,12 @@ var onResolved_1 = require("./hooks/onResolved");
|
|
|
89
86
|
Object.defineProperty(exports, "onResolved", { enumerable: true, get: function () { return onResolved_1.onResolved; } });
|
|
90
87
|
Object.defineProperty(exports, "OnResolvedModule", { enumerable: true, get: function () { return onResolved_1.OnResolvedModule; } });
|
|
91
88
|
Object.defineProperty(exports, "resolved", { enumerable: true, get: function () { return onResolved_1.resolved; } });
|
|
92
|
-
var
|
|
93
|
-
Object.defineProperty(exports, "
|
|
89
|
+
var combinators_1 = require("./hooks/combinators");
|
|
90
|
+
Object.defineProperty(exports, "sequential", { enumerable: true, get: function () { return combinators_1.sequential; } });
|
|
91
|
+
Object.defineProperty(exports, "parallel", { enumerable: true, get: function () { return combinators_1.parallel; } });
|
|
92
|
+
Object.defineProperty(exports, "oncePerInstance", { enumerable: true, get: function () { return combinators_1.oncePerInstance; } });
|
|
94
93
|
var HookExecutionStrategy_1 = require("./hooks/HookExecutionStrategy");
|
|
95
94
|
Object.defineProperty(exports, "HookExecutionStrategy", { enumerable: true, get: function () { return HookExecutionStrategy_1.HookExecutionStrategy; } });
|
|
96
|
-
var AsyncHookExecutionStrategy_1 = require("./hooks/AsyncHookExecutionStrategy");
|
|
97
|
-
Object.defineProperty(exports, "AsyncHookExecutionStrategy", { enumerable: true, get: function () { return AsyncHookExecutionStrategy_1.AsyncHookExecutionStrategy; } });
|
|
98
95
|
var SequentialSync_1 = require("./hooks/SequentialSync");
|
|
99
96
|
Object.defineProperty(exports, "SequentialSync", { enumerable: true, get: function () { return SequentialSync_1.SequentialSync; } });
|
|
100
97
|
var SequentialAsync_1 = require("./hooks/SequentialAsync");
|
|
@@ -149,6 +146,9 @@ Object.defineProperty(exports, "getMethodTags", { enumerable: true, get: functio
|
|
|
149
146
|
var errorHandler_1 = require("./utils/errorHandler");
|
|
150
147
|
Object.defineProperty(exports, "handleError", { enumerable: true, get: function () { return errorHandler_1.handleError; } });
|
|
151
148
|
Object.defineProperty(exports, "handleAsyncError", { enumerable: true, get: function () { return errorHandler_1.handleAsyncError; } });
|
|
149
|
+
var task_1 = require("./utils/task");
|
|
150
|
+
Object.defineProperty(exports, "runInOrder", { enumerable: true, get: function () { return task_1.runInOrder; } });
|
|
151
|
+
Object.defineProperty(exports, "runAtOnce", { enumerable: true, get: function () { return task_1.runAtOnce; } });
|
|
152
152
|
var throttle_1 = require("./utils/throttle");
|
|
153
153
|
Object.defineProperty(exports, "throttle", { enumerable: true, get: function () { return throttle_1.throttle; } });
|
|
154
154
|
var debounce_1 = require("./utils/debounce");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAtOnce = exports.runInOrder = void 0;
|
|
4
|
+
const runInOrder = (tasks, from = 0) => {
|
|
5
|
+
for (let i = from; i < tasks.length; i++) {
|
|
6
|
+
const result = tasks[i]();
|
|
7
|
+
if (result instanceof Promise) {
|
|
8
|
+
return result.then(() => (0, exports.runInOrder)(tasks, i + 1));
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
exports.runInOrder = runInOrder;
|
|
13
|
+
const runAtOnce = (tasks) => {
|
|
14
|
+
const pending = [];
|
|
15
|
+
for (const task of tasks) {
|
|
16
|
+
const result = task();
|
|
17
|
+
if (result instanceof Promise) {
|
|
18
|
+
pending.push(result);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
|
|
22
|
+
};
|
|
23
|
+
exports.runAtOnce = runAtOnce;
|
|
@@ -1,24 +1,6 @@
|
|
|
1
1
|
import { resolveConstructor } from '../metadata/target.js';
|
|
2
2
|
import { getHooks, hasHooks, toHookFn } from './hook.js';
|
|
3
3
|
import { createHookExecutionContext } from './HookContext.js';
|
|
4
|
-
export const runInOrder = (hooks, context, from = 0) => {
|
|
5
|
-
for (let i = from; i < hooks.length; i++) {
|
|
6
|
-
const result = hooks[i](context);
|
|
7
|
-
if (result instanceof Promise) {
|
|
8
|
-
return result.then(() => runInOrder(hooks, context, i + 1));
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
export const runAtOnce = (hooks, context) => {
|
|
13
|
-
const pending = [];
|
|
14
|
-
for (const hook of hooks) {
|
|
15
|
-
const result = hook(context);
|
|
16
|
-
if (result instanceof Promise) {
|
|
17
|
-
pending.push(result);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
|
|
21
|
-
};
|
|
22
4
|
export class HookExecutionStrategy {
|
|
23
5
|
key;
|
|
24
6
|
onError;
|
|
@@ -43,9 +25,9 @@ export class HookExecutionStrategy {
|
|
|
43
25
|
}
|
|
44
26
|
collect(target, scope, { createExecutionContext = this.options.createExecutionContext, mapExecutionContext = this.options.mapExecutionContext, predicate = this.options.predicate, }) {
|
|
45
27
|
const members = [];
|
|
46
|
-
for (const { methodName,
|
|
28
|
+
for (const { methodName, hook } of this.hooksOf(target)) {
|
|
47
29
|
if (predicate(methodName)) {
|
|
48
|
-
members.push({
|
|
30
|
+
members.push({ hook, context: mapExecutionContext(createExecutionContext(target, scope, methodName)) });
|
|
49
31
|
}
|
|
50
32
|
}
|
|
51
33
|
return members;
|
|
@@ -54,7 +36,7 @@ export class HookExecutionStrategy {
|
|
|
54
36
|
const Target = resolveConstructor(target);
|
|
55
37
|
let hooks = this.hooksByClass.get(Target);
|
|
56
38
|
if (!hooks) {
|
|
57
|
-
hooks = Array.from(getHooks(Target, this.key), ([methodName,
|
|
39
|
+
hooks = Array.from(getHooks(Target, this.key), ([methodName, fn]) => ({ methodName, hook: toHookFn(fn) }));
|
|
58
40
|
this.hooksByClass.set(Target, hooks);
|
|
59
41
|
}
|
|
60
42
|
return hooks;
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { HookExecutionStrategy } from './HookExecutionStrategy.js';
|
|
2
|
+
import { runAtOnce } from '../utils/task.js';
|
|
3
|
+
export class ParallelAsync extends HookExecutionStrategy {
|
|
3
4
|
processHooks(members) {
|
|
4
|
-
|
|
5
|
-
for (const member of members) {
|
|
6
|
-
const result = this.runMember(member);
|
|
7
|
-
if (result) {
|
|
8
|
-
pending.push(result);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
|
|
5
|
+
return runAtOnce(members.map(({ hook, context }) => () => hook(context)));
|
|
12
6
|
}
|
|
13
7
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (result) {
|
|
7
|
-
return result.then(() => this.processHooks(members, i + 1));
|
|
8
|
-
}
|
|
9
|
-
}
|
|
1
|
+
import { HookExecutionStrategy } from './HookExecutionStrategy.js';
|
|
2
|
+
import { runInOrder } from '../utils/task.js';
|
|
3
|
+
export class SequentialAsync extends HookExecutionStrategy {
|
|
4
|
+
processHooks(members) {
|
|
5
|
+
return runInOrder(members.map(({ hook, context }) => () => hook(context)));
|
|
10
6
|
}
|
|
11
7
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { HookExecutionStrategy } from './HookExecutionStrategy.js';
|
|
2
2
|
export class SequentialSync extends HookExecutionStrategy {
|
|
3
3
|
processHooks(members) {
|
|
4
|
-
for (const {
|
|
5
|
-
|
|
6
|
-
hook(context);
|
|
7
|
-
}
|
|
4
|
+
for (const { hook, context } of members) {
|
|
5
|
+
hook(context);
|
|
8
6
|
}
|
|
9
7
|
}
|
|
10
8
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { runAtOnce, runInOrder } from '../utils/task.js';
|
|
2
|
+
import { toHookFn } from './hook.js';
|
|
3
|
+
export const sequential = (...hooks) => {
|
|
4
|
+
const fns = hooks.map(toHookFn);
|
|
5
|
+
return (context) => runInOrder(fns.map((fn) => () => fn(context)));
|
|
6
|
+
};
|
|
7
|
+
export const parallel = (...hooks) => {
|
|
8
|
+
const fns = hooks.map(toHookFn);
|
|
9
|
+
return (context) => runAtOnce(fns.map((fn) => () => fn(context)));
|
|
10
|
+
};
|
|
11
|
+
export const oncePerInstance = (execute) => {
|
|
12
|
+
const invokedInstances = new WeakSet();
|
|
13
|
+
const fn = toHookFn(execute);
|
|
14
|
+
return (context) => {
|
|
15
|
+
if (invokedInstances.has(context.instance)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
invokedInstances.add(context.instance);
|
|
19
|
+
return fn(context);
|
|
20
|
+
};
|
|
21
|
+
};
|
package/esm/hooks/hook.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { Is } from '../utils/basic.js';
|
|
2
2
|
import { resolveConstructor } from '../metadata/target.js';
|
|
3
|
-
export const appendHooks = (...fns) => (...prev) => [...prev, ...fns];
|
|
4
|
-
export const prependHooks = (...fns) => (...prev) => [...fns, ...prev];
|
|
5
|
-
export const append = appendHooks;
|
|
6
|
-
export const prepend = prependHooks;
|
|
7
3
|
const isHookClassConstructor = (execute) => {
|
|
8
4
|
return Is.constructor(execute) && execute.prototype.execute;
|
|
9
5
|
};
|
|
@@ -22,8 +18,8 @@ export function getHooks(target, key) {
|
|
|
22
18
|
for (const ctor of getConstructorChain(resolveConstructor(target)).reverse()) {
|
|
23
19
|
const ownHooks = Reflect.getOwnMetadata(key, ctor);
|
|
24
20
|
if (ownHooks) {
|
|
25
|
-
for (const [methodName,
|
|
26
|
-
merged.set(methodName,
|
|
21
|
+
for (const [methodName, fn] of ownHooks) {
|
|
22
|
+
merged.set(methodName, fn);
|
|
27
23
|
}
|
|
28
24
|
}
|
|
29
25
|
}
|
|
@@ -32,10 +28,10 @@ export function getHooks(target, key) {
|
|
|
32
28
|
export function hasHooks(target, key) {
|
|
33
29
|
return getConstructorChain(resolveConstructor(target)).some((ctor) => Reflect.hasOwnMetadata(key, ctor));
|
|
34
30
|
}
|
|
35
|
-
export const hook = (key,
|
|
31
|
+
export const hook = (key, fn) => (target, propertyKey) => {
|
|
36
32
|
const hooks = Reflect.hasOwnMetadata(key, target.constructor)
|
|
37
33
|
? Reflect.getOwnMetadata(key, target.constructor)
|
|
38
34
|
: new Map();
|
|
39
|
-
hooks.set(propertyKey,
|
|
35
|
+
hooks.set(propertyKey, fn);
|
|
40
36
|
Reflect.defineMetadata(key, hooks, target.constructor);
|
|
41
37
|
};
|
package/esm/hooks/onConstruct.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { hook
|
|
2
|
-
export const onConstruct = (
|
|
1
|
+
import { hook } from './hook.js';
|
|
2
|
+
export const onConstruct = (fn) => hook('onConstruct', fn);
|
|
3
3
|
export class OnConstructModule {
|
|
4
4
|
strategy;
|
|
5
5
|
constructor(strategy) {
|
package/esm/hooks/onResolved.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { registerPipe } from '../registration/IRegistration.js';
|
|
2
2
|
import { Is } from '../utils/basic.js';
|
|
3
|
-
import { hook
|
|
4
|
-
export const onResolved = (
|
|
3
|
+
import { hook } from './hook.js';
|
|
4
|
+
export const onResolved = (fn) => hook('onResolved', fn);
|
|
5
5
|
const runHooks = (strategy) => (dependency, scope) => {
|
|
6
6
|
if (Is.object(dependency)) {
|
|
7
7
|
strategy.execute(dependency, { scope });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { hook
|
|
2
|
-
export const onScopeDisposed = (
|
|
1
|
+
import { hook } from './hook.js';
|
|
2
|
+
export const onScopeDisposed = (fn) => hook('onScopeDisposed', fn);
|
|
3
3
|
export class OnDisposeModule {
|
|
4
4
|
strategy;
|
|
5
5
|
constructor(strategy) {
|
package/esm/index.js
CHANGED
|
@@ -19,15 +19,14 @@ export { ProviderDisposedError } from './errors/ProviderDisposedError.js';
|
|
|
19
19
|
export { CannonSingletonApplyTwiceError } from './errors/CannonSingletonApplyTwiceError.js';
|
|
20
20
|
export { UnsupportedTokenTypeError } from './errors/UnsupportedTokenTypeError.js';
|
|
21
21
|
export { TypedEventDisposedError } from './errors/TypedEventDisposedError.js';
|
|
22
|
-
export { getHooks, hook, hasHooks,
|
|
22
|
+
export { getHooks, hook, hasHooks, toHookFn, } from './hooks/hook.js';
|
|
23
23
|
export { HookContext, createHookContextFactory, createHookExecutionContext, } from './hooks/HookContext.js';
|
|
24
24
|
export { injectProp } from './hooks/injectProp.js';
|
|
25
25
|
export { onConstruct, OnConstructModule } from './hooks/onConstruct.js';
|
|
26
26
|
export { onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
|
|
27
27
|
export { onResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
|
|
28
|
-
export { oncePerInstance } from './hooks/
|
|
28
|
+
export { sequential, parallel, oncePerInstance } from './hooks/combinators.js';
|
|
29
29
|
export { HookExecutionStrategy, } from './hooks/HookExecutionStrategy.js';
|
|
30
|
-
export { AsyncHookExecutionStrategy, } from './hooks/AsyncHookExecutionStrategy.js';
|
|
31
30
|
export { SequentialSync } from './hooks/SequentialSync.js';
|
|
32
31
|
export { SequentialAsync } from './hooks/SequentialAsync.js';
|
|
33
32
|
export { ParallelAsync } from './hooks/ParallelAsync.js';
|
|
@@ -45,6 +44,7 @@ export { addClassMeta, getClassMeta, addClassLabel, getClassLabels, addClassTag,
|
|
|
45
44
|
export { addParamMeta, getParamMeta, addParamLabel, getParamLabels, addParamTag, getParamTags, } from './metadata/parameter.js';
|
|
46
45
|
export { addMethodMeta, getMethodMeta, addMethodLabel, getMethodLabels, addMethodTag, getMethodTags, } from './metadata/method.js';
|
|
47
46
|
export { handleError, handleAsyncError } from './utils/errorHandler.js';
|
|
47
|
+
export { runInOrder, runAtOnce } from './utils/task.js';
|
|
48
48
|
export { throttle } from './utils/throttle.js';
|
|
49
49
|
export { debounce } from './utils/debounce.js';
|
|
50
50
|
export { shallowCache } from './utils/shallowCache.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const runInOrder = (tasks, from = 0) => {
|
|
2
|
+
for (let i = from; i < tasks.length; i++) {
|
|
3
|
+
const result = tasks[i]();
|
|
4
|
+
if (result instanceof Promise) {
|
|
5
|
+
return result.then(() => runInOrder(tasks, i + 1));
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
export const runAtOnce = (tasks) => {
|
|
10
|
+
const pending = [];
|
|
11
|
+
for (const task of tasks) {
|
|
12
|
+
const result = task();
|
|
13
|
+
if (result instanceof Promise) {
|
|
14
|
+
pending.push(result);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
|
|
18
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "67.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",
|
|
@@ -15,12 +15,10 @@ export type HookExecutionStrategyProps = HookExecutionOptions & {
|
|
|
15
15
|
key: string | symbol;
|
|
16
16
|
onError?: OnErrorHandler;
|
|
17
17
|
};
|
|
18
|
-
export type
|
|
19
|
-
|
|
18
|
+
export type MemberHook = {
|
|
19
|
+
hook: HookFn;
|
|
20
20
|
context: IHookContext;
|
|
21
21
|
};
|
|
22
|
-
export declare const runInOrder: (hooks: HookFn[], context: IHookContext, from?: number) => void | Promise<void>;
|
|
23
|
-
export declare const runAtOnce: (hooks: HookFn[], context: IHookContext) => void | Promise<void>;
|
|
24
22
|
export declare abstract class HookExecutionStrategy {
|
|
25
23
|
private readonly key;
|
|
26
24
|
private readonly onError?;
|
|
@@ -29,7 +27,7 @@ export declare abstract class HookExecutionStrategy {
|
|
|
29
27
|
constructor({ key, onError, createExecutionContext, mapExecutionContext, predicate, }: HookExecutionStrategyProps);
|
|
30
28
|
hasHooks(target: Instance): boolean;
|
|
31
29
|
execute(target: Instance, { scope, ...overrides }: HookExecutionContext): void;
|
|
32
|
-
protected abstract processHooks(members:
|
|
30
|
+
protected abstract processHooks(members: MemberHook[]): void | Promise<void>;
|
|
33
31
|
private collect;
|
|
34
32
|
private hooksOf;
|
|
35
33
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
protected processHooks(members: MemberHooks[]): void | Promise<void>;
|
|
1
|
+
import { HookExecutionStrategy, type MemberHook } from './HookExecutionStrategy.js';
|
|
2
|
+
export declare class ParallelAsync extends HookExecutionStrategy {
|
|
3
|
+
protected processHooks(members: MemberHook[]): void | Promise<void>;
|
|
5
4
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
protected processHooks(members: MemberHooks[], from?: number): void | Promise<void>;
|
|
1
|
+
import { HookExecutionStrategy, type MemberHook } from './HookExecutionStrategy.js';
|
|
2
|
+
export declare class SequentialAsync extends HookExecutionStrategy {
|
|
3
|
+
protected processHooks(members: MemberHook[]): void | Promise<void>;
|
|
5
4
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HookExecutionStrategy, type
|
|
1
|
+
import { HookExecutionStrategy, type MemberHook } from './HookExecutionStrategy.js';
|
|
2
2
|
export declare class SequentialSync extends HookExecutionStrategy {
|
|
3
|
-
protected processHooks(members:
|
|
3
|
+
protected processHooks(members: MemberHook[]): void;
|
|
4
4
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { IContainer } from '../container/IContainer.js';
|
|
2
2
|
import { type HookFn, type HookType } from './hook.js';
|
|
3
3
|
export type ResolvedObjectHook = (dependency: object, scope: IContainer) => void;
|
|
4
|
+
export declare const sequential: (...hooks: HookType[]) => HookFn;
|
|
5
|
+
export declare const parallel: (...hooks: HookType[]) => HookFn;
|
|
4
6
|
export declare const oncePerInstance: (execute: HookType) => HookFn;
|
package/typings/hooks/hook.d.ts
CHANGED
|
@@ -8,13 +8,8 @@ export interface HookClass<T extends IHookContext = IHookContext> {
|
|
|
8
8
|
execute(context: Omit<T, 'scope'>): void | Promise<void>;
|
|
9
9
|
}
|
|
10
10
|
export type HookType<T extends IHookContext = IHookContext> = HookFn<T> | constructor<HookClass<T>>;
|
|
11
|
-
export type
|
|
12
|
-
export type HooksOfClass = Map<string, HookType[]>;
|
|
13
|
-
export declare const appendHooks: (...fns: HookType[]) => MapHooksFn;
|
|
14
|
-
export declare const prependHooks: (...fns: HookType[]) => MapHooksFn;
|
|
15
|
-
export declare const append: (...fns: HookType[]) => MapHooksFn;
|
|
16
|
-
export declare const prepend: (...fns: HookType[]) => MapHooksFn;
|
|
11
|
+
export type HooksOfClass = Map<string, HookType>;
|
|
17
12
|
export declare const toHookFn: <C extends IHookContext>(execute: HookFn<C> | constructor<HookClass<C>>) => HookFn<C>;
|
|
18
13
|
export declare function getHooks(target: Instance | constructor<unknown>, key: string | symbol): HooksOfClass;
|
|
19
14
|
export declare function hasHooks(target: Instance | constructor<unknown>, key: string | symbol): boolean;
|
|
20
|
-
export declare const hook: (key: string | symbol,
|
|
15
|
+
export declare const hook: (key: string | symbol, fn: HookType) => (target: object, propertyKey: string | symbol) => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type HookType } from './hook.js';
|
|
2
2
|
import type { IContainer, IContainerModule } from '../container/IContainer.js';
|
|
3
3
|
import { type HookExecutionStrategy } from './HookExecutionStrategy.js';
|
|
4
|
-
export declare const onConstruct: (
|
|
4
|
+
export declare const onConstruct: (fn: HookType) => (target: object, propertyKey: string | symbol) => void;
|
|
5
5
|
export declare class OnConstructModule implements IContainerModule {
|
|
6
6
|
private readonly strategy;
|
|
7
7
|
constructor(strategy: HookExecutionStrategy);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IContainer, IContainerModule } from '../container/IContainer.js';
|
|
2
2
|
import { type HookExecutionStrategy } from './HookExecutionStrategy.js';
|
|
3
3
|
import { type HookType } from './hook.js';
|
|
4
|
-
export declare const onResolved: (
|
|
4
|
+
export declare const onResolved: (fn: HookType) => (target: object, propertyKey: string | symbol) => void;
|
|
5
5
|
export declare class OnResolvedModule implements IContainerModule {
|
|
6
6
|
private readonly runHooks;
|
|
7
7
|
constructor(strategy: HookExecutionStrategy);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type HookType } from './hook.js';
|
|
2
2
|
import type { IContainer, IContainerModule } from '../container/IContainer.js';
|
|
3
3
|
import { type HookExecutionStrategy } from './HookExecutionStrategy.js';
|
|
4
|
-
export declare const onScopeDisposed: (
|
|
4
|
+
export declare const onScopeDisposed: (fn: HookType) => (target: object, propertyKey: string | symbol) => void;
|
|
5
5
|
export declare class OnDisposeModule implements IContainerModule {
|
|
6
6
|
private readonly strategy;
|
|
7
7
|
constructor(strategy: HookExecutionStrategy);
|
package/typings/index.d.ts
CHANGED
|
@@ -20,15 +20,14 @@ export { ProviderDisposedError } from './errors/ProviderDisposedError.js';
|
|
|
20
20
|
export { CannonSingletonApplyTwiceError } from './errors/CannonSingletonApplyTwiceError.js';
|
|
21
21
|
export { UnsupportedTokenTypeError } from './errors/UnsupportedTokenTypeError.js';
|
|
22
22
|
export { TypedEventDisposedError } from './errors/TypedEventDisposedError.js';
|
|
23
|
-
export { getHooks, hook, hasHooks,
|
|
23
|
+
export { getHooks, hook, hasHooks, toHookFn, type HookFn, type HookClass, type HookType, type InjectFn, type HooksOfClass, } from './hooks/hook.js';
|
|
24
24
|
export { HookContext, createHookContextFactory, createHookExecutionContext, type CreateHookExecutionContext, type IHookContext, } from './hooks/HookContext.js';
|
|
25
25
|
export { injectProp } from './hooks/injectProp.js';
|
|
26
26
|
export { onConstruct, OnConstructModule } from './hooks/onConstruct.js';
|
|
27
27
|
export { onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
|
|
28
28
|
export { onResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
|
|
29
|
-
export { oncePerInstance, type ResolvedObjectHook } from './hooks/
|
|
30
|
-
export { HookExecutionStrategy, type HookExecutionContext, type HookExecutionOptions, type HookExecutionStrategyProps, type MapHookExecutionContext, type
|
|
31
|
-
export { AsyncHookExecutionStrategy, type AsyncHookExecutionStrategyProps, type MethodStrategy, } from './hooks/AsyncHookExecutionStrategy.js';
|
|
29
|
+
export { sequential, parallel, oncePerInstance, type ResolvedObjectHook } from './hooks/combinators.js';
|
|
30
|
+
export { HookExecutionStrategy, type HookExecutionContext, type HookExecutionOptions, type HookExecutionStrategyProps, type MapHookExecutionContext, type MemberHook, type OnErrorHandler, } from './hooks/HookExecutionStrategy.js';
|
|
32
31
|
export { SequentialSync } from './hooks/SequentialSync.js';
|
|
33
32
|
export { SequentialAsync } from './hooks/SequentialAsync.js';
|
|
34
33
|
export { ParallelAsync } from './hooks/ParallelAsync.js';
|
|
@@ -46,6 +45,7 @@ export { addClassMeta, getClassMeta, addClassLabel, getClassLabels, addClassTag,
|
|
|
46
45
|
export { addParamMeta, getParamMeta, addParamLabel, getParamLabels, addParamTag, getParamTags, } from './metadata/parameter.js';
|
|
47
46
|
export { addMethodMeta, getMethodMeta, addMethodLabel, getMethodLabels, addMethodTag, getMethodTags, } from './metadata/method.js';
|
|
48
47
|
export { handleError, handleAsyncError, type HandleErrorParams } from './utils/errorHandler.js';
|
|
48
|
+
export { runInOrder, runAtOnce, type Task } from './utils/task.js';
|
|
49
49
|
export { throttle } from './utils/throttle.js';
|
|
50
50
|
export { debounce } from './utils/debounce.js';
|
|
51
51
|
export { shallowCache } from './utils/shallowCache.js';
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AsyncHookExecutionStrategy = void 0;
|
|
4
|
-
const HookExecutionStrategy_1 = require("./HookExecutionStrategy");
|
|
5
|
-
class AsyncHookExecutionStrategy extends HookExecutionStrategy_1.HookExecutionStrategy {
|
|
6
|
-
methodStrategy;
|
|
7
|
-
constructor({ methodStrategy = 'sequential', ...props }) {
|
|
8
|
-
super(props);
|
|
9
|
-
this.methodStrategy = methodStrategy;
|
|
10
|
-
}
|
|
11
|
-
runMember({ hooks, context }) {
|
|
12
|
-
return this.methodStrategy === 'parallel' ? (0, HookExecutionStrategy_1.runAtOnce)(hooks, context) : (0, HookExecutionStrategy_1.runInOrder)(hooks, context);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.AsyncHookExecutionStrategy = AsyncHookExecutionStrategy;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.oncePerInstance = void 0;
|
|
4
|
-
const hook_1 = require("./hook");
|
|
5
|
-
const oncePerInstance = (execute) => {
|
|
6
|
-
const invokedInstances = new WeakSet();
|
|
7
|
-
return (context) => {
|
|
8
|
-
if (invokedInstances.has(context.instance)) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
invokedInstances.add(context.instance);
|
|
12
|
-
return (0, hook_1.toHookFn)(execute)(context);
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
exports.oncePerInstance = oncePerInstance;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { HookExecutionStrategy, runAtOnce, runInOrder, } from './HookExecutionStrategy.js';
|
|
2
|
-
export class AsyncHookExecutionStrategy extends HookExecutionStrategy {
|
|
3
|
-
methodStrategy;
|
|
4
|
-
constructor({ methodStrategy = 'sequential', ...props }) {
|
|
5
|
-
super(props);
|
|
6
|
-
this.methodStrategy = methodStrategy;
|
|
7
|
-
}
|
|
8
|
-
runMember({ hooks, context }) {
|
|
9
|
-
return this.methodStrategy === 'parallel' ? runAtOnce(hooks, context) : runInOrder(hooks, context);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { toHookFn } from './hook.js';
|
|
2
|
-
export const oncePerInstance = (execute) => {
|
|
3
|
-
const invokedInstances = new WeakSet();
|
|
4
|
-
return (context) => {
|
|
5
|
-
if (invokedInstances.has(context.instance)) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
invokedInstances.add(context.instance);
|
|
9
|
-
return toHookFn(execute)(context);
|
|
10
|
-
};
|
|
11
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { HookExecutionStrategy, type HookExecutionStrategyProps, type MemberHooks } from './HookExecutionStrategy.js';
|
|
2
|
-
export type MethodStrategy = 'sequential' | 'parallel';
|
|
3
|
-
export type AsyncHookExecutionStrategyProps = HookExecutionStrategyProps & {
|
|
4
|
-
methodStrategy?: MethodStrategy;
|
|
5
|
-
};
|
|
6
|
-
export declare abstract class AsyncHookExecutionStrategy extends HookExecutionStrategy {
|
|
7
|
-
private readonly methodStrategy;
|
|
8
|
-
constructor({ methodStrategy, ...props }: AsyncHookExecutionStrategyProps);
|
|
9
|
-
protected runMember({ hooks, context }: MemberHooks): void | Promise<void>;
|
|
10
|
-
}
|