@glion/mllp-client 0.19.0 → 0.21.0
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/README.md +156 -58
- package/dist/assertions.d.ts +9 -2
- package/dist/assertions.d.ts.map +1 -1
- package/dist/chunks/mllp-invalid-option-error.js +32 -0
- package/dist/chunks/mllp-invalid-option-error.js.map +1 -0
- package/dist/client.d.ts +33 -14
- package/dist/client.d.ts.map +1 -1
- package/dist/errors/base.d.ts +0 -1
- package/dist/errors/base.d.ts.map +1 -1
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/mllp-client-closed-error.d.ts +1 -2
- package/dist/errors/mllp-client-closed-error.d.ts.map +1 -1
- package/dist/events.d.ts +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +227 -189
- package/dist/index.js.map +1 -1
- package/dist/messages.d.ts +7 -25
- package/dist/messages.d.ts.map +1 -1
- package/dist/queue.d.ts +25 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/runtime/node.d.ts +29 -7
- package/dist/runtime/node.d.ts.map +1 -1
- package/dist/runtime/node.js +44 -23
- package/dist/runtime/node.js.map +1 -1
- package/dist/runtime/workers.d.ts +33 -0
- package/dist/runtime/workers.d.ts.map +1 -0
- package/dist/runtime/workers.js +70 -0
- package/dist/runtime/workers.js.map +1 -0
- package/dist/state.d.ts +10 -7
- package/dist/state.d.ts.map +1 -1
- package/package.json +29 -12
- package/dist/errors/mllp-already-sending-error.d.ts +0 -14
- package/dist/errors/mllp-already-sending-error.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @glion/mllp-client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An HL7v2 MLLP client for Node.js, Bun, Deno, and Cloudflare Workers.
|
|
4
4
|
|
|
5
5
|
- 📦 **MLLP built in.** Framing, message boundaries and acknowledgment matching are handled. You send a parsed message and get one back.
|
|
6
6
|
- 🔄 **Predictable connection lifecycle.** Timeouts on connecting and on waiting for a reply, connection attempts retried with backoff, TCP keepalive by default, and explicit states you can read.
|
|
7
|
-
- ⚡ **Thin over TCP.** One socket, one message at a time.
|
|
7
|
+
- ⚡ **Thin over TCP.** One socket, one message on the wire at a time. Further sends queue in call order. No worker threads, no polling.
|
|
8
8
|
- 🧯 **Errors you can act on.** Every failure carries a stable code and says whether the connection is still usable.
|
|
9
|
-
- 🧩 **Any transport.** TCP
|
|
9
|
+
- 🧩 **Any transport.** TCP and TLS on Node.js, Bun, Deno, and Cloudflare Workers included. An in-memory or custom socket plugs in behind the same two-method interface.
|
|
10
10
|
- 🔤 **Typed end to end.** TypeScript throughout, with parsed HL7v2 going in and coming out.
|
|
11
11
|
|
|
12
|
-
> **Coming soon** — TLS and Cloudflare Workers adapters. Today the only bundled adapter is Node.js over TCP.
|
|
13
|
-
|
|
14
12
|
## Install
|
|
15
13
|
|
|
16
14
|
```bash
|
|
@@ -171,22 +169,23 @@ Sends one message and resolves with the acknowledgment that answers it. Connects
|
|
|
171
169
|
- `AckException` — the receiver refused the message. The connection stays open.
|
|
172
170
|
- `MllpInvalidMessageError` — no MSH-10, or the message could not be serialized. Nothing was sent.
|
|
173
171
|
- `MllpInvalidOptionError` — `timeoutMs` is out of range. Nothing was sent.
|
|
174
|
-
- `
|
|
175
|
-
- `MllpClientClosedError` — the client is closed.
|
|
172
|
+
- `MllpClientClosedError` — the client is closed, or closed while this send was waiting its turn.
|
|
176
173
|
- `MllpConnectionFailedError`, `MllpConnectionTimeoutError` — the connection could not be opened.
|
|
177
174
|
- `MllpSendTimeoutError`, `MllpConnectionLostError`, `MllpInvalidResponseError` — the exchange failed. These close the connection; see [Errors](#errors).
|
|
175
|
+
- `MllpSendAbortedError` — `destroy()` cut the send off. Delivery is unknown.
|
|
178
176
|
|
|
179
177
|
Every error carries `delivery`, `not-sent` or `unknown`, the one fact a retry needs; see [Errors](#errors).
|
|
180
178
|
|
|
181
|
-
One message at a time.
|
|
179
|
+
One message is on the wire at a time. A `send()` arriving while another is in flight waits its turn, and sends go out in the order they were called, so a batch may be fired at once:
|
|
182
180
|
|
|
183
181
|
```ts
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
182
|
+
const outcomes = await Promise.allSettled(
|
|
183
|
+
batch.map((message) => client.send(message))
|
|
184
|
+
);
|
|
188
185
|
```
|
|
189
186
|
|
|
187
|
+
The queue is in memory and has no bound. `timeoutMs` runs from the moment the write starts, not from the call. A send still waiting when `close()` or `destroy()` is called, or when a failure closes the client, rejects at once with `delivery: "not-sent"`: with `MllpClientClosedError`, or with the failure itself when the failure is one of not being sent, such as the dial's `MllpConnectionFailedError` or `MllpConnectionTimeoutError`, as `connect()` gets. Nothing behind a failed message goes out. See [Does `send()` queue?](#does-send-queue).
|
|
188
|
+
|
|
190
189
|
### `client.connect()`
|
|
191
190
|
|
|
192
191
|
```ts
|
|
@@ -197,7 +196,7 @@ Opens the connection without sending anything, dialing again under the [reconnec
|
|
|
197
196
|
|
|
198
197
|
Idempotent. On a connected client it resolves at once; while an attempt is in flight it waits for the outcome and shares it.
|
|
199
198
|
|
|
200
|
-
**Throws** the last attempt's `MllpConnectionFailedError` or `MllpConnectionTimeoutError`, or `MllpClientClosedError` when the client is already closed or `close()` cancelled the attempt.
|
|
199
|
+
**Throws** the last attempt's `MllpConnectionFailedError` or `MllpConnectionTimeoutError`, or `MllpClientClosedError` when the client is already closed or `close()` or `destroy()` cancelled the attempt.
|
|
201
200
|
|
|
202
201
|
### `client.close()`
|
|
203
202
|
|
|
@@ -205,9 +204,9 @@ Idempotent. On a connected client it resolves at once; while an attempt is in fl
|
|
|
205
204
|
close(): Promise<void>
|
|
206
205
|
```
|
|
207
206
|
|
|
208
|
-
Closes the connection once the message in flight has been acknowledged. New sends are refused from the moment it is called
|
|
207
|
+
Closes the connection once the message in flight has been acknowledged. New sends, and sends still waiting their turn, are refused from the moment it is called with `MllpClientClosedError`; the message in flight is never cut off. Await the sends you want delivered before calling it. An attempt to connect stops at once.
|
|
209
208
|
|
|
210
|
-
Resolves when the connection is down, from any phase. Never throws. Idempotent. The wait is bounded by the in-flight send's own deadline.
|
|
209
|
+
Resolves when the connection is down, from any phase. Never throws. Idempotent. The wait is bounded by the in-flight send's own deadline. If the message it waits for fails, the client closes with that failure; otherwise with `null`, the owner's decision.
|
|
211
210
|
|
|
212
211
|
```ts
|
|
213
212
|
process.on("SIGTERM", async () => {
|
|
@@ -216,13 +215,13 @@ process.on("SIGTERM", async () => {
|
|
|
216
215
|
});
|
|
217
216
|
```
|
|
218
217
|
|
|
219
|
-
### `client.destroy()`
|
|
218
|
+
### `client.destroy(reason?)`
|
|
220
219
|
|
|
221
220
|
```ts
|
|
222
|
-
destroy(): Promise<void>
|
|
221
|
+
destroy(reason?: MllpClientError | null): Promise<void>
|
|
223
222
|
```
|
|
224
223
|
|
|
225
|
-
Closes the connection now, without waiting for anything in flight. A message in flight rejects with `MllpSendAbortedError`. An attempt to connect stops at once.
|
|
224
|
+
Closes the connection now, without waiting for anything in flight. A message in flight rejects with `MllpSendAbortedError`. An attempt to connect stops at once. The client closes with `reason`: the `close` event carries it, and so does `cause` on every later call's `MllpClientClosedError`. Omitted or `null`, the client closed by its owner's decision, as `net.Socket.destroy(error)` does. Sends waiting their turn are rejected with `reason` itself when its delivery is `not-sent`, and with `MllpClientClosedError` carrying `reason` otherwise. Arriving while the client is already closing, it cuts the message in flight and joins the ending under way; `reason` is recorded when no failure is known yet.
|
|
226
225
|
|
|
227
226
|
Resolves when the connection is down, from any phase. Never throws. Idempotent.
|
|
228
227
|
|
|
@@ -243,17 +242,25 @@ Calls `close()`. Lets a client be scoped with `await using`:
|
|
|
243
242
|
readonly state: MllpClientState
|
|
244
243
|
```
|
|
245
244
|
|
|
246
|
-
| Value | Meaning
|
|
247
|
-
| ------------ |
|
|
248
|
-
| `idle` | Nothing opened yet. The first `send()` or `connect()` opens the connection.
|
|
249
|
-
| `connecting` | The connection is being opened, further attempts included.
|
|
250
|
-
| `connected` | Open, with no message in flight.
|
|
251
|
-
| `sending` | A message is on the wire, waiting for its acknowledgment.
|
|
252
|
-
| `closing` |
|
|
253
|
-
| `closed` |
|
|
245
|
+
| Value | Meaning |
|
|
246
|
+
| ------------ | -------------------------------------------------------------------------------- |
|
|
247
|
+
| `idle` | Nothing opened yet. The first `send()` or `connect()` opens the connection. |
|
|
248
|
+
| `connecting` | The connection is being opened, further attempts included. |
|
|
249
|
+
| `connected` | Open, with no message in flight. |
|
|
250
|
+
| `sending` | A message is on the wire, waiting for its acknowledgment. Further sends wait. |
|
|
251
|
+
| `closing` | The client is ending: a message being waited out, or the connection coming down. |
|
|
252
|
+
| `closed` | The connection is down. |
|
|
254
253
|
|
|
255
254
|
A client closes once. After `close()`, `destroy()`, a connection the reconnect policy could not open, or a connection that was lost, every call throws `MllpClientClosedError`; construct a new client to send again.
|
|
256
255
|
|
|
256
|
+
### `client.pending`
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
readonly pending: number
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
How many sends wait their turn, the one in flight excluded. The queue's backlog, for a metric or a backpressure decision; `0` whenever nothing waits.
|
|
263
|
+
|
|
257
264
|
### `client.connected`
|
|
258
265
|
|
|
259
266
|
```ts
|
|
@@ -271,10 +278,10 @@ off<E>(event: E, listener: MllpClientListener<E>): this
|
|
|
271
278
|
|
|
272
279
|
Adds or removes a listener. Both return the client, so calls chain.
|
|
273
280
|
|
|
274
|
-
| Event | Listener | Fires when
|
|
275
|
-
| --------- | ------------------------------------------ |
|
|
276
|
-
| `connect` | `() => void` | The connection opened.
|
|
277
|
-
| `close` | `(error: MllpClientError \| null) => void` | The
|
|
281
|
+
| Event | Listener | Fires when |
|
|
282
|
+
| --------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
283
|
+
| `connect` | `() => void` | The connection opened. |
|
|
284
|
+
| `close` | `(error: MllpClientError \| null) => void` | The connection is down. Fires once, from any phase, even if it never connected. `error` is the failure that closed the client, or `null` when you closed it. |
|
|
278
285
|
|
|
279
286
|
A lost connection is not an event of its own: it closes the client, so `close` fires with the failure. Listeners are synchronous, and one that throws propagates to whatever triggered the event.
|
|
280
287
|
|
|
@@ -288,9 +295,16 @@ client
|
|
|
288
295
|
|
|
289
296
|
## Runtimes
|
|
290
297
|
|
|
291
|
-
The client speaks MLLP over a pair of byte streams and knows nothing else about the transport. That whole dependency is [`MllpSocket`](#custom-socket) — two methods — so supporting a
|
|
298
|
+
The client speaks MLLP over a pair of byte streams and knows nothing else about the transport. That whole dependency is [`MllpSocket`](#custom-socket) — two methods — so supporting a runtime means an adapter, not a fork of the client.
|
|
292
299
|
|
|
293
|
-
|
|
300
|
+
| Runtime | Adapter | Import | TLS | Proven by |
|
|
301
|
+
| ------------------ | -------------------------------------- | ---------------------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
302
|
+
| Node.js ≥ 22 | [`nodeSocket`](#nodejs) | `@glion/mllp-client/node` | [Trust store, CA, client certificate](#tls) | Conformance suite in CI, Node 22 and 24 |
|
|
303
|
+
| Bun | [`nodeSocket`](#nodejs) | `@glion/mllp-client/node` | [Trust store, CA, client certificate](#tls) | Conformance suite in CI, Bun 1.4 |
|
|
304
|
+
| Deno | [`nodeSocket`](#nodejs) | `@glion/mllp-client/node` | [Trust store, CA, client certificate](#tls) | Conformance suite in CI, Deno 2.9 |
|
|
305
|
+
| Cloudflare Workers | [`workersSocket`](#cloudflare-workers) | `@glion/mllp-client/workers` | Public trust store only | Integration suite in CI, inside `workerd`; TCP only, TLS handshake untested ([#626](https://github.com/rethinkhealth/glion/issues/626)) |
|
|
306
|
+
|
|
307
|
+
Every adapter runs the same conformance suite: the [`MllpSocket` contract](#custom-socket) case by case, and the client's behaviour over a real socket scenario by scenario. On Node.js, Bun, and Deno it runs twice, over TCP and over TLS. A custom socket can run it too; see `tests/integration/conformance/` in the package source.
|
|
294
308
|
|
|
295
309
|
### Node.js
|
|
296
310
|
|
|
@@ -300,16 +314,17 @@ import { nodeSocket } from "@glion/mllp-client/node";
|
|
|
300
314
|
nodeSocket(options: NodeSocketOptions): MllpSocket
|
|
301
315
|
```
|
|
302
316
|
|
|
303
|
-
|
|
317
|
+
TCP over `net.Socket`, or TLS over `tls.TLSSocket` when `tls` is set. The same adapter runs on Bun and Deno through their `node:net` and `node:tls` compatibility; no separate import is needed there.
|
|
304
318
|
|
|
305
|
-
| Option | Type
|
|
306
|
-
| ----------------- |
|
|
307
|
-
| `host` | `string`
|
|
308
|
-
| `port` | `number`
|
|
309
|
-
| `
|
|
310
|
-
| `
|
|
319
|
+
| Option | Type | Default | Description |
|
|
320
|
+
| ----------------- | --------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
321
|
+
| `host` | `string` | required | Host name or address of the receiver. |
|
|
322
|
+
| `port` | `number` | required | TCP port of the receiver. |
|
|
323
|
+
| `tls` | `boolean \| NodeTlsOptions` | `false` | TLS for the connection. See [TLS](#tls). |
|
|
324
|
+
| `gracefulCloseMs` | `number` | `1000` | How long a socket gets to end cleanly before it is destroyed. |
|
|
325
|
+
| `keepAliveIdleMs` | `number` | `30000` | Idle time before the first keepalive probe. Once the probes fail, the OS ends the socket, and the next send fails at once with `CONNECTION_LOST` instead of waiting out `sendTimeoutMs`. |
|
|
311
326
|
|
|
312
|
-
`TCP_NODELAY` is set, so a message goes out immediately rather than waiting on Nagle's algorithm.
|
|
327
|
+
`TCP_NODELAY` is set, so a message goes out immediately rather than waiting on Nagle's algorithm. On Bun and Deno the keepalive delay is passed through to the runtime; whether the runtime honours it is not verified.
|
|
313
328
|
|
|
314
329
|
```ts
|
|
315
330
|
const client = new MllpClient({
|
|
@@ -317,6 +332,91 @@ const client = new MllpClient({
|
|
|
317
332
|
});
|
|
318
333
|
```
|
|
319
334
|
|
|
335
|
+
Deno needs `--allow-net` for the receiver's host and port.
|
|
336
|
+
|
|
337
|
+
#### TLS
|
|
338
|
+
|
|
339
|
+
`tls: true` verifies the receiver's certificate against the runtime's trusted CAs, for `host`, and needs no certificate files. `host` is sent as the server name (SNI) unless it is an IP address.
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
nodeSocket({ host: "hl7.example.org", port: 2575, tls: true });
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
An object passes Node's `tls.connect()` options:
|
|
346
|
+
|
|
347
|
+
| Option | Type | Default | Description |
|
|
348
|
+
| -------------------- | --------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
349
|
+
| `ca` | `string \| Buffer \| Array` | Runtime CAs | CA certificates that issued the receiver's certificate, PEM. Replaces the runtime's trusted CAs. |
|
|
350
|
+
| `cert` | `string \| Buffer \| Array` | none | Client certificate chain for mutual TLS, PEM. |
|
|
351
|
+
| `key` | `string \| Buffer \| Array` | none | Private key for `cert`, PEM. |
|
|
352
|
+
| `passphrase` | `string` | none | Passphrase for an encrypted `key` or `pfx`. |
|
|
353
|
+
| `pfx` | `string \| Buffer \| Array` | none | Client certificate and key as PKCS#12. |
|
|
354
|
+
| `servername` | `string` | `host`, unless an IP address | Name the receiver's certificate is verified against, and the SNI name. |
|
|
355
|
+
| `rejectUnauthorized` | `boolean` | `true` | `false` accepts any certificate, including one presented by an attacker. |
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
import { readFileSync } from "node:fs";
|
|
359
|
+
|
|
360
|
+
nodeSocket({
|
|
361
|
+
host: "10.20.0.15",
|
|
362
|
+
port: 2575,
|
|
363
|
+
tls: {
|
|
364
|
+
ca: readFileSync("hospital-ca.pem"),
|
|
365
|
+
cert: readFileSync("client.pem"),
|
|
366
|
+
key: readFileSync("client-key.pem"),
|
|
367
|
+
servername: "hl7.hospital.internal",
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
A receiver dialed by IP address must present a certificate that lists that address, or `servername` must name one the certificate lists.
|
|
373
|
+
|
|
374
|
+
A handshake that fails rejects with [`CONNECTION_FAILED`](#connection_failed), with Node's TLS error on `cause`: for example `UNABLE_TO_VERIFY_LEAF_SIGNATURE` or `ERR_TLS_CERT_ALTNAME_INVALID`.
|
|
375
|
+
|
|
376
|
+
A receiver that refuses the client certificate over TLS 1.2 fails the handshake: [`CONNECTION_FAILED`](#connection_failed), nothing sent. Over TLS 1.3 it refuses after the handshake, so the connection opens and the first `send()` rejects with `CONNECTION_LOST`, delivery `unknown`.
|
|
377
|
+
|
|
378
|
+
On Deno, a wrong `passphrase` does not fail the handshake; the connection opens without the client certificate and fails as a refused client certificate.
|
|
379
|
+
|
|
380
|
+
### Cloudflare Workers
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
import { workersSocket } from "@glion/mllp-client/workers";
|
|
384
|
+
|
|
385
|
+
workersSocket(options: WorkersSocketOptions): MllpSocket
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
TCP or TLS over `cloudflare:sockets`. The module resolves only inside the Workers runtime; import it from the `./workers` subpath, never from `.`.
|
|
389
|
+
|
|
390
|
+
| Option | Type | Default | Description |
|
|
391
|
+
| ------ | --------- | -------- | --------------------------------------------------------------------------------------------- |
|
|
392
|
+
| `host` | `string` | required | Host name or address of the receiver. |
|
|
393
|
+
| `port` | `number` | required | TCP port of the receiver. |
|
|
394
|
+
| `tls` | `boolean` | `false` | `true` verifies the receiver's certificate against the public CAs Workers trusts, for `host`. |
|
|
395
|
+
|
|
396
|
+
```ts
|
|
397
|
+
import { MllpClient } from "@glion/mllp-client";
|
|
398
|
+
import { workersSocket } from "@glion/mllp-client/workers";
|
|
399
|
+
|
|
400
|
+
export default {
|
|
401
|
+
async fetch(request: Request): Promise<Response> {
|
|
402
|
+
await using client = new MllpClient({
|
|
403
|
+
socket: workersSocket({ host: "hl7.example.org", port: 2575 }),
|
|
404
|
+
});
|
|
405
|
+
const ack = await client.send(await messageFrom(request));
|
|
406
|
+
return Response.json({ code: ack.code, controlId: ack.controlId });
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
What differs from Node:
|
|
412
|
+
|
|
413
|
+
- A Worker reaches only endpoints routable from Cloudflare's network. A receiver on a private network needs a publicly reachable endpoint in front of it.
|
|
414
|
+
- `close()` resolves as soon as the runtime has ended the socket; there is no grace window.
|
|
415
|
+
- Locally, under Miniflare (`wrangler dev` or the Vitest integration), connections go through a proxy, so `MllpConnectionFailedError.cause` carries the proxy's message rather than a socket error code. `code` is the same in both.
|
|
416
|
+
- Locally, under Miniflare, a `tls: true` connection fails with the proxy's message, whatever certificate the receiver presents. TLS to a receiver works only when the Worker runs on Cloudflare.
|
|
417
|
+
- Cloudflare blocks some destination ports.
|
|
418
|
+
- `tls` takes no CA, client certificate, or server name. The receiver must present a publicly trusted certificate for `host`, so dial a host name rather than an address. Any value other than a boolean throws `MllpInvalidOptionError`.
|
|
419
|
+
|
|
320
420
|
### Custom Socket
|
|
321
421
|
|
|
322
422
|
You can expand `MllpSocket` to build a custom socket to one remote system, which the client opens, uses, and ends.
|
|
@@ -350,10 +450,10 @@ A rejection from the receiver is **not** an `MllpClientError` — see [`AckExcep
|
|
|
350
450
|
|
|
351
451
|
`delivery` is the one fact a retry decision needs:
|
|
352
452
|
|
|
353
|
-
| `delivery` | Meaning | Codes
|
|
354
|
-
| ---------- | --------------------------------------------------------------------------------- |
|
|
355
|
-
| `not-sent` | Nothing reached the wire. The message may be sent again as it is. | `INVALID_OPTION`, `INVALID_MESSAGE`, `
|
|
356
|
-
| `unknown` | The message may have reached the receiver. Sending it again may deliver it twice. | `SEND_TIMEOUT`, `CONNECTION_LOST`, `SEND_ABORTED`, `INVALID_RESPONSE`
|
|
453
|
+
| `delivery` | Meaning | Codes |
|
|
454
|
+
| ---------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
455
|
+
| `not-sent` | Nothing reached the wire. The message may be sent again as it is. | `INVALID_OPTION`, `INVALID_MESSAGE`, `CLOSED`, `CONNECTION_FAILED`, `CONNECTION_TIMEOUT` |
|
|
456
|
+
| `unknown` | The message may have reached the receiver. Sending it again may deliver it twice. | `SEND_TIMEOUT`, `CONNECTION_LOST`, `SEND_ABORTED`, `INVALID_RESPONSE` |
|
|
357
457
|
|
|
358
458
|
```ts
|
|
359
459
|
import { MllpClientError, MllpErrorCode } from "@glion/mllp-client";
|
|
@@ -381,7 +481,7 @@ The four failures of the wire — `CONNECTION_FAILED`, `CONNECTION_TIMEOUT`, `SE
|
|
|
381
481
|
|
|
382
482
|
`MllpInvalidOptionError` · delivery `not-sent`
|
|
383
483
|
|
|
384
|
-
A constructor option or a per-send `timeoutMs` is out of range — a timeout that is not a positive number of milliseconds, a `maxBufferedBytes` that is not a positive integer, or a `reconnect.attempts` that is not a non-negative integer or `Infinity`. The message names which one.
|
|
484
|
+
A constructor option or a per-send `timeoutMs` is out of range — a timeout that is not a positive number of milliseconds, a `maxBufferedBytes` that is not a positive integer, or a `reconnect.attempts` that is not a non-negative integer or `Infinity`. `workersSocket()` also throws it for a `tls` that is not a boolean. The message names which one.
|
|
385
485
|
|
|
386
486
|
Thrown before anything is opened or sent. A configuration bug, not a runtime condition.
|
|
387
487
|
|
|
@@ -393,29 +493,21 @@ The message cannot be sent as it stands: no MSH-10 control ID, or it could not b
|
|
|
393
493
|
|
|
394
494
|
**Nothing reached the wire and the connection is still in step**, so the next message can go out on it. Fix or quarantine the message; do not reconnect.
|
|
395
495
|
|
|
396
|
-
### `ALREADY_SENDING`
|
|
397
|
-
|
|
398
|
-
`MllpAlreadySendingError` · delivery `not-sent` · field: `controlId`
|
|
399
|
-
|
|
400
|
-
`send()` was called while another send was in flight. `controlId` identifies the message already on the wire.
|
|
401
|
-
|
|
402
|
-
The client is lockstep by design. Await each send before starting the next, or give each concurrent stream its own client.
|
|
403
|
-
|
|
404
496
|
### `CLOSED`
|
|
405
497
|
|
|
406
498
|
`MllpClientClosedError` · delivery `not-sent` · field: `cause`
|
|
407
499
|
|
|
408
|
-
The client is closed, so the call cannot be served. Also the error a `connect()` gets when `close()` cancelled the attempt it was waiting for.
|
|
500
|
+
The client is closed or closing, so the call cannot be served. Also the error a `connect()` gets when `close()` or `destroy()` cancelled the attempt it was waiting for, and the error a `send()` gets when the client closed while it was waiting its turn; a send waiting behind a dial that failed gets the dial's error instead.
|
|
409
501
|
|
|
410
|
-
A client closes once. Construct a new one to send again. When the client closed
|
|
502
|
+
A client closes once. Construct a new one to send again. When the client closed on a failure, `cause` is that failure: the last attempt's `CONNECTION_FAILED` or `CONNECTION_TIMEOUT` when the reconnect policy gave up, the `CONNECTION_LOST`, `SEND_TIMEOUT`, or `INVALID_RESPONSE` that ended an earlier message, including one `close()` was waiting out, or the `reason` given to `destroy()`.
|
|
411
503
|
|
|
412
504
|
### `CONNECTION_FAILED`
|
|
413
505
|
|
|
414
506
|
`MllpConnectionFailedError` · delivery `not-sent` · field: `cause`
|
|
415
507
|
|
|
416
|
-
The socket could not be opened. `cause` carries the underlying error — `ECONNREFUSED`, `ENOTFOUND`, `EHOSTUNREACH
|
|
508
|
+
The socket could not be opened. `cause` carries the underlying error — `ECONNREFUSED`, `ENOTFOUND`, `EHOSTUNREACH`, or a TLS error such as `UNABLE_TO_VERIFY_LEAF_SIGNATURE`.
|
|
417
509
|
|
|
418
|
-
Check host, port,
|
|
510
|
+
Check host, port, whether a firewall allows the route, and, over TLS, the certificate the receiver presents. Nothing was opened, so there is nothing to close.
|
|
419
511
|
|
|
420
512
|
### `CONNECTION_TIMEOUT`
|
|
421
513
|
|
|
@@ -423,7 +515,7 @@ Check host, port, and whether a firewall allows the route. Nothing was opened, s
|
|
|
423
515
|
|
|
424
516
|
The receiver did not accept the connection within `connectTimeoutMs`.
|
|
425
517
|
|
|
426
|
-
Typically a packet-dropping firewall rather than a refused connection — a refusal arrives fast and surfaces as `CONNECTION_FAILED`.
|
|
518
|
+
Typically a packet-dropping firewall rather than a refused connection — a refusal arrives fast and surfaces as `CONNECTION_FAILED`. With `tls` set, also a receiver that speaks plain TCP and never answers the TLS handshake.
|
|
427
519
|
|
|
428
520
|
### `SEND_TIMEOUT`
|
|
429
521
|
|
|
@@ -489,6 +581,12 @@ Clients that pipeline can survive a timeout, because they keep a table of outsta
|
|
|
489
581
|
|
|
490
582
|
The client closes with the failure, and never sends the failed message again — only you know whether the receiver already has it. Construct a new client to go on, as you would open a new socket.
|
|
491
583
|
|
|
584
|
+
### Does `send()` queue?
|
|
585
|
+
|
|
586
|
+
Yes, in memory and without a bound. A `send()` arriving while a message is on the wire waits for that message's acknowledgment, then goes out; sends leave in the order they were called, one at a time, so an A01 fired before its A03 reaches the receiver first. Nothing goes out behind a message whose delivery is unknown: a failure closes the client, and every send still waiting rejects with `CLOSED` and `delivery: "not-sent"`. A send waiting behind a dial that fails rejects with the dial's error, as `connect()` does.
|
|
587
|
+
|
|
588
|
+
The queue exists only in this process. A message waiting in it is not on disk, so a crash loses it without a trace, and a producer faster than the receiver grows it without limit. An interface that must not lose events keeps its own persistent outbound queue and hands the client one message at a time; the client's line is for a batch whose outcomes the caller is awaiting.
|
|
589
|
+
|
|
492
590
|
### Why a socket rather than a host and port?
|
|
493
591
|
|
|
494
592
|
The client handles MLLP and deliberately handles no transport. Putting the whole runtime dependency behind two methods means the same client runs over TCP, TLS, a Unix socket, or a pair of in-memory streams — and the test suite covers every lifecycle path without opening a port.
|
package/dist/assertions.d.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Option validation. Each `assert*`
|
|
3
|
-
* an option a caller passed out of
|
|
2
|
+
* Option validation, and the client's invariants. Each option `assert*`
|
|
3
|
+
* throws {@link MllpInvalidOptionError} for an option a caller passed out of
|
|
4
|
+
* range, before anything happens. {@link assertPhase} throws for a phase the
|
|
5
|
+
* client cannot be in where it is asserted: a bug.
|
|
4
6
|
*
|
|
5
7
|
* @module
|
|
6
8
|
*/
|
|
9
|
+
import type { State } from "./state";
|
|
7
10
|
export declare function assertTimeoutMs(option: string, ms: number): void;
|
|
8
11
|
export declare function assertByteCap(bytes: number): void;
|
|
12
|
+
/** `state` is in `phase`; `where` names the site for the report. */
|
|
13
|
+
export declare function assertPhase<P extends State["phase"]>(state: State, phase: P, where: string): asserts state is Extract<State, {
|
|
14
|
+
phase: P;
|
|
15
|
+
}>;
|
|
9
16
|
export declare function assertReconnectAttempts(attempts: number): void;
|
|
10
17
|
//# sourceMappingURL=assertions.d.ts.map
|
package/dist/assertions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAMhE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMjD;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,CAAC,SAAS,KAAK,CAAC,OAAO,CAAC,EAClD,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,CAAC,EACR,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,CAM/C;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAO9D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/errors/base.ts
|
|
2
|
+
/**
|
|
3
|
+
* The base every client error extends, and what each one carries: a fixed
|
|
4
|
+
* `code`, a fixed message, what became of the message, and the lower layer's
|
|
5
|
+
* failure on `cause`.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
const MllpErrorCode = {
|
|
10
|
+
CLOSED: "CLOSED",
|
|
11
|
+
CONNECTION_FAILED: "CONNECTION_FAILED",
|
|
12
|
+
CONNECTION_LOST: "CONNECTION_LOST",
|
|
13
|
+
CONNECTION_TIMEOUT: "CONNECTION_TIMEOUT",
|
|
14
|
+
INVALID_MESSAGE: "INVALID_MESSAGE",
|
|
15
|
+
INVALID_OPTION: "INVALID_OPTION",
|
|
16
|
+
INVALID_RESPONSE: "INVALID_RESPONSE",
|
|
17
|
+
SEND_ABORTED: "SEND_ABORTED",
|
|
18
|
+
SEND_TIMEOUT: "SEND_TIMEOUT"
|
|
19
|
+
};
|
|
20
|
+
var MllpClientError = class extends Error {};
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/errors/mllp-invalid-option-error.ts
|
|
23
|
+
/** An option is out of range. Raised before anything happens. */
|
|
24
|
+
var MllpInvalidOptionError = class extends MllpClientError {
|
|
25
|
+
name = "MllpInvalidOptionError";
|
|
26
|
+
code = MllpErrorCode.INVALID_OPTION;
|
|
27
|
+
delivery = "not-sent";
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { MllpClientError as n, MllpErrorCode as r, MllpInvalidOptionError as t };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=mllp-invalid-option-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mllp-invalid-option-error.js","names":[],"sources":["../../src/errors/base.ts","../../src/errors/mllp-invalid-option-error.ts"],"sourcesContent":["/**\n * The base every client error extends, and what each one carries: a fixed\n * `code`, a fixed message, what became of the message, and the lower layer's\n * failure on `cause`.\n *\n * @module\n */\n\nexport const MllpErrorCode = {\n CLOSED: \"CLOSED\",\n CONNECTION_FAILED: \"CONNECTION_FAILED\",\n CONNECTION_LOST: \"CONNECTION_LOST\",\n CONNECTION_TIMEOUT: \"CONNECTION_TIMEOUT\",\n INVALID_MESSAGE: \"INVALID_MESSAGE\",\n INVALID_OPTION: \"INVALID_OPTION\",\n INVALID_RESPONSE: \"INVALID_RESPONSE\",\n SEND_ABORTED: \"SEND_ABORTED\",\n SEND_TIMEOUT: \"SEND_TIMEOUT\",\n} as const;\n\nexport type MllpErrorCode = (typeof MllpErrorCode)[keyof typeof MllpErrorCode];\n\n/**\n * What became of the message. `not-sent`: nothing reached the wire, and the\n * message may be sent again as it is. `unknown`: it may have reached the\n * remote system, and sending it again may deliver it twice.\n */\nexport type MllpDelivery = \"not-sent\" | \"unknown\";\n\nexport abstract class MllpClientError extends Error {\n abstract readonly code: MllpErrorCode;\n abstract readonly delivery: MllpDelivery;\n}\n","import { MllpClientError, MllpErrorCode } from \"./base\";\n\n/** An option is out of range. Raised before anything happens. */\nexport class MllpInvalidOptionError extends MllpClientError {\n override readonly name = \"MllpInvalidOptionError\";\n readonly code = MllpErrorCode.INVALID_OPTION;\n readonly delivery = \"not-sent\";\n}\n"],"mappings":";;;;;;;;AAQA,MAAa,gBAAgB;CAC3B,QAAQ;CACR,mBAAmB;CACnB,iBAAiB;CACjB,oBAAoB;CACpB,iBAAiB;CACjB,gBAAgB;CAChB,kBAAkB;CAClB,cAAc;CACd,cAAc;CACf;AAWD,IAAsB,kBAAtB,cAA8C,MAAM;;;;AC1BpD,IAAa,yBAAb,cAA4C,gBAAgB;CAC1D,OAAyB;CACzB,OAAgB,cAAc;CAC9B,WAAoB"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { Root } from "@glion/ast";
|
|
2
|
+
import { MllpClientError } from "./errors";
|
|
2
3
|
import { MllpClientEmitter } from "./events";
|
|
3
4
|
import type { MllpClientOptions, MllpClientResponse, MllpClientState, MllpSendOptions } from "./types";
|
|
4
5
|
/**
|
|
5
6
|
* Sends HL7v2 messages to one remote system over MLLP and returns each
|
|
6
7
|
* message's acknowledgment.
|
|
7
8
|
*
|
|
8
|
-
* One client owns one socket and
|
|
9
|
-
* the message, waits for the acknowledgment, checks that it
|
|
10
|
-
* message, and resolves with it.
|
|
9
|
+
* One client owns one socket and puts one message on the wire at a time.
|
|
10
|
+
* `send()` writes the message, waits for the acknowledgment, checks that it
|
|
11
|
+
* answers this message, and resolves with it. A send arriving while another
|
|
12
|
+
* is in flight waits its turn; sends go out in the order they were called.
|
|
11
13
|
*
|
|
12
14
|
* ```ts
|
|
13
15
|
* import { MllpClient } from "@glion/mllp-client";
|
|
@@ -47,6 +49,8 @@ export declare class MllpClient extends MllpClientEmitter {
|
|
|
47
49
|
* `closing`, or `closed`.
|
|
48
50
|
*/
|
|
49
51
|
get state(): MllpClientState;
|
|
52
|
+
/** How many sends wait their turn, the one in flight excluded. */
|
|
53
|
+
get pending(): number;
|
|
50
54
|
/** Whether the connection is open. True in both `connected` and `sending`. */
|
|
51
55
|
get connected(): boolean;
|
|
52
56
|
/**
|
|
@@ -59,23 +63,30 @@ export declare class MllpClient extends MllpClientEmitter {
|
|
|
59
63
|
* @throws {MllpConnectionFailedError} The last attempt could not open the
|
|
60
64
|
* socket.
|
|
61
65
|
* @throws {MllpConnectionTimeoutError} The last attempt did not open in time.
|
|
62
|
-
* @throws {MllpClientClosedError} The client is closed, or `close()`
|
|
63
|
-
* while the connection was still being established.
|
|
66
|
+
* @throws {MllpClientClosedError} The client is closed, or `close()` or
|
|
67
|
+
* `destroy()` arrived while the connection was still being established.
|
|
64
68
|
*/
|
|
65
69
|
connect(): Promise<void>;
|
|
66
70
|
/**
|
|
67
71
|
* Sends one message and returns its acknowledgment. Connects first when the
|
|
68
|
-
* client is not connected yet
|
|
72
|
+
* client is not connected yet, and waits for the send in flight, if any,
|
|
73
|
+
* before writing.
|
|
74
|
+
*
|
|
75
|
+
* Sends go out in the order `send()` was called. The queue has no bound.
|
|
76
|
+
* `timeoutMs` runs from the moment the write starts, not from the call. A
|
|
77
|
+
* send still waiting when the client closes rejects with
|
|
78
|
+
* {@link MllpClientClosedError}; one waiting behind a dial that fails
|
|
79
|
+
* rejects with the dial's error, as `connect()` does.
|
|
69
80
|
*
|
|
70
81
|
* Nothing is written when an option, phase, or message error is thrown.
|
|
71
|
-
* Every
|
|
82
|
+
* Every wire failure also closes the client; a NAK does not.
|
|
72
83
|
*
|
|
73
84
|
* @throws {AckException} The remote system answered with a NAK. The
|
|
74
85
|
* connection stays open.
|
|
75
86
|
* @throws {MllpInvalidOptionError} `timeoutMs` is out of range.
|
|
76
87
|
* @throws {MllpInvalidMessageError} The message cannot be sent as-is.
|
|
77
|
-
* @throws {MllpClientClosedError} The client is closed
|
|
78
|
-
*
|
|
88
|
+
* @throws {MllpClientClosedError} The client is closed, or closed while
|
|
89
|
+
* this send was waiting its turn.
|
|
79
90
|
* @throws {MllpConnectionFailedError} The connection could not be opened.
|
|
80
91
|
* @throws {MllpConnectionTimeoutError} The connection did not open in time.
|
|
81
92
|
* @throws {MllpSendTimeoutError} No acknowledgment arrived in time.
|
|
@@ -87,21 +98,29 @@ export declare class MllpClient extends MllpClientEmitter {
|
|
|
87
98
|
send(message: Root, opts?: MllpSendOptions): Promise<MllpClientResponse>;
|
|
88
99
|
/**
|
|
89
100
|
* Ends the connection once the message in flight is acknowledged, and
|
|
90
|
-
* resolves when it is down. New sends
|
|
91
|
-
* called. An attempt to connect stops at
|
|
101
|
+
* resolves when it is down. New sends, and sends waiting their turn, are
|
|
102
|
+
* refused from the moment this is called. An attempt to connect stops at
|
|
103
|
+
* once.
|
|
92
104
|
*
|
|
93
105
|
* Resolves from any phase. Never rejects. Idempotent. The wait is bounded by
|
|
94
106
|
* the in-flight send's own deadline; {@link destroy} does not wait at all.
|
|
107
|
+
* If the message it waits for fails, the client closes with that failure;
|
|
108
|
+
* otherwise with `null`.
|
|
95
109
|
*/
|
|
96
110
|
close(): Promise<void>;
|
|
97
111
|
/**
|
|
98
112
|
* Ends the connection now, and resolves when it is down. A message in flight
|
|
99
113
|
* rejects with {@link MllpSendAbortedError}. An attempt to connect stops at
|
|
100
|
-
* once.
|
|
114
|
+
* once. The client closes with `reason`: the failure it reports on `close`
|
|
115
|
+
* and on every later call, or `null` for the owner's own decision.
|
|
101
116
|
*
|
|
102
|
-
* Resolves from any phase. Never rejects. Idempotent.
|
|
117
|
+
* Resolves from any phase. Never rejects. Idempotent. Sends waiting their
|
|
118
|
+
* turn are rejected with `reason` when its delivery is `not-sent`, and with
|
|
119
|
+
* {@link MllpClientClosedError} carrying `reason` otherwise. Arriving while
|
|
120
|
+
* the client is already closing, it cuts the message in flight and joins
|
|
121
|
+
* the ending under way; `reason` is recorded when no failure is known yet.
|
|
103
122
|
*/
|
|
104
|
-
destroy(): Promise<void>;
|
|
123
|
+
destroy(reason?: MllpClientError | null): Promise<void>;
|
|
105
124
|
/** Calls {@link close}. Enables `await using`. */
|
|
106
125
|
[Symbol.asyncDispose](): Promise<void>;
|
|
107
126
|
}
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAevC,OAAO,EAEL,eAAe,EAIhB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAQ7C,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,EAEhB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,UAAW,SAAQ,iBAAiB;;IAQ/C;;;OAGG;gBACS,IAAI,EAAE,iBAAiB;IA0BnC;;;OAGG;IACH,IAAI,KAAK,IAAI,eAAe,CAE3B;IAED,kEAAkE;IAClE,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,8EAA8E;IAC9E,IAAI,SAAS,IAAI,OAAO,CAGvB;IAED;;;;;;;;;;;;OAYG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC9B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,IAAI,CACR,OAAO,EAAE,IAAI,EACb,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,kBAAkB,CAAC;IA0B9B;;;;;;;;;;OAUG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B5B;;;;;;;;;;;OAWG;IACG,OAAO,CAAC,MAAM,GAAE,eAAe,GAAG,IAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CnE,kDAAkD;IAC5C,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;CAkJ7C"}
|
package/dist/errors/base.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/errors/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/errors/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;CAUhB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAE/E;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAElD,8BAAsB,eAAgB,SAAQ,KAAK;IACjD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;CAC1C"}
|
package/dist/errors/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { MllpClientError } from "./base";
|
|
2
2
|
/**
|
|
3
3
|
* The call cannot be served: the client is closed, by `close()`, by
|
|
4
|
-
* `destroy()`, or by a
|
|
5
|
-
* That last failure is on `cause`.
|
|
4
|
+
* `destroy()`, or by a failure. The failure is on `cause`.
|
|
6
5
|
*/
|
|
7
6
|
export declare class MllpClientClosedError extends MllpClientError {
|
|
8
7
|
readonly name = "MllpClientClosedError";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mllp-client-closed-error.d.ts","sourceRoot":"","sources":["../../src/errors/mllp-client-closed-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,QAAQ,CAAC;AAExD
|
|
1
|
+
{"version":3,"file":"mllp-client-closed-error.d.ts","sourceRoot":"","sources":["../../src/errors/mllp-client-closed-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,QAAQ,CAAC;AAExD;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,eAAe;IACxD,SAAkB,IAAI,2BAA2B;IACjD,QAAQ,CAAC,IAAI,WAAwB;IACrC,QAAQ,CAAC,QAAQ,cAAc;gBAEnB,KAAK,GAAE,eAAe,GAAG,IAAW;CAQjD"}
|
package/dist/events.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ export interface MllpClientEvents {
|
|
|
8
8
|
/** The connection is open and ready for messages. */
|
|
9
9
|
connect(): void;
|
|
10
10
|
/**
|
|
11
|
-
* The
|
|
12
|
-
*
|
|
11
|
+
* The connection is down and the client will not connect again. `error` is
|
|
12
|
+
* the failure that closed it, or `null` when the owner did.
|
|
13
13
|
*/
|
|
14
14
|
close(error: MllpClientError | null): void;
|
|
15
15
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,6 @@ export { MllpClient } from "./client";
|
|
|
15
15
|
export { MllpClientEmitter } from "./events";
|
|
16
16
|
export type { MllpClientEvent, MllpClientEvents, MllpClientListener, } from "./events";
|
|
17
17
|
export type { MllpClientOptions, MllpClientResponse, MllpClientState, MllpReconnectOptions, MllpSendOptions, MllpSocket, MllpStreams, } from "./types";
|
|
18
|
-
export {
|
|
18
|
+
export { MllpClientClosedError, MllpClientError, MllpConnectionError, MllpConnectionFailedError, MllpConnectionLostError, MllpConnectionTimeoutError, MllpErrorCode, MllpInvalidMessageError, MllpInvalidOptionError, MllpInvalidResponseError, MllpSendAbortedError, MllpSendTimeoutError, } from "./errors";
|
|
19
19
|
export type { MllpDelivery } from "./errors";
|
|
20
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|