Latest Results
feat(mllp-client): native TypeScript implementation (no framework)
Replace the connection lifecycle with a plain TypeScript client — no state-machine
framework — built on the proven wire engine and codecs carried over from the
XState experiment (#667). This is the "basic standard implementation" the rewrite
baseline recommended.
- client.ts: a thin MllpClient — a phase field (idle/connecting/connected/closed)
+ a single-flight latch. connect/send/close are plain async methods; send() is
`await connection.exchange(...)`, a real request/response Promise. The thing
XState couldn't do (return the response) is just a method return here, because
the client owns the connection object.
- Reuse (framework-agnostic, battle-tested): connection.ts (read loop, decoder,
single in-flight ACK deferred, drop detection), errors.ts, backoff.ts, ack.ts,
the Node adapter, and the whole test suite. Drop main's pre-XState monolith
(duplex.ts, hl7v2.ts, the 760-line client.ts, the 6-state enum, the send signal).
- @glion/ack: bring the additive ackExceptionFor / isAckNakCode helpers.
- docs/mllp-client-rewrite-baseline.md carried over as the design baseline.
Passes the full regression suite unchanged: package 130 tests, monorepo 47/47
types, 87/87 tests, 45/45 build, lint 0/0. Retry/backoff and a FIFO send queue
are the next steps (backoff.ts is in place, not yet wired).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> fix(mllp-client): the send deadline covers the write, and a timeout is connection-terminal
Production-readiness review findings LC-1 (blocker, verified empirically)
and LC-2 (major):
- LC-1: the per-send deadline was created only after writer.write
resolved, so a remote system that accepts the connection but stops
reading (the classic wedged interface engine) parked send() forever —
no SEND_TIMEOUT, no error, the outbound feed silently stalled, while
the docs promised "a send is bounded by its ACK deadline". The deadline
now spans the whole exchange: the write races the deadline signal, and
a deadline that fires mid-write fails the send with SEND_TIMEOUT.
- LC-2: a timed-out send left the connection open, so its late ACK
queued and permanently desynchronized correlation — send N consumed
ACK N-1 and failed INVALID_RESPONSE forever, turning one transient
remote slowdown into a total outage with a duplicate-delivery retry
hazard. A send timeout now drops the connection (the recycling most
MLLP implementations do): after a timeout a late ACK could never be
matched safely, mid-write doubly so (a partial frame may be on the
wire). errors.ts, README, and changeset now state the terminal
semantics; the "connection stays open" guidance is gone.
Pins: wedged-write SEND_TIMEOUT at both client and connection layers;
timeout drops with the timeout on cause; late ACK lands on the dead wire,
never on the next exchange; stalled partials cannot poison later sends.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Latest Branches
0%
dependabot/npm_and_yarn/tools/testing/npm_and_yarn-945fe4de7f 0%
0%
© 2026 CodSpeed Technology