The main IoC service container.

Provides type-safe dependency injection with support for:

  • Value, factory, class, alias, and async factory providers
  • Singleton, transient, and scoped lifecycles
  • Hierarchical scopes (child inherits parent registrations)
  • Circular dependency detection
  • Resolve middleware (logging, metrics, decoration)
  • Automatic disposal of services implementing Disposable
  • Event-driven observability

1.2.0

Implements

Constructors

Properties

scopeId: string = 'root'

Unique scope identifier (auto-generated for child scopes).

Accessors

Methods

  • Acquire a tracked, ref-counted reference to a service.

    Returns a ServiceRef that must be .release()'d when no longer needed. Multiple acquireRef() calls for the same singleton token return different refs to the same instance — the ref count tracks how many holders exist.

    Type Parameters

    • T

      The service type.

    Parameters

    Returns ServiceRef<T>

    A new ServiceRef<T> linked to this context's ref registry.

    If no provider is registered for the token.

    1.2.0

    // Component A
    const rpcRef = ctx.acquireRef(Tokens.RPC);
    await rpcRef.current.getBalance(pubkey);

    // Component B — same singleton, separate ref
    const rpcRef2 = ctx.acquireRef(Tokens.RPC);
    ctx.refCount(Tokens.RPC); // → 2

    // Cleanup
    rpcRef.release(); // ref count → 1
    rpcRef2.release(); // ref count → 0
  • Acquire tracked refs for multiple tokens at once.

    Returns a ServiceBinding whose .services proxy lazily resolves each token. A single .release() frees all refs.

    Type Parameters

    Parameters

    • tokens: T

      Record mapping property names to service tokens.

    Returns ServiceBinding<T>

    A binding with lazy services and batch release.

    1.2.0

    const binding = ctx.bind({
    rpc: Tokens.RPC,
    das: Tokens.DAS,
    programs: Tokens.PROGRAMS,
    });

    await binding.services.rpc.getBalance(pubkey);
    binding.release(); // releases all at once
  • Create a child scope that inherits all parent registrations.

    Scoped services get fresh instances in the child scope. The child scope is tracked and disposed when the parent is disposed.

    Parameters

    • OptionalscopeId: string

      Unique identifier for the child scope.

    Returns SynapseContext

    A new SynapseContext linked to this parent.

    1.2.0

    const reqScope = ctx.createScope(`request-${id}`);
    reqScope.register(REQUEST_CTX, { useValue: { id, user } });
    // ... handle request ...
    reqScope.dispose();
  • Dispose this context and all child scopes.

    Calls .dispose() on all singleton/scoped services that implement Disposable. After disposal, any call to resolve() throws.

    Returns Promise<number>

    Number of services disposed.

    1.2.0

  • Enable a memory guard with configurable thresholds.

    The guard monitors ref counts and emits pressure/leak events. Can only be called once per context.

    Parameters

    Returns MemoryGuard

    The created MemoryGuard.

    1.2.0

    const guard = ctx.enableMemoryGuard({
    maxRefAgeMs: 30_000,
    maxActiveRefs: 50,
    checkIntervalMs: 10_000,
    });

    guard.onPressure(stats => console.warn('Memory pressure:', stats));
    guard.onLeak(leak => console.error('Leaked ref:', leak));
  • Number of active (unreleased) refs for a specific token.

    Returns 0 if no refs have been acquired or the ref registry hasn't been initialized yet.

    Parameters

    Returns number

    1.2.0

  • Register a service provider for a token.

    Type Parameters

    • T

    Parameters

    • token: ServiceToken<T>

      The service token.

    • provider: ServiceProvider<T>

      How to create the service.

    • Optionaltags: string[]

      Optional tags for filtering.

    Returns this

    this for chaining.

    ctx.register(DB, { useFactory: r => new PostgresDB(r.resolve(CONFIG)) });
    ctx.register(LOGGER, { useValue: console }, ['core']);
    ctx.register(CACHE, { useClass: RedisCache, lifecycle: 'singleton' });

    1.2.0

  • Register a service only if the token is not already registered.

    Useful for default/fallback providers that should not override user-provided registrations.

    Type Parameters

    • T

    Parameters

    Returns this

    1.2.0

  • Register multiple services at once.

    Parameters

    Returns this

    this for chaining.

    1.2.0

  • Return a snapshot of registered services for debugging.

    Returns {
        lifecycle: ServiceLifecycle;
        resolved: boolean;
        tags: string[];
        token: string;
    }[]

    1.2.0

  • Add a resolve middleware.

    Middleware functions wrap every resolve() call. They execute in the order they are added (first-in, outermost).

    Parameters

    Returns this

    this for chaining.

    1.2.0

    ctx.use((token, next) => {
    console.time(token.name);
    const result = next();
    console.timeEnd(token.name);
    return result;
    });