Skip to content

DI Bag API / index / Builder

Interface: Builder<E extends Entry, C extends NeedConstraint = never> ​

Defined in: di-bag.ts:336

An immutable, type-checked graph builder. Every operation returns a new builder. Create one with DiBagApi.createBuilder. The same builder value can Builder.build a bag once its graph is complete, or Builder.buildModule a reusable module whose unmet dependencies become requirements the installing host must satisfy.

See ​

https://dany-fedorov.github.io/di-bag/agent/api-card.html#builder

Type Parameters ​

Type ParameterDescription
E-
C-

Properties ​

contribute ​

ts
readonly contribute: BuilderContribute<E, C>;

Defined in: di-bag.ts:432

Append a provider to a typed-token collection.

Param ​

token

The collection's typed token.

Param ​

registration

A registration whose output satisfies the token service type.

Returns ​

A new builder preserving contribution order.

Throws ​

DI_BAG_INVALID_TOKEN for a bad token; DI_BAG_INVALID_REGISTRATION for an invalid registration.

Example ​

ts
const toolsKey = Symbol('tools');
const tools = DiBag.token(toolsKey).of<string>();
const builder = DiBag.createBuilder().contribute(tools, () => 'search').contribute(tools, () => 'fetch');

Methods ​

alias() ​

ts
alias<const D extends AliasSelection, const T extends AliasSelection>(destination: D & (unknown extends AliasAdmission<D> ? Introduces<RegistrationsFromEntries<E>, AliasEntries<RegistrationsFromEntries<E>, D, T>> : AliasAdmission<D>), target: T & AliasAdmission<T> & (unknown extends AliasAdmission<T> ? AliasTarget<RegistrationsFromEntries<E>, T> & AliasDestination<RegistrationsFromEntries<E>, NoInfer<D>, T> : unknown) & (unknown extends AliasAdmission<D> & AliasAdmission<T> ? IncrementalChecked<E, AliasEntries<RegistrationsFromEntries<E>, NoInfer<D>, NoInfer<T>>> & CheckedConstraints<C, OverrideRegistrations<RegistrationsFromEntries<E>, AliasEntries<RegistrationsFromEntries<E>, NoInfer<D>, NoInfer<T>>>> : unknown), ...invalid: [D] extends [never] ? [never] : [T] extends [never] ? [never] : []): Builder<E | AliasEntry<RegistrationsFromEntries<E>, D, T>, C>;

Defined in: di-bag.ts:406

Add another lookup name or token for an existing service.

Type Parameters ​

Type ParameterDescription
D-
T-

Parameters ​

ParameterDescription
destinationA new string name or typed token.
targetThe existing name or token whose canonical acquisition is reused.
...invalid-

Returns ​

A new builder; aliases add no cache or ownership of their own.

Throws ​

DI_BAG_INVALID_TOKEN for a bad token; DI_BAG_DUPLICATE_REGISTRATION when the destination exists; DI_BAG_INVALID_ALIAS for an absent named target.

Example ​

ts
const builder = DiBag.createBuilder().register({ clock: () => Date.now() }).alias('now', 'clock');

build() ​

ts
build(this: Builder<E, C> & CheckDependencyCompleteness<RegistrationsFromEntries<E>> & CompleteConstraints<C, RegistrationsFromEntries<E>> & CheckedLifetimes<RegistrationsFromEntries<E>, C>): Bag<RegistrationsFromEntries<E>, C>;

Defined in: di-bag.ts:563

Finish a complete graph as a lazy bag. The bag owns what it acquires; close it when done.

Parameters ​

ParameterDescription
this-

Returns ​

A fresh bag that owns the acquisitions it creates.

Throws ​

DI_BAG_CLASSIFIER_REQUIRED when a registration uses auto acquisition, the facade has no Promise classifier, and the host has no process.getBuiltinModule.

Example ​

ts
const bag = DiBag.createBuilder().register({ greeting: () => 'hello' }).build();
await bag.close();

buildAndStart() ​

ts
buildAndStart<const K extends readonly unknown[]>(this: Builder<E, C> & CheckDependencyCompleteness<RegistrationsFromEntries<E>> & CompleteConstraints<C, RegistrationsFromEntries<E>> & CheckedLifetimes<RegistrationsFromEntries<E>, C>, keys: K & Selection<RegistrationsFromEntries<E>, K, 'buildAndStart'>, options?: StartupOptions): Promise<Bag<RegistrationsFromEntries<E>, C>>;

Defined in: di-bag.ts:583

Create a fresh bag and acquire selected services before returning it.

Type Parameters ​

Type ParameterDescription
K-

Parameters ​

ParameterDescription
this-
keysA finite tuple of existing names or typed tokens to make ready.
options?Optional cancellation signal, positive timeout, and parallel, sequential, or positive safe integer bounded scheduling.

Returns ​

A promise for the new bag after every selected final stage is ready.

Throws ​

DiBagStartupError (DI_BAG_STARTUP_FAILED) after rollback on acquisition failure; DiBagStartupCancelledError (DI_BAG_STARTUP_CANCELLED) promptly on abort or timeout; DI_BAG_INVALID_STARTUP for malformed keys or options; DI_BAG_INVALID_TOKEN for a bad token; DI_BAG_CLASSIFIER_REQUIRED as for Builder.build. Each arrives as a rejection.

Example ​

ts
const bag = await DiBag.createBuilder()
  .register({ db: async () => ({ ping: () => true }) })
  .buildAndStart(['db'], { timeoutMs: 5_000 });

buildModule() ​

ts
buildModule<const K extends readonly unknown[]>(keys: K & Selection<RegistrationsFromEntries<E>, K, 'buildModule'> & SealAdmission<RegistrationsFromEntries<E>, Extract<SelectionKey<K[number]>, keyof RegistrationsFromEntries<E>>, C>, options?: ModuleOptions): Module<ExportedServices<ServicesOf<RegistrationsFromEntries<E>>, Extract<SelectionKey<K[number]>, keyof RegistrationsFromEntries<E>>>, ExternalRequirements<ModuleSealedConstraints<E, C, Extract<SelectionKey<K[number]>, keyof RegistrationsFromEntries<E>>>>, ModuleSealedConstraints<E, C, Extract<SelectionKey<K[number]>, keyof RegistrationsFromEntries<E>>>, ModulePublicProviders<RegistrationsFromEntries<E>, Extract<SelectionKey<K[number]>, keyof RegistrationsFromEntries<E>>>>;

Defined in: di-bag.ts:539

Seal this graph as a reusable module and select its public names and typed tokens. Unselected registrations stay private to each installation; unmet dependencies become requirements of the module. Installed modules nest: their private bindings and retained constraints are re-scoped inside this module.

Type Parameters ​

Type ParameterDescription
K-

Parameters ​

ParameterDescription
keysA finite tuple of existing names or tokens; an empty tuple is allowed.
options?An optional label; each installation names its private bindings <label>/<key> in
error messages, cycle paths, inspectGraph(), and observer events, and nested labels compose as outer/inner/key.

Returns ​

An immutable module that can be renamed or installed in another builder.

Throws ​

DI_BAG_INVALID_EXPORT if the selection is not a tuple, contains an absent name or token, or the label is not a non-empty string; DI_BAG_INVALID_TOKEN for a value that is not a genuine token.

Example ​

ts
const orders = DiBag.createBuilder()
  .register({ repository: () => new Map<string, number>() })
  .register({ placeOrder: ({ repository }: { repository: Map<string, number> }) => (id: string) => repository.set(id, 1) })
  .buildModule(['placeOrder'], { label: 'orders' });
// Errors and inspectGraph() name the private binding 'orders/repository'.
const app = DiBag.createBuilder().installModule(orders).build();

installModule() ​

ts
installModule<P extends object, R extends object, MC extends NeedConstraint, D extends Registrations>(module: Module<P, R, MC, D> & IntroducesKeys<EntryKeys<E>, keyof D> & IncrementalChecked<E, D> & IncrementalConstraints<C, MC, RegistrationsFromEntries<E>, D>): Builder<E | RegistrationEntries<D>, C | MC>;

Defined in: di-bag.ts:495

Install a sealed module, allocating fresh private bindings for this installation. The installing host must register every requirement the module does not register itself.

Type Parameters ​

Type ParameterDescription
P-
R-
MC-
D-

Parameters ​

ParameterDescription
moduleA module whose public names do not collide and whose external requirements remain checkable.

Returns ​

A new builder exposing only the module's selected exports.

Throws ​

DI_BAG_INVALID_MODULE for a value not made by buildModule; DI_BAG_DUPLICATE_REGISTRATION when an export name is already registered.

Example ​

ts
const greeting = DiBag.createBuilder()
  .register({ greet: ({ name }: { name: string }) => `hello, ${name}` })
  .buildModule(['greet']);
const bag = DiBag.createBuilder().installModule(greeting).register({ name: () => 'Ada' }).build();

register() ​

Call Signature ​

ts
register<N extends {
    [K in keyof N]: Registration;
}>(more: N & Registrations & ([N] extends [never] ? never : NamedAdmission<N> & ThenableAdmission<N> & IntroducesKeys<EntryKeys<E>, keyof N> & IncrementalChecked<E, N> & CheckedConstraints<C, OverrideRegistrations<RegistrationsFromEntries<E>, N>>)): Builder<E | RegistrationEntries<N>, C>;

Defined in: di-bag.ts:364

Add new string-named registrations. A factory declares its dependencies in the type of its one object parameter; destructure it or read deps.name, never spread it.

Type Parameters ​
Type ParameterDescription
N-
Parameters ​
ParameterDescription
moreA finite object whose own string keys are service names and values are registrations.
Returns ​

A new builder containing snapshots of the supplied registrations.

Throws ​

DI_BAG_INVALID_REGISTRATION for a malformed object or value; DI_BAG_DUPLICATE_REGISTRATION for a name already registered.

Example ​
ts
type Clock = { now(): number };
const builder = DiBag.createBuilder()
  .register({ clock: (): Clock => ({ now: () => Date.now() }) })
  .register({ stamp: ({ clock }: { clock: Clock }) => clock.now() });

Call Signature ​

ts
register<T extends TokenBase, V extends Registration>(token: T & TokenTupleAdmission<readonly [T]> & IntroducesKeys<EntryKeys<E>, TokenKey<T>>, registration: V & Registration & BindingOutput<NoInfer<T>, NoInfer<V>> & ThenableAdmission<Record<TokenKey<T>, NoInfer<V>>> & IncrementalChecked<E, Record<TokenKey<T>, TokenBinding<NoInfer<T>, NoInfer<V>>>> & CheckedConstraints<C, OverrideRegistrations<RegistrationsFromEntries<E>, Record<TokenKey<T>, TokenBinding<NoInfer<T>, NoInfer<V>>>>>): Builder<E | {
    key: TokenKey<T>;
    registration: TokenBinding<T, V>;
}, C>;

Defined in: di-bag.ts:378

Register a provider to a typed token.

Type Parameters ​
Type ParameterDescription
T-
V-
Parameters ​
ParameterDescription
tokenA new typed token identity.
registrationA registration whose exposed output satisfies the token service type.
Returns ​

A new builder retaining the provider's metadata, lifetime, dependencies, and ownership stages.

Throws ​

DI_BAG_INVALID_TOKEN for a bad token; DI_BAG_DUPLICATE_REGISTRATION when it is already registered; DI_BAG_INVALID_REGISTRATION for an invalid registration.


replace() ​

Call Signature ​

ts
replace<const K extends string, V extends (ReplacementFactory<ReplacementOutput<NoInfer<RegistrationsFromEntries<E>>, K, C>>) | FactoryWithDisposal<ReplacementFactory<ReplacementOutput<NoInfer<RegistrationsFromEntries<E>>, K, C>>>>(key: K & ReplacementKeyOf<EntryKeys<E>, K>, registration: V & (Factory | FactoryWithDisposal<Factory>) & ZeroDependencyAdmission<NoInfer<V>> & CheckedConstraints<C, OverrideRegistrations<RegistrationsFromEntries<E>, Record<K, NoInfer<V>>>>): Builder<Exclude<E, {
    key: K;
}> | {
    key: K;
    registration: V;
}, WithoutExportObligations<C, K>>;

Defined in: di-bag.ts:456

Replace an existing string-named registration with a dependency-free factory.

Type Parameters ​
Type ParameterDescription
K-
VThe exact replacement factory or disposable-factory type.
Parameters ​
ParameterDescription
keyOne existing string-literal service name.
registrationThe replacement, checked against every surviving consumer.
Returns ​

A new builder with the replacement.

Throws ​

DI_BAG_INVALID_REPLACEMENT for an absent key; DI_BAG_INVALID_REGISTRATION for an invalid registration.

Example ​
ts
const builder = DiBag.createBuilder().register({ clock: () => Date.now() }).replace('clock', () => 0);

Call Signature ​

ts
replace<const K extends string | TokenBase, V extends Registration>(key: K & NoInfer<ReplacementAdmission<RegistrationsFromEntries<E>, K>>, registration: V & Registration & BuilderReplacementRegistration<E, C, NoInfer<K>, V>): Builder<ReplacedEntries<E, K, V>, WithoutExportObligations<C, SelectionKey<K>>>;

Defined in: di-bag.ts:468

Replace an existing named or typed-token registration.

Type Parameters ​
Type ParameterDescription
K-
V-
Parameters ​
ParameterDescription
keyThe single existing name or token to replace.
registrationA replacement compatible with the token and known consumers.
Returns ​

A new builder with the replacement and its inferred service type.

Throws ​

DI_BAG_INVALID_REPLACEMENT for an absent key; DI_BAG_INVALID_TOKEN or DI_BAG_INVALID_REGISTRATION for malformed input.


verifyGraph() ​

ts
verifyGraph<Self extends Builder<E, C>>(this: Self): CompositionReport<Self>;

Defined in: di-bag.ts:515

Report at the type level why this graph would not build; the runtime call does nothing. Write builder.verifyGraph() satisfies void; so a rejected graph fails on that line with the complete message and details, instead of at the start of the builder expression.

Type Parameters ​

Type ParameterDescription
Self-

Parameters ​

ParameterDescription
this-

Returns ​

void for a buildable graph; otherwise the failure that build() would report.

Example ​

ts
const builder = DiBag.createBuilder().register({ greeting: () => 'hello' });
builder.verifyGraph() satisfies void;

Ordinary services. Checked composition. Explicit ownership.