ts-ioc-container 61.0.0 → 62.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +42 -50
  2. package/cjm/hooks/HooksRunner.js +30 -22
  3. package/cjm/hooks/onConstruct.js +1 -9
  4. package/cjm/hooks/onResolved.js +7 -3
  5. package/cjm/hooks/onScopeDisposed.js +22 -0
  6. package/cjm/hooks/resolveHooks.js +3 -14
  7. package/cjm/index.js +8 -19
  8. package/esm/hooks/HooksRunner.js +28 -21
  9. package/esm/hooks/onConstruct.js +2 -10
  10. package/esm/hooks/onResolved.js +7 -3
  11. package/esm/hooks/onScopeDisposed.js +17 -0
  12. package/esm/hooks/resolveHooks.js +2 -12
  13. package/esm/index.js +2 -5
  14. package/package.json +1 -1
  15. package/typings/hooks/HooksRunner.d.ts +4 -2
  16. package/typings/hooks/onConstruct.d.ts +1 -3
  17. package/typings/hooks/onResolved.d.ts +4 -2
  18. package/typings/hooks/onScopeDisposed.d.ts +10 -0
  19. package/typings/hooks/resolveHooks.d.ts +2 -4
  20. package/typings/index.d.ts +3 -6
  21. package/cjm/errors/UnexpectedHookResultError.js +0 -12
  22. package/cjm/hooks/onConstructAsync.js +0 -28
  23. package/cjm/hooks/onContainerDisposed.js +0 -18
  24. package/cjm/hooks/onResolvedAsync.js +0 -24
  25. package/cjm/utils/promise.js +0 -5
  26. package/esm/errors/UnexpectedHookResultError.js +0 -8
  27. package/esm/hooks/onConstructAsync.js +0 -23
  28. package/esm/hooks/onContainerDisposed.js +0 -13
  29. package/esm/hooks/onResolvedAsync.js +0 -19
  30. package/esm/utils/promise.js +0 -1
  31. package/typings/errors/UnexpectedHookResultError.d.ts +0 -5
  32. package/typings/hooks/onConstructAsync.d.ts +0 -11
  33. package/typings/hooks/onContainerDisposed.d.ts +0 -8
  34. package/typings/hooks/onResolvedAsync.d.ts +0 -12
  35. package/typings/utils/promise.d.ts +0 -1
package/README.md CHANGED
@@ -18,7 +18,7 @@ provider pipelines, aliases, and custom injector strategies.
18
18
  - clean API for classes, keys, tokens, aliases, and scopes
19
19
  - no global container object; pass containers and scopes explicitly
20
20
  - supports tagged application, request, transaction, page, and widget scopes
21
- - decorator support with `@register`, `@inject`, `@onConstruct`, and `@onContainerDisposed`
21
+ - decorator support with `@register`, `@inject`, `@onConstruct`, and `@onScopeDisposed`
22
22
  - can [inject properties](#inject-property)
23
23
  - can inject [lazy dependencies](#lazy)
24
24
  - composable provider and registration pipelines
@@ -56,8 +56,7 @@ provider pipelines, aliases, and custom injector strategies.
56
56
  - [Hook](#hook) `@hook`
57
57
  - [Hook domains](#hook-domains) `ScopeHook` `InjectorHook` `ProviderHook`
58
58
  - [OnConstruct](#onconstruct) `@onConstruct`
59
- - [OnConstructAsync](#onconstructasync) `@onConstructAsync`
60
- - [OnContainerDisposed](#oncontainerdisposed) `@onContainerDisposed`
59
+ - [OnScopeDisposed](#onscopedisposed) `@onScopeDisposed`
61
60
  - [Inject Property](#inject-property)
62
61
  - [Inject Method](#inject-method)
63
62
  - [Mock](#mock)
@@ -108,7 +107,7 @@ bundlers tree-shake unused exports.
108
107
 
109
108
  > [!NOTE]
110
109
  > The default `MetadataInjector` (and the `@inject` / `@onConstruct` /
111
- > `@onContainerDisposed` decorators) rely on `reflect-metadata`. It is declared as an
110
+ > `@onScopeDisposed` decorators) rely on `reflect-metadata`. It is declared as an
112
111
  > optional peer dependency — install it and import it once at your entrypoint.
113
112
  > `SimpleInjector` and `ProxyInjector` do not need it.
114
113
 
@@ -455,7 +454,7 @@ describe('Instances', function () {
455
454
  Sometimes you want to dispose a container or scope. For example, when a request, page, widget, or other local lifecycle ends.
456
455
 
457
456
  - container can be disposed
458
- - when container is disposed then it runs its `onContainerDisposed` hooks, unregisters its providers, removes its local instances, and detaches from its parent
457
+ - when container is disposed then it runs its `onScopeDisposed` hooks, unregisters its providers, removes its local instances, and detaches from its parent
459
458
 
460
459
  > [!IMPORTANT]
461
460
  > Dispose is local to the container being disposed. Child scopes are not disposed automatically; dispose them explicitly when their own lifecycle ends.
@@ -474,7 +473,7 @@ import { bindTo, Container, ContainerDisposedError, register, Registration as R,
474
473
  * - Cache entries cleared
475
474
  *
476
475
  * The container.dispose() method:
477
- * 1. Executes all onContainerDisposed hooks
476
+ * 1. Executes all onScopeDisposed hooks
478
477
  * 2. Clears all instances and registrations
479
478
  * 3. Detaches from parent scope
480
479
  * 4. Prevents further resolution
@@ -2829,10 +2828,27 @@ Decorators are applied bottom-up, so `authorize` runs first, then `validate` and
2829
2828
  `(...prev) => [...prev].reverse()` to reorder, or `() => [onlyThisOne]` to
2830
2829
  replace the accumulated hooks.
2831
2830
 
2832
- `@onConstruct`, `@onConstructAsync` and `@onContainerDisposed` keep their
2833
- variadic signature and compensate for the bottom-up application order, so
2834
- stacked decorators run in declaration order: `@onConstruct(h1) @onConstruct(h2)`
2835
- runs `h1` before `h2`.
2831
+ `@onConstruct` and `@onScopeDisposed` keep their variadic signature and
2832
+ compensate for the bottom-up application order, so stacked decorators run in
2833
+ declaration order: `@onConstruct(h1) @onConstruct(h2)` runs `h1` before `h2`.
2834
+
2835
+ Every hook may be sync or async — one decorator and one module take both, so
2836
+ there is no separate async form to reach for. A `HooksRunner` runs a hook chain
2837
+ eagerly and stays synchronous until a hook returns a promise, then awaits the
2838
+ rest of that chain. Sync hooks therefore finish before `resolve` (or `dispose`)
2839
+ returns, exactly as before; async ones are started there and settle afterwards,
2840
+ so `resolve` returns before they finish. Instances that must expose readiness
2841
+ should publish it themselves, for example by storing the pending promise on the
2842
+ instance.
2843
+
2844
+ `HooksRunner.execute` mirrors that: it returns `undefined` when nothing went
2845
+ async and a promise otherwise, so a caller running its own hooks can `await` the
2846
+ result either way.
2847
+
2848
+ Every module takes an optional `onException` handler, and it catches both kinds
2849
+ of failure — what a sync hook threw and what an async hook rejected with.
2850
+ Without one, a sync hook throws out of the call and an async hook surfaces as an
2851
+ unhandled promise rejection.
2836
2852
 
2837
2853
  ### Hook domains
2838
2854
 
@@ -2866,9 +2882,8 @@ it was added. Scope hooks, by contrast, are copied into a child at `createScope`
2866
2882
  time, so a child inherits what its parent held then and later additions to either
2867
2883
  stay local.
2868
2884
 
2869
- The built-in modules follow the same split. `OnConstructModule` and
2870
- `OnConstructAsyncModule` are **injector** modules (`IInjectorModule`), applied
2871
- with `injector.useModule(...)`:
2885
+ The built-in modules follow the same split. `OnConstructModule` is an
2886
+ **injector** module (`IInjectorModule`), applied with `injector.useModule(...)`:
2872
2887
 
2873
2888
  ```typescript
2874
2889
  const injector = new MetadataInjector().useModule(new OnConstructModule());
@@ -2876,8 +2891,8 @@ const container = new Container({ injector });
2876
2891
  ```
2877
2892
 
2878
2893
  `OnDisposeModule` is a container module hooking `onScopeDisposed`, and
2879
- `OnResolvedModule` / `OnResolvedAsyncModule` are container modules reaching every
2880
- provider through `onRegistered`.
2894
+ `OnResolvedModule` is a container module reaching every provider through
2895
+ `onRegistered`.
2881
2896
 
2882
2897
  ### OnConstruct
2883
2898
 
@@ -2899,6 +2914,10 @@ const execute: HookFn = (ctx) => {
2899
2914
  ctx.invokeMethod({ args: ctx.resolveArgs() });
2900
2915
  };
2901
2916
 
2917
+ const executeAsync: HookFn = async (ctx) => {
2918
+ await ctx.invokeMethod({ args: ctx.resolveArgs() });
2919
+ };
2920
+
2902
2921
  describe('onConstruct', function () {
2903
2922
  it('should run initialization method after dependencies are resolved', function () {
2904
2923
  class DatabaseConnection {
@@ -2983,34 +3002,7 @@ describe('onConstruct', function () {
2983
3002
 
2984
3003
  expect(scope).toBe(child);
2985
3004
  });
2986
- });
2987
3005
 
2988
- ```
2989
-
2990
- ### OnConstructAsync
2991
-
2992
- `@onConstructAsync` runs promise-returning initialization. Resolution stays
2993
- synchronous: `OnConstructAsyncModule` starts the hooks when the instance
2994
- is created and they settle afterwards, so `resolve` returns before they finish.
2995
-
2996
- ```typescript
2997
- import 'reflect-metadata';
2998
- import {
2999
- MetadataInjector,
3000
- OnConstructAsyncModule,
3001
- Container,
3002
- type ExecutionContext,
3003
- type HookFn,
3004
- inject,
3005
- onConstructAsync,
3006
- Registration as R,
3007
- } from 'ts-ioc-container';
3008
-
3009
- const execute: HookFn = async (ctx) => {
3010
- await ctx.invokeMethod({ args: ctx.resolveArgs() });
3011
- };
3012
-
3013
- describe('onConstructAsync', function () {
3014
3006
  it('should run an async initialization method after the instance is created', async function () {
3015
3007
  class DatabaseConnection {
3016
3008
  isConnected = false;
@@ -3025,7 +3017,7 @@ describe('onConstructAsync', function () {
3025
3017
  });
3026
3018
  }
3027
3019
 
3028
- @onConstructAsync(execute)
3020
+ @onConstruct(executeAsync)
3029
3021
  async connect(@inject('ConnectionString') connectionString: string) {
3030
3022
  await Promise.resolve();
3031
3023
  this.connectionString = connectionString;
@@ -3035,7 +3027,7 @@ describe('onConstructAsync', function () {
3035
3027
  }
3036
3028
 
3037
3029
  const container = new Container({
3038
- injector: new MetadataInjector().useModule(new OnConstructAsyncModule()),
3030
+ injector: new MetadataInjector().useModule(new OnConstructModule()),
3039
3031
  }).addRegistration(R.fromValue('postgres://localhost:5432').bindTo('ConnectionString'));
3040
3032
 
3041
3033
  const db = container.resolve(DatabaseConnection);
@@ -3053,14 +3045,14 @@ describe('onConstructAsync', function () {
3053
3045
  const failure = new Error('boom');
3054
3046
 
3055
3047
  class BrokenService {
3056
- @onConstructAsync(() => Promise.reject(failure))
3048
+ @onConstruct(() => Promise.reject(failure))
3057
3049
  init() {}
3058
3050
  }
3059
3051
 
3060
3052
  let captured: { ex: unknown; context: ExecutionContext } | undefined;
3061
3053
  const container = new Container({
3062
3054
  injector: new MetadataInjector().useModule(
3063
- new OnConstructAsyncModule((ex, context) => {
3055
+ new OnConstructModule((ex, context) => {
3064
3056
  captured = { ex, context };
3065
3057
  }),
3066
3058
  ),
@@ -3078,7 +3070,7 @@ describe('onConstructAsync', function () {
3078
3070
 
3079
3071
  ```
3080
3072
 
3081
- ### OnContainerDisposed
3073
+ ### OnScopeDisposed
3082
3074
 
3083
3075
  ```typescript
3084
3076
  import 'reflect-metadata';
@@ -3088,7 +3080,7 @@ import {
3088
3080
  Container,
3089
3081
  type HookFn,
3090
3082
  inject,
3091
- onContainerDisposed,
3083
+ onScopeDisposed,
3092
3084
  register,
3093
3085
  Registration as R,
3094
3086
  singleton,
@@ -3117,13 +3109,13 @@ class Logger {
3117
3109
  this.messages.push(message);
3118
3110
  }
3119
3111
 
3120
- @onContainerDisposed(execute)
3112
+ @onScopeDisposed(execute)
3121
3113
  save() {
3122
3114
  this.logsRepo.saveLogs(this.messages);
3123
3115
  }
3124
3116
  }
3125
3117
 
3126
- describe('onContainerDisposed', function () {
3118
+ describe('onScopeDisposed', function () {
3127
3119
  it('should invoke hooks on all instances when container is disposed', function () {
3128
3120
  const container = new Container()
3129
3121
  .useModule(new OnDisposeModule())
@@ -1,10 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HooksRunner = void 0;
3
+ exports.runHooks = exports.HooksRunner = void 0;
4
4
  const HookContext_1 = require("./HookContext");
5
5
  const hook_1 = require("./hook");
6
- const UnexpectedHookResultError_1 = require("../errors/UnexpectedHookResultError");
7
- const promise_1 = require("../utils/promise");
6
+ const runFrom = (fns, index, context) => {
7
+ for (let i = index; i < fns.length; i++) {
8
+ const result = fns[i](context);
9
+ if (result instanceof Promise) {
10
+ return result.then(() => runFrom(fns, i + 1, context));
11
+ }
12
+ }
13
+ };
8
14
  class HooksRunner {
9
15
  key;
10
16
  constructor(key) {
@@ -15,28 +21,30 @@ class HooksRunner {
15
21
  }
16
22
  execute(target, { scope, createContext = HookContext_1.createHookContext, mapContext = (context) => context, predicate = () => true, }) {
17
23
  const hooks = Array.from((0, hook_1.getHooks)(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
18
- const runMethodHooks = (methodName, executions) => {
19
- const context = mapContext(createContext(target, scope, methodName));
20
- for (const execute of executions) {
21
- const result = execute(context);
22
- if (result instanceof Promise) {
23
- throw new UnexpectedHookResultError_1.UnexpectedHookResultError(`Hook ${methodName} returned a promise, use runHooksAsync instead`);
24
- }
25
- }
26
- };
24
+ const pending = [];
27
25
  for (const [methodName, executions] of hooks) {
28
- runMethodHooks(methodName, executions.map(hook_1.toHookFn));
29
- }
30
- }
31
- async executeAsync(target, { scope, createContext = HookContext_1.createHookContext, mapContext = (context) => context, predicate = () => true, }) {
32
- const hooks = Array.from((0, hook_1.getHooks)(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
33
- const runMethodHooks = async (methodName, executions) => {
34
26
  const context = mapContext(createContext(target, scope, methodName));
35
- for (const execute of executions) {
36
- await (0, promise_1.promisify)(execute(context));
27
+ const result = runFrom(executions.map(hook_1.toHookFn), 0, context);
28
+ if (result) {
29
+ pending.push(result);
37
30
  }
38
- };
39
- return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(hook_1.toHookFn))));
31
+ }
32
+ return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
40
33
  }
41
34
  }
42
35
  exports.HooksRunner = HooksRunner;
36
+ const runHooks = (runner, target, scope, onException) => {
37
+ const report = (ex) => {
38
+ if (!onException) {
39
+ throw ex;
40
+ }
41
+ onException(ex, { scope });
42
+ };
43
+ try {
44
+ runner.execute(target, { scope })?.catch(report);
45
+ }
46
+ catch (ex) {
47
+ report(ex);
48
+ }
49
+ };
50
+ exports.runHooks = runHooks;
@@ -13,15 +13,7 @@ class OnConstructModule {
13
13
  }
14
14
  applyTo(injector) {
15
15
  injector.onConstructed((instance, scope) => {
16
- try {
17
- exports.onConstructHooksRunner.execute(instance, { scope });
18
- }
19
- catch (ex) {
20
- if (!this.onException) {
21
- throw ex;
22
- }
23
- this.onException(ex, { scope });
24
- }
16
+ (0, HooksRunner_1.runHooks)(exports.onConstructHooksRunner, instance, scope, this.onException);
25
17
  });
26
18
  }
27
19
  }
@@ -7,14 +7,18 @@ const resolveHooks_1 = require("./resolveHooks");
7
7
  exports.onResolvedHooksRunner = new HooksRunner_1.HooksRunner('onResolved');
8
8
  exports.onResolved = (0, resolveHooks_1.resolvedHook)('onResolved');
9
9
  exports.onceResolved = (0, resolveHooks_1.onceResolvedHook)('onResolved');
10
- const runHooks = (0, resolveHooks_1.forEachResolvedObject)((0, resolveHooks_1.executeHooks)(exports.onResolvedHooksRunner));
10
+ const runHooks = (onException) => (0, resolveHooks_1.forEachResolvedObject)((0, resolveHooks_1.executeHooks)(exports.onResolvedHooksRunner, onException));
11
11
  class OnResolvedModule {
12
+ runHooks;
13
+ constructor(onException) {
14
+ this.runHooks = runHooks(onException);
15
+ }
12
16
  applyTo(container) {
13
17
  container.onRegistered((provider) => {
14
- provider.onResolved(runHooks);
18
+ provider.onResolved(this.runHooks);
15
19
  });
16
20
  }
17
21
  }
18
22
  exports.OnResolvedModule = OnResolvedModule;
19
- const resolved = () => (0, IRegistration_1.registerPipe)((p) => p.onResolved(runHooks));
23
+ const resolved = (onException) => (0, IRegistration_1.registerPipe)((p) => p.onResolved(runHooks(onException)));
20
24
  exports.resolved = resolved;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OnDisposeModule = exports.onScopeDisposed = exports.onScopeDisposedHooksRunner = void 0;
4
+ const hook_1 = require("./hook");
5
+ const HooksRunner_1 = require("./HooksRunner");
6
+ exports.onScopeDisposedHooksRunner = new HooksRunner_1.HooksRunner('onScopeDisposed');
7
+ const onScopeDisposed = (...fns) => (0, hook_1.hook)('onScopeDisposed', (0, hook_1.prependHooks)(...fns));
8
+ exports.onScopeDisposed = onScopeDisposed;
9
+ class OnDisposeModule {
10
+ onException;
11
+ constructor(onException) {
12
+ this.onException = onException;
13
+ }
14
+ applyTo(container) {
15
+ container.onScopeDisposed((scope) => {
16
+ for (const instance of scope.getInstances()) {
17
+ (0, HooksRunner_1.runHooks)(exports.onScopeDisposedHooksRunner, instance, scope, this.onException);
18
+ }
19
+ });
20
+ }
21
+ }
22
+ exports.OnDisposeModule = OnDisposeModule;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeHooksAsync = exports.executeHooks = exports.forEachResolvedObject = exports.onceResolvedHook = exports.resolvedHook = exports.invokeMethod = void 0;
3
+ exports.executeHooks = exports.forEachResolvedObject = exports.onceResolvedHook = exports.resolvedHook = exports.invokeMethod = void 0;
4
+ const HooksRunner_1 = require("./HooksRunner");
4
5
  const hook_1 = require("./hook");
5
6
  const basic_1 = require("../utils/basic");
6
7
  const invokeMethod = (context) => {
@@ -28,17 +29,5 @@ const forEachResolvedObject = (run) => (dependency, scope) => {
28
29
  }
29
30
  };
30
31
  exports.forEachResolvedObject = forEachResolvedObject;
31
- const executeHooks = (runner) => (dependency, scope) => runner.execute(dependency, { scope });
32
+ const executeHooks = (runner, onException) => (dependency, scope) => (0, HooksRunner_1.runHooks)(runner, dependency, scope, onException);
32
33
  exports.executeHooks = executeHooks;
33
- const executeHooksAsync = (runner, onException) => (dependency, scope) => {
34
- if (!runner.hasHooks(dependency)) {
35
- return;
36
- }
37
- runner.executeAsync(dependency, { scope }).catch((ex) => {
38
- if (!onException) {
39
- throw ex;
40
- }
41
- onException(ex, { scope });
42
- });
43
- };
44
- exports.executeHooksAsync = executeHooksAsync;
package/cjm/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createHookContextFactory = exports.HookContext = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnsupportedTokenTypeError = exports.CannonSingletonApplyTwiceError = exports.UnexpectedHookResultError = exports.ProviderDisposedError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.ContainerNotFoundError = exports.DependencyNotFoundError = exports.ContainerError = exports.Registration = exports.onResolve = exports.appendArgsFn = exports.appendArgs = exports.decorate = exports.singleton = exports.autoResolve = exports.lazy = exports.scopeAccess = exports.scope = exports.bindTo = exports.register = exports.toRegistrationFn = exports.toProviderFn = exports.toBindToken = exports.registerPipe = exports.isProviderPipe = exports.Provider = exports.ProxyInjector = exports.SimpleInjector = exports.resolveArgs = exports.argsFn = exports.args = exports.arg = exports.inject = exports.MetadataInjector = exports.Injector = exports.EmptyContainer = exports.AutoResolveModule = exports.Container = exports.isDependencyKey = void 0;
4
- exports.addMethodMeta = exports.getParamTags = exports.addParamTag = exports.getParamLabels = exports.addParamLabel = exports.getParamMeta = exports.addParamMeta = exports.getClassTags = exports.addClassTag = exports.getClassLabels = exports.addClassLabel = exports.getClassMeta = exports.addClassMeta = exports.resolveConstructor = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken = exports.SingleToken = exports.ClassToken = exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.argToToken = exports.toMappedToken = exports.toToken = exports.InjectionToken = exports.HooksRunner = exports.invokeMethod = exports.resolvedAsync = exports.OnResolvedAsyncModule = exports.onceResolvedAsync = exports.onResolvedAsync = exports.onResolvedAsyncHooksRunner = exports.resolved = exports.OnResolvedModule = exports.onceResolved = exports.onResolved = exports.onResolvedHooksRunner = exports.OnDisposeModule = exports.onContainerDisposed = exports.onContainerDisposedHooksRunner = exports.OnConstructAsyncModule = exports.onConstructAsync = exports.onConstructAsyncHooksRunner = exports.OnConstructModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = exports.createHookContext = void 0;
5
- exports.Is = exports.unwrapProxy = exports.ProxyRegistry = exports.pipe = exports.select = exports.once = exports.shallowCache = exports.debounce = exports.throttle = exports.handleAsyncError = exports.handleError = exports.getMethodTags = exports.addMethodTag = exports.getMethodLabels = exports.addMethodLabel = exports.getMethodMeta = void 0;
3
+ exports.createHookContext = exports.createHookContextFactory = exports.HookContext = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnsupportedTokenTypeError = exports.CannonSingletonApplyTwiceError = exports.ProviderDisposedError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.ContainerNotFoundError = exports.DependencyNotFoundError = exports.ContainerError = exports.Registration = exports.onResolve = exports.appendArgsFn = exports.appendArgs = exports.decorate = exports.singleton = exports.autoResolve = exports.lazy = exports.scopeAccess = exports.scope = exports.bindTo = exports.register = exports.toRegistrationFn = exports.toProviderFn = exports.toBindToken = exports.registerPipe = exports.isProviderPipe = exports.Provider = exports.ProxyInjector = exports.SimpleInjector = exports.resolveArgs = exports.argsFn = exports.args = exports.arg = exports.inject = exports.MetadataInjector = exports.Injector = exports.EmptyContainer = exports.AutoResolveModule = exports.Container = exports.isDependencyKey = void 0;
4
+ exports.throttle = exports.handleAsyncError = exports.handleError = exports.getMethodTags = exports.addMethodTag = exports.getMethodLabels = exports.addMethodLabel = exports.getMethodMeta = exports.addMethodMeta = exports.getParamTags = exports.addParamTag = exports.getParamLabels = exports.addParamLabel = exports.getParamMeta = exports.addParamMeta = exports.getClassTags = exports.addClassTag = exports.getClassLabels = exports.addClassLabel = exports.getClassMeta = exports.addClassMeta = exports.resolveConstructor = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken = exports.SingleToken = exports.ClassToken = exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.argToToken = exports.toMappedToken = exports.toToken = exports.InjectionToken = exports.runHooks = exports.HooksRunner = exports.invokeMethod = exports.resolved = exports.OnResolvedModule = exports.onceResolved = exports.onResolved = exports.onResolvedHooksRunner = exports.OnDisposeModule = exports.onScopeDisposed = exports.onScopeDisposedHooksRunner = exports.OnConstructModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = void 0;
5
+ exports.Is = exports.unwrapProxy = exports.ProxyRegistry = exports.pipe = exports.select = exports.once = exports.shallowCache = exports.debounce = void 0;
6
6
  var IContainer_1 = require("./container/IContainer");
7
7
  Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
8
8
  var Container_1 = require("./container/Container");
@@ -59,8 +59,6 @@ var ContainerDisposedError_1 = require("./errors/ContainerDisposedError");
59
59
  Object.defineProperty(exports, "ContainerDisposedError", { enumerable: true, get: function () { return ContainerDisposedError_1.ContainerDisposedError; } });
60
60
  var ProviderDisposedError_1 = require("./errors/ProviderDisposedError");
61
61
  Object.defineProperty(exports, "ProviderDisposedError", { enumerable: true, get: function () { return ProviderDisposedError_1.ProviderDisposedError; } });
62
- var UnexpectedHookResultError_1 = require("./errors/UnexpectedHookResultError");
63
- Object.defineProperty(exports, "UnexpectedHookResultError", { enumerable: true, get: function () { return UnexpectedHookResultError_1.UnexpectedHookResultError; } });
64
62
  var CannonSingletonApplyTwiceError_1 = require("./errors/CannonSingletonApplyTwiceError");
65
63
  Object.defineProperty(exports, "CannonSingletonApplyTwiceError", { enumerable: true, get: function () { return CannonSingletonApplyTwiceError_1.CannonSingletonApplyTwiceError; } });
66
64
  var UnsupportedTokenTypeError_1 = require("./errors/UnsupportedTokenTypeError");
@@ -83,30 +81,21 @@ var onConstruct_1 = require("./hooks/onConstruct");
83
81
  Object.defineProperty(exports, "onConstructHooksRunner", { enumerable: true, get: function () { return onConstruct_1.onConstructHooksRunner; } });
84
82
  Object.defineProperty(exports, "onConstruct", { enumerable: true, get: function () { return onConstruct_1.onConstruct; } });
85
83
  Object.defineProperty(exports, "OnConstructModule", { enumerable: true, get: function () { return onConstruct_1.OnConstructModule; } });
86
- var onConstructAsync_1 = require("./hooks/onConstructAsync");
87
- Object.defineProperty(exports, "onConstructAsyncHooksRunner", { enumerable: true, get: function () { return onConstructAsync_1.onConstructAsyncHooksRunner; } });
88
- Object.defineProperty(exports, "onConstructAsync", { enumerable: true, get: function () { return onConstructAsync_1.onConstructAsync; } });
89
- Object.defineProperty(exports, "OnConstructAsyncModule", { enumerable: true, get: function () { return onConstructAsync_1.OnConstructAsyncModule; } });
90
- var onContainerDisposed_1 = require("./hooks/onContainerDisposed");
91
- Object.defineProperty(exports, "onContainerDisposedHooksRunner", { enumerable: true, get: function () { return onContainerDisposed_1.onContainerDisposedHooksRunner; } });
92
- Object.defineProperty(exports, "onContainerDisposed", { enumerable: true, get: function () { return onContainerDisposed_1.onContainerDisposed; } });
93
- Object.defineProperty(exports, "OnDisposeModule", { enumerable: true, get: function () { return onContainerDisposed_1.OnDisposeModule; } });
84
+ var onScopeDisposed_1 = require("./hooks/onScopeDisposed");
85
+ Object.defineProperty(exports, "onScopeDisposedHooksRunner", { enumerable: true, get: function () { return onScopeDisposed_1.onScopeDisposedHooksRunner; } });
86
+ Object.defineProperty(exports, "onScopeDisposed", { enumerable: true, get: function () { return onScopeDisposed_1.onScopeDisposed; } });
87
+ Object.defineProperty(exports, "OnDisposeModule", { enumerable: true, get: function () { return onScopeDisposed_1.OnDisposeModule; } });
94
88
  var onResolved_1 = require("./hooks/onResolved");
95
89
  Object.defineProperty(exports, "onResolvedHooksRunner", { enumerable: true, get: function () { return onResolved_1.onResolvedHooksRunner; } });
96
90
  Object.defineProperty(exports, "onResolved", { enumerable: true, get: function () { return onResolved_1.onResolved; } });
97
91
  Object.defineProperty(exports, "onceResolved", { enumerable: true, get: function () { return onResolved_1.onceResolved; } });
98
92
  Object.defineProperty(exports, "OnResolvedModule", { enumerable: true, get: function () { return onResolved_1.OnResolvedModule; } });
99
93
  Object.defineProperty(exports, "resolved", { enumerable: true, get: function () { return onResolved_1.resolved; } });
100
- var onResolvedAsync_1 = require("./hooks/onResolvedAsync");
101
- Object.defineProperty(exports, "onResolvedAsyncHooksRunner", { enumerable: true, get: function () { return onResolvedAsync_1.onResolvedAsyncHooksRunner; } });
102
- Object.defineProperty(exports, "onResolvedAsync", { enumerable: true, get: function () { return onResolvedAsync_1.onResolvedAsync; } });
103
- Object.defineProperty(exports, "onceResolvedAsync", { enumerable: true, get: function () { return onResolvedAsync_1.onceResolvedAsync; } });
104
- Object.defineProperty(exports, "OnResolvedAsyncModule", { enumerable: true, get: function () { return onResolvedAsync_1.OnResolvedAsyncModule; } });
105
- Object.defineProperty(exports, "resolvedAsync", { enumerable: true, get: function () { return onResolvedAsync_1.resolvedAsync; } });
106
94
  var resolveHooks_1 = require("./hooks/resolveHooks");
107
95
  Object.defineProperty(exports, "invokeMethod", { enumerable: true, get: function () { return resolveHooks_1.invokeMethod; } });
108
96
  var HooksRunner_1 = require("./hooks/HooksRunner");
109
97
  Object.defineProperty(exports, "HooksRunner", { enumerable: true, get: function () { return HooksRunner_1.HooksRunner; } });
98
+ Object.defineProperty(exports, "runHooks", { enumerable: true, get: function () { return HooksRunner_1.runHooks; } });
110
99
  var InjectionToken_1 = require("./token/InjectionToken");
111
100
  Object.defineProperty(exports, "InjectionToken", { enumerable: true, get: function () { return InjectionToken_1.InjectionToken; } });
112
101
  var toToken_1 = require("./token/toToken");
@@ -1,7 +1,13 @@
1
1
  import { createHookContext } from './HookContext.js';
2
2
  import { getHooks, hasHooks, toHookFn } from './hook.js';
3
- import { UnexpectedHookResultError } from '../errors/UnexpectedHookResultError.js';
4
- import { promisify } from '../utils/promise.js';
3
+ const runFrom = (fns, index, context) => {
4
+ for (let i = index; i < fns.length; i++) {
5
+ const result = fns[i](context);
6
+ if (result instanceof Promise) {
7
+ return result.then(() => runFrom(fns, i + 1, context));
8
+ }
9
+ }
10
+ };
5
11
  export class HooksRunner {
6
12
  key;
7
13
  constructor(key) {
@@ -12,27 +18,28 @@ export class HooksRunner {
12
18
  }
13
19
  execute(target, { scope, createContext = createHookContext, mapContext = (context) => context, predicate = () => true, }) {
14
20
  const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
15
- const runMethodHooks = (methodName, executions) => {
16
- const context = mapContext(createContext(target, scope, methodName));
17
- for (const execute of executions) {
18
- const result = execute(context);
19
- if (result instanceof Promise) {
20
- throw new UnexpectedHookResultError(`Hook ${methodName} returned a promise, use runHooksAsync instead`);
21
- }
22
- }
23
- };
21
+ const pending = [];
24
22
  for (const [methodName, executions] of hooks) {
25
- runMethodHooks(methodName, executions.map(toHookFn));
26
- }
27
- }
28
- async executeAsync(target, { scope, createContext = createHookContext, mapContext = (context) => context, predicate = () => true, }) {
29
- const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
30
- const runMethodHooks = async (methodName, executions) => {
31
23
  const context = mapContext(createContext(target, scope, methodName));
32
- for (const execute of executions) {
33
- await promisify(execute(context));
24
+ const result = runFrom(executions.map(toHookFn), 0, context);
25
+ if (result) {
26
+ pending.push(result);
34
27
  }
35
- };
36
- return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(toHookFn))));
28
+ }
29
+ return pending.length > 0 ? Promise.all(pending).then(() => undefined) : undefined;
37
30
  }
38
31
  }
32
+ export const runHooks = (runner, target, scope, onException) => {
33
+ const report = (ex) => {
34
+ if (!onException) {
35
+ throw ex;
36
+ }
37
+ onException(ex, { scope });
38
+ };
39
+ try {
40
+ runner.execute(target, { scope })?.catch(report);
41
+ }
42
+ catch (ex) {
43
+ report(ex);
44
+ }
45
+ };
@@ -1,5 +1,5 @@
1
1
  import { hook, prependHooks } from './hook.js';
2
- import { HooksRunner } from './HooksRunner.js';
2
+ import { HooksRunner, runHooks } from './HooksRunner.js';
3
3
  export const onConstructHooksRunner = new HooksRunner('onConstruct');
4
4
  export const onConstruct = (...fns) => hook('onConstruct', prependHooks(...fns));
5
5
  export class OnConstructModule {
@@ -9,15 +9,7 @@ export class OnConstructModule {
9
9
  }
10
10
  applyTo(injector) {
11
11
  injector.onConstructed((instance, scope) => {
12
- try {
13
- onConstructHooksRunner.execute(instance, { scope });
14
- }
15
- catch (ex) {
16
- if (!this.onException) {
17
- throw ex;
18
- }
19
- this.onException(ex, { scope });
20
- }
12
+ runHooks(onConstructHooksRunner, instance, scope, this.onException);
21
13
  });
22
14
  }
23
15
  }
@@ -4,12 +4,16 @@ import { executeHooks, forEachResolvedObject, onceResolvedHook, resolvedHook } f
4
4
  export const onResolvedHooksRunner = new HooksRunner('onResolved');
5
5
  export const onResolved = resolvedHook('onResolved');
6
6
  export const onceResolved = onceResolvedHook('onResolved');
7
- const runHooks = forEachResolvedObject(executeHooks(onResolvedHooksRunner));
7
+ const runHooks = (onException) => forEachResolvedObject(executeHooks(onResolvedHooksRunner, onException));
8
8
  export class OnResolvedModule {
9
+ runHooks;
10
+ constructor(onException) {
11
+ this.runHooks = runHooks(onException);
12
+ }
9
13
  applyTo(container) {
10
14
  container.onRegistered((provider) => {
11
- provider.onResolved(runHooks);
15
+ provider.onResolved(this.runHooks);
12
16
  });
13
17
  }
14
18
  }
15
- export const resolved = () => registerPipe((p) => p.onResolved(runHooks));
19
+ export const resolved = (onException) => registerPipe((p) => p.onResolved(runHooks(onException)));
@@ -0,0 +1,17 @@
1
+ import { hook, prependHooks } from './hook.js';
2
+ import { HooksRunner, runHooks } from './HooksRunner.js';
3
+ export const onScopeDisposedHooksRunner = new HooksRunner('onScopeDisposed');
4
+ export const onScopeDisposed = (...fns) => hook('onScopeDisposed', prependHooks(...fns));
5
+ export class OnDisposeModule {
6
+ onException;
7
+ constructor(onException) {
8
+ this.onException = onException;
9
+ }
10
+ applyTo(container) {
11
+ container.onScopeDisposed((scope) => {
12
+ for (const instance of scope.getInstances()) {
13
+ runHooks(onScopeDisposedHooksRunner, instance, scope, this.onException);
14
+ }
15
+ });
16
+ }
17
+ }
@@ -1,3 +1,4 @@
1
+ import { runHooks } from './HooksRunner.js';
1
2
  import { hook, prependHooks, toHookFn } from './hook.js';
2
3
  import { Is } from '../utils/basic.js';
3
4
  export const invokeMethod = (context) => {
@@ -21,15 +22,4 @@ export const forEachResolvedObject = (run) => (dependency, scope) => {
21
22
  run(dependency, scope);
22
23
  }
23
24
  };
24
- export const executeHooks = (runner) => (dependency, scope) => runner.execute(dependency, { scope });
25
- export const executeHooksAsync = (runner, onException) => (dependency, scope) => {
26
- if (!runner.hasHooks(dependency)) {
27
- return;
28
- }
29
- runner.executeAsync(dependency, { scope }).catch((ex) => {
30
- if (!onException) {
31
- throw ex;
32
- }
33
- onException(ex, { scope });
34
- });
35
- };
25
+ export const executeHooks = (runner, onException) => (dependency, scope) => runHooks(runner, dependency, scope, onException);
package/esm/index.js CHANGED
@@ -16,19 +16,16 @@ export { DependencyMissingKeyError } from './errors/DependencyMissingKeyError.js
16
16
  export { MethodNotImplementedError } from './errors/MethodNotImplementedError.js';
17
17
  export { ContainerDisposedError } from './errors/ContainerDisposedError.js';
18
18
  export { ProviderDisposedError } from './errors/ProviderDisposedError.js';
19
- export { UnexpectedHookResultError } from './errors/UnexpectedHookResultError.js';
20
19
  export { CannonSingletonApplyTwiceError } from './errors/CannonSingletonApplyTwiceError.js';
21
20
  export { UnsupportedTokenTypeError } from './errors/UnsupportedTokenTypeError.js';
22
21
  export { getHooks, hook, hasHooks, appendHooks, prependHooks, append, prepend, } from './hooks/hook.js';
23
22
  export { HookContext, createHookContextFactory, createHookContext } from './hooks/HookContext.js';
24
23
  export { injectProp } from './hooks/injectProp.js';
25
24
  export { onConstructHooksRunner, onConstruct, OnConstructModule } from './hooks/onConstruct.js';
26
- export { onConstructAsyncHooksRunner, onConstructAsync, OnConstructAsyncModule } from './hooks/onConstructAsync.js';
27
- export { onContainerDisposedHooksRunner, onContainerDisposed, OnDisposeModule } from './hooks/onContainerDisposed.js';
25
+ export { onScopeDisposedHooksRunner, onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
28
26
  export { onResolvedHooksRunner, onResolved, onceResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
29
- export { onResolvedAsyncHooksRunner, onResolvedAsync, onceResolvedAsync, OnResolvedAsyncModule, resolvedAsync, } from './hooks/onResolvedAsync.js';
30
27
  export { invokeMethod } from './hooks/resolveHooks.js';
31
- export { HooksRunner } from './hooks/HooksRunner.js';
28
+ export { HooksRunner, runHooks, } from './hooks/HooksRunner.js';
32
29
  export { InjectionToken } from './token/InjectionToken.js';
33
30
  export { toToken, toMappedToken, argToToken } from './token/toToken.js';
34
31
  export { GroupAliasToken, toGroupAlias } from './token/GroupAliasToken.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "61.0.0",
3
+ "version": "62.0.0",
4
4
  "description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -1,7 +1,9 @@
1
1
  import { type CreateHookContext, type IHookContext } from './HookContext.js';
2
2
  import type { IContainer } from '../container/IContainer.js';
3
3
  import { type Instance } from '../utils/basic.js';
4
+ import type { ExecutionContext } from '../ExecutionContext.js';
4
5
  export type MapHookContext = (context: IHookContext) => IHookContext;
6
+ export type OnExceptionHandler = (ex: unknown, context: ExecutionContext) => void;
5
7
  export type HooksRunnerContext = {
6
8
  scope: IContainer;
7
9
  createContext?: CreateHookContext;
@@ -12,6 +14,6 @@ export declare class HooksRunner {
12
14
  private readonly key;
13
15
  constructor(key: string | symbol);
14
16
  hasHooks(target: Instance): boolean;
15
- execute(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): void;
16
- executeAsync(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): Promise<void[]>;
17
+ execute(target: Instance, { scope, createContext, mapContext, predicate, }: HooksRunnerContext): void | Promise<void>;
17
18
  }
19
+ export declare const runHooks: (runner: HooksRunner, target: Instance, scope: IContainer, onException?: OnExceptionHandler) => void;
@@ -1,10 +1,8 @@
1
1
  import { HookType } from './hook.js';
2
2
  import type { IInjector, IInjectorModule } from '../injector/IInjector.js';
3
- import { HooksRunner } from './HooksRunner.js';
4
- import type { ExecutionContext } from '../ExecutionContext.js';
3
+ import { HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
5
4
  export declare const onConstructHooksRunner: HooksRunner;
6
5
  export declare const onConstruct: (...fns: HookType[]) => (target: object, propertyKey: string | symbol) => void;
7
- export type OnExceptionHandler = (ex: unknown, context: ExecutionContext) => void;
8
6
  export declare class OnConstructModule implements IInjectorModule {
9
7
  private readonly onException?;
10
8
  constructor(onException?: OnExceptionHandler | undefined);
@@ -1,9 +1,11 @@
1
1
  import type { IContainer, IContainerModule } from '../container/IContainer.js';
2
- import { HooksRunner } from './HooksRunner.js';
2
+ import { HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
3
3
  export declare const onResolvedHooksRunner: HooksRunner;
4
4
  export declare const onResolved: (...hooks: import("./hook.js").HookType[]) => (target: object, propertyKey: string | symbol) => void;
5
5
  export declare const onceResolved: (...hooks: import("./hook.js").HookType[]) => (target: object, propertyKey: string | symbol) => void;
6
6
  export declare class OnResolvedModule implements IContainerModule {
7
+ private readonly runHooks;
8
+ constructor(onException?: OnExceptionHandler);
7
9
  applyTo(container: IContainer): void;
8
10
  }
9
- export declare const resolved: <T = unknown>() => import("../registration/IRegistration.js").ProviderPipe<T>;
11
+ export declare const resolved: <T = unknown>(onException?: OnExceptionHandler) => import("../registration/IRegistration.js").ProviderPipe<T>;
@@ -0,0 +1,10 @@
1
+ import { HookType } from './hook.js';
2
+ import type { IContainer, IContainerModule } from '../container/IContainer.js';
3
+ import { HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
4
+ export declare const onScopeDisposedHooksRunner: HooksRunner;
5
+ export declare const onScopeDisposed: (...fns: HookType[]) => (target: object, propertyKey: string | symbol) => void;
6
+ export declare class OnDisposeModule implements IContainerModule {
7
+ private readonly onException?;
8
+ constructor(onException?: OnExceptionHandler | undefined);
9
+ applyTo(container: IContainer): void;
10
+ }
@@ -1,12 +1,10 @@
1
1
  import type { IContainer } from '../container/IContainer.js';
2
2
  import type { ProviderHook } from '../provider/IProvider.js';
3
- import type { HooksRunner } from './HooksRunner.js';
3
+ import { type HooksRunner, type OnExceptionHandler } from './HooksRunner.js';
4
4
  import { type HookFn, type HookType } from './hook.js';
5
- import type { OnExceptionHandler } from './onConstruct.js';
6
5
  export type ResolvedObjectHook = (dependency: object, scope: IContainer) => void;
7
6
  export declare const invokeMethod: HookFn;
8
7
  export declare const resolvedHook: (key: string) => (...hooks: HookType[]) => (target: object, propertyKey: string | symbol) => void;
9
8
  export declare const onceResolvedHook: (key: string) => (...hooks: HookType[]) => (target: object, propertyKey: string | symbol) => void;
10
9
  export declare const forEachResolvedObject: (run: ResolvedObjectHook) => ProviderHook;
11
- export declare const executeHooks: (runner: HooksRunner) => ResolvedObjectHook;
12
- export declare const executeHooksAsync: (runner: HooksRunner, onException?: OnExceptionHandler) => ResolvedObjectHook;
10
+ export declare const executeHooks: (runner: HooksRunner, onException?: OnExceptionHandler) => ResolvedObjectHook;
@@ -17,19 +17,16 @@ export { DependencyMissingKeyError } from './errors/DependencyMissingKeyError.js
17
17
  export { MethodNotImplementedError } from './errors/MethodNotImplementedError.js';
18
18
  export { ContainerDisposedError } from './errors/ContainerDisposedError.js';
19
19
  export { ProviderDisposedError } from './errors/ProviderDisposedError.js';
20
- export { UnexpectedHookResultError } from './errors/UnexpectedHookResultError.js';
21
20
  export { CannonSingletonApplyTwiceError } from './errors/CannonSingletonApplyTwiceError.js';
22
21
  export { UnsupportedTokenTypeError } from './errors/UnsupportedTokenTypeError.js';
23
22
  export { getHooks, hook, hasHooks, appendHooks, prependHooks, append, prepend, type HookFn, type HookClass, type HookType, type MapHooksFn, type InjectFn, type HooksOfClass, } from './hooks/hook.js';
24
23
  export { HookContext, createHookContextFactory, createHookContext, type IHookContext } from './hooks/HookContext.js';
25
24
  export { injectProp } from './hooks/injectProp.js';
26
- export { onConstructHooksRunner, onConstruct, OnConstructModule, type OnExceptionHandler } from './hooks/onConstruct.js';
27
- export { onConstructAsyncHooksRunner, onConstructAsync, OnConstructAsyncModule } from './hooks/onConstructAsync.js';
28
- export { onContainerDisposedHooksRunner, onContainerDisposed, OnDisposeModule } from './hooks/onContainerDisposed.js';
25
+ export { onConstructHooksRunner, onConstruct, OnConstructModule } from './hooks/onConstruct.js';
26
+ export { onScopeDisposedHooksRunner, onScopeDisposed, OnDisposeModule } from './hooks/onScopeDisposed.js';
29
27
  export { onResolvedHooksRunner, onResolved, onceResolved, OnResolvedModule, resolved } from './hooks/onResolved.js';
30
- export { onResolvedAsyncHooksRunner, onResolvedAsync, onceResolvedAsync, OnResolvedAsyncModule, resolvedAsync, } from './hooks/onResolvedAsync.js';
31
28
  export { invokeMethod, type ResolvedObjectHook } from './hooks/resolveHooks.js';
32
- export { HooksRunner, type HooksRunnerContext, type MapHookContext } from './hooks/HooksRunner.js';
29
+ export { HooksRunner, runHooks, type HooksRunnerContext, type MapHookContext, type OnExceptionHandler, } from './hooks/HooksRunner.js';
33
30
  export { InjectionToken } from './token/InjectionToken.js';
34
31
  export { type Injectable, toToken, toMappedToken, argToToken } from './token/toToken.js';
35
32
  export { GroupAliasToken, toGroupAlias } from './token/GroupAliasToken.js';
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UnexpectedHookResultError = void 0;
4
- const ContainerError_1 = require("./ContainerError");
5
- class UnexpectedHookResultError extends ContainerError_1.ContainerError {
6
- name = 'UnexpectedHookResultError';
7
- constructor(message) {
8
- super(message);
9
- Object.setPrototypeOf(this, UnexpectedHookResultError.prototype);
10
- }
11
- }
12
- exports.UnexpectedHookResultError = UnexpectedHookResultError;
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OnConstructAsyncModule = exports.onConstructAsync = exports.onConstructAsyncHooksRunner = void 0;
4
- const hook_1 = require("./hook");
5
- const HooksRunner_1 = require("./HooksRunner");
6
- exports.onConstructAsyncHooksRunner = new HooksRunner_1.HooksRunner('onConstructAsync');
7
- const onConstructAsync = (...fns) => (0, hook_1.hook)('onConstructAsync', (0, hook_1.prependHooks)(...fns));
8
- exports.onConstructAsync = onConstructAsync;
9
- class OnConstructAsyncModule {
10
- onException;
11
- constructor(onException) {
12
- this.onException = onException;
13
- }
14
- applyTo(injector) {
15
- injector.onConstructed((instance, scope) => {
16
- if (!exports.onConstructAsyncHooksRunner.hasHooks(instance)) {
17
- return;
18
- }
19
- exports.onConstructAsyncHooksRunner.executeAsync(instance, { scope }).catch((ex) => {
20
- if (!this.onException) {
21
- throw ex;
22
- }
23
- this.onException(ex, { scope });
24
- });
25
- });
26
- }
27
- }
28
- exports.OnConstructAsyncModule = OnConstructAsyncModule;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OnDisposeModule = exports.onContainerDisposed = exports.onContainerDisposedHooksRunner = void 0;
4
- const hook_1 = require("./hook");
5
- const HooksRunner_1 = require("./HooksRunner");
6
- exports.onContainerDisposedHooksRunner = new HooksRunner_1.HooksRunner('onContainerDisposed');
7
- const onContainerDisposed = (...fns) => (0, hook_1.hook)('onContainerDisposed', (0, hook_1.prependHooks)(...fns));
8
- exports.onContainerDisposed = onContainerDisposed;
9
- class OnDisposeModule {
10
- applyTo(container) {
11
- container.onScopeDisposed((scope) => {
12
- for (const instance of scope.getInstances()) {
13
- exports.onContainerDisposedHooksRunner.execute(instance, { scope });
14
- }
15
- });
16
- }
17
- }
18
- exports.OnDisposeModule = OnDisposeModule;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolvedAsync = exports.OnResolvedAsyncModule = exports.onceResolvedAsync = exports.onResolvedAsync = exports.onResolvedAsyncHooksRunner = void 0;
4
- const HooksRunner_1 = require("./HooksRunner");
5
- const IRegistration_1 = require("../registration/IRegistration");
6
- const resolveHooks_1 = require("./resolveHooks");
7
- exports.onResolvedAsyncHooksRunner = new HooksRunner_1.HooksRunner('onResolvedAsync');
8
- exports.onResolvedAsync = (0, resolveHooks_1.resolvedHook)('onResolvedAsync');
9
- exports.onceResolvedAsync = (0, resolveHooks_1.onceResolvedHook)('onResolvedAsync');
10
- const runHooks = (onException) => (0, resolveHooks_1.forEachResolvedObject)((0, resolveHooks_1.executeHooksAsync)(exports.onResolvedAsyncHooksRunner, onException));
11
- class OnResolvedAsyncModule {
12
- runHooks;
13
- constructor(onException) {
14
- this.runHooks = runHooks(onException);
15
- }
16
- applyTo(container) {
17
- container.onRegistered((provider) => {
18
- provider.onResolved(this.runHooks);
19
- });
20
- }
21
- }
22
- exports.OnResolvedAsyncModule = OnResolvedAsyncModule;
23
- const resolvedAsync = (onException) => (0, IRegistration_1.registerPipe)((p) => p.onResolved(runHooks(onException)));
24
- exports.resolvedAsync = resolvedAsync;
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.promisify = void 0;
4
- const promisify = (arg) => (arg instanceof Promise ? arg : Promise.resolve(arg));
5
- exports.promisify = promisify;
@@ -1,8 +0,0 @@
1
- import { ContainerError } from './ContainerError.js';
2
- export class UnexpectedHookResultError extends ContainerError {
3
- name = 'UnexpectedHookResultError';
4
- constructor(message) {
5
- super(message);
6
- Object.setPrototypeOf(this, UnexpectedHookResultError.prototype);
7
- }
8
- }
@@ -1,23 +0,0 @@
1
- import { hook, prependHooks } from './hook.js';
2
- import { HooksRunner } from './HooksRunner.js';
3
- export const onConstructAsyncHooksRunner = new HooksRunner('onConstructAsync');
4
- export const onConstructAsync = (...fns) => hook('onConstructAsync', prependHooks(...fns));
5
- export class OnConstructAsyncModule {
6
- onException;
7
- constructor(onException) {
8
- this.onException = onException;
9
- }
10
- applyTo(injector) {
11
- injector.onConstructed((instance, scope) => {
12
- if (!onConstructAsyncHooksRunner.hasHooks(instance)) {
13
- return;
14
- }
15
- onConstructAsyncHooksRunner.executeAsync(instance, { scope }).catch((ex) => {
16
- if (!this.onException) {
17
- throw ex;
18
- }
19
- this.onException(ex, { scope });
20
- });
21
- });
22
- }
23
- }
@@ -1,13 +0,0 @@
1
- import { hook, prependHooks } from './hook.js';
2
- import { HooksRunner } from './HooksRunner.js';
3
- export const onContainerDisposedHooksRunner = new HooksRunner('onContainerDisposed');
4
- export const onContainerDisposed = (...fns) => hook('onContainerDisposed', prependHooks(...fns));
5
- export class OnDisposeModule {
6
- applyTo(container) {
7
- container.onScopeDisposed((scope) => {
8
- for (const instance of scope.getInstances()) {
9
- onContainerDisposedHooksRunner.execute(instance, { scope });
10
- }
11
- });
12
- }
13
- }
@@ -1,19 +0,0 @@
1
- import { HooksRunner } from './HooksRunner.js';
2
- import { registerPipe } from '../registration/IRegistration.js';
3
- import { executeHooksAsync, forEachResolvedObject, onceResolvedHook, resolvedHook } from './resolveHooks.js';
4
- export const onResolvedAsyncHooksRunner = new HooksRunner('onResolvedAsync');
5
- export const onResolvedAsync = resolvedHook('onResolvedAsync');
6
- export const onceResolvedAsync = onceResolvedHook('onResolvedAsync');
7
- const runHooks = (onException) => forEachResolvedObject(executeHooksAsync(onResolvedAsyncHooksRunner, onException));
8
- export class OnResolvedAsyncModule {
9
- runHooks;
10
- constructor(onException) {
11
- this.runHooks = runHooks(onException);
12
- }
13
- applyTo(container) {
14
- container.onRegistered((provider) => {
15
- provider.onResolved(this.runHooks);
16
- });
17
- }
18
- }
19
- export const resolvedAsync = (onException) => registerPipe((p) => p.onResolved(runHooks(onException)));
@@ -1 +0,0 @@
1
- export const promisify = (arg) => (arg instanceof Promise ? arg : Promise.resolve(arg));
@@ -1,5 +0,0 @@
1
- import { ContainerError } from './ContainerError.js';
2
- export declare class UnexpectedHookResultError extends ContainerError {
3
- name: string;
4
- constructor(message: string);
5
- }
@@ -1,11 +0,0 @@
1
- import { HookType } from './hook.js';
2
- import type { IInjector, IInjectorModule } from '../injector/IInjector.js';
3
- import { HooksRunner } from './HooksRunner.js';
4
- import type { OnExceptionHandler } from './onConstruct.js';
5
- export declare const onConstructAsyncHooksRunner: HooksRunner;
6
- export declare const onConstructAsync: (...fns: HookType[]) => (target: object, propertyKey: string | symbol) => void;
7
- export declare class OnConstructAsyncModule implements IInjectorModule {
8
- private readonly onException?;
9
- constructor(onException?: OnExceptionHandler | undefined);
10
- applyTo(injector: IInjector): void;
11
- }
@@ -1,8 +0,0 @@
1
- import { HookType } from './hook.js';
2
- import type { IContainer, IContainerModule } from '../container/IContainer.js';
3
- import { HooksRunner } from './HooksRunner.js';
4
- export declare const onContainerDisposedHooksRunner: HooksRunner;
5
- export declare const onContainerDisposed: (...fns: HookType[]) => (target: object, propertyKey: string | symbol) => void;
6
- export declare class OnDisposeModule implements IContainerModule {
7
- applyTo(container: IContainer): void;
8
- }
@@ -1,12 +0,0 @@
1
- import type { IContainer, IContainerModule } from '../container/IContainer.js';
2
- import { HooksRunner } from './HooksRunner.js';
3
- import type { OnExceptionHandler } from './onConstruct.js';
4
- export declare const onResolvedAsyncHooksRunner: HooksRunner;
5
- export declare const onResolvedAsync: (...hooks: import("./hook.js").HookType[]) => (target: object, propertyKey: string | symbol) => void;
6
- export declare const onceResolvedAsync: (...hooks: import("./hook.js").HookType[]) => (target: object, propertyKey: string | symbol) => void;
7
- export declare class OnResolvedAsyncModule implements IContainerModule {
8
- private readonly runHooks;
9
- constructor(onException?: OnExceptionHandler);
10
- applyTo(container: IContainer): void;
11
- }
12
- export declare const resolvedAsync: <T = unknown>(onException?: OnExceptionHandler) => import("../registration/IRegistration.js").ProviderPipe<T>;
@@ -1 +0,0 @@
1
- export declare const promisify: <T>(arg: T | Promise<T>) => Promise<T>;