Skip to main content
Version: v0.0.3

Interface: StarterServerOptions

Options for createStarterServer(), the "three lines of code" factory.

Extends ServerOptions with port, host, and handleSignals. Defaults: autoAck: 'AA', drainTimeoutMs: 30_000, Symbol.asyncDispose wired.

Example

import { createStarterServer } from '@cosyte/mllp';

const server = await createStarterServer({
port: 2575,
onMessage: (buf) => buildAckBuffer(buf),
});
// server is listening, auto-ACK enabled, Symbol.asyncDispose wired
await using _ = server; // closes on scope exit

Extends

Properties

allowWildcardBind?

optional allowWildcardBind?: boolean

Opt-in required to bind a wildcard host, a bind-safety guardrail. Without this flag, listen() rejects a wildcard host in two tiers: literal spellings ('0.0.0.0', '::', '', '::0', '0:0:0:0:0:0:0:0', '::ffff:0.0.0.0', …) reject pre-bind (fast path, nothing is ever bound); resolver-only shorthands ('0', '0.0', '0x0.0.0.0', hostnames resolving to the unspecified address, …) are caught post-bind against the OS-normalized bound address, the just-bound server closes before any connection can be accepted and listen() rejects, with no listening state and no 'listening' event either way. When true, binding a wildcard host emits a one-time 'securityWarning' (MLLP_BIND_ALL_INTERFACES) at listen time.

Default

false

Inherited from

ServerOptions.allowWildcardBind


autoAck?

optional autoAck?: "AA" | ((payload, meta, conn) => Buffer<ArrayBufferLike> | Promise<Buffer<ArrayBufferLike>>)

Auto-ACK mode. When set, the server builds and sends the ACK for each message.

  • 'AA', auto-acknowledge with the fail-safe commit contract:
    • With an onMessage handler ⇒ commit-gated (recommended). The server awaits onMessage (the durable-commit step), then sends AA on success or a negative ACK on failure (AE by default; AR via MllpAckError). The positive ACK cannot precede a successful commit, a handler throw can never yield AA.
    • Without an onMessage handler ⇒ transport-accept. AA is sent on frame receipt. This AA means only "bytes received and framed", not "application-processed". ⚠️ For clinical messages this is unsafe on its own: pair 'AA' with an onMessage handler that durably commits, so the ACK reflects real processing.
  • fn, fn(payload, meta, conn) builds the ACK bytes the server sends; the caller fully owns MSA-1 (e.g. to emit enhanced-mode CA/CE/CR).

The 'message' event always fires BEFORE the ACK is sent. Do NOT call conn.send() in onMessage when autoAck is set, this results in two ACKs.

Inherited from

ServerOptions.autoAck


deadPeerTimeoutMs?

optional deadPeerTimeoutMs?: number

Application-level idle close timeout in ms. If no HL7 messages are received on a connection for this interval, the connection is destroyed via conn.destroy(new Error('idle timeout')). Resets on every 'message' event. Distinct from keepaliveIntervalMs (OS TCP probe).

Inherited from

ServerOptions.deadPeerTimeoutMs


drainTimeoutMs?

optional drainTimeoutMs?: number

Graceful drain timeout passed to conn.close() during server.close(). Default: 30 000 ms.

Inherited from

ServerOptions.drainTimeoutMs


framing?

optional framing?: Omit<FrameReaderOptions, "onFrame" | "onWarning">

FrameReader tolerance options applied to every accepted connection. Merged with SERVER_DEFAULT_FRAMING, caller-supplied values override defaults. onFrame and onWarning are managed internally and must not be supplied here.

Inherited from

ServerOptions.framing


handleSignals?

optional handleSignals?: boolean

Register process.once('SIGTERM') and process.once('SIGINT') handlers that call server.close() then process.exit(0). Default: false.

Handlers are automatically removed when server.close() is called, so process.listenerCount('SIGTERM') === 0 after close() completes, preventing handler accumulation across test instances or multiple server restarts.


host?

optional host?: string

Host to bind to. Default '127.0.0.1' (bind-safety hardening, was '0.0.0.0'; binding all interfaces now requires ServerOptions.allowWildcardBind: true).


keepaliveIntervalMs?

optional keepaliveIntervalMs?: number

TCP keepalive probe interval in ms. Calls socket.setKeepAlive(true, ms) on each accepted socket. Uses OS TCP stack to detect dead peers (half-open, network partitions). Distinct from deadPeerTimeoutMs (application-level idle close).

Inherited from

ServerOptions.keepaliveIntervalMs


onMessage?

optional onMessage?: (payload, meta, conn) => void | Promise<void>

Called for each decoded MLLP message.

Its role depends on autoAck, this is the commit contract (HL7 v2.5.1 §2.9.2):

  • autoAck: 'AA' + this handler ⇒ commit-gated (the safe default). The handler is the durable-commit step. The server awaits it and only then sends the ACK: resolve ⇒ AA; throw/reject ⇒ AE (or AR via MllpAckError), a positive ACK can never precede a successful commit. Do not call conn.send() here in this mode.
  • autoAck unset ⇒ manual mode. The handler owns the response; build and send the ACK yourself via conn.send(encodeFrame(ackPayload)). Its return value is ignored.
  • autoAck: fn ⇒ observation only. fn builds the ACK; this handler runs first as a side effect and its return value is ignored. Do not call conn.send() here.

May be sync or async; an async handler is awaited in commit-gated mode.

Parameters

payload

Buffer

meta

MessageMeta

conn

Connection

Returns

void | Promise<void>

Inherited from

ServerOptions.onMessage


onWarning?

optional onWarning?: (w) => void

Per-connection warning subscriber. Called for every framing warning on every connection.

Parameters

w

MllpWarning

Returns

void

Inherited from

ServerOptions.onWarning


port

port: number

Port to listen on.


tls?

optional tls?: ServerTlsOptions

Enable TLS (MLLPS) for this server. When set, the server binds a tls.Server instead of a plain net.Server, consumes 'secureConnection' (post-handshake sockets) instead of 'connection', and surfaces failed handshakes via the 'tlsClientError' event rather than crashing.

Spec anchor: IHE ATNA ITI-19 (https://profiles.ihe.net/ITI/TF/Volume2/ITI-19.html).

Default

undefined (plaintext TCP)

Inherited from

ServerOptions.tls