ts-ioc-container
Version:
Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.
36 lines (35 loc) • 1.82 kB
JavaScript
import { createHookContext } from './HookContext';
import { getHooks, toHookFn } from './hook';
import { UnexpectedHookResultError } from '../errors/UnexpectedHookResultError';
import { promisify } from '../utils/promise';
export class HooksRunner {
key;
constructor(key) {
this.key = key;
}
execute(target, { scope, createContext = createHookContext, mapContext = (context) => context, predicate = () => true, }) {
const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
const runMethodHooks = (methodName, executions) => {
const context = mapContext(createContext(target, scope, methodName));
for (const execute of executions) {
const result = execute(context);
if (result instanceof Promise) {
throw new UnexpectedHookResultError(`Hook ${methodName} returned a promise, use runHooksAsync instead`);
}
}
};
for (const [methodName, executions] of hooks) {
runMethodHooks(methodName, executions.map(toHookFn));
}
}
async executeAsync(target, { scope, createContext = createHookContext, mapContext = (context) => context, predicate = () => true, }) {
const hooks = Array.from(getHooks(target, this.key).entries()).filter(([methodName]) => predicate(methodName));
const runMethodHooks = async (methodName, executions) => {
const context = mapContext(createContext(target, scope, methodName));
for (const execute of executions) {
await promisify(execute(context));
}
};
return Promise.all(hooks.map(([methodName, executions]) => runMethodHooks(methodName, executions.map(toHookFn))));
}
}