PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Services
  • Libraries
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
DAL Library
SDK Library
    Architecture: Ports & AdaptersBuild, Tooling & CI/CDCI/CD & NPM PublishingConfiguration ManagementCore ModulesDatabase MigrationsEnvironment ValidationGetting StartedGlossaryHTTP Server & Health ChecksLifecycle & Graceful ShutdownModule Test PatternsNATS Messaging ClientOverviewService Registration & HeartbeatTest Infrastructure & ConfigurationTestingTypeScript Build ConfigurationREADME
powered by Zudoku
SDK Library

NATS Messaging Client

NATS Messaging Client

Relevant source files

The following files were used as context for generating this wiki page:

  • pnpm-lock.yaml
  • src/nats/tests/nats-client.test.ts
  • src/nats/nats-client.ts

The nats module provides a singleton-based management layer for NATS connectivity. It facilitates connection sharing across a microservice, supports JetStream integration, and handles graceful teardown. To maintain a lightweight footprint, the SDK treats nats as an optional peer dependency, allowing services that do not require messaging to omit the library entirely src/nats/nats-client.ts:7-10.

Architecture and Design

The NatsClient class follows a singleton pattern to ensure that only one connection to the NATS server is established and maintained per process src/nats/nats-client.ts:11-13. It provides lazy initialization, meaning the connection is only created when getConnection() is first invoked src/nats/nats-client.ts:15-18.

NATS Client Data Flow

The following diagram illustrates the lifecycle of a NATS connection within the SDK, from initialization to JetStream access and final closure.

NATS Connection Lifecycle

Code
sequenceDiagram participant Consumer as "Service Logic" participant SDK as "NatsClient" participant ENV as "process.env.NATS_URL" participant NATS as "NATS Server" Consumer->>SDK: getConnection() alt nc is null SDK->>ENV: Read NATS_URL ENV-->>SDK: URL (or default 127.0.0.1:4222) SDK->>NATS: connect({ servers: natsUrl }) NATS-->>SDK: NatsConnection SDK->>SDK: nc.jetstream() else nc exists SDK-->>Consumer: Return existing nc end SDK-->>Consumer: NatsConnection Consumer->>SDK: getJetStream() SDK-->>Consumer: JetStreamClient Consumer->>SDK: close() SDK->>NATS: nc.close() SDK->>SDK: Reset nc/js to null

Sources: src/nats/nats-client.ts:15-38

Implementation Details

Connection Management

The client uses the NATS_URL environment variable to locate the server. If this variable is not provided, it defaults to nats://127.0.0.1:4222 src/nats/nats-client.ts:17-18.

MethodRoleBehavior
getConnection()Lazy InitializerChecks if nc exists; if not, calls connect() and initializes JetStream src/nats/nats-client.ts:15-22.
getJetStream()AccessorReturns the initialized JetStreamClient. Throws an error if getConnection() hasn't been called src/nats/nats-client.ts:24-29.
close()TeardownCloses the active connection and nullifies internal references to allow for clean re-initialization src/nats/nats-client.ts:31-38.

Peer Dependency Model

The SDK is designed so that nats is not a hard requirement. This is achieved by:

  1. Listing nats under devDependencies in the SDK itself for testing pnpm-lock.yaml:14-16.
  2. Expecting the consumer to provide the nats package if they import the nats module from the SDK src/nats/nats-client.ts:7-9.
  3. Ensuring no other SDK modules (like config or http) import from the nats directory.

Code Entity Mapping

The following diagram maps the logical messaging components to the specific TypeScript entities in the nats module.

Messaging Entity Map

Code
graph TD subgraph "NATS Module" NC["class NatsClient"] GC["static getConnection()"] GJS["static getJetStream()"] CL["static close()"] end subgraph "External Dependencies" NATS_LIB["peer-dep: nats"] ENV_VAR["process.env.NATS_URL"] end NC --> GC NC --> GJS NC --> CL GC -.->|uses| NATS_LIB GC -.->|reads| ENV_VAR GJS -.->|returns| JS_TYPE["JetStreamClient"] GC -.->|returns| NC_TYPE["NatsConnection"]

Sources: src/nats/nats-client.ts:1-39

Testing and Singleton Resets

Because NatsClient maintains a static state, tests must explicitly reset the singleton to ensure isolation. The test suite utilizes vi.mock("nats", ...) to intercept connection attempts and NatsClient.close() within beforeEach hooks to clear the internal state between test cases src/nats/tests/nats-client.test.ts:4-20.

Key Test Scenarios:

  • Singleton Verification: Ensuring multiple calls to getConnection() return the exact same instance src/nats/tests/nats-client.test.ts:26-31.
  • Initialization Guard: Verifying that getJetStream() throws an error if the connection has not been established yet src/nats/tests/nats-client.test.ts:33-35.
  • Reconnection Logic: Confirming that calling close() allows a subsequent getConnection() to initiate a fresh connection src/nats/tests/nats-client.test.ts:43-49.

Sources: src/nats/tests/nats-client.test.ts:1-54, src/nats/nats-client.ts:1-39


Last modified on July 13, 2026
Module Test PatternsOverview
On this page
  • Architecture and Design
    • NATS Client Data Flow
  • Implementation Details
    • Connection Management
    • Peer Dependency Model
  • Code Entity Mapping
  • Testing and Singleton Resets