@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/CHANGELOG.md +269 -108
- package/README.md +23 -18
- package/TRADEMARKS.md +30 -0
- package/dist/ack-from-hl7/index.cjs +54 -14
- package/dist/ack-from-hl7/index.cjs.map +1 -1
- package/dist/ack-from-hl7/index.d.cts +113 -38
- package/dist/ack-from-hl7/index.d.ts +113 -38
- package/dist/ack-from-hl7/index.mjs +53 -14
- package/dist/ack-from-hl7/index.mjs.map +1 -1
- package/dist/{index-DjGQJtYE.d.cts → index-DAZ4BvJE.d.cts} +5 -5
- package/dist/{index-DjGQJtYE.d.ts → index-DAZ4BvJE.d.ts} +5 -5
- package/dist/index.cjs +90 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +239 -239
- package/dist/index.d.ts +239 -239
- package/dist/index.mjs +90 -90
- package/dist/index.mjs.map +1 -1
- package/dist/testing/index.cjs +3 -3
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +8 -8
- package/dist/testing/index.d.ts +8 -8
- package/dist/testing/index.mjs +3 -3
- package/dist/testing/index.mjs.map +1 -1
- package/package.json +15 -7
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
|
|
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)
|
|
34
|
-
* whose fault is not a specific byte (`MLLP_FRAME_TOO_LARGE
|
|
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
|
|
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
|
|
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)
|
|
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'
|
|
489
|
-
* handshake-complete 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
993
|
+
// VT, MLLP start block
|
|
994
994
|
28
|
|
995
|
-
// FS
|
|
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
|
|
1228
|
+
/** `true` when `ServerOptions.tls` is set, `_netServer` is actually a `tls.Server`. */
|
|
1229
1229
|
_isTls;
|
|
1230
1230
|
_listening = false;
|
|
1231
|
-
/** Phase 8
|
|
1231
|
+
/** Phase 8, single-flight guard: `true` while a `listen()` call is settling. */
|
|
1232
1232
|
_listenInFlight = false;
|
|
1233
1233
|
/**
|
|
1234
|
-
* Phase 8
|
|
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
|
|
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
|
|
1308
|
-
* still in flight
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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}'
|
|
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}')
|
|
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}')
|
|
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()
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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)
|
|
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`)
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2387
|
-
* `'secureConnect'
|
|
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
|
|
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
|
|
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'
|
|
2505
|
+
* - `'tls-verify'`, certificate-verification failures
|
|
2506
2506
|
* ({@link isTlsVerificationErrorCode}).
|
|
2507
|
-
* - `'tls-handshake'
|
|
2507
|
+
* - `'tls-handshake'`, TLS-**protocol**-shaped failures only
|
|
2508
2508
|
* ({@link isTlsProtocolError}): `ERR_SSL_*`, `EPROTO`, OpenSSL
|
|
2509
2509
|
* alert-bearing errors.
|
|
2510
|
-
* - **No `connectionCause
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|