@cosyte/mllp 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -25,13 +25,13 @@ var MllpFramingError = class _MllpFramingError extends Error {
25
25
  /**
26
26
  * Up to 64 bytes copied from around the anomaly.
27
27
  *
28
- * This is a **copied** Buffer — isolated from the source buffer so it remains
28
+ * This is a **copied** Buffer, isolated from the source buffer so it remains
29
29
  * valid after the underlying buffer is reused or overwritten.
30
30
  *
31
31
  * **PHI contract (MLLP-9):** the decoder only ever populates this with the single
32
32
  * framing-boundary byte that violated the frame structure (whose hex value the
33
- * `message` already discloses) — never a run of payload content bytes. For anomalies
34
- * whose fault is not a specific byte (`MLLP_FRAME_TOO_LARGE` — the accumulated size),
33
+ * `message` already discloses), never a run of payload content bytes. For anomalies
34
+ * whose fault is not a specific byte (`MLLP_FRAME_TOO_LARGE`, the accumulated size),
35
35
  * the snippet is **empty**: a payload slice on a public error field would leak a
36
36
  * field-body slice of clinical content. Callers constructing this directly are
37
37
  * responsible for the same discipline.
@@ -104,7 +104,7 @@ var FrameReader = class {
104
104
  _opts;
105
105
  _maxFrameSize;
106
106
  _state = "SCANNING_FOR_VT";
107
- /** Reusable accumulator buffer — grown by doubling as needed. */
107
+ /** Reusable accumulator buffer, grown by doubling as needed. */
108
108
  _accumulator = Buffer.allocUnsafe(INITIAL_ACCUMULATOR_SIZE);
109
109
  /** Number of payload bytes written to accumulator in current frame. */
110
110
  _writePos = 0;
@@ -116,7 +116,7 @@ var FrameReader = class {
116
116
  _wsCount = 0;
117
117
  /** Byte offset of the VT byte that started the current frame. */
118
118
  _frameStartOffset = 0;
119
- /** Per-frame warning accumulator — cleared after each _deliverFrame(). */
119
+ /** Per-frame warning accumulator, cleared after each _deliverFrame(). */
120
120
  _frameWarnings = [];
121
121
  /**
122
122
  * Construct a chunked MLLP frame reader.
@@ -240,7 +240,7 @@ var FrameReader = class {
240
240
  this._emitWarning(
241
241
  "MLLP_MISSING_LEADING_VT",
242
242
  this._byteOffset,
243
- `Missing leading VT (0x0B) \u2014 treating byte 0x${byte.toString(16).padStart(2, "0")} at offset ${this._byteOffset} as payload start`
243
+ `Missing leading VT (0x0B), treating byte 0x${byte.toString(16).padStart(2, "0")} at offset ${this._byteOffset} as payload start`
244
244
  );
245
245
  this._frameStartOffset = this._byteOffset;
246
246
  this._state = "READING_PAYLOAD";
@@ -485,8 +485,8 @@ var TlsTransport = class {
485
485
  this._socket.on("data", fn);
486
486
  }
487
487
  /**
488
- * See {@link Transport.onConnect}. Armed on `'secureConnect'` — the TLS
489
- * handshake-complete event — not the raw TCP `'connect'` event.
488
+ * See {@link Transport.onConnect}. Armed on `'secureConnect'`, the TLS
489
+ * handshake-complete event, not the raw TCP `'connect'` event.
490
490
  */
491
491
  onConnect(fn) {
492
492
  this._socket.removeAllListeners("secureConnect");
@@ -567,14 +567,14 @@ var Connection = class extends EventEmitter {
567
567
  _lastByteOutAt = null;
568
568
  /** Ring buffer: last MAX_WARNINGS entries (OBS-05). */
569
569
  _warningBuffer = [];
570
- /** Accurate total counts per code — unaffected by ring buffer truncation (OBS-05). */
570
+ /** Accurate total counts per code, unaffected by ring buffer truncation (OBS-05). */
571
571
  _warningsByCode = /* @__PURE__ */ new Map();
572
572
  /** Set to true once the ring buffer overflows (OBS-05). */
573
573
  _warningsTruncated = false;
574
574
  _onWarningFn = null;
575
575
  _drainPromise = null;
576
576
  /**
577
- * beforeClose hook — no-op default that resolves immediately.
577
+ * beforeClose hook, no-op default that resolves immediately.
578
578
  *
579
579
  * Phase 4 (Server) and Phase 5 (Client) override this instance property to
580
580
  * register ACK-drain and send-queue drain logic respectively (D-07/D-08).
@@ -758,7 +758,7 @@ var Connection = class extends EventEmitter {
758
758
  * Abruptly destroy the connection, discarding any pending writes.
759
759
  *
760
760
  * Transitions from any non-terminal state directly to `CLOSED` and calls
761
- * `transport.destroy(reason)`. Emits `'close'` event. Idempotent — safe to
761
+ * `transport.destroy(reason)`. Emits `'close'` event. Idempotent, safe to
762
762
  * call multiple times.
763
763
  *
764
764
  * @param reason - Optional error to propagate to the transport.
@@ -858,12 +858,12 @@ var Connection = class extends EventEmitter {
858
858
  * Node throws `ERR_UNHANDLED_ERROR` when `'error'` is emitted on an `EventEmitter` with no
859
859
  * listener. Every `'error'` emission in this class is reached from inside a transport callback
860
860
  * (the socket's `'data'`/`'error'` listener), so an unguarded emit would become an **uncaught
861
- * exception that kills the process** — the exact failure the containment above exists to
861
+ * exception that kills the process**, the exact failure the containment above exists to
862
862
  * prevent, merely relocated one frame up the stack.
863
863
  *
864
864
  * `Connection` is a public export and can legitimately be driven with no `'error'` listener
865
865
  * (`MllpServer` and `MllpClient` each attach one; a bare `Connection` need not). The connection
866
- * is still torn down and `'stateChange'`/`'close'` still fire, so a caller is never blind —
866
+ * is still torn down and `'stateChange'`/`'close'` still fire, so a caller is never blind,
867
867
  * they simply do not get the typed error object they never asked for. Mirrors
868
868
  * `MllpServer._emitErrorIfListened`.
869
869
  */
@@ -882,7 +882,7 @@ var Connection = class extends EventEmitter {
882
882
  * consumers keep the stable `code` and `byteOffset`), then **destroy this connection only**.
883
883
  *
884
884
  * Why destroy rather than resynchronize: once `push` has thrown, the reader's position within
885
- * the byte stream is no longer trustworthy — the next bytes could be the middle of a message.
885
+ * the byte stream is no longer trustworthy, the next bytes could be the middle of a message.
886
886
  * Guessing where the next frame starts is how a clinical message gets silently mis-split, so
887
887
  * the connection is dropped instead. A server drops that one peer and keeps serving everyone
888
888
  * else.
@@ -894,7 +894,7 @@ var Connection = class extends EventEmitter {
894
894
  * engine that is already unwell. A compatibility failure is not a network blip.
895
895
  *
896
896
  * If a peer's quirk is *expected* (trailing junk, keepalive bytes, a missing leading VT), the
897
- * decoder's tolerance opt-ins are the supported answer — they turn the throw into a warning.
897
+ * decoder's tolerance opt-ins are the supported answer, they turn the throw into a warning.
898
898
  */
899
899
  _onFatalFramingError(err) {
900
900
  if (this._state === "CLOSED") return;
@@ -908,13 +908,13 @@ var Connection = class extends EventEmitter {
908
908
  this.destroy(err);
909
909
  }
910
910
  /**
911
- * Backstop for a NON-framing throw escaping `FrameReader.push` — i.e. our own bug, or a
911
+ * Backstop for a NON-framing throw escaping `FrameReader.push`, i.e. our own bug, or a
912
912
  * subscriber's, rather than the peer's bytes.
913
913
  *
914
914
  * `_onFrameDecoded` already contains subscriber throws at the dispatch site, so this should be
915
915
  * unreachable. It exists because "unreachable" and "cannot kill the process from inside a
916
916
  * socket `'data'` handler" are different claims, and only the second one is safe to bet a
917
- * clinical interface on. Reported honestly as an internal receive error — never dressed up as
917
+ * clinical interface on. Reported honestly as an internal receive error, never dressed up as
918
918
  * a peer framing fault.
919
919
  */
920
920
  _onInternalReceiveError(err) {
@@ -990,9 +990,9 @@ var UNSAFE_FIELD_SEPARATORS = /* @__PURE__ */ new Set([
990
990
  SEGMENT_SEPARATOR_CR,
991
991
  SEGMENT_SEPARATOR_LF,
992
992
  11,
993
- // VT — MLLP start block
993
+ // VT, MLLP start block
994
994
  28
995
- // FS — MLLP end block
995
+ // FS, MLLP end block
996
996
  ]);
997
997
  function isMshSegmentAt(buf, i) {
998
998
  return i + 3 < buf.length && buf[i] === ASCII_M && buf[i + 1] === ASCII_S && buf[i + 2] === ASCII_H && !UNSAFE_FIELD_SEPARATORS.has(buf[i + 3]);
@@ -1225,13 +1225,13 @@ var MllpServer = class extends EventEmitter {
1225
1225
  _netServer;
1226
1226
  _connections = /* @__PURE__ */ new Set();
1227
1227
  _opts;
1228
- /** `true` when `ServerOptions.tls` is set — `_netServer` is actually a `tls.Server`. */
1228
+ /** `true` when `ServerOptions.tls` is set, `_netServer` is actually a `tls.Server`. */
1229
1229
  _isTls;
1230
1230
  _listening = false;
1231
- /** Phase 8 — single-flight guard: `true` while a `listen()` call is settling. */
1231
+ /** Phase 8, single-flight guard: `true` while a `listen()` call is settling. */
1232
1232
  _listenInFlight = false;
1233
1233
  /**
1234
- * Phase 8 — settle hook for an in-flight `listen()`. Non-null only while a
1234
+ * Phase 8, settle hook for an in-flight `listen()`. Non-null only while a
1235
1235
  * `listen()` is in flight; invoked by `close()` so a close racing startup
1236
1236
  * rejects the pending `listen()` (typed) instead of leaving it hung with
1237
1237
  * the single-flight guard stuck. Cleared on every settle path.
@@ -1241,7 +1241,7 @@ var MllpServer = class extends EventEmitter {
1241
1241
  _host = null;
1242
1242
  _acceptedTotal = 0;
1243
1243
  _closedTotal = 0;
1244
- /** Phase 8 — count of `'tlsClientError'` events since listen(). */
1244
+ /** Phase 8, count of `'tlsClientError'` events since listen(). */
1245
1245
  _tlsClientErrorsTotal = 0;
1246
1246
  /**
1247
1247
  * Construct an MLLP server. Created idle; call `listen()` (or use
@@ -1304,23 +1304,23 @@ var MllpServer = class extends EventEmitter {
1304
1304
  * `Object.freeze({ port: actualPort, host: actualHost })`.
1305
1305
  *
1306
1306
  * **Single-flight:** one `listen()` per server lifecycle at a time. A call
1307
- * while the server is already listening — or while another `listen()` is
1308
- * still in flight — rejects with a typed `MllpConnectionError` (concurrent
1307
+ * while the server is already listening, or while another `listen()` is
1308
+ * still in flight, rejects with a typed `MllpConnectionError` (concurrent
1309
1309
  * binds raced each other's post-bind safety checks). Call `close()` before
1310
1310
  * re-listening; sequential `listen()` → `close()` → `listen()` is fine.
1311
1311
  *
1312
1312
  * **`close()` during an in-flight `listen()`** rejects that `listen()` with
1313
1313
  * a typed `MllpConnectionError` (never a hang) and clears the single-flight
1314
- * guard — a subsequent `listen()` on the same server works. This makes
1314
+ * guard, a subsequent `listen()` on the same server works. This makes
1315
1315
  * `Symbol.asyncDispose` (which delegates to `close()`) safe even before a
1316
1316
  * `listen()` has settled. (Exception: `close({ signal })` with an
1317
- * already-aborted signal is a no-op AbortError rejection — the in-flight
1317
+ * already-aborted signal is a no-op AbortError rejection, the in-flight
1318
1318
  * `listen()` is left to settle on its own bind outcome; see `close()`.)
1319
1319
  *
1320
1320
  * @param port - TCP port to bind. Use `0` to let the OS assign an ephemeral port.
1321
1321
  * @param hostOrOpts - Host string or object with `host` and optional `signal`.
1322
1322
  * Default host: `'127.0.0.1'` (Phase 8 bind-safety hardening). Wildcard hosts
1323
- * are rejected unless `ServerOptions.allowWildcardBind: true` — literal
1323
+ * are rejected unless `ServerOptions.allowWildcardBind: true`, literal
1324
1324
  * spellings pre-bind, resolver-only shorthands post-bind via the
1325
1325
  * OS-normalized bound address.
1326
1326
  *
@@ -1340,7 +1340,7 @@ var MllpServer = class extends EventEmitter {
1340
1340
  if (this._listening || this._listenInFlight) {
1341
1341
  return Promise.reject(
1342
1342
  new MllpConnectionError(
1343
- this._listening ? "listen() rejected: server is already listening \u2014 call close() before re-listening" : "listen() rejected: another listen() is already in flight on this server",
1343
+ this._listening ? "listen() rejected: server is already listening, call close() before re-listening" : "listen() rejected: another listen() is already in flight on this server",
1344
1344
  {
1345
1345
  cause: new Error("listen already listening or in flight"),
1346
1346
  phase: "connect"
@@ -1351,7 +1351,7 @@ var MllpServer = class extends EventEmitter {
1351
1351
  if (isWildcardHost(host) && this._opts.allowWildcardBind !== true) {
1352
1352
  return Promise.reject(
1353
1353
  new MllpConnectionError(
1354
- `refusing to bind wildcard host '${host}' \u2014 set ServerOptions.allowWildcardBind: true to bind all interfaces`,
1354
+ `refusing to bind wildcard host '${host}', set ServerOptions.allowWildcardBind: true to bind all interfaces`,
1355
1355
  {
1356
1356
  cause: new Error("wildcard bind requires allowWildcardBind"),
1357
1357
  phase: "connect"
@@ -1430,7 +1430,7 @@ var MllpServer = class extends EventEmitter {
1430
1430
  {
1431
1431
  ok: false,
1432
1432
  error: new MllpConnectionError(
1433
- `refusing to bind wildcard host '${host}' (bound address '${actualHost}') \u2014 set ServerOptions.allowWildcardBind: true to bind all interfaces`,
1433
+ `refusing to bind wildcard host '${host}' (bound address '${actualHost}'), set ServerOptions.allowWildcardBind: true to bind all interfaces`,
1434
1434
  {
1435
1435
  cause: new Error("wildcard bind requires allowWildcardBind"),
1436
1436
  phase: "connect"
@@ -1457,7 +1457,7 @@ var MllpServer = class extends EventEmitter {
1457
1457
  }
1458
1458
  };
1459
1459
  const wildcardBound = isWildcardHost(actualHost);
1460
- const wildcardMessage = `MLLP server is bound to ALL network interfaces (host='${actualHost}') \u2014 set a specific bind address unless this is intentional.`;
1460
+ const wildcardMessage = `MLLP server is bound to ALL network interfaces (host='${actualHost}'), set a specific bind address unless this is intentional.`;
1461
1461
  if (wildcardBound) {
1462
1462
  process.emitWarning(wildcardMessage, { code: MLLP_BIND_ALL_INTERFACES });
1463
1463
  }
@@ -1486,18 +1486,18 @@ var MllpServer = class extends EventEmitter {
1486
1486
  * Stop accepting new connections and gracefully close all active connections.
1487
1487
  *
1488
1488
  * Sequence (D-06):
1489
- * 1. `net.Server.close()` — stops accepting new connections immediately
1489
+ * 1. `net.Server.close()`, stops accepting new connections immediately
1490
1490
  * 2. If `_connections` is empty: resolves immediately (no drain needed)
1491
- * 3. Calls `_drainAll(drainTimeoutMs)` — Promise.all + side-effect setTimeout
1491
+ * 3. Calls `_drainAll(drainTimeoutMs)`, Promise.all + side-effect setTimeout
1492
1492
  * that force-destroys stragglers after the drain window
1493
1493
  *
1494
1494
  * Calling `close()` while a `listen()` is still in flight proactively
1495
1495
  * settles that `listen()` with a typed `MllpConnectionError` rejection
1496
- * and clears the single-flight guard — the server is immediately
1496
+ * and clears the single-flight guard, the server is immediately
1497
1497
  * re-listenable. `Symbol.asyncDispose` (which delegates here) is
1498
1498
  * therefore safe before `listen()` settles. **Qualification:** a
1499
1499
  * `close({ signal })` whose signal is **already aborted** rejects
1500
- * immediately with `AbortError` and performs no work — it does NOT close
1500
+ * immediately with `AbortError` and performs no work, it does NOT close
1501
1501
  * the server and does NOT settle the in-flight `listen()`, which simply
1502
1502
  * continues and settles on its own bind outcome.
1503
1503
  *
@@ -1549,7 +1549,7 @@ var MllpServer = class extends EventEmitter {
1549
1549
  /**
1550
1550
  * Drain all active connections with a shared timeout.
1551
1551
  *
1552
- * Uses Promise.all (not Promise.race) for coordination — the timeout is a
1552
+ * Uses Promise.all (not Promise.race) for coordination, the timeout is a
1553
1553
  * side effect that calls `conn.destroy()` on stragglers after `drainTimeoutMs`.
1554
1554
  * Promise.all resolves when all `conn.close()` promises settle (which happens
1555
1555
  * because `conn.destroy()` transitions connections to CLOSED).
@@ -1572,7 +1572,7 @@ var MllpServer = class extends EventEmitter {
1572
1572
  }
1573
1573
  }
1574
1574
  /**
1575
- * Async disposal — delegates to `close()` for `await using` support.
1575
+ * Async disposal, delegates to `close()` for `await using` support.
1576
1576
  *
1577
1577
  * @example
1578
1578
  * ```typescript
@@ -1619,7 +1619,7 @@ var MllpServer = class extends EventEmitter {
1619
1619
  };
1620
1620
  }
1621
1621
  /**
1622
- * Emit on `'error'` only when a listener is attached — an unlistened
1622
+ * Emit on `'error'` only when a listener is attached, an unlistened
1623
1623
  * `EventEmitter` `'error'` emission throws (see the class JSDoc error
1624
1624
  * contract). The single guard shared by the optional-tap forwarding sites
1625
1625
  * in this class; the constructor's net.Server forwarder deliberately does
@@ -1629,7 +1629,7 @@ var MllpServer = class extends EventEmitter {
1629
1629
  /**
1630
1630
  * Emit a server event, containing a throwing subscriber.
1631
1631
  *
1632
- * Every event this server emits is reachable from a callback we do not own — the `net.Server`
1632
+ * Every event this server emits is reachable from a callback we do not own, the `net.Server`
1633
1633
  * `'connection'` listener, the `tls.Server` `'tlsClientError'` listener, a socket's `'data'`
1634
1634
  * listener (via `Connection`), or the `catch` block of a `void`-ed async ACK task. A throwing
1635
1635
  * subscriber would therefore unwind into that callback and kill the process (or reject a void-ed
@@ -1735,7 +1735,7 @@ var MllpServer = class extends EventEmitter {
1735
1735
  }
1736
1736
  /**
1737
1737
  * Extract a minimal, content-free peer-certificate summary (Phase 8, ATNA
1738
- * ITI-19 mutual authentication) — CN strings, expiry, and the verification
1738
+ * ITI-19 mutual authentication), CN strings, expiry, and the verification
1739
1739
  * outcome (`authorized`) only; never the full certificate object. Returns
1740
1740
  * `null` when no peer certificate was presented (e.g. `clientAuth: 'WANT'`
1741
1741
  * with no client cert).
@@ -1753,7 +1753,7 @@ var MllpServer = class extends EventEmitter {
1753
1753
  subjectCN: asCn(cert.subject?.CN),
1754
1754
  issuerCN: asCn(cert.issuer?.CN),
1755
1755
  validTo: cert.valid_to ?? null,
1756
- // Verification outcome — under 'WANT' a certificate can be present yet
1756
+ // Verification outcome, under 'WANT' a certificate can be present yet
1757
1757
  // UNVERIFIED (see PeerCertificateSummary.authorized JSDoc).
1758
1758
  authorized: socket.authorized === true
1759
1759
  });
@@ -1765,12 +1765,12 @@ var MllpServer = class extends EventEmitter {
1765
1765
  * then dispatches: resolve ⇒ `AA`; throw/reject ⇒ a negative ACK (`AE` by default,
1766
1766
  * `AR` via {@link MllpAckError}). A positive ACK can never precede a successful commit.
1767
1767
  *
1768
- * Without an `onMessage` handler, `'AA'` degrades to a **transport-accept** — `AA`
1768
+ * Without an `onMessage` handler, `'AA'` degrades to a **transport-accept**, `AA`
1769
1769
  * meaning "bytes received and framed", not "application-processed".
1770
1770
  *
1771
1771
  * A handler failure is **expected flow**, not a server error: it produces a negative
1772
1772
  * ACK and a `'nack'` event. The thrown error's message is never placed on the wire or
1773
- * in the event (it may carry PHI) — only the static `ackCode` and the inbound control
1773
+ * in the event (it may carry PHI), only the static `ackCode` and the inbound control
1774
1774
  * metadata reach the peer.
1775
1775
  */
1776
1776
  async _sendCommitAck(payload, meta, conn) {
@@ -1802,18 +1802,18 @@ var MllpServer = class extends EventEmitter {
1802
1802
  }
1803
1803
  /**
1804
1804
  * Resolve the auto-ACK code for a message the server would otherwise acknowledge
1805
- * **positively** (`AA`) — the no-handler transport-accept and the post-commit success
1805
+ * **positively** (`AA`), the no-handler transport-accept and the post-commit success
1806
1806
  * paths. Fail-safe: downgrade to `AE` and emit a PHI-safe `'nack'` whenever the message
1807
1807
  * cannot carry a correlatable positive ACK, so `AA` never names a control ID the sender
1808
1808
  * cannot match (→ timeout → resend → **duplicate clinical message**).
1809
1809
  *
1810
1810
  * Two independent disqualifiers, one from the bytes and one from the frame:
1811
1811
  *
1812
- * - **`rawAckUncorrelatable(payload)`** — no readable `MSH`, an empty MSH-10, or a
1812
+ * - **`rawAckUncorrelatable(payload)`**, no readable `MSH`, an empty MSH-10, or a
1813
1813
  * batch/concatenated-message shape. This is the SAME predicate `buildRawAck` enforces
1814
1814
  * on the wire; it is re-checked here so the downgrade is **observable** (a `'nack'`
1815
1815
  * event) rather than a silent code change inside the builder.
1816
- * - **`MLLP_TRAILING_BYTES`** in the frame's warnings — a mid-payload `VT` made the
1816
+ * - **`MLLP_TRAILING_BYTES`** in the frame's warnings, a mid-payload `VT` made the
1817
1817
  * decoder discard accumulated bytes and deliver only the fragment after it. The
1818
1818
  * clinical message was destroyed in transit, so even a fragment that happens to carry
1819
1819
  * a readable MSH must not be positively acknowledged. This condition is invisible to
@@ -1822,7 +1822,7 @@ var MllpServer = class extends EventEmitter {
1822
1822
  * accumulating the delivered frame, so it is frame-scoped: it names *this* payload's own
1823
1823
  * discard, never a neighbouring frame's trailing junk.
1824
1824
  *
1825
- * `'discarded-bytes'` takes precedence in the reason when both hold — it is the root cause.
1825
+ * `'discarded-bytes'` takes precedence in the reason when both hold, it is the root cause.
1826
1826
  */
1827
1827
  _resolveAutoAckPositive(payload, meta, conn) {
1828
1828
  const discarded = meta.warnings.some((w) => w.code === "MLLP_TRAILING_BYTES");
@@ -1857,7 +1857,7 @@ var MllpServer = class extends EventEmitter {
1857
1857
  /**
1858
1858
  * The custom-builder path for `autoAck: fn`. Awaits the builder and dispatches its
1859
1859
  * Buffer as the ACK; the caller owns MSA-1. A builder error is re-emitted as `'error'`
1860
- * on the connection — the server never crashes (D-04).
1860
+ * on the connection, the server never crashes (D-04).
1861
1861
  */
1862
1862
  async _sendCustomAck(fn, payload, meta, conn) {
1863
1863
  try {
@@ -1871,7 +1871,7 @@ var MllpServer = class extends EventEmitter {
1871
1871
  /**
1872
1872
  * Frame an ACK payload and write it to the connection. `Connection.send()` returns
1873
1873
  * `false` under backpressure (socket write buffer full); that drops the ACK and emits
1874
- * a `MllpConnectionError({ phase: 'send' })` on the connection (D-04) — the peer will
1874
+ * a `MllpConnectionError({ phase: 'send' })` on the connection (D-04), the peer will
1875
1875
  * time out waiting and may retry. The server never crashes.
1876
1876
  */
1877
1877
  _dispatchAck(conn, ackPayload) {
@@ -1936,7 +1936,7 @@ var Correlator = class {
1936
1936
  _sendSeq = 0;
1937
1937
  _queueBytes = 0;
1938
1938
  /**
1939
- * PLAN-06 — count of pending entries with `sentAt !== null` (D-26 / B-01).
1939
+ * PLAN-06, count of pending entries with `sentAt !== null` (D-26 / B-01).
1940
1940
  * Maintained at every site that mutates `entry.sentAt` or removes a
1941
1941
  * flushed entry: `markFlushed`, `remove`, `matchAck`, `expireDue`, `clear`.
1942
1942
  */
@@ -1972,7 +1972,7 @@ var Correlator = class {
1972
1972
  /**
1973
1973
  * Enqueue a new send awaiting its ACK. Returns the assigned
1974
1974
  * `correlationKey`, or `null` if `maxInFlight` is reached (caller awaits
1975
- * drain — PLAN-05's `pipeline:false`).
1975
+ * drain, PLAN-05's `pipeline:false`).
1976
1976
  */
1977
1977
  enqueue(frame, controlIdOrNull, resolve, reject) {
1978
1978
  if (this._pending.size >= this._opts.maxInFlight) return null;
@@ -1991,7 +1991,7 @@ var Correlator = class {
1991
1991
  return key;
1992
1992
  }
1993
1993
  /**
1994
- * Record write-flush timestamp (CLIENT-04 — clock starts at flush, NOT
1994
+ * Record write-flush timestamp (CLIENT-04, clock starts at flush, NOT
1995
1995
  * at `send()` call). No-op if key is unknown (e.g. removed by abort).
1996
1996
  */
1997
1997
  markFlushed(key, now) {
@@ -2061,7 +2061,7 @@ var Correlator = class {
2061
2061
  /**
2062
2062
  * Sweep live entries; expire those past `sentAt + ackTimeoutMs`.
2063
2063
  * Fires `onTimeout(entry, elapsedMs)`; entries move to graveyard (D-04).
2064
- * Driven externally by `MllpClient`'s periodic sweep tick — Correlator
2064
+ * Driven externally by `MllpClient`'s periodic sweep tick, Correlator
2065
2065
  * itself owns no timers (D-03).
2066
2066
  */
2067
2067
  expireDue(now) {
@@ -2084,7 +2084,7 @@ var Correlator = class {
2084
2084
  /**
2085
2085
  * Reject every live entry with `reason` (insertion order) and clear
2086
2086
  * the live store. Graveyard is left intact (ages out via lazy eviction).
2087
- * Used by FIFO reconnect-reject (D-07 — PLAN-04 wraps in MllpConnectionError)
2087
+ * Used by FIFO reconnect-reject (D-07, PLAN-04 wraps in MllpConnectionError)
2088
2088
  * and `MllpClient.close()` to cancel pending sends.
2089
2089
  */
2090
2090
  clear(reason) {
@@ -2265,7 +2265,7 @@ var MllpClient = class extends EventEmitter {
2265
2265
  /** 0-indexed attempt counter for the current reconnect cycle. */
2266
2266
  _attempt = 0;
2267
2267
  /**
2268
- * W-02 — total reconnect attempts since construction. Read by PLAN-06 for
2268
+ * W-02, total reconnect attempts since construction. Read by PLAN-06 for
2269
2269
  * `getStats().reconnectAttempts`. Incremented at the entry of every
2270
2270
  * `_handleDisconnect` invocation that proceeds to schedule a backoff.
2271
2271
  */
@@ -2287,7 +2287,7 @@ var MllpClient = class extends EventEmitter {
2287
2287
  _onBackpressure;
2288
2288
  /** Pipeline flag; default `true` (parallel up to highWaterMark). */
2289
2289
  _pipeline;
2290
- /** Dead-peer idle timer (Plan 05 — D-11). `null` when not armed. */
2290
+ /** Dead-peer idle timer (Plan 05, D-11). `null` when not armed. */
2291
2291
  _deadPeerTimer = null;
2292
2292
  /** True once the self-'ack' listener that resets the dead-peer timer
2293
2293
  * has been attached. Guards against duplicate listeners on reconnect. */
@@ -2301,13 +2301,13 @@ var MllpClient = class extends EventEmitter {
2301
2301
  /** Listener-removal handle for the abort listener bound in connect(). */
2302
2302
  _abortListener = null;
2303
2303
  /**
2304
- * Test-only seam — when set, `_beginReconnectAttempt` builds the new
2304
+ * Test-only seam, when set, `_beginReconnectAttempt` builds the new
2305
2305
  * Connection through this factory instead of opening a real net.Socket.
2306
2306
  *
2307
2307
  * @internal
2308
2308
  */
2309
2309
  _reconnectFactory = null;
2310
- // ── PLAN-06 — observability counters for getStats (OBS-01, D-26) ─────────
2310
+ // ── PLAN-06, observability counters for getStats (OBS-01, D-26) ─────────
2311
2311
  /** Total successful `conn.send()` flushes since construction. */
2312
2312
  _sentTotal = 0;
2313
2313
  /** Total ACKs resolved since construction. */
@@ -2361,9 +2361,9 @@ var MllpClient = class extends EventEmitter {
2361
2361
  return this._connection?.state ?? this._state;
2362
2362
  }
2363
2363
  /**
2364
- * Open a TCP (or TLS — Phase 8) connection to the configured `host:port`
2364
+ * Open a TCP (or TLS, Phase 8) connection to the configured `host:port`
2365
2365
  * and attach a Phase 3 {@link Connection} to it. Resolves once the FSM
2366
- * enters `CONNECTED` — for TLS, on `'secureConnect'` (handshake complete,
2366
+ * enters `CONNECTED`, for TLS, on `'secureConnect'` (handshake complete,
2367
2367
  * including certificate verification when it is on).
2368
2368
  *
2369
2369
  * Rejects with:
@@ -2383,11 +2383,11 @@ var MllpClient = class extends EventEmitter {
2383
2383
  *
2384
2384
  * **TLS 1.3 + mutual TLS caveat (RFC 8446 §4.4.2):** `connect()` resolving
2385
2385
  * does NOT guarantee that a `clientAuth: 'MUST'` server accepted your
2386
- * client certificate. Under TLS 1.3 the client's handshake — and its
2387
- * `'secureConnect'` — can complete before the server finishes validating
2386
+ * client certificate. Under TLS 1.3 the client's handshake, and its
2387
+ * `'secureConnect'`, can complete before the server finishes validating
2388
2388
  * the certificate; a rejection then surfaces moments later as a typed
2389
2389
  * post-connect error (`'error'` event with an `ERR_SSL_*`/alert cause,
2390
- * classified **permanent** — no auto-reconnect loop). ACK correlation via
2390
+ * classified **permanent**, no auto-reconnect loop). ACK correlation via
2391
2391
  * {@link MllpClient.send} remains the delivery guarantee: no send resolves
2392
2392
  * without its ACK, so a rejected session can never silently "deliver".
2393
2393
  *
@@ -2471,7 +2471,7 @@ var MllpClient = class extends EventEmitter {
2471
2471
  *
2472
2472
  * Plaintext (`ClientOptions.tls` unset): a `net.Socket` wrapped in
2473
2473
  * `NetTransport`. TLS (Phase 8): a `tls.TLSSocket` wrapped in
2474
- * `TlsTransport` — verification defaults **on**
2474
+ * `TlsTransport`, verification defaults **on**
2475
2475
  * (`rejectUnauthorized: !allowUnverified`), floor `minVersion: 'TLSv1.2'`
2476
2476
  * (the IHE ATNA ITI-19 BCP195 floor), `servername` defaulting to
2477
2477
  * `ClientOptions.host`.
@@ -2502,12 +2502,12 @@ var MllpClient = class extends EventEmitter {
2502
2502
  * Wrap a connect-phase socket error as `MllpConnectionError`, classifying
2503
2503
  * TLS failures (Phase 8) into the additive `connectionCause`:
2504
2504
  *
2505
- * - `'tls-verify'` — certificate-verification failures
2505
+ * - `'tls-verify'`, certificate-verification failures
2506
2506
  * ({@link isTlsVerificationErrorCode}).
2507
- * - `'tls-handshake'` — TLS-**protocol**-shaped failures only
2507
+ * - `'tls-handshake'`, TLS-**protocol**-shaped failures only
2508
2508
  * ({@link isTlsProtocolError}): `ERR_SSL_*`, `EPROTO`, OpenSSL
2509
2509
  * alert-bearing errors.
2510
- * - **No `connectionCause`** — pure TCP-level failures (`ECONNREFUSED`,
2510
+ * - **No `connectionCause`**, pure TCP-level failures (`ECONNREFUSED`,
2511
2511
  * `ETIMEDOUT`, …) even on a TLS-configured connection; these carry the
2512
2512
  * same shape as plaintext connect failures.
2513
2513
  */
@@ -2535,7 +2535,7 @@ var MllpClient = class extends EventEmitter {
2535
2535
  /**
2536
2536
  * Emit a client event, containing a throwing subscriber.
2537
2537
  *
2538
- * Every event this client emits is reached from a callback we do not own — a socket's
2538
+ * Every event this client emits is reached from a callback we do not own, a socket's
2539
2539
  * `'connect'`/`'secureConnect'`/`'data'`/`'error'` listener, or a backoff timer. A throwing
2540
2540
  * subscriber would unwind into it and kill the process, and on several paths it would also skip
2541
2541
  * the work queued after the emit (the `resolve()` of `connect()`, the backoff scheduling).
@@ -2549,7 +2549,7 @@ var MllpClient = class extends EventEmitter {
2549
2549
  }
2550
2550
  /**
2551
2551
  * Emit the per-connection insecure-TLS warning (Phase 8) when
2552
- * `tls.allowUnverified === true` — fires on EVERY successful
2552
+ * `tls.allowUnverified === true`, fires on EVERY successful
2553
2553
  * `secureConnect`, initial connect and every reconnect. Emits both a frozen
2554
2554
  * `'securityWarning'` event and `process.emitWarning`. No-op for plaintext
2555
2555
  * connections or when verification is on.
@@ -2558,7 +2558,7 @@ var MllpClient = class extends EventEmitter {
2558
2558
  const tlsOpt = this._opts.tls;
2559
2559
  if (tlsOpt === void 0 || tlsOpt === true) return;
2560
2560
  if (tlsOpt.allowUnverified !== true) return;
2561
- const message = "MLLP TLS certificate verification is DISABLED (allowUnverified: true) \u2014 this connection does not authenticate the peer.";
2561
+ const message = "MLLP TLS certificate verification is DISABLED (allowUnverified: true), this connection does not authenticate the peer.";
2562
2562
  const warning = Object.freeze({
2563
2563
  code: MLLP_TLS_VERIFY_DISABLED,
2564
2564
  message,
@@ -2572,7 +2572,7 @@ var MllpClient = class extends EventEmitter {
2572
2572
  /**
2573
2573
  * Wire a Connection's events through to this MllpClient. Every re-emitted
2574
2574
  * payload is `Object.freeze`'d before emission (D-25), even though the
2575
- * Connection layer already freezes — defense-in-depth, harmless on
2575
+ * Connection layer already freezes, defense-in-depth, harmless on
2576
2576
  * already-frozen objects.
2577
2577
  *
2578
2578
  * Builds the unified `Correlator` (D-03/A1) bound to this Connection and
@@ -2586,7 +2586,7 @@ var MllpClient = class extends EventEmitter {
2586
2586
  this._correlator = new Correlator({
2587
2587
  mode: this._correlateByControlId ? "controlId" : "fifo",
2588
2588
  ackTimeoutMs: this._ackTimeoutMs,
2589
- // Plan 05 — pipeline:false collapses the in-flight set to ≤1 (D-06).
2589
+ // Plan 05, pipeline:false collapses the in-flight set to ≤1 (D-06).
2590
2590
  maxInFlight: this._pipeline ? Number.POSITIVE_INFINITY : 1,
2591
2591
  onWarning: (code, ctx) => {
2592
2592
  this._aggregatedWarningsByCode[code] = (this._aggregatedWarningsByCode[code] ?? 0) + 1;
@@ -2685,7 +2685,7 @@ var MllpClient = class extends EventEmitter {
2685
2685
  }
2686
2686
  }
2687
2687
  /**
2688
- * Arm (or re-arm) the dead-peer idle timer (Plan 05 — CLIENT-08, D-11).
2688
+ * Arm (or re-arm) the dead-peer idle timer (Plan 05, CLIENT-08, D-11).
2689
2689
  * No-op when `deadPeerTimeoutMs` is unset.
2690
2690
  */
2691
2691
  _armDeadPeerTimer() {
@@ -2699,7 +2699,7 @@ var MllpClient = class extends EventEmitter {
2699
2699
  this._deadPeerTimer.unref();
2700
2700
  }
2701
2701
  /**
2702
- * Clear the dead-peer idle timer (Plan 05 — D-14 timer cleanup on
2702
+ * Clear the dead-peer idle timer (Plan 05, D-14 timer cleanup on
2703
2703
  * every transition out of CONNECTED).
2704
2704
  */
2705
2705
  _clearDeadPeerTimer() {
@@ -2709,13 +2709,13 @@ var MllpClient = class extends EventEmitter {
2709
2709
  }
2710
2710
  }
2711
2711
  /**
2712
- * Disconnect handler — Plan 04 reconnect FSM core.
2712
+ * Disconnect handler, Plan 04 reconnect FSM core.
2713
2713
  *
2714
2714
  * Implements:
2715
2715
  * - CLIENT-17 hybrid in-flight handling (D-08): controlId mode preserves
2716
2716
  * pending sends for resend; FIFO mode rejects in-flight with
2717
2717
  * `connectionCause: 'in-flight-orphan'` and queued with `'fifo-unsafe'`.
2718
- * - CLIENT-18 classifier-first (Composition A — D-16): permanent errors
2718
+ * - CLIENT-18 classifier-first (Composition A, D-16): permanent errors
2719
2719
  * transition straight to CLOSED without invoking `retryStrategy`.
2720
2720
  * - W-01 backoff-reset on recent success: first disconnect after a
2721
2721
  * successful ACK on the prior session resets `_attempt` to 0.
@@ -2723,7 +2723,7 @@ var MllpClient = class extends EventEmitter {
2723
2723
  * - D-15 frozen RetryContext + D-17 null-return halts.
2724
2724
  * - D-19 default exponential strategy.
2725
2725
  *
2726
- * Invoked from the SINGLE `_onStateChange` hook — no parallel listener
2726
+ * Invoked from the SINGLE `_onStateChange` hook, no parallel listener
2727
2727
  * (B-04). Idempotent across same-cycle re-entry: cycle-start flag
2728
2728
  * coordinates first-disconnect vs subsequent-within-cycle behavior.
2729
2729
  */
@@ -2912,7 +2912,7 @@ var MllpClient = class extends EventEmitter {
2912
2912
  this._reconnectCycleStartedAt = null;
2913
2913
  }
2914
2914
  /**
2915
- * Test seam — install a factory that produces the next reconnect Connection.
2915
+ * Test seam, install a factory that produces the next reconnect Connection.
2916
2916
  *
2917
2917
  * @internal
2918
2918
  */
@@ -2920,7 +2920,7 @@ var MllpClient = class extends EventEmitter {
2920
2920
  this._reconnectFactory = factory;
2921
2921
  }
2922
2922
  /**
2923
- * Test seam — capture or rebind the connect-signal mid-flight (W-07).
2923
+ * Test seam, capture or rebind the connect-signal mid-flight (W-07).
2924
2924
  *
2925
2925
  * @internal
2926
2926
  */
@@ -2950,7 +2950,7 @@ var MllpClient = class extends EventEmitter {
2950
2950
  * anchor and passes it to `matchAck` for keyed lookup.
2951
2951
  *
2952
2952
  * Called from the SINGLE `'message'` listener registered in `_attachConnection`.
2953
- * No parallel listener is registered — downstream plans extend at the named
2953
+ * No parallel listener is registered, downstream plans extend at the named
2954
2954
  * anchor (B-04).
2955
2955
  */
2956
2956
  _onAckPayload(ackPayload, byteOffset) {
@@ -2989,9 +2989,9 @@ var MllpClient = class extends EventEmitter {
2989
2989
  }
2990
2990
  /**
2991
2991
  * Emit a frozen `'drain'` event when the queue depth and bytes fall below
2992
- * both configured caps (Plan 05 — D-24). Called from `_onAckMatched`
2992
+ * both configured caps (Plan 05, D-24). Called from `_onAckMatched`
2993
2993
  * (every successful ACK) and from the Correlator's `onTimeout` callback
2994
- * (every expired send) — both code paths free a live-store slot.
2994
+ * (every expired send), both code paths free a live-store slot.
2995
2995
  */
2996
2996
  _maybeEmitDrain() {
2997
2997
  const corr = this._correlator;
@@ -3066,7 +3066,7 @@ var MllpClient = class extends EventEmitter {
3066
3066
  * ```
3067
3067
  *
3068
3068
  * @param payload Raw bytes; MLLP framing is added internally via `encodeFrame`.
3069
- * @param opts.signal AbortSignal — aborting cancels the ACK wait (CLIENT-11).
3069
+ * @param opts.signal AbortSignal, aborting cancels the ACK wait (CLIENT-11).
3070
3070
  */
3071
3071
  send(payload, opts) {
3072
3072
  const signal = opts?.signal;
@@ -3154,7 +3154,7 @@ var MllpClient = class extends EventEmitter {
3154
3154
  });
3155
3155
  }
3156
3156
  /**
3157
- * 'wait'-mode backpressure handler (Plan 05 — CLIENT-07/CLIENT-11).
3157
+ * 'wait'-mode backpressure handler (Plan 05, CLIENT-07/CLIENT-11).
3158
3158
  *
3159
3159
  * Awaits one of three terminating signals, in order:
3160
3160
  * - `'drain'` event → re-enter `send()` (the gate will now pass).
@@ -3216,7 +3216,7 @@ var MllpClient = class extends EventEmitter {
3216
3216
  this._clearDeadPeerTimer();
3217
3217
  }
3218
3218
  /**
3219
- * **Test seam** — attach an externally-built {@link Connection} directly,
3219
+ * **Test seam**, attach an externally-built {@link Connection} directly,
3220
3220
  * bypassing the `net.createConnection` + `NetTransport` path. Used by
3221
3221
  * lifecycle tests driving `InMemoryTransport.pair()` for determinism.
3222
3222
  *
@@ -3295,7 +3295,7 @@ var MllpClient = class extends EventEmitter {
3295
3295
  }
3296
3296
  }
3297
3297
  /**
3298
- * Abruptly destroy the client — force-transitions the underlying Connection
3298
+ * Abruptly destroy the client, force-transitions the underlying Connection
3299
3299
  * to `CLOSED` immediately. No-op if no Connection is attached. Idempotent.
3300
3300
  *
3301
3301
  * @example
@@ -3321,7 +3321,7 @@ var MllpClient = class extends EventEmitter {
3321
3321
  /**
3322
3322
  * Returns a JSON-serializable observability snapshot (OBS-01, D-26).
3323
3323
  *
3324
- * All fields are plain values — no Buffers, no class instances, no Maps,
3324
+ * All fields are plain values, no Buffers, no class instances, no Maps,
3325
3325
  * no circular refs. Safe to `JSON.stringify` directly.
3326
3326
  *
3327
3327
  * `inFlight` is the count of correlator entries with `sentAt !== null`
@@ -3365,7 +3365,7 @@ var MllpClient = class extends EventEmitter {
3365
3365
  };
3366
3366
  }
3367
3367
  /**
3368
- * Async disposal — delegates to {@link MllpClient.close} for `await using` support.
3368
+ * Async disposal, delegates to {@link MllpClient.close} for `await using` support.
3369
3369
  *
3370
3370
  * @example
3371
3371
  * ```typescript
@@ -3421,7 +3421,7 @@ async function createStarterClient(opts) {
3421
3421
  }
3422
3422
 
3423
3423
  // src/index.ts
3424
- var VERSION = "0.0.1";
3424
+ var VERSION = "0.0.2";
3425
3425
 
3426
3426
  export { Connection, FrameReader, MLLP_BIND_ALL_INTERFACES, MLLP_TLS_VERIFY_DISABLED, MllpAckError, MllpBackpressureError, MllpClient, MllpConnectionError, MllpFramingError, MllpServer, MllpTimeoutError, NetTransport, TlsTransport, VERSION, buildRawAck, createClient, createServer, createStarterClient, createStarterServer, createWarning, encodeFrame, isTlsProtocolError, isTlsVerificationErrorCode, isTransientConnectionError, rawAckUncorrelatable, resolveNackCode };
3427
3427
  //# sourceMappingURL=index.mjs.map