Skip to content

DI Bag API / index / Bag

Interface: Bag<R extends Registrations, C extends NeedConstraint = never> ​

Defined in: di-bag.ts:73

A resolving container with lazy acquisition, caching, and independent resource ownership.

Create bags through DiBagApi.createBuilder followed by Builder.build or Builder.buildAndStart; the class is exported as a type and has no public constructor.

See ​

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

Type Parameters ​

Type ParameterDescription
R-
C-

Methods ​

close() ​

ts
close(options?: CloseOptions): Promise<void>;

Defined in: di-bag.ts:323

Close this bag, drain in-flight work, and dispose owned resources once. Dependents are disposed before dependencies; remaining independent acquisitions use reverse acquisition order. Without options the promise waits for cleanup however long it takes, and repeated calls return the same promise. With timeoutMs or signal, cleanup starts the same way but the returned promise stops waiting when either fires; scopes and forks accept the same options. Close every scope and fork you create; a parent closes its live scopes, never forks.

Parameters ​

ParameterDescription
options?An optional deadline and abort signal bounding the wait, not the cleanup.

Returns ​

The shared shutdown promise, or a bounded wait on it when options are given.

Throws ​

DiBagCleanupError (DI_BAG_CLEANUP_FAILED) when one or more disposers fail after all cleanup is attempted; DI_BAG_CLOSE_FAILED for other shutdown failures; DiBagCloseCancelledError (DI_BAG_CLOSE_TIMEOUT or DI_BAG_CLOSE_ABORTED) when the wait stops first, naming unfinished disposers in details.pending; DI_BAG_INVALID_CLOSE for malformed options.

Example ​

ts
const bag = DiBag.createBuilder().register({ value: () => 1 }).build();
await bag.close({ timeoutMs: 10_000, signal: AbortSignal.timeout(15_000) });

createScope() ​

Call Signature ​

ts
createScope<const S extends readonly unknown[]>(options: ScopeOptions<R, S>): Bag<ScopedAliases<R, R, S>, C>;

Defined in: di-bag.ts:181

Create a tracked child that borrows selected parent acquisitions.

Type Parameters ​
Type ParameterDescription
S-
Parameters ​
ParameterDescription
optionsA checked selection of non-transient services to share lazily.
Returns ​

A child owned by this bag; closing the parent closes the child first.

Throws ​

DI_BAG_INVALID_SCOPE for a malformed or transient share selection; DI_BAG_INVALID_TOKEN for a bad token; DI_BAG_CLOSING or DI_BAG_CLOSED after close().

Call Signature ​

ts
createScope<const K extends readonly unknown[], O extends OverrideFactoryContext<R, K, O>, const S extends readonly unknown[] = readonly []>(keys: K & Selection<R, K, 'createScope'>, overrides: O & object & Record<SelectionKey<K[number]>, Registration> & Overrides<R, SelectedRegistrations<K, O>> & CheckDependencyCompatibility<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CheckDependencyCompleteness<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CheckedConstraints<C, OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CompleteConstraints<C, OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CheckedScopeLifetimes<NoInfer<ScopedAliases<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>, R, S>>, NoInfer<SelectedRegistrations<K, O>>, WithoutExportObligations<C, SelectionKey<K[number]>>>, options?: ScopeOptions<R, S> & DisjointScopeSelection<K, S>): Bag<ScopedAliases<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>, R, S>, WithoutExportObligations<C, SelectionKey<K[number]>>>;

Defined in: di-bag.ts:191

Create a tracked child with selected replacements and optional parent sharing.

Type Parameters ​
Type ParameterDescription
K-
O-
S-
Parameters ​
ParameterDescription
keysExisting names or tokens to replace in the child.
overridesOwn registration properties for every selected key.
options?A disjoint selection of non-transient parent acquisitions to share.
Returns ​

A child with fresh scoped acquisitions and ownership for unshared services.

Throws ​

DI_BAG_INVALID_SCOPE for invalid selections, overrides, or sharing; DI_BAG_INVALID_TOKEN or DI_BAG_INVALID_REGISTRATION for malformed input; DI_BAG_CLOSING or DI_BAG_CLOSED after close(); DI_BAG_CLASSIFIER_REQUIRED as for Builder.build.

Call Signature ​

ts
createScope(): Bag<UnsharedAliases<R>, C>;

Defined in: di-bag.ts:219

Create a tracked child with the same graph and fresh scoped acquisitions. Close every scope you create, typically one per request; closing the parent closes its live scopes first.

Returns ​

A child that is closed before its parent finishes closing.

Throws ​

DI_BAG_CLOSING or DI_BAG_CLOSED after close().

Example ​
ts
const app = DiBag.createBuilder().register({ requestId: () => Math.random() }).build();
const request = app.createScope();
const id: number = request.resolve('requestId');
await request.close();

fork() ​

Call Signature ​

ts
fork(this: Bag<R, C> & CheckedLifetimes<UnsharedAliases<R>, C>): Bag<UnsharedAliases<R>, C>;

Defined in: di-bag.ts:231

Create an independent bag with the same graph and fresh instances.

Parameters ​
ParameterDescription
this-
Returns ​

A new ownership family that must be closed separately.

Throws ​

DI_BAG_CLOSING or DI_BAG_CLOSED after close().

Call Signature ​

ts
fork<const K extends readonly unknown[], O extends OverrideFactoryContext<R, K, O>>(keys: K & Selection<R, K>, overrides: O & object & Record<SelectionKey<K[number]>, Registration> & Overrides<R, SelectedRegistrations<K, O>> & CheckDependencyCompatibility<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CheckDependencyCompleteness<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CheckedConstraints<C, OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CompleteConstraints<C, OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>> & CheckedLifetimes<UnsharedAliases<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>>, WithoutExportObligations<C, SelectionKey<K[number]>>>): Bag<UnsharedAliases<OverrideRegistrations<R, ReboundSelection<R, SelectedRegistrations<K, O>>>>, WithoutExportObligations<C, SelectionKey<K[number]>>>;

Defined in: di-bag.ts:251

Create an independent bag with selected replacements, the way tests substitute dependencies. Each override must satisfy the original contract; close the fork, since its parent does not.

Type Parameters ​
Type ParameterDescription
K-
O-
Parameters ​
ParameterDescription
keysExisting names or tokens to replace.
overridesOwn registration properties for every selected key.
Returns ​

A fresh ownership family whose graph uses the checked replacements.

Throws ​

DI_BAG_INVALID_OVERRIDE for an absent key or a missing own override; DI_BAG_INVALID_TOKEN or DI_BAG_INVALID_REGISTRATION for malformed input; DI_BAG_CLOSING or DI_BAG_CLOSED after close(); DI_BAG_CLASSIFIER_REQUIRED as for Builder.build.

Example ​
ts
type Clock = { now(): number };
const app = DiBag.createBuilder().register({ clock: (): Clock => ({ now: () => Date.now() }) }).build();
const test = app.fork(['clock'], { clock: (): Clock => ({ now: () => 0 }) });
await test.close();

inspect() ​

ts
inspect<K extends (keyof R & string) | TokenBase>(token: K & ([K] extends [string] ? unknown : TokenMember<R, K>)): RegistrationSnapshot<ProviderRegistrationMetadata<R[SelectionKey<K> & keyof R]>, ProviderAcquisitionMetadata<R[SelectionKey<K> & keyof R]>>;

Defined in: di-bag.ts:156

Inspect static metadata and copied acquisition state without resolving a service.

Type Parameters ​

Type ParameterDescription
K-

Parameters ​

ParameterDescription
tokenAn existing public string name or typed token.

Returns ​

A frozen point-in-time snapshot. Application-owned metadata payloads are not frozen.

Throws ​

DI_BAG_INVALID_TOKEN or DI_BAG_MISSING_REGISTRATION for a bad selection; DI_BAG_CYCLE for an alias cycle.

Example ​

ts
const bag = DiBag.createBuilder().register({ greeting: () => 'hello' }).build();
const acquired = bag.inspect('greeting').acquisitions.length;

inspectAll() ​

ts
inspectAll<T extends TokenBase>(token: T & TokenTupleAdmission<readonly [T]> & CollectionMember<T, C>, ...invalid: [T] extends [never] ? [never] : []): readonly RegistrationSnapshot<object, readonly unknown[]>[];

Defined in: di-bag.ts:141

Inspect every contribution for a token without running its factories.

Type Parameters ​

Type ParameterDescription
T-

Parameters ​

ParameterDescription
tokenThe collection token to inspect.
...invalid-

Returns ​

Frozen snapshots in contribution order.

Throws ​

DI_BAG_INVALID_TOKEN for a bad token.

Example ​

ts
const toolsKey = Symbol('tools');
const tools = DiBag.token(toolsKey).of<string>();
const bag = DiBag.createBuilder().contribute(tools, () => 'search').build();
const labels = bag.inspectAll(tools).map(snapshot => snapshot.label);

inspectGraph() ​

ts
inspectGraph(): GraphSnapshot;

Defined in: di-bag.ts:172

Describe every binding this bag can resolve and the dependency edges observed so far. Nothing is acquired. Named dependencies declared on factory parameters are not visible until the factory runs; the static graph tool reports them from source.

Returns ​

A frozen point-in-time snapshot; application-owned metadata payloads are not frozen.

Example ​

ts
const bag = DiBag.createBuilder().register({ greeting: () => 'hello' }).build();
const labels = bag.inspectGraph().bindings.map(binding => binding.label);

resolve() ​

ts
resolve<K extends (keyof R & string) | TokenBase>(token: K & ([K] extends [string] ? unknown : TokenMember<R, K>)): ServicesOf<R>[SelectionKey<K> & keyof R];

Defined in: di-bag.ts:105

Resolve a named or typed-token service, acquiring it lazily when needed. Scoped and root services are cached according to their lifetime; transient services create a new acquisition for each call. Promise-valued services keep their identity. An async factory's service is its Promise; nothing is awaited for you.

Type Parameters ​

Type ParameterDescription
K-

Parameters ​

ParameterDescription
tokenAn existing public string name or typed token.

Returns ​

The service exposed by the selected registration.

Throws ​

DI_BAG_CLOSING or DI_BAG_CLOSED after close(); DI_BAG_INVALID_TOKEN or DI_BAG_MISSING_REGISTRATION for a bad selection; during acquisition DI_BAG_MISSING_DEPENDENCY, DI_BAG_CYCLE, DI_BAG_LIFETIME_DEPENDENCY, DI_BAG_INVALID_DEPENDENCY_ACCESS, DI_BAG_STRUCTURAL_THENABLE, DI_BAG_INVALID_CLASSIFIER_RESULT, DI_BAG_INVALID_METADATA, DI_BAG_PLUGIN_VALIDATION, or the factory's own error.

Example ​

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

resolveAll() ​

ts
resolveAll<T extends TokenBase>(token: T & TokenTupleAdmission<readonly [T]> & CollectionMember<T, C>, ...invalid: [T] extends [never] ? [never] : []): ReadonlyArray<TokenService<T>>;

Defined in: di-bag.ts:124

Resolve every contribution for a typed token in declaration and installation order.

Type Parameters ​

Type ParameterDescription
T-

Parameters ​

ParameterDescription
tokenThe collection token whose contributions to acquire.
...invalid-

Returns ​

A fresh frozen array; an unpopulated collection returns an empty array.

Throws ​

DI_BAG_CLOSING or DI_BAG_CLOSED after close(); DI_BAG_INVALID_TOKEN for a bad token; a contribution's acquisition errors as listed for Bag.resolve.

Example ​

ts
const toolsKey = Symbol('tools');
const tools = DiBag.token(toolsKey).of<string>();
const bag = DiBag.createBuilder().contribute(tools, () => 'search').contribute(tools, () => 'fetch').build();
const names: readonly string[] = bag.resolveAll(tools);

Ordinary services. Checked composition. Explicit ownership.