ts-ioc-container 32.9.0 → 32.10.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 CHANGED
@@ -1289,11 +1289,13 @@ describe('inject property', () => {
1289
1289
  import { by, Container, executeHooks, hook, inject, invokeExecution, MetadataInjector, Registration } from 'ts-ioc-container';
1290
1290
 
1291
1291
  describe('inject method', () => {
1292
- it('should inject method', () => {
1292
+ const sleep = (number: number) => new Promise((resolve) => setTimeout(resolve, number));
1293
+
1294
+ it('should inject method', async () => {
1293
1295
  class App {
1294
1296
  greeting!: string;
1295
1297
 
1296
- @hook('onInit', invokeExecution({ handleError: jest.fn(), handleResult: jest.fn() }))
1298
+ @hook('onInit', invokeExecution({ handleResult: jest.fn() }))
1297
1299
  setGreeting(@inject(by.key('greeting')) greeting: string) {
1298
1300
  this.greeting = greeting;
1299
1301
  }
@@ -1302,10 +1304,30 @@ describe('inject method', () => {
1302
1304
 
1303
1305
  const container = new Container(new MetadataInjector()).add(Registration.fromValue(expected).to('greeting'));
1304
1306
  const app = container.resolve(App);
1305
- executeHooks(app, 'onInit', { scope: container });
1307
+ await executeHooks(app, 'onInit', { scope: container, handleError: jest.fn() });
1306
1308
 
1307
1309
  expect(app.greeting).toBe(expected);
1308
1310
  });
1311
+
1312
+ it('should inject method asyncronically', async () => {
1313
+ class App {
1314
+ greeting!: string;
1315
+
1316
+ @hook('onInit', invokeExecution({ handleResult: jest.fn() }))
1317
+ setGreeting(@inject(by.key('greeting')) greeting: string, @inject(by.key('person')) person: string) {
1318
+ this.greeting = `${greeting}${person}`;
1319
+ }
1320
+ }
1321
+
1322
+ const container = new Container(new MetadataInjector())
1323
+ .add(Registration.fromFn(() => sleep(50).then(() => 'Hello,')).to('greeting'))
1324
+ .add(Registration.fromFn(() => sleep(25).then(() => 'world')).to('person'));
1325
+
1326
+ const app = container.resolve(App);
1327
+ await executeHooks(app, 'onInit', { scope: container, handleError: jest.fn() });
1328
+
1329
+ expect(app.greeting).toBe('Hello,world');
1330
+ });
1309
1331
  });
1310
1332
 
1311
1333
  ```
package/cjm/hooks/hook.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.invokeExecution = exports.injectProp = exports.executeHooks = exports.hasHooks = exports.getHooks = exports.hook = void 0;
4
4
  const ExecutionContext_1 = require("./ExecutionContext");
5
- const MetadataInjector_1 = require("../injector/MetadataInjector");
5
+ const utils_1 = require("../utils");
6
6
  const hook = (key, ...fns) => (target, propertyKey) => {
7
7
  const hooks = Reflect.hasMetadata(key, target.constructor)
8
8
  ? Reflect.getMetadata(key, target.constructor)
@@ -19,24 +19,17 @@ function hasHooks(target, key) {
19
19
  return Reflect.hasMetadata(key, target.constructor);
20
20
  }
21
21
  exports.hasHooks = hasHooks;
22
- const executeHooks = (target, key, { scope, createContext = (c) => c, }) => {
23
- for (const [methodName, executions] of getHooks(target, key)) {
24
- for (const execute of executions) {
25
- execute(createContext(new ExecutionContext_1.ExecutionContext(target, methodName, scope)));
26
- }
27
- }
22
+ const executeHooks = (target, key, { scope, decorateContext = (c) => c, handleError, }) => {
23
+ const hooks = Array.from(getHooks(target, key).entries());
24
+ const createContext = (methodName) => decorateContext(new ExecutionContext_1.ExecutionContext(target, methodName, scope));
25
+ const runExecution = (execute, context) => (0, utils_1.promisify)(execute(context)).catch((e) => handleError(e, scope));
26
+ return Promise.all(hooks.flatMap(([methodName, executions]) => executions.map((execute) => runExecution(execute, createContext(methodName)))));
28
27
  };
29
28
  exports.executeHooks = executeHooks;
30
29
  const injectProp = (fn) => (context) => context.injectProperty(fn);
31
30
  exports.injectProp = injectProp;
32
- const invokeExecution = ({ handleError, handleResult, }) => (context) => {
33
- const args = (0, MetadataInjector_1.resolveArgs)(context.instance.constructor, context.methodName)(context.scope);
34
- try {
35
- const result = context.invokeMethod({ args });
36
- handleResult(result, context);
37
- }
38
- catch (e) {
39
- handleError(e, context.scope);
40
- }
31
+ const invokeExecution = ({ handleResult }) => async (context) => {
32
+ const args = await Promise.all(context.resolveArgs().map(utils_1.promisify));
33
+ return handleResult(context.invokeMethod({ args }), context);
41
34
  };
42
35
  exports.invokeExecution = invokeExecution;
package/cjm/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lazyProxy = exports.isConstructor = exports.constant = exports.fillEmptyIndexes = exports.pipe = void 0;
3
+ exports.promisify = exports.lazyProxy = exports.isConstructor = exports.constant = exports.fillEmptyIndexes = exports.pipe = void 0;
4
4
  const pipe = (...mappers) => (value) => mappers.reduce((acc, current) => current(acc), value);
5
5
  exports.pipe = pipe;
6
6
  function fillEmptyIndexes(baseArr, insertArr) {
@@ -29,3 +29,5 @@ function lazyProxy(resolveInstance) {
29
29
  });
30
30
  }
31
31
  exports.lazyProxy = lazyProxy;
32
+ const promisify = (arg) => (arg instanceof Promise ? arg : Promise.resolve(arg));
33
+ exports.promisify = promisify;
package/esm/hooks/hook.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ExecutionContext } from './ExecutionContext';
2
- import { resolveArgs } from '../injector/MetadataInjector';
2
+ import { promisify } from '../utils';
3
3
  export const hook = (key, ...fns) => (target, propertyKey) => {
4
4
  const hooks = Reflect.hasMetadata(key, target.constructor)
5
5
  ? Reflect.getMetadata(key, target.constructor)
@@ -13,21 +13,14 @@ export function getHooks(target, key) {
13
13
  export function hasHooks(target, key) {
14
14
  return Reflect.hasMetadata(key, target.constructor);
15
15
  }
16
- export const executeHooks = (target, key, { scope, createContext = (c) => c, }) => {
17
- for (const [methodName, executions] of getHooks(target, key)) {
18
- for (const execute of executions) {
19
- execute(createContext(new ExecutionContext(target, methodName, scope)));
20
- }
21
- }
16
+ export const executeHooks = (target, key, { scope, decorateContext = (c) => c, handleError, }) => {
17
+ const hooks = Array.from(getHooks(target, key).entries());
18
+ const createContext = (methodName) => decorateContext(new ExecutionContext(target, methodName, scope));
19
+ const runExecution = (execute, context) => promisify(execute(context)).catch((e) => handleError(e, scope));
20
+ return Promise.all(hooks.flatMap(([methodName, executions]) => executions.map((execute) => runExecution(execute, createContext(methodName)))));
22
21
  };
23
22
  export const injectProp = (fn) => (context) => context.injectProperty(fn);
24
- export const invokeExecution = ({ handleError, handleResult, }) => (context) => {
25
- const args = resolveArgs(context.instance.constructor, context.methodName)(context.scope);
26
- try {
27
- const result = context.invokeMethod({ args });
28
- handleResult(result, context);
29
- }
30
- catch (e) {
31
- handleError(e, context.scope);
32
- }
23
+ export const invokeExecution = ({ handleResult }) => async (context) => {
24
+ const args = await Promise.all(context.resolveArgs().map(promisify));
25
+ return handleResult(context.invokeMethod({ args }), context);
33
26
  };
package/esm/utils.js CHANGED
@@ -21,3 +21,4 @@ export function lazyProxy(resolveInstance) {
21
21
  },
22
22
  });
23
23
  }
24
+ export const promisify = (arg) => (arg instanceof Promise ? arg : Promise.resolve(arg));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "32.9.0",
3
+ "version": "32.10.0",
4
4
  "description": "Typescript IoC container",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -59,5 +59,5 @@
59
59
  "ts-node": "^10.9.1",
60
60
  "typescript": "5.4.3"
61
61
  },
62
- "gitHead": "17060847c051dbbdfd167675ec27af2ae78efbfe"
62
+ "gitHead": "1feb3be27939265fa91d93aabc3c08fd5c235c27"
63
63
  }
@@ -1,16 +1,20 @@
1
1
  import { IContainer } from '../container/IContainer';
2
2
  import { ExecutionContext } from './ExecutionContext';
3
3
  import { InjectFn } from '../injector/MetadataInjector';
4
- export type Execution<T extends ExecutionContext = ExecutionContext> = (context: T) => void;
5
- export declare const hook: (key: string | symbol, ...fns: Execution[]) => (target: object, propertyKey: string | symbol) => void;
6
- export declare function getHooks(target: object, key: string | symbol): Map<string, Execution[]>;
4
+ export type Execution<T extends ExecutionContext = ExecutionContext> = (context: T) => void | Promise<void>;
5
+ type HookList = Execution[];
6
+ type Hooks = Map<string, HookList>;
7
+ export declare const hook: (key: string | symbol, ...fns: HookList) => (target: object, propertyKey: string | symbol) => void;
8
+ export declare function getHooks(target: object, key: string | symbol): Hooks;
7
9
  export declare function hasHooks(target: object, key: string | symbol): boolean;
8
- export declare const executeHooks: <Context extends ExecutionContext>(target: object, key: string | symbol, { scope, createContext, }: {
10
+ export declare const executeHooks: <Context extends ExecutionContext>(target: object, key: string | symbol, { scope, decorateContext, handleError, }: {
9
11
  scope: IContainer;
10
- createContext?: ((c: ExecutionContext) => Context) | undefined;
11
- }) => void;
12
- export declare const injectProp: (fn: InjectFn) => Execution;
13
- export declare const invokeExecution: ({ handleError, handleResult, }: {
12
+ decorateContext?: ((c: ExecutionContext) => Context) | undefined;
14
13
  handleError: (e: Error, s: IContainer) => void;
15
- handleResult: (result: unknown, context: ExecutionContext) => void;
14
+ }) => Promise<any[]>;
15
+ export declare const injectProp: (fn: InjectFn) => Execution;
16
+ type HandleResult = (result: unknown, context: ExecutionContext) => void | Promise<void>;
17
+ export declare const invokeExecution: ({ handleResult }: {
18
+ handleResult: HandleResult;
16
19
  }) => Execution;
20
+ export {};
@@ -5,3 +5,4 @@ export declare function fillEmptyIndexes<T>(baseArr: (T | undefined)[], insertAr
5
5
  export declare const constant: <T>(value: T) => () => T;
6
6
  export declare const isConstructor: (T: unknown) => T is constructor<unknown>;
7
7
  export declare function lazyProxy<T>(resolveInstance: () => T): T;
8
+ export declare const promisify: (arg: unknown) => Promise<any>;