@glion/mllp 0.14.1

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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +486 -0
  3. package/dist/errors.d.ts +22 -0
  4. package/dist/errors.d.ts.map +1 -0
  5. package/dist/index.d.ts +9 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +38 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/mllp.js +791 -0
  10. package/dist/mllp.js.map +1 -0
  11. package/dist/node/adapter.d.ts +75 -0
  12. package/dist/node/adapter.d.ts.map +1 -0
  13. package/dist/node/index.d.ts +15 -0
  14. package/dist/node/index.d.ts.map +1 -0
  15. package/dist/node/serve.d.ts +150 -0
  16. package/dist/node/serve.d.ts.map +1 -0
  17. package/dist/node.js +324 -0
  18. package/dist/node.js.map +1 -0
  19. package/dist/server/adapter.d.ts +64 -0
  20. package/dist/server/adapter.d.ts.map +1 -0
  21. package/dist/server/compose.d.ts +15 -0
  22. package/dist/server/compose.d.ts.map +1 -0
  23. package/dist/server/context.d.ts +33 -0
  24. package/dist/server/context.d.ts.map +1 -0
  25. package/dist/server/mllp.d.ts +102 -0
  26. package/dist/server/mllp.d.ts.map +1 -0
  27. package/dist/server/router.d.ts +49 -0
  28. package/dist/server/router.d.ts.map +1 -0
  29. package/dist/server/types.d.ts +139 -0
  30. package/dist/server/types.d.ts.map +1 -0
  31. package/dist/transport/constants.d.ts +24 -0
  32. package/dist/transport/constants.d.ts.map +1 -0
  33. package/dist/transport/decoder-stream.d.ts +49 -0
  34. package/dist/transport/decoder-stream.d.ts.map +1 -0
  35. package/dist/transport/decoder.d.ts +18 -0
  36. package/dist/transport/decoder.d.ts.map +1 -0
  37. package/dist/transport/dynamic-buffer.d.ts +28 -0
  38. package/dist/transport/dynamic-buffer.d.ts.map +1 -0
  39. package/dist/transport/encoder.d.ts +14 -0
  40. package/dist/transport/encoder.d.ts.map +1 -0
  41. package/dist/transport/errors.d.ts +13 -0
  42. package/dist/transport/errors.d.ts.map +1 -0
  43. package/dist/transport/index.d.ts +8 -0
  44. package/dist/transport/index.d.ts.map +1 -0
  45. package/dist/transport/types.d.ts +49 -0
  46. package/dist/transport/types.d.ts.map +1 -0
  47. package/package.json +68 -0
@@ -0,0 +1,139 @@
1
+ import type { Root } from "@glion/ast";
2
+ import type { Processor } from "unified";
3
+ import type { VFile } from "vfile";
4
+ /**
5
+ * Connection metadata for an MLLP socket.
6
+ */
7
+ export interface ConnectionInfo {
8
+ readonly id: number;
9
+ readonly remoteAddress: string;
10
+ readonly remotePort: number;
11
+ readonly localPort: number;
12
+ readonly secure: boolean;
13
+ readonly state: Map<string, unknown>;
14
+ }
15
+ /**
16
+ * MLLP response — a raw HL7v2 string that the server encodes
17
+ * with MLLP framing before sending back over TCP.
18
+ *
19
+ * Acknowledgment helpers (ack/nak) are not built in — register
20
+ * an acknowledgment middleware via `.use()` to generate ACK/NAK responses.
21
+ */
22
+ export interface Response {
23
+ readonly raw: string;
24
+ }
25
+ /**
26
+ * The MLLP context object.
27
+ *
28
+ * Routing fields (messageType, triggerEvent, etc.) are extracted from
29
+ * the **pre-transform** parsed tree and are always available synchronously.
30
+ *
31
+ * The transformed tree, VFile, and compiled result are lazy — they
32
+ * trigger pipeline stages on first access. See ADR-0013.
33
+ */
34
+ export interface Context {
35
+ /** Incoming message data */
36
+ readonly req: {
37
+ /** Original HL7 message string (without MLLP framing) */
38
+ readonly raw: string;
39
+ /** Raw bytes from MLLP frame payload */
40
+ readonly bytes: Uint8Array;
41
+ };
42
+ /** TCP connection metadata */
43
+ readonly connection: ConnectionInfo;
44
+ /**
45
+ * Parsed AST — always available synchronously. Use this for reading
46
+ * MSH fields, building ACKs, routing, or any operation that doesn't
47
+ * need to wait for transforms to complete.
48
+ *
49
+ * Note: this is the same object reference as the tree returned by
50
+ * `tree()`. After `tree()` resolves, transformers may have enriched
51
+ * it in-place (e.g., decoded escapes, resolved message structure).
52
+ * The routing fields (messageType, triggerEvent, etc.) are cached
53
+ * as separate string properties and always reflect the original
54
+ * wire values regardless of transforms.
55
+ */
56
+ readonly ast: Root;
57
+ /**
58
+ * Transformed AST. Triggers `run()` (transformers) on first call.
59
+ * Cached after first access — subsequent calls return the same tree.
60
+ */
61
+ tree(): Promise<Root>;
62
+ /**
63
+ * VFile with diagnostics and lint messages. Created during context
64
+ * creation. Diagnostics accumulate after `tree()` triggers transformers.
65
+ */
66
+ file: VFile;
67
+ /**
68
+ * Compiled result from the processor's compiler (e.g., JSON from
69
+ * hl7v2Jsonify). Triggers both `run()` and `stringify()` on first call.
70
+ * Undefined when the processor has no compiler.
71
+ * Cached after first access.
72
+ */
73
+ result(): Promise<unknown | undefined>;
74
+ /** Response to send back. Set by middleware or handler. */
75
+ res: Response | undefined;
76
+ /** MSH-9.1 message type (e.g., "ADT") — from pre-transform parse */
77
+ messageType: string;
78
+ /** MSH-9.2 trigger event (e.g., "A01") — from pre-transform parse */
79
+ triggerEvent: string;
80
+ /** MSH-9.3 message structure (e.g., "ADT_A01") — from pre-transform parse */
81
+ messageStructure: string;
82
+ /** MSH-12 version (e.g., "2.5.1") — from pre-transform parse */
83
+ version: string;
84
+ /** MSH-10 message control ID — from pre-transform parse */
85
+ controlId: string;
86
+ /** Store a variable */
87
+ set<K extends string>(key: K, value: unknown): void;
88
+ /** Retrieve a variable */
89
+ get<K extends string>(key: K): unknown;
90
+ /** Read-only snapshot of all variables */
91
+ readonly var: Readonly<Record<string, unknown>>;
92
+ }
93
+ /**
94
+ * A unified `Processor` that parses HL7v2 messages into `Root` trees.
95
+ *
96
+ * Only `ParseTree` is constrained — the remaining type params are left
97
+ * loose so that any processor built with `unified().use(hl7v2Parser)`
98
+ * is assignable regardless of which transformer/compiler plugins are added.
99
+ */
100
+ export type Hl7v2Processor = Processor<Root, Root, Root>;
101
+ /**
102
+ * Middleware function signature (Hono/Koa onion model).
103
+ */
104
+ export type MiddlewareReturn = Promise<Response | undefined | void> | Promise<void> | Response | undefined | void;
105
+ export type Middleware = (ctx: Context, next: () => Promise<void>) => MiddlewareReturn;
106
+ /**
107
+ * Terminal route handler — may return a response or void (no response).
108
+ */
109
+ export type Handler = (ctx: Context) => Promise<Response | undefined | void> | Response | undefined | void;
110
+ /**
111
+ * Error handler — receives the error and context, returns a response.
112
+ */
113
+ export type ErrorHandler = (err: Error, ctx: Context) => Promise<Response | undefined | void> | Response | undefined | void;
114
+ /**
115
+ * A filter function for route or middleware matching.
116
+ * Receives the full context and returns true if the route/middleware applies.
117
+ */
118
+ export type RouteFilter = (ctx: Context) => boolean;
119
+ /**
120
+ * Parsed route pattern for matching against incoming messages.
121
+ */
122
+ export interface RoutePattern {
123
+ /** Original pattern string (e.g., "ADT^A01") */
124
+ readonly source: string;
125
+ /** Message type to match, or "*" for wildcard */
126
+ readonly messageType: string;
127
+ /** Trigger event to match, or "*" for wildcard */
128
+ readonly triggerEvent: string;
129
+ }
130
+ /**
131
+ * Parse a pattern string like "ADT^A01", "ADT^*", "*^A01", or "*"
132
+ * into a structured RoutePattern.
133
+ */
134
+ export declare function parsePattern(pattern: string): RoutePattern;
135
+ /**
136
+ * Test whether a route pattern matches a given message type and trigger event.
137
+ */
138
+ export declare function matchPattern(pattern: RoutePattern, messageType: string, triggerEvent: string): boolean;
139
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * MLLP Start Byte - Vertical Tab (VT)
3
+ * Marks the beginning of an MLLP frame
4
+ */
5
+ export declare const MLLP_START_BYTE = 11;
6
+ /**
7
+ * MLLP End Byte 1 - File Separator (FS)
8
+ * First byte of the end sequence
9
+ */
10
+ export declare const MLLP_END_BYTE_1 = 28;
11
+ /**
12
+ * MLLP End Byte 2 - Carriage Return (CR)
13
+ * Second byte of the end sequence
14
+ */
15
+ export declare const MLLP_END_BYTE_2 = 13;
16
+ /**
17
+ * MLLP header as a Uint8Array containing the start byte
18
+ */
19
+ export declare const MLLP_HEADER: Uint8Array<ArrayBuffer>;
20
+ /**
21
+ * MLLP trailer as a Uint8Array containing the end sequence
22
+ */
23
+ export declare const MLLP_TRAILER: Uint8Array<ArrayBuffer>;
24
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/transport/constants.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,eAAe,KAAO,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,eAAe,KAAO,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,eAAe,KAAO,CAAC;AAMpC;;GAEG;AACH,eAAO,MAAM,WAAW,yBAAoC,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,YAAY,yBAAqD,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { DecodedMessage, DecoderOptions } from "./types";
2
+ /**
3
+ * Create a `TransformStream` that extracts MLLP messages from a raw
4
+ * byte stream.
5
+ *
6
+ * Pipe a TCP socket's `ReadableStream<Uint8Array>` through this stream
7
+ * to receive one {@link DecodedMessage} per MLLP frame, regardless of
8
+ * how the bytes are chunked on the wire.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { createDecoderStream } from "@glion/mllp";
13
+ *
14
+ * const decoder = createDecoderStream({
15
+ * maxMessageSize: 1024 * 1024, // 1 MB limit
16
+ * onError: (err) => log.warn(err), // custom error handler
17
+ * });
18
+ *
19
+ * const messages = socket.readable.pipeThrough(decoder).getReader();
20
+ *
21
+ * while (true) {
22
+ * const { done, value } = await messages.read();
23
+ * if (done) break;
24
+ * console.log(value.text); // HL7v2 message string
25
+ * }
26
+ * ```;
27
+ *
28
+ * @param options - Optional decoder settings (max size, encoding, error
29
+ * handler).
30
+ * @returns A `TransformStream<Uint8Array, DecodedMessage>`.
31
+ */
32
+ export declare function createDecoderStream(options?: DecoderOptions): TransformStream<Uint8Array, DecodedMessage>;
33
+ /**
34
+ * Class-based variant of {@link createDecoderStream} for cases where
35
+ * a reusable instance is preferred over the factory function.
36
+ *
37
+ * Functionally identical — both delegate to the same internal
38
+ * transformer.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const decoder = new MLLPDecoderStream({ maxMessageSize: 512_000 });
43
+ * socket.readable.pipeThrough(decoder);
44
+ * ```;
45
+ */
46
+ export declare class MLLPDecoderStream extends TransformStream<Uint8Array, DecodedMessage> {
47
+ constructor(options?: DecoderOptions);
48
+ }
49
+ //# sourceMappingURL=decoder-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoder-stream.d.ts","sourceRoot":"","sources":["../../src/transport/decoder-stream.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA0W9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,CAAC,EAAE,cAAc,GACvB,eAAe,CAAC,UAAU,EAAE,cAAc,CAAC,CAE7C;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAkB,SAAQ,eAAe,CACpD,UAAU,EACV,cAAc,CACf;gBACa,OAAO,CAAC,EAAE,cAAc;CAGrC"}
@@ -0,0 +1,18 @@
1
+ import type { DecodedMessage, DecoderOptions } from "./types";
2
+ /**
3
+ * Decode a single MLLP frame (VT ... FS CR) into a message.
4
+ *
5
+ * Validates framing, strips the envelope, and returns the payload as
6
+ * both raw bytes and decoded text. Throws {@link TransportError} on
7
+ * any structural issue.
8
+ *
9
+ * For streaming / chunked TCP data, use {@link createDecoderStream} instead.
10
+ *
11
+ * @throws TransportError with `INVALID_START_BYTE` if byte 0 is not 0x0B
12
+ * @throws TransportError with `INVALID_END_SEQUENCE` if frame doesn't end with
13
+ * 0x1C 0x0D
14
+ * @throws TransportError with `MESSAGE_TOO_LARGE` if payload exceeds
15
+ * `maxMessageSize`
16
+ */
17
+ export declare function decode(frame: Uint8Array, options?: DecoderOptions): DecodedMessage;
18
+ //# sourceMappingURL=decoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../src/transport/decoder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CACpB,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,cAAc,GACvB,cAAc,CAiDhB"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A growable byte buffer with geometric capacity doubling.
3
+ *
4
+ * Designed for protocol decoders that accumulate bytes from arbitrarily
5
+ * chunked TCP streams. Amortizes copy cost to O(n) total — the same
6
+ * strategy used by pg-protocol, NATS.js, and Java's ArrayList.
7
+ *
8
+ * The buffer maintains a read offset so consumed bytes can be skipped
9
+ * without shifting data. When the wasted prefix exceeds half the
10
+ * capacity, the buffer auto-compacts by shifting remaining bytes to
11
+ * the front.
12
+ *
13
+ * @internal
14
+ */
15
+ export declare class DynamicBuffer {
16
+ private _buffer;
17
+ private _length;
18
+ private _offset;
19
+ constructor(initialCapacity?: number);
20
+ get capacity(): number;
21
+ get available(): number;
22
+ append(chunk: Uint8Array): void;
23
+ view(): Uint8Array;
24
+ consume(n: number): void;
25
+ reset(): void;
26
+ private _compact;
27
+ }
28
+ //# sourceMappingURL=dynamic-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-buffer.d.ts","sourceRoot":"","sources":["../../src/transport/dynamic-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAK;gBAER,eAAe,SAAO;IAIlC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAY/B,IAAI,IAAI,UAAU;IAIlB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAYxB,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,QAAQ;CAMjB"}
@@ -0,0 +1,14 @@
1
+ import type { EncoderInput, EncoderOptions } from "./types";
2
+ /**
3
+ * Encode a single HL7v2 message into an MLLP frame.
4
+ *
5
+ * Wraps the message with MLLP framing:
6
+ * - Start byte: 0x0B (VT)
7
+ * - End sequence: 0x1C 0x0D (FS + CR)
8
+ */
9
+ export declare function encode(message: EncoderInput, _options?: EncoderOptions): Uint8Array;
10
+ /**
11
+ * Encode multiple HL7v2 messages into concatenated MLLP frames.
12
+ */
13
+ export declare function encodeMultiple(messages: EncoderInput[], options?: EncoderOptions): Uint8Array;
14
+ //# sourceMappingURL=encoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../src/transport/encoder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK5D;;;;;;GAMG;AACH,wBAAgB,MAAM,CACpB,OAAO,EAAE,YAAY,EACrB,QAAQ,CAAC,EAAE,cAAc,GACxB,UAAU,CAWZ;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,CAAC,EAAE,cAAc,GACvB,UAAU,CAaZ"}
@@ -0,0 +1,13 @@
1
+ import { MllpError } from "../errors";
2
+ import type { TransportErrorCode } from "./types";
3
+ /**
4
+ * Transport-level error for MLLP framing issues (invalid framing, incomplete
5
+ * messages, etc.)
6
+ */
7
+ export declare class TransportError extends MllpError {
8
+ readonly code: TransportErrorCode;
9
+ /** Position in the data where the error occurred (if applicable) */
10
+ readonly position?: number;
11
+ constructor(code: TransportErrorCode, message: string, position?: number);
12
+ }
13
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/transport/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;GAGG;AACH,qBAAa,cAAe,SAAQ,SAAS;IAC3C,SAAiB,IAAI,EAAE,kBAAkB,CAAC;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;gBAEf,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;CAKzE"}
@@ -0,0 +1,8 @@
1
+ export { MLLP_END_BYTE_1, MLLP_END_BYTE_2, MLLP_HEADER, MLLP_START_BYTE, MLLP_TRAILER, } from "./constants";
2
+ export { decode } from "./decoder";
3
+ export { createDecoderStream, MLLPDecoderStream } from "./decoder-stream";
4
+ export { encode, encodeMultiple } from "./encoder";
5
+ export { TransportError } from "./errors";
6
+ export { TransportErrorCode as ErrorCode } from "./types";
7
+ export type { DecodedMessage, DecoderOptions, EncoderInput, EncoderOptions, } from "./types";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,eAAe,EACf,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,kBAAkB,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAC1D,YAAY,EACV,cAAc,EACd,cAAc,EACd,YAAY,EACZ,cAAc,GACf,MAAM,SAAS,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { TransportError } from "./errors";
2
+ /**
3
+ * Input types for encoding - supports both string and binary
4
+ */
5
+ export type EncoderInput = string | Uint8Array;
6
+ /**
7
+ * Decoded message result from MLLP frame
8
+ */
9
+ export interface DecodedMessage {
10
+ /** The raw message payload (without MLLP framing) */
11
+ data: Uint8Array;
12
+ /** Message decoded as string (convenience) */
13
+ text: string;
14
+ /** Byte length of the original message */
15
+ byteLength: number;
16
+ }
17
+ /**
18
+ * Options for the MLLP encoder
19
+ */
20
+ export interface EncoderOptions {
21
+ /** Encoding for string input (default: 'utf-8') */
22
+ encoding?: string;
23
+ }
24
+ /**
25
+ * Options for the MLLP decoder
26
+ */
27
+ export interface DecoderOptions {
28
+ /** Maximum message size in bytes (optional, no default limit) */
29
+ maxMessageSize?: number;
30
+ /** Encoding for text conversion (default: 'utf-8') */
31
+ encoding?: string;
32
+ /** Error callback for logging/handling errors */
33
+ onError?: (error: TransportError) => void;
34
+ }
35
+ /**
36
+ * Error codes for MLLP frame-level errors
37
+ */
38
+ export declare const TransportErrorCode: {
39
+ /** Stream ended with incomplete MLLP message */
40
+ readonly INCOMPLETE_MESSAGE: "INCOMPLETE_MESSAGE";
41
+ /** Frame does not end with MLLP end sequence (0x1C 0x0D) */
42
+ readonly INVALID_END_SEQUENCE: "INVALID_END_SEQUENCE";
43
+ /** Frame does not start with MLLP start byte (0x0B) */
44
+ readonly INVALID_START_BYTE: "INVALID_START_BYTE";
45
+ /** Message exceeds configured maximum size */
46
+ readonly MESSAGE_TOO_LARGE: "MESSAGE_TOO_LARGE";
47
+ };
48
+ export type TransportErrorCode = (typeof TransportErrorCode)[keyof typeof TransportErrorCode];
49
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,EAAE,UAAU,CAAC;IACjB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CAC3C;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB;IAC7B,gDAAgD;;IAEhD,4DAA4D;;IAE5D,uDAAuD;;IAEvD,8CAA8C;;CAEtC,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAC5B,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@glion/mllp",
3
+ "version": "0.14.1",
4
+ "description": "Transport-agnostic MLLP (Minimal Lower Layer Protocol) engine for HL7v2 messaging",
5
+ "keywords": [
6
+ "health",
7
+ "healthcare",
8
+ "hl7",
9
+ "hl7v2",
10
+ "mllp",
11
+ "nodejs",
12
+ "streaming",
13
+ "typescript"
14
+ ],
15
+ "homepage": "https://glion.dev",
16
+ "license": "MIT",
17
+ "author": {
18
+ "name": "Melek Somai",
19
+ "email": "melek@rethinkhealth.io"
20
+ },
21
+ "repository": "rethinkhealth/glion.git",
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "type": "module",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./node": {
33
+ "types": "./dist/node/index.d.ts",
34
+ "import": "./dist/node.js"
35
+ }
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "dependencies": {
41
+ "unified": "11.0.5",
42
+ "vfile": "6.0.3",
43
+ "@glion/ast": "0.14.1",
44
+ "@glion/parser": "0.14.1",
45
+ "@glion/util-query": "0.14.1"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^25.5.0",
49
+ "@vitest/coverage-v8": "4.1.2",
50
+ "tsdown": "0.21.7",
51
+ "typescript": "^5.9.3",
52
+ "vitest": "4.1.2",
53
+ "@glion/hl7v2": "0.14.1",
54
+ "@glion/tsconfig": "0.0.1",
55
+ "@glion/testing": "0.0.2"
56
+ },
57
+ "engines": {
58
+ "node": ">=18"
59
+ },
60
+ "scripts": {
61
+ "build": "tsdown && tsc --emitDeclarationOnly",
62
+ "check-types": "tsc --noEmit",
63
+ "bench": "vitest bench --run",
64
+ "test": "vitest run",
65
+ "test:coverage": "vitest run --coverage",
66
+ "test:watch": "vitest"
67
+ }
68
+ }