@glion/mllp-client 0.16.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/LICENSE +21 -0
- package/README.md +326 -0
- package/dist/client.js +549 -0
- package/dist/client.js.map +1 -0
- package/dist/core/acknowledgment.d.ts +103 -0
- package/dist/core/acknowledgment.d.ts.map +1 -0
- package/dist/core/client.d.ts +256 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/connect.d.ts +101 -0
- package/dist/core/connect.d.ts.map +1 -0
- package/dist/core/errors.d.ts +81 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/index.d.ts +23 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +2 -0
- package/dist/core/internal/ack-parser-stream.d.ts +22 -0
- package/dist/core/internal/ack-parser-stream.d.ts.map +1 -0
- package/dist/core/internal/subscribe-abort.d.ts +30 -0
- package/dist/core/internal/subscribe-abort.d.ts.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/node.js +214 -0
- package/dist/node.js.map +1 -0
- package/dist/runtimes/internal/node-error-mapping.d.ts +68 -0
- package/dist/runtimes/internal/node-error-mapping.d.ts.map +1 -0
- package/dist/runtimes/node.d.ts +47 -0
- package/dist/runtimes/node.d.ts.map +1 -0
- package/dist/runtimes/node.js +3 -0
- package/dist/runtimes/workers.d.ts +64 -0
- package/dist/runtimes/workers.d.ts.map +1 -0
- package/dist/runtimes/workers.js +143 -0
- package/dist/runtimes/workers.js.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acknowledgment parsing for the MLLP client.
|
|
3
|
+
*
|
|
4
|
+
* This module owns three things:
|
|
5
|
+
*
|
|
6
|
+
* 1. The {@link Acknowledgment} interface — a structured view of an ACK message
|
|
7
|
+
* exposing the fields callers most often need (MSA-1/2/3, ERR-3/4) without
|
|
8
|
+
* forcing them to walk the AST themselves.
|
|
9
|
+
* 2. {@link parseAck} — turns a raw wire-format ACK string into an
|
|
10
|
+
* {@link Acknowledgment}, or throws {@link MllpClientError} when the payload
|
|
11
|
+
* is not a recognisable ACK.
|
|
12
|
+
* 3. {@link throwOnNak} — inspects an {@link Acknowledgment} and throws the
|
|
13
|
+
* matching `AckException` subclass when MSA-1 indicates a NAK.
|
|
14
|
+
*
|
|
15
|
+
* Both helpers are internal to the package — only the {@link Acknowledgment}
|
|
16
|
+
* type is re-exported from `@glion/mllp-client`. Application code interacts
|
|
17
|
+
* with parsed acknowledgments through the return value (and thrown errors)
|
|
18
|
+
* of `MllpClient.send()`.
|
|
19
|
+
*
|
|
20
|
+
* The HL7v2 ACK structure used here (Section 2.9.2 of the HL7v2 standard):
|
|
21
|
+
*
|
|
22
|
+
* MSH | header (sender, receiver, timestamp, message control id) MSA |
|
|
23
|
+
* acknowledgment code (MSA-1), original control id (MSA-2), text (MSA-3) ERR |
|
|
24
|
+
* optional error segment with HL7 condition code (ERR-3) and severity (ERR-4)
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
import type { AckCodeValue } from "@glion/ack";
|
|
29
|
+
import type { Root } from "@glion/ast";
|
|
30
|
+
/**
|
|
31
|
+
* An HL7v2 acknowledgment message returned by an MLLP receiver, with
|
|
32
|
+
* structured access to the fields callers most often need.
|
|
33
|
+
*
|
|
34
|
+
* Returned by `MllpClient.send()` on AA/CA. On NAK (AE/AR/CE/CR) an
|
|
35
|
+
* `AckException` is thrown instead — the same shape is available there
|
|
36
|
+
* via `error.message` (MSA-3), `error.errorCode` (ERR-3), `error.severity`
|
|
37
|
+
* (ERR-4), and `error.raw` (the wire ACK).
|
|
38
|
+
*/
|
|
39
|
+
export interface Acknowledgment {
|
|
40
|
+
/** The raw HL7v2 ACK message as received from the wire. */
|
|
41
|
+
readonly raw: string;
|
|
42
|
+
/**
|
|
43
|
+
* The full ACK message AST, typed against `@glion/ast`. Use for
|
|
44
|
+
* advanced inspection beyond the structured fields below; consumers
|
|
45
|
+
* that walk the tree should install `@glion/ast` for the type.
|
|
46
|
+
*/
|
|
47
|
+
readonly tree: Root;
|
|
48
|
+
/**
|
|
49
|
+
* MSA-1 acknowledgment code.
|
|
50
|
+
*
|
|
51
|
+
* Typed as the standard {@link AckCodeValue} union (`AA`, `AE`, `AR`,
|
|
52
|
+
* `CA`, `CE`, `CR`) widened with an opaque `string` escape hatch — the
|
|
53
|
+
* `(string & {})` form preserves auto-completion for the standard
|
|
54
|
+
* codes while still accepting vendor-specific values that real
|
|
55
|
+
* receivers occasionally send.
|
|
56
|
+
*/
|
|
57
|
+
readonly code: AckCodeValue | (string & {});
|
|
58
|
+
/** MSA-2 message control ID — references the original message's MSH-10. */
|
|
59
|
+
readonly controlId: string;
|
|
60
|
+
/** MSA-3 text message. Typically populated on NAK; optional on accept ACKs. */
|
|
61
|
+
readonly textMessage: string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* ERR-3 HL7 error condition code (Table 0357). Present when an ERR segment is
|
|
64
|
+
* included.
|
|
65
|
+
*/
|
|
66
|
+
readonly errorCode: string | undefined;
|
|
67
|
+
/** ERR-4 severity (Table 0516). Present when an ERR segment is included. */
|
|
68
|
+
readonly severity: string | undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns `true` for any acknowledgment code that should terminate the
|
|
72
|
+
* client's read loop. Intermediate codes (CA) return `false`; every
|
|
73
|
+
* other code — including vendor-specific values — is treated as final
|
|
74
|
+
* to avoid hanging on responses we do not recognise.
|
|
75
|
+
*/
|
|
76
|
+
export declare function isFinalAckCode(code: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Parse a raw ACK frame string into an {@link Acknowledgment}.
|
|
79
|
+
*
|
|
80
|
+
* Field extraction is delegated to `@glion/util-query`'s `value()` helper —
|
|
81
|
+
* this is the same path used elsewhere in the Glion stack and avoids
|
|
82
|
+
* hand-rolling AST traversal here.
|
|
83
|
+
*
|
|
84
|
+
* Throws `MllpClientError(MALFORMED_ACK)` when:
|
|
85
|
+
*
|
|
86
|
+
* - The parser fails to produce a tree (malformed HL7v2), or
|
|
87
|
+
* - MSA-1 is missing (the message is not a valid acknowledgment).
|
|
88
|
+
*
|
|
89
|
+
* Other missing fields (MSA-3, ERR-3, ERR-4) are not fatal — they are
|
|
90
|
+
* exposed as `undefined` because real-world ACKs frequently omit them.
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseAck(raw: string): Acknowledgment;
|
|
93
|
+
/**
|
|
94
|
+
* Inspect an {@link Acknowledgment} and throw the matching `AckException`
|
|
95
|
+
* subclass when MSA-1 indicates a NAK. Returns the acknowledgment unchanged
|
|
96
|
+
* on AA/CA.
|
|
97
|
+
*
|
|
98
|
+
* The thrown exception mirrors the receiver-side exception types — a
|
|
99
|
+
* caller that already handles `AckApplicationError` from a server's
|
|
100
|
+
* middleware can reuse the same `catch` blocks here.
|
|
101
|
+
*/
|
|
102
|
+
export declare function throwOnNak(ack: Acknowledgment): Acknowledgment;
|
|
103
|
+
//# sourceMappingURL=acknowledgment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acknowledgment.d.ts","sourceRoot":"","sources":["../../src/core/acknowledgment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,OAAO,KAAK,EACV,YAAY,EAKb,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAUvC;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB;;;;;;;;OAQG;IAEH,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC5C,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAgCD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAmBpD;AAuBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,cAAc,CAK9D"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-free core of `@glion/mllp-client`.
|
|
3
|
+
*
|
|
4
|
+
* This module owns {@link MllpClient}, the class application code
|
|
5
|
+
* instantiates to send HL7v2 messages and receive acknowledgments.
|
|
6
|
+
* The class is **transport-agnostic**: it composes a Web-Streams
|
|
7
|
+
* pipeline (`socket → decoder → ack-parser`) and consumes parsed
|
|
8
|
+
* acknowledgments from the readable side. It does **not** know how
|
|
9
|
+
* to open a TCP/TLS connection. That concern is supplied by a
|
|
10
|
+
* {@link MllpConnect} function passed in via
|
|
11
|
+
* {@link MllpClientOptions.connect}. Per-runtime adapters
|
|
12
|
+
* (`@glion/mllp-client/node`, `/deno`, `/workers`) ship pre-wired
|
|
13
|
+
* `MllpClient` subclasses so the common case stays a single import.
|
|
14
|
+
*
|
|
15
|
+
* Each call to `client.send()` performs one short-lived round trip:
|
|
16
|
+
*
|
|
17
|
+
* ┌─────────────┐ ① connect ┌──────────┐
|
|
18
|
+
* │ client │ ───────────────▶ │ duplex │
|
|
19
|
+
* │ │ └────┬─────┘
|
|
20
|
+
* │ │ ② write MLLP frame │
|
|
21
|
+
* │ │ ─────────────────────▶│ <VT> ... <FS><CR>
|
|
22
|
+
* │ │ │
|
|
23
|
+
* │ │ ③ read frames via │
|
|
24
|
+
* │ │ decoder + parser │
|
|
25
|
+
* │ │ ◀─────────────────────│ <VT> ACK <FS><CR> ...
|
|
26
|
+
* │ │ ┌────┴─────┐
|
|
27
|
+
* │ │ ④ close + parse │ duplex │ closed
|
|
28
|
+
* └─────────────┘ └──────────┘
|
|
29
|
+
*
|
|
30
|
+
* The four phases share a single deadline ({@link MllpClientOptions.timeout}).
|
|
31
|
+
* If any phase exceeds the budget, the duplex is closed and a typed
|
|
32
|
+
* `MllpClientError(TIMEOUT)` is thrown. Connections are deliberately
|
|
33
|
+
* **not** pooled or reused — each `send()` opens its own duplex.
|
|
34
|
+
*
|
|
35
|
+
* @module
|
|
36
|
+
*/
|
|
37
|
+
import type { Acknowledgment } from "./acknowledgment";
|
|
38
|
+
import type { MllpConnect } from "./connect";
|
|
39
|
+
/**
|
|
40
|
+
* TLS configuration for an MLLP client connection.
|
|
41
|
+
*
|
|
42
|
+
* Mirrors the relevant subset of TLS options across runtimes. When
|
|
43
|
+
* this object is provided to {@link MllpClientOptions.tls}, the
|
|
44
|
+
* runtime adapter establishes a TLS connection (rather than plain
|
|
45
|
+
* TCP). Server certificates are **always** verified unless
|
|
46
|
+
* {@link insecure} is explicitly set to `true`.
|
|
47
|
+
*
|
|
48
|
+
* Not every runtime adapter supports every field — `passphrase` and
|
|
49
|
+
* mutual-TLS material (`cert`/`key`) are honoured by the Node
|
|
50
|
+
* adapter; Cloudflare Workers and Deno expose a smaller subset.
|
|
51
|
+
* Adapters silently ignore fields they cannot use.
|
|
52
|
+
*/
|
|
53
|
+
export interface MllpClientTlsOptions {
|
|
54
|
+
/** Trusted CA certificate(s) for verifying the server. */
|
|
55
|
+
ca?: string | Uint8Array;
|
|
56
|
+
/** Client certificate for mutual TLS. */
|
|
57
|
+
cert?: string | Uint8Array;
|
|
58
|
+
/** Client private key for mutual TLS. */
|
|
59
|
+
key?: string | Uint8Array;
|
|
60
|
+
/** Passphrase for the private key, if encrypted. */
|
|
61
|
+
passphrase?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Override the server name used for SNI and certificate
|
|
64
|
+
* verification. Defaults to {@link MllpClientOptions.host}.
|
|
65
|
+
*
|
|
66
|
+
* Setting this to anything other than the real server hostname
|
|
67
|
+
* effectively disables strict hostname verification — use only
|
|
68
|
+
* when SNI multiplexing requires a different name from the
|
|
69
|
+
* connection target.
|
|
70
|
+
*/
|
|
71
|
+
servername?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Disable server-certificate verification.
|
|
74
|
+
*
|
|
75
|
+
* **DO NOT enable this in production.** When set to `true` the
|
|
76
|
+
* client accepts self-signed, expired, and otherwise invalid
|
|
77
|
+
* certificates, making the connection vulnerable to active
|
|
78
|
+
* man-in-the-middle attacks. The option exists so that local
|
|
79
|
+
* development and integration tests can connect to throwaway
|
|
80
|
+
* servers — never as a workaround for real certificate problems.
|
|
81
|
+
*
|
|
82
|
+
* Only the literal value `true` opts out. There is no `false`
|
|
83
|
+
* form because the secure default is non-negotiable.
|
|
84
|
+
*/
|
|
85
|
+
insecure?: true;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Configuration for an {@link MllpClient}. All fields are immutable
|
|
89
|
+
* once the client is constructed; create a new client to change
|
|
90
|
+
* them.
|
|
91
|
+
*
|
|
92
|
+
* Application code that imports from `@glion/mllp-client/node`,
|
|
93
|
+
* `/deno`, or `/workers` does **not** need to pass `connect` — the
|
|
94
|
+
* runtime adapter provides it.
|
|
95
|
+
*/
|
|
96
|
+
export interface MllpClientOptions {
|
|
97
|
+
/** Hostname or IP of the MLLP server. */
|
|
98
|
+
host: string;
|
|
99
|
+
/** TCP port of the MLLP server. */
|
|
100
|
+
port: number;
|
|
101
|
+
/**
|
|
102
|
+
* Function that opens a connection to the receiver and returns a
|
|
103
|
+
* Web-Streams duplex. Runtime adapters supply this for you.
|
|
104
|
+
*/
|
|
105
|
+
connect: MllpConnect;
|
|
106
|
+
/**
|
|
107
|
+
* Maximum total milliseconds for the connect → write → read-ACK
|
|
108
|
+
* round trip. The same budget covers all phases — if connecting
|
|
109
|
+
* consumes 4s of a 10s budget, the remaining 6s is what's left to
|
|
110
|
+
* receive the ACK.
|
|
111
|
+
*
|
|
112
|
+
* @default 30000
|
|
113
|
+
*/
|
|
114
|
+
timeout?: number;
|
|
115
|
+
/**
|
|
116
|
+
* Maximum bytes accepted for an inbound ACK frame. When omitted,
|
|
117
|
+
* no limit is enforced. Set this when receiving from untrusted
|
|
118
|
+
* peers to cap memory use from a malicious or malformed stream.
|
|
119
|
+
*/
|
|
120
|
+
maxAckSize?: number;
|
|
121
|
+
/**
|
|
122
|
+
* TLS configuration. **Defaults to `true`** — HL7v2 messages
|
|
123
|
+
* commonly carry PHI, so the secure default is TLS-on. Callers
|
|
124
|
+
* who genuinely want plain TCP (e.g. trusted hospital intranet,
|
|
125
|
+
* or a TLS terminator hop in front of the receiver) must opt out
|
|
126
|
+
* explicitly with `tls: false`.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* // TLS on, defaults (system trust, hostname verification)
|
|
131
|
+
* new MllpClient({ host, port });
|
|
132
|
+
*
|
|
133
|
+
* // Same — explicit form
|
|
134
|
+
* new MllpClient({ host, port, tls: true });
|
|
135
|
+
*
|
|
136
|
+
* // TLS with config (mutual TLS, custom CA, SNI override, ...)
|
|
137
|
+
* new MllpClient({ host, port, tls: { servername: "h" } });
|
|
138
|
+
*
|
|
139
|
+
* // Plain TCP — caller takes the security trade-off explicitly
|
|
140
|
+
* new MllpClient({ host, port, tls: false });
|
|
141
|
+
* ```;
|
|
142
|
+
*
|
|
143
|
+
* @default true
|
|
144
|
+
*/
|
|
145
|
+
tls?: boolean | MllpClientTlsOptions;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Construction options accepted by the **runtime adapters'**
|
|
149
|
+
* `MllpClient` subclasses (`@glion/mllp-client/node`, `/deno`,
|
|
150
|
+
* `/workers`). Identical to {@link MllpClientOptions} except that
|
|
151
|
+
* `connect` is omitted — the adapter binds it for you.
|
|
152
|
+
*/
|
|
153
|
+
export type BoundMllpClientOptions = Omit<MllpClientOptions, "connect">;
|
|
154
|
+
/**
|
|
155
|
+
* HL7v2 acknowledgment level the send waits for. Mirrors the two
|
|
156
|
+
* acknowledgment levels in HL7v2 §2.9.2.
|
|
157
|
+
*
|
|
158
|
+
* - `"OnApplication"` (default) — return when the receiver's application-level
|
|
159
|
+
* ACK arrives (`AA`/`AE`/`AR`). Intermediate `CA` (Commit Accept) frames sent
|
|
160
|
+
* by enhanced-mode receivers are surfaced via iteration but do not resolve
|
|
161
|
+
* the send. Use this when "did the receiver successfully process my message?"
|
|
162
|
+
* is the question.
|
|
163
|
+
* - `"OnCommit"` — return on the first frame regardless of code, typically a
|
|
164
|
+
* commit-level ACK (`CA`/`CE`/`CR`). The send resolves as soon as the
|
|
165
|
+
* receiver confirms receipt of the message; later processing-level frames are
|
|
166
|
+
* not observed because the connection is closed once the resolving frame
|
|
167
|
+
* arrives. Use this for receivers that only send commit-level ACKs (basic
|
|
168
|
+
* mode) or when the caller wants the commit confirmation without waiting for
|
|
169
|
+
* the processing result.
|
|
170
|
+
*/
|
|
171
|
+
export type SendMode = "OnApplication" | "OnCommit";
|
|
172
|
+
/**
|
|
173
|
+
* Per-call options accepted by {@link MllpClient.send}.
|
|
174
|
+
*/
|
|
175
|
+
export interface SendOptions {
|
|
176
|
+
/**
|
|
177
|
+
* Cancel the in-flight `send()` from outside. Composed with the
|
|
178
|
+
* client's internal `timeout` deadline via `AbortSignal.any`, so
|
|
179
|
+
* either source aborts the send.
|
|
180
|
+
*
|
|
181
|
+
* Typical use: tie a batch of `send()`s to an app-shutdown
|
|
182
|
+
* `AbortController` so they all cancel cleanly when the process
|
|
183
|
+
* exits.
|
|
184
|
+
*
|
|
185
|
+
* When this signal aborts, the resulting `MllpClientError` has
|
|
186
|
+
* `code: TIMEOUT` and forwards the caller's `signal.reason` as
|
|
187
|
+
* its `cause` (when the reason is itself an `Error`).
|
|
188
|
+
*/
|
|
189
|
+
signal?: AbortSignal;
|
|
190
|
+
/**
|
|
191
|
+
* HL7v2 acknowledgment level to wait for. See {@link SendMode}.
|
|
192
|
+
*
|
|
193
|
+
* @default "OnApplication"
|
|
194
|
+
*/
|
|
195
|
+
mode?: SendMode;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Runtime-free MLLP client. Instantiate via a runtime adapter
|
|
199
|
+
* (`@glion/mllp-client/node`, `/deno`, `/workers`) for the common
|
|
200
|
+
* case.
|
|
201
|
+
*
|
|
202
|
+
* **TLS-on by default.** `MllpClientOptions.tls` defaults to `true`;
|
|
203
|
+
* pass `tls: false` for plain TCP. See {@link MllpClientOptions.tls}.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* Send a message and read the ACK on Node:
|
|
207
|
+
*
|
|
208
|
+
* ```ts
|
|
209
|
+
* import { MllpClient } from "@glion/mllp-client/node";
|
|
210
|
+
*
|
|
211
|
+
* const client = new MllpClient({ host: "127.0.0.1", port: 2575 });
|
|
212
|
+
* const ack = await client.send(rawHl7Message);
|
|
213
|
+
* console.log(ack.code, ack.controlId); // "AA" "MSG001"
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
export declare class MllpClient {
|
|
217
|
+
#private;
|
|
218
|
+
constructor(options: MllpClientOptions);
|
|
219
|
+
/** The host this client connects to. */
|
|
220
|
+
get host(): string;
|
|
221
|
+
/** The port this client connects to. */
|
|
222
|
+
get port(): number;
|
|
223
|
+
/**
|
|
224
|
+
* Send a single HL7v2 message and resolve with the resolving accept ACK.
|
|
225
|
+
*
|
|
226
|
+
* Throws:
|
|
227
|
+
*
|
|
228
|
+
* - {@link MllpClientError} for transport failures. `code` identifies the mode:
|
|
229
|
+
* `INVALID_INPUT`, `CONNECTION_REFUSED`, `TIMEOUT`, `CONNECTION_CLOSED`,
|
|
230
|
+
* `MALFORMED_FRAME`, or `MALFORMED_ACK`.
|
|
231
|
+
* - An `AckException` subclass from `@glion/ack` (`AckApplicationError`,
|
|
232
|
+
* `AckApplicationReject`, `AckCommitError`, `AckCommitReject`) when MSA-1 ∈
|
|
233
|
+
* {AE, AR, CE, CR}. The thrown exception's `raw` attribute holds the
|
|
234
|
+
* wire-format ACK.
|
|
235
|
+
*
|
|
236
|
+
* To observe each accept ACK as it arrives (e.g. seeing the
|
|
237
|
+
* intermediate `CA` frame in HL7v2 enhanced mode), use
|
|
238
|
+
* {@link MllpClient.stream} instead.
|
|
239
|
+
*/
|
|
240
|
+
send(message: string | Uint8Array, options?: SendOptions): Promise<Acknowledgment>;
|
|
241
|
+
/**
|
|
242
|
+
* Send a single HL7v2 message and yield each accept ACK as it
|
|
243
|
+
* arrives. The iterable completes after the resolving frame.
|
|
244
|
+
*
|
|
245
|
+
* In HL7v2 enhanced mode the iterable yields `CA` then the
|
|
246
|
+
* application-level ACK; in basic mode it yields a single
|
|
247
|
+
* application-level ACK. NAK codes (`AE`/`AR`/`CE`/`CR`) throw the
|
|
248
|
+
* matching `AckException` from the iterator with the wire-format
|
|
249
|
+
* ACK on `error.raw`.
|
|
250
|
+
*
|
|
251
|
+
* Use {@link MllpClient.send} for the simple "give me the resolving
|
|
252
|
+
* answer" case.
|
|
253
|
+
*/
|
|
254
|
+
stream(message: string | Uint8Array, options?: SendOptions): AsyncIterable<Acknowledgment>;
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAS7C;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,oBAAoB;IACnC,0DAA0D;IAC1D,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IACzB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,IAAI,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,EAAE,WAAW,CAAC;IACrB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,GAAG,CAAC,EAAE,OAAO,GAAG,oBAAoB,CAAC;CACtC;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,QAAQ,GAAG,eAAe,GAAG,UAAU,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAaD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,UAAU;;gBAQT,OAAO,EAAE,iBAAiB;IAmBtC,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;;;;;;;;;;;;OAgBG;IACG,IAAI,CACR,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,cAAc,CAAC;IAmB1B;;;;;;;;;;;;OAYG;IACH,MAAM,CACJ,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,OAAO,GAAE,WAAgB,GACxB,aAAa,CAAC,cAAc,CAAC;CA+GjC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for the runtime-free core of `@glion/mllp-client`.
|
|
3
|
+
*
|
|
4
|
+
* These types describe the shape of the pluggable transport that the
|
|
5
|
+
* client uses to read and write bytes on the wire. The core does not
|
|
6
|
+
* import any runtime-specific module — every connection is opened by
|
|
7
|
+
* a {@link MllpConnect} function the caller supplies. Per-runtime
|
|
8
|
+
* adapters (`@glion/mllp-client/node`, `/deno`, `/workers`) ship
|
|
9
|
+
* pre-wired implementations so most callers never write a `connect`
|
|
10
|
+
* function themselves.
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import type { MllpClientTlsOptions } from "./client";
|
|
15
|
+
/**
|
|
16
|
+
* Connect to an MLLP receiver and return a {@link MllpDuplexStream}
|
|
17
|
+
* over which the client will write the framed message and read the
|
|
18
|
+
* acknowledgment.
|
|
19
|
+
*
|
|
20
|
+
* Implementations must:
|
|
21
|
+
*
|
|
22
|
+
* - Resolve once the underlying transport is ready for I/O (TCP `connect` has
|
|
23
|
+
* fired, or the TLS handshake has completed when `tls` is set).
|
|
24
|
+
* - Reject with a thrown `Error` if the connection cannot be established. The
|
|
25
|
+
* client maps native errors into typed `MllpClientError` instances.
|
|
26
|
+
* - Honour `signal` if the caller passes one — abort the connect attempt and
|
|
27
|
+
* reject when the signal aborts. Future revisions of the client may pass a
|
|
28
|
+
* signal here to enforce the connect-phase deadline.
|
|
29
|
+
*
|
|
30
|
+
* The returned duplex must remain usable until {@link MllpDuplexStream.close}
|
|
31
|
+
* is called.
|
|
32
|
+
*/
|
|
33
|
+
export type MllpConnect = (params: MllpConnectParams) => Promise<MllpDuplexStream>;
|
|
34
|
+
/**
|
|
35
|
+
* Parameters supplied to a {@link MllpConnect} implementation.
|
|
36
|
+
*/
|
|
37
|
+
export interface MllpConnectParams {
|
|
38
|
+
/** Hostname or IP of the receiver. */
|
|
39
|
+
host: string;
|
|
40
|
+
/** TCP port of the receiver. */
|
|
41
|
+
port: number;
|
|
42
|
+
/**
|
|
43
|
+
* TLS configuration. When set, the connector should establish a TLS
|
|
44
|
+
* connection (rather than plain TCP).
|
|
45
|
+
*/
|
|
46
|
+
tls?: MllpClientTlsOptions;
|
|
47
|
+
/**
|
|
48
|
+
* Optional abort signal. Implementations should listen for `abort`
|
|
49
|
+
* and tear the partial connection down so that the client's deadline
|
|
50
|
+
* fires cleanly.
|
|
51
|
+
*/
|
|
52
|
+
signal?: AbortSignal;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A Web-Streams duplex over which the client reads and writes bytes.
|
|
56
|
+
*
|
|
57
|
+
* The runtime adapters wrap their native socket types into this shape.
|
|
58
|
+
* The core has no awareness of the underlying transport — TCP, TLS,
|
|
59
|
+
* a WebSocket bridge, or an in-memory pipe (for tests) all work
|
|
60
|
+
* provided they expose Web Streams.
|
|
61
|
+
*/
|
|
62
|
+
export interface MllpDuplexStream {
|
|
63
|
+
/** Inbound byte stream from the receiver. */
|
|
64
|
+
readonly readable: ReadableStream<Uint8Array>;
|
|
65
|
+
/** Outbound byte stream to the receiver. */
|
|
66
|
+
readonly writable: WritableStream<Uint8Array>;
|
|
67
|
+
/**
|
|
68
|
+
* Tear the connection down. The client calls `close()` both from
|
|
69
|
+
* the abort signal handler (to interrupt pending I/O) and from a
|
|
70
|
+
* `finally` block (final cleanup).
|
|
71
|
+
*
|
|
72
|
+
* Implementations **must**:
|
|
73
|
+
*
|
|
74
|
+
* - Be **idempotent** — `close()` may be called multiple times on the same
|
|
75
|
+
* duplex (typically twice: once from the abort handler when the signal
|
|
76
|
+
* fires, once from the `finally` block as the generator unwinds).
|
|
77
|
+
* - **Resolve, never reject.** The client does **not** wrap `close()` in
|
|
78
|
+
* `try/catch` — error handling for cleanup belongs at the adapter layer,
|
|
79
|
+
* where each runtime knows what its socket primitives can fail with. A
|
|
80
|
+
* rejection from the abort handler would surface as an unhandled promise
|
|
81
|
+
* rejection; a rejection from the `finally` block would replace any
|
|
82
|
+
* in-flight error (NAK exception, transport error) with a confusing
|
|
83
|
+
* close-time error. Adapters must absorb their own idempotency and teardown
|
|
84
|
+
* errors internally and resolve cleanly.
|
|
85
|
+
* - **Propagate the close into the readable side** so that any pending
|
|
86
|
+
* `reader.read()` settles. Real sockets do this naturally via the
|
|
87
|
+
* underlying transport's close. Test fakes must close their readable
|
|
88
|
+
* controller from inside `close()` to honour the same contract.
|
|
89
|
+
*
|
|
90
|
+
* The return type is `Promise<void>` so that adapters whose underlying
|
|
91
|
+
* transport has async destruction (e.g. Cloudflare Workers'
|
|
92
|
+
* `socket.close()`) can model it honestly. Adapters with sync teardown
|
|
93
|
+
* (e.g. Node's `socket.destroy()`) wrap as a trivially-resolving async
|
|
94
|
+
* function. The client awaits `close()` in `finally` blocks so resource
|
|
95
|
+
* release is observable; the abort handler fires-and-forgets via
|
|
96
|
+
* `void duplex.close()` since the abort path does not need to await
|
|
97
|
+
* teardown.
|
|
98
|
+
*/
|
|
99
|
+
close(): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/core/connect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,iBAAiB,KACtB,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,GAAG,CAAC,EAAE,oBAAoB,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAC9C,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { MllpError } from "@glion/mllp-transport";
|
|
2
|
+
import type { MllpErrorOptions } from "@glion/mllp-transport";
|
|
3
|
+
/**
|
|
4
|
+
* Machine-readable codes for `MllpClient` transport failures.
|
|
5
|
+
*
|
|
6
|
+
* These cover everything that can go wrong between the moment
|
|
7
|
+
* `MllpClient.send()` is called and the moment a complete ACK frame
|
|
8
|
+
* has been decoded — i.e. everything that is not an HL7v2
|
|
9
|
+
* application-level NAK. NAK responses (MSA-1 ∈ {AE, AR, CE, CR})
|
|
10
|
+
* surface as `AckException` subclasses thrown directly from
|
|
11
|
+
* `@glion/ack`, not as transport errors.
|
|
12
|
+
*/
|
|
13
|
+
export declare const MllpClientErrorCode: {
|
|
14
|
+
/** No ACK arrived within the configured `timeout`. */
|
|
15
|
+
/** The peer closed the connection before a complete ACK arrived. */
|
|
16
|
+
readonly CONNECTION_CLOSED: "CONNECTION_CLOSED";
|
|
17
|
+
/** TCP connection could not be established (refused, DNS, routing). */
|
|
18
|
+
readonly CONNECTION_REFUSED: "CONNECTION_REFUSED";
|
|
19
|
+
/**
|
|
20
|
+
* The caller passed a payload that could not be MLLP-encoded —
|
|
21
|
+
* typically because it was not a `string` or `Uint8Array`. Also
|
|
22
|
+
* surfaced when constructor options fail validation (bad
|
|
23
|
+
* host/port/timeout/etc). Thrown before any socket is opened, so
|
|
24
|
+
* no connection is made and no resources need cleanup.
|
|
25
|
+
*/
|
|
26
|
+
readonly INVALID_INPUT: "INVALID_INPUT";
|
|
27
|
+
readonly MALFORMED_ACK: "MALFORMED_ACK";
|
|
28
|
+
/** The remote sent bytes that did not form a valid MLLP frame. */
|
|
29
|
+
readonly MALFORMED_FRAME: "MALFORMED_FRAME";
|
|
30
|
+
/** A frame was received but could not be parsed as a valid HL7v2 ACK. */
|
|
31
|
+
readonly TIMEOUT: "TIMEOUT";
|
|
32
|
+
/**
|
|
33
|
+
* TLS handshake failed — typically because of certificate
|
|
34
|
+
* verification, hostname mismatch, expired cert, untrusted CA, or
|
|
35
|
+
* a TLS protocol error. Distinct from `CONNECTION_REFUSED` (the
|
|
36
|
+
* TCP connection succeeded but the TLS upgrade failed) so
|
|
37
|
+
* operators can identify TLS misconfiguration quickly in
|
|
38
|
+
* healthcare deployments where it is a recurring incident class.
|
|
39
|
+
*/
|
|
40
|
+
readonly TLS_HANDSHAKE_FAILED: "TLS_HANDSHAKE_FAILED";
|
|
41
|
+
};
|
|
42
|
+
export type MllpClientErrorCode = (typeof MllpClientErrorCode)[keyof typeof MllpClientErrorCode];
|
|
43
|
+
/**
|
|
44
|
+
* Error thrown by `MllpClient.send()` for transport-level failures.
|
|
45
|
+
*
|
|
46
|
+
* Extends {@link MllpError} so callers can catch any MLLP error —
|
|
47
|
+
* server- or client-side — with a single `instanceof MllpError`
|
|
48
|
+
* check. The {@link MllpClientErrorCode | code} field discriminates
|
|
49
|
+
* the failure mode for typed handling.
|
|
50
|
+
*
|
|
51
|
+
* Application-level NAK responses are **not** thrown as
|
|
52
|
+
* `MllpClientError`; they are thrown as `AckException` subclasses
|
|
53
|
+
* from `@glion/ack`. A typical `catch` block handles both:
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* import { AckException } from "@glion/ack";
|
|
57
|
+
* import { MllpClientError } from "@glion/mllp-client";
|
|
58
|
+
*
|
|
59
|
+
* try {
|
|
60
|
+
* await client.send(message);
|
|
61
|
+
* } catch (error) {
|
|
62
|
+
* if (error instanceof AckException) {
|
|
63
|
+
* // Application-level NAK.
|
|
64
|
+
* } else if (error instanceof MllpClientError) {
|
|
65
|
+
* // Transport-level failure.
|
|
66
|
+
* }
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare class MllpClientError extends MllpError {
|
|
71
|
+
/**
|
|
72
|
+
* Narrowed view of the inherited `MllpError.code` field. `declare`
|
|
73
|
+
* keeps the runtime value (set by the base constructor) while
|
|
74
|
+
* exposing the discriminated {@link MllpClientErrorCode} union to
|
|
75
|
+
* TypeScript — callers can `switch` on `error.code` with full
|
|
76
|
+
* exhaustiveness checking.
|
|
77
|
+
*/
|
|
78
|
+
readonly code: MllpClientErrorCode;
|
|
79
|
+
constructor(code: MllpClientErrorCode, message: string, options?: MllpErrorOptions);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;IAC9B,sDAAsD;IACtD,oEAAoE;;IAEpE,uEAAuE;;IAEvE;;;;;;OAMG;;;IAGH,kEAAkE;;IAElE,yEAAyE;;IAEzE;;;;;;;OAOG;;CAEK,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAC7B,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,eAAgB,SAAQ,SAAS;IAC5C;;;;;;OAMG;IACH,SAAiB,IAAI,EAAE,mBAAmB,CAAC;gBAGzC,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,gBAAgB;CAK7B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-free entry point of `@glion/mllp-client`.
|
|
3
|
+
*
|
|
4
|
+
* Use this when you need to run the client in a non-standard runtime
|
|
5
|
+
* (for example, in a browser via a WebSocket-to-MLLP gateway, or
|
|
6
|
+
* with an in-memory pipe for tests). Construction requires you to
|
|
7
|
+
* supply your own {@link MllpConnect} function.
|
|
8
|
+
*
|
|
9
|
+
* For the common case (Node, Bun, Deno, Cloudflare Workers), prefer
|
|
10
|
+
* the per-runtime adapters which ship a pre-wired connector:
|
|
11
|
+
*
|
|
12
|
+
* - `@glion/mllp-client` — Node and Bun (default entry)
|
|
13
|
+
* - `@glion/mllp-client/deno` — Deno
|
|
14
|
+
* - `@glion/mllp-client/workers` — Cloudflare Workers
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
export type { Acknowledgment } from "./acknowledgment";
|
|
19
|
+
export { MllpClient } from "./client";
|
|
20
|
+
export type { BoundMllpClientOptions, MllpClientOptions, MllpClientTlsOptions, SendMode, SendOptions, } from "./client";
|
|
21
|
+
export type { MllpConnect, MllpConnectParams, MllpDuplexStream, } from "./connect";
|
|
22
|
+
export { MllpClientError, MllpClientErrorCode } from "./errors";
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EACV,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EACR,WAAW,GACZ,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `TransformStream<DecodedMessage, Acknowledgment>` that parses each
|
|
3
|
+
* decoded MLLP frame as an HL7v2 acknowledgment. Internal to
|
|
4
|
+
* `@glion/mllp-client`.
|
|
5
|
+
*
|
|
6
|
+
* On a malformed ACK the transform errors the readable with the
|
|
7
|
+
* typed `MllpClientError(MALFORMED_ACK)` from {@link parseAck}.
|
|
8
|
+
* Downstream `for await ... of` consumers reject with that error;
|
|
9
|
+
* `MllpClient.send()` translates it at its single catch site.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import type { DecodedMessage } from "@glion/mllp-transport";
|
|
14
|
+
import type { Acknowledgment } from "../acknowledgment";
|
|
15
|
+
/**
|
|
16
|
+
* Build a transform that consumes decoded MLLP frames and produces
|
|
17
|
+
* parsed `Acknowledgment` objects. A parse failure errors the
|
|
18
|
+
* readable side rather than enqueuing — the consumer's `for await`
|
|
19
|
+
* loop rejects with the typed error.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createAckParserStream(): TransformStream<DecodedMessage, Acknowledgment>;
|
|
22
|
+
//# sourceMappingURL=ack-parser-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ack-parser-stream.d.ts","sourceRoot":"","sources":["../../../src/core/internal/ack-parser-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CACtD,cAAc,EACd,cAAc,CACf,CAUA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscribe to an `AbortSignal` and run a callback once if it
|
|
3
|
+
* aborts. Returns a disposer that unsubscribes — call it from a
|
|
4
|
+
* `finally` block so we never leak listeners.
|
|
5
|
+
*
|
|
6
|
+
* If the signal is already aborted at subscription time, the
|
|
7
|
+
* callback fires synchronously and the returned disposer is a
|
|
8
|
+
* no-op. This collapses the "aborted vs aborting" branch every
|
|
9
|
+
* caller would otherwise need to write by hand.
|
|
10
|
+
*
|
|
11
|
+
* Internal to `@glion/mllp-client`.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Subscribe `onAbort` to fire once when `signal` aborts. Returns a
|
|
17
|
+
* disposer that removes the listener.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const dispose = subscribeAbort(signal, () => socket.destroy());
|
|
22
|
+
* try {
|
|
23
|
+
* await waitForReady(socket);
|
|
24
|
+
* } finally {
|
|
25
|
+
* dispose();
|
|
26
|
+
* }
|
|
27
|
+
* ```;
|
|
28
|
+
*/
|
|
29
|
+
export declare function subscribeAbort(signal: AbortSignal, onAbort: () => void): () => void;
|
|
30
|
+
//# sourceMappingURL=subscribe-abort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscribe-abort.d.ts","sourceRoot":"","sources":["../../../src/core/internal/subscribe-abort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,IAAI,GAClB,MAAM,IAAI,CAOZ"}
|