@vielzeug/conduit
v1.0.3
Published
Lightweight dependency injection container — singletons, transient instances, factories, and named scopes
Readme
@vielzeug/conduit
Typed dependency injection for TypeScript.
Package: @vielzeug/conduit · Category: Di
Key exports: createContainer, token, scope, loadModules
When to use: Type-safe DI container with async-first resolution, singleton/transient/named-scope lifetimes, scope containers, disposal hooks, and cycle detection.
Related: @vielzeug/rune · @vielzeug/herald · @vielzeug/ward
@vielzeug/conduit is part of Vielzeug and ships as a zero-dependency TypeScript package with ESM+CJS output.
Installation
pnpm add @vielzeug/conduit
npm install @vielzeug/conduit
yarn add @vielzeug/conduitQuick Start
import { createContainer, token, loadModules, type ContainerModule } from '@vielzeug/conduit';
const Logger = token<{ log(message: string): void }>('Logger');
const Service = token<{ run(): Promise<void> }>('Service');
const appModule: ContainerModule = (c) => {
c.value(Logger, console);
c.factory(Service, async (r) => {
const logger = await r.resolve(Logger);
return { run: async () => logger.log('running') };
});
};
const container = createContainer();
await loadModules(container, appModule);
const service = await container.resolve(Service);
await service.run();
await container.dispose();Features
- Typed symbol tokens via
token()with phantom type inference - Named scope tokens via
scope()andcreateScope()for explicit lifecycle control value()andfactory()registration with optional dispose hookssingleton,transient, and named-scope lifetimes- Async-first
resolve()with concurrent-caller deduplication - Sync
resolveSync()for cached values and post-warm-up hot paths resolveMany()to resolve multiple tokens in parallel with typed tuplesresolveAll()to eagerly warm all singletons at startuphas()to check registration without executing the factoryContainerModulefor grouping and async provider setup vialoadModules()freeze()to lock the container after startup (runs cycle detection)inspect()to get a serializable dependency graphon()to subscribe to container lifecycle events withsourcemetadata- Named scope containers for request, job, or test scopes
Symbol.asyncDisposesupport forawait using- Free-function helpers:
resolveOptional,resolveOrDefault,tryResolve,resolveSyncOptional,resolveSyncOrDefault
Errors
| Error | When thrown |
| ----------------------------------- | --------------------------------------------------------------------------------- |
| ConduitProviderNotFoundError | resolve() called for an unregistered token; message includes container name |
| ConduitDuplicateRegistrationError | value() or factory() called for an already-registered token |
| ConduitSyncResolutionError | resolveSync() called for a transient or not-yet-resolved factory |
| ConduitScopedResolutionError | resolve() called outside a matching named-scope container |
| ConduitCircularDependencyError | freeze() detected a cycle; message includes the full path |
| ConduitDisposedError | Any operation called after dispose(); message includes container name |
| ConduitFrozenError | value() or factory() called after freeze(); message includes container name |
Documentation
License
MIT © Helmuth Saatkamp — part of the Vielzeug monorepo.
