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.
29 lines (28 loc) • 1.58 kB
JavaScript
import { SingleToken } from '../token/SingleToken';
import { isBindToken } from '../token/BindToken';
import { addClassMeta, getClassMeta } from '../metadata/class';
export const isProviderPipe = (obj) => obj !== null && typeof obj === 'object' && 'mapProvider' in obj;
export const registerPipe = (mapProvider) => ({
mapProvider,
mapRegistration: (r) => r.pipe(mapProvider),
});
const METADATA_KEY = 'registration';
export const getTransformers = (Target) => getClassMeta(Target, METADATA_KEY) ?? [];
export const register = (...mappers) => addClassMeta(METADATA_KEY, (acc) => {
const result = mappers.map((m) => isProviderPipe(m) ? (r) => m.mapRegistration(r) : m);
return acc ? [...result, ...acc] : result;
});
export const bindTo = (...tokens) => (r) => {
for (const token of tokens) {
const targetToken = isBindToken(token) ? token : new SingleToken(token);
targetToken.bindTo(r);
}
return r;
};
export const scope = (...rules) => (r) => r.when(...rules);
export const appendArgs = (...extraArgs) => registerPipe((p) => p.addArgsFn((_, { args = [] } = {}) => [...args, ...extraArgs]));
export const appendArgsFn = (fn) => registerPipe((p) => p.addArgsFn((scope, options) => [...(options?.args ?? []), ...fn(scope, options)]));
export const scopeAccess = (rule) => registerPipe((p) => p.addAccessRule(rule));
export const lazy = () => registerPipe((p) => p.lazy());
export const decorate = (...fns) => registerPipe((p) => p.map(...fns));
export const singleton = (getCacheKey) => registerPipe((p) => p.singleton(getCacheKey));