@cosyte/astm 0.0.4 → 0.0.5

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/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  // src/common/errors.ts
2
2
  var FATAL_CODES = {
3
- /** Input was empty or whitespace-only — there is nothing to parse. Shared across layers. */
3
+ /** Input was empty or whitespace-only: there is nothing to parse. Shared across layers. */
4
4
  EMPTY_INPUT: "EMPTY_INPUT",
5
- /** The first record is not an `H` (header) record — an ASTM message must lead with `H`. */
5
+ /** The first record is not an `H` (header) record: an ASTM message must lead with `H`. */
6
6
  ASTM_RECORD_NO_HEADER: "ASTM_RECORD_NO_HEADER",
7
7
  /** The `H` record is too short to declare the four delimiters (field/repeat/component/escape). */
8
8
  ASTM_RECORD_UNDECLARED_DELIMITERS: "ASTM_RECORD_UNDECLARED_DELIMITERS"
@@ -119,21 +119,21 @@ function primaryCode(u) {
119
119
 
120
120
  // src/common/warnings.ts
121
121
  var WARNING_CODES = {
122
- /** A record's type letter is not one of the modeled types — surfaced as an unsupported record. */
122
+ /** A record's type letter is not one of the modeled types: surfaced as an unsupported record. */
123
123
  ASTM_RECORD_UNKNOWN_TYPE: "ASTM_RECORD_UNKNOWN_TYPE",
124
- /** The header declared delimiters other than the canonical `H|\^&` — tolerated, noted. */
124
+ /** The header declared delimiters other than the canonical `H|\^&`: tolerated, noted. */
125
125
  ASTM_NONSTANDARD_DELIMITERS: "ASTM_NONSTANDARD_DELIMITERS",
126
- /** An escape sequence body was not one of `&F&`/`&S&`/`&R&`/`&E&` — preserved verbatim. */
126
+ /** An escape sequence body was not one of `&F&`/`&S&`/`&R&`/`&E&`: preserved verbatim. */
127
127
  ASTM_UNKNOWN_ESCAPE_SEQUENCE: "ASTM_UNKNOWN_ESCAPE_SEQUENCE",
128
128
  /**
129
129
  * A result value field carried an *unescaped* component delimiter, so it split into more than one
130
- * component. Both the full raw value and the split are surfaced and this warning fires — the
130
+ * component. Both the full raw value and the split are surfaced and this warning fires: the
131
131
  * ambiguity is never resolved silently into a truncated value.
132
132
  */
133
133
  ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT: "ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT",
134
134
  /**
135
135
  * A result's abnormal-flag field (`R` field 7) carried a letter outside HL7 Table 0078. The flag is
136
- * surfaced as `undefined` — never dropped, and **never coerced to `normal`** (a clinical error).
136
+ * surfaced as `undefined`: never dropped, and **never coerced to `normal`** (a clinical error).
137
137
  */
138
138
  ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG: "ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG",
139
139
  /**
@@ -143,7 +143,7 @@ var WARNING_CODES = {
143
143
  ASTM_RECORD_UNDEFINED_RESULT_STATUS: "ASTM_RECORD_UNDEFINED_RESULT_STATUS",
144
144
  /**
145
145
  * A result's reference-range field (`R` field 6) did not match a recognized form (`low-high`,
146
- * `<high`, `>low`). The text is surfaced verbatim as `unparsed` — a bound is **never fabricated**.
146
+ * `<high`, `>low`). The text is surfaced verbatim as `unparsed`: a bound is **never fabricated**.
147
147
  */
148
148
  ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE: "ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE",
149
149
  /**
@@ -152,25 +152,25 @@ var WARNING_CODES = {
152
152
  */
153
153
  ASTM_RECORD_UNITS_ABSENT: "ASTM_RECORD_UNITS_ABSENT",
154
154
  /**
155
- * A `C` (comment) record had no valid preceding `H`/`P`/`O`/`R` parent — an **orphan**. The comment
155
+ * A `C` (comment) record had no valid preceding `H`/`P`/`O`/`R` parent: an **orphan**. The comment
156
156
  * is attached to the message root (`attachedToRoot: true`) and surfaced, **never dropped**.
157
157
  */
158
158
  ASTM_RECORD_ORPHAN_COMMENT: "ASTM_RECORD_ORPHAN_COMMENT",
159
159
  /**
160
160
  * A `YYYYMMDDHHMMSS` timestamp had an odd digit run that truncates a two-digit component in half
161
161
  * (e.g. a partial day/hour). The raw run is preserved and the structured value stops at the last
162
- * **complete** component — the dangling digit is **never zero-filled into a fabricated time**.
162
+ * **complete** component: the dangling digit is **never zero-filled into a fabricated time**.
163
163
  */
164
164
  ASTM_RECORD_PARTIAL_TIMESTAMP: "ASTM_RECORD_PARTIAL_TIMESTAMP",
165
165
  /**
166
166
  * A `Q` (request-information) record carried a request-information status code (field 13). The code
167
167
  * *set* is `[OSS-derived / paywalled]` with no publicly-groundable enumeration, so the parser
168
168
  * interprets **none** of them: the status is surfaced verbatim and this value-free warning flags that
169
- * it was passed through **uninterpreted** — never mapped to a guessed meaning.
169
+ * it was passed through **uninterpreted**, never mapped to a guessed meaning.
170
170
  */
171
171
  ASTM_RECORD_UNINTERPRETED_QUERY_STATUS: "ASTM_RECORD_UNINTERPRETED_QUERY_STATUS",
172
172
  /**
173
- * A message carried **both** a `Q` (request) and an `R` (result) record — a contradictory shape. The
173
+ * A message carried **both** a `Q` (request) and an `R` (result) record: a contradictory shape. The
174
174
  * message is classified `host-query` (the `Q` **dominates**, so it is never read as a result set) and
175
175
  * this warning flags the anomaly. Positional context only; no field value.
176
176
  */
@@ -179,7 +179,7 @@ var WARNING_CODES = {
179
179
  * A later `H` (header) record declared a **different** delimiter set from the one in force, and the
180
180
  * parser **followed it**: that header and every record after it are read with the newly-declared
181
181
  * delimiters, until the next `H`. Records already read keep the set that was in force when they were
182
- * read — a redeclaration never reinterprets bytes that have already been consumed.
182
+ * read: a redeclaration never reinterprets bytes that have already been consumed.
183
183
  *
184
184
  * A stream carrying several messages back to back is ordinary, and a header that simply **repeats**
185
185
  * the delimiters already in force is a no-op that warns nothing. This code fires only when the set
@@ -188,13 +188,13 @@ var WARNING_CODES = {
188
188
  */
189
189
  ASTM_RECORD_DELIMITERS_REDECLARED: "ASTM_RECORD_DELIMITERS_REDECLARED",
190
190
  /**
191
- * A later `H` (header) record could not declare a usable delimiter set — it was too short, or the
191
+ * A later `H` (header) record could not declare a usable delimiter set: it was too short, or the
192
192
  * field separator it named also appeared among the other three, leaving the four roles
193
193
  * indistinguishable. The delimiters **already in force are kept** and every record is still surfaced;
194
194
  * a set is never guessed and no record is dropped.
195
195
  *
196
196
  * The same condition on the *first* header is unrecoverable and remains the
197
- * `ASTM_RECORD_UNDECLARED_DELIMITERS` fatal — there is no earlier set to fall back to.
197
+ * `ASTM_RECORD_UNDECLARED_DELIMITERS` fatal: there is no earlier set to fall back to.
198
198
  */
199
199
  ASTM_RECORD_UNREADABLE_REDECLARATION: "ASTM_RECORD_UNREADABLE_REDECLARATION",
200
200
  /**
@@ -202,7 +202,7 @@ var WARNING_CODES = {
202
202
  * (see `src/profiles/`). The original warning is **never dropped**: its code moves to
203
203
  * {@link AstmRecordWarning.toleratedCode}, the warning is re-badged `PROFILE_QUIRK_APPLIED` with
204
204
  * `expected: true` and the tolerating profile named, so a consumer can filter known, grounded noise
205
- * while the fact of the deviation — and where it was — survives. A profile can only ever reach this
205
+ * while the fact of the deviation, and where it was, survives. A profile can only ever reach this
206
206
  * path for a **non-safety-critical** code (enforced at profile-definition time); a safety-critical
207
207
  * deviation (a result value, flag, status, patient identifier, code system, or a frame-integrity
208
208
  * warning) can **never** be tolerated, so it can never be re-badged here.
@@ -212,28 +212,28 @@ var WARNING_CODES = {
212
212
  function unknownRecordType(position) {
213
213
  return {
214
214
  code: WARNING_CODES.ASTM_RECORD_UNKNOWN_TYPE,
215
- message: "Unrecognized record type \u2014 surfaced verbatim as an unsupported record.",
215
+ message: "Unrecognized record type, surfaced verbatim as an unsupported record.",
216
216
  position
217
217
  };
218
218
  }
219
219
  function nonStandardDelimiters(position) {
220
220
  return {
221
221
  code: WARNING_CODES.ASTM_NONSTANDARD_DELIMITERS,
222
- message: "Header declared non-canonical delimiters \u2014 read from the header and honored.",
222
+ message: "Header declared non-canonical delimiters, read from the header and honored.",
223
223
  position
224
224
  };
225
225
  }
226
226
  function delimitersRedeclared(position) {
227
227
  return {
228
228
  code: WARNING_CODES.ASTM_RECORD_DELIMITERS_REDECLARED,
229
- message: "A later header declared different delimiters \u2014 honored from that header onward; earlier records keep the set they were read with.",
229
+ message: "A later header declared different delimiters, honored from that header onward; earlier records keep the set they were read with.",
230
230
  position
231
231
  };
232
232
  }
233
233
  function unreadableRedeclaration(position) {
234
234
  return {
235
235
  code: WARNING_CODES.ASTM_RECORD_UNREADABLE_REDECLARATION,
236
- message: "A later header could not declare a usable delimiter set \u2014 the delimiters already in force were kept.",
236
+ message: "A later header could not declare a usable delimiter set, the delimiters already in force were kept.",
237
237
  position
238
238
  };
239
239
  }
@@ -247,63 +247,63 @@ function unknownEscapeSequence(position) {
247
247
  function ambiguousValueSplit(position) {
248
248
  return {
249
249
  code: WARNING_CODES.ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT,
250
- message: "Result value contained an unescaped component delimiter \u2014 full raw value and split both surfaced.",
250
+ message: "Result value contained an unescaped component delimiter, full raw value and split both surfaced.",
251
251
  position
252
252
  };
253
253
  }
254
254
  function undefinedAbnormalFlag(position) {
255
255
  return {
256
256
  code: WARNING_CODES.ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG,
257
- message: "Abnormal flag is not in HL7 Table 0078 \u2014 surfaced as undefined, never as normal.",
257
+ message: "Abnormal flag is not in HL7 Table 0078, surfaced as undefined, never as normal.",
258
258
  position
259
259
  };
260
260
  }
261
261
  function undefinedResultStatus(position) {
262
262
  return {
263
263
  code: WARNING_CODES.ASTM_RECORD_UNDEFINED_RESULT_STATUS,
264
- message: "Result status is not a recognized status letter \u2014 surfaced as undefined.",
264
+ message: "Result status is not a recognized status letter, surfaced as undefined.",
265
265
  position
266
266
  };
267
267
  }
268
268
  function unparseableReferenceRange(position) {
269
269
  return {
270
270
  code: WARNING_CODES.ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE,
271
- message: "Reference range did not match a recognized form \u2014 surfaced verbatim, no bound invented.",
271
+ message: "Reference range did not match a recognized form, surfaced verbatim, no bound invented.",
272
272
  position
273
273
  };
274
274
  }
275
275
  function unitsAbsent(position) {
276
276
  return {
277
277
  code: WARNING_CODES.ASTM_RECORD_UNITS_ABSENT,
278
- message: "Numeric result value carried no units \u2014 never defaulted, guessed, or converted.",
278
+ message: "Numeric result value carried no units, never defaulted, guessed, or converted.",
279
279
  position
280
280
  };
281
281
  }
282
282
  function orphanComment(position) {
283
283
  return {
284
284
  code: WARNING_CODES.ASTM_RECORD_ORPHAN_COMMENT,
285
- message: "Comment had no valid preceding parent \u2014 attached to the message root, never dropped.",
285
+ message: "Comment had no valid preceding parent, attached to the message root, never dropped.",
286
286
  position
287
287
  };
288
288
  }
289
289
  function partialTimestamp(position) {
290
290
  return {
291
291
  code: WARNING_CODES.ASTM_RECORD_PARTIAL_TIMESTAMP,
292
- message: "Timestamp digit run truncates a component \u2014 preserved verbatim, never zero-filled.",
292
+ message: "Timestamp digit run truncates a component, preserved verbatim, never zero-filled.",
293
293
  position
294
294
  };
295
295
  }
296
296
  function uninterpretedQueryStatus(position) {
297
297
  return {
298
298
  code: WARNING_CODES.ASTM_RECORD_UNINTERPRETED_QUERY_STATUS,
299
- message: "Query request-information status surfaced verbatim \u2014 code set paywalled, never interpreted.",
299
+ message: "Query request-information status surfaced verbatim, code set paywalled, never interpreted.",
300
300
  position
301
301
  };
302
302
  }
303
303
  function ambiguousMessageKind(position) {
304
304
  return {
305
305
  code: WARNING_CODES.ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND,
306
- message: "Message carried both a Q (request) and an R (result) record \u2014 classified host-query; Q dominates.",
306
+ message: "Message carried both a Q (request) and an R (result) record, classified host-query; Q dominates.",
307
307
  position
308
308
  };
309
309
  }
@@ -567,12 +567,12 @@ var FRAME_WARNING_CODES = {
567
567
  * A frame's two-hex-char checksum did not match the modulo-256 sum recomputed over its bytes. The
568
568
  * frame is surfaced with `trusted: false` and its text is **never merged** into a reassembled
569
569
  * record (default **warn** in lenient mode, escalated to a thrown error in `strict`). Corruption is
570
- * never silently trusted — the "checksums are routinely not validated" claim was refuted; we
570
+ * never silently trusted: the "checksums are routinely not validated" claim was refuted; we
571
571
  * validate.
572
572
  */
573
573
  ASTM_FRAME_BAD_CHECKSUM: "ASTM_FRAME_BAD_CHECKSUM",
574
574
  /**
575
- * A frame's sequence number was not the expected next value (`1 → … → 7 → 0 → …`) — a frame was
575
+ * A frame's sequence number was not the expected next value (`1 → … → 7 → 0 → …`): a frame was
576
576
  * possibly dropped. The stream is **never silently concatenated across the gap** as if contiguous;
577
577
  * the in-progress record is tainted and not emitted as a clean reassembly.
578
578
  */
@@ -586,7 +586,7 @@ var FRAME_WARNING_CODES = {
586
586
  ASTM_FRAME_UNTERMINATED: "ASTM_FRAME_UNTERMINATED",
587
587
  /**
588
588
  * A frame's record text exceeded the 240-byte limit without a split. The frame is still surfaced
589
- * (and, if its checksum validates, reassembled) — the deviation is flagged, not silently dropped
589
+ * (and, if its checksum validates, reassembled): the deviation is flagged, not silently dropped
590
590
  * (warn in lenient, thrown in `strict`).
591
591
  */
592
592
  ASTM_FRAME_OVERSIZE: "ASTM_FRAME_OVERSIZE"
@@ -594,28 +594,28 @@ var FRAME_WARNING_CODES = {
594
594
  function frameBadChecksum(position) {
595
595
  return {
596
596
  code: FRAME_WARNING_CODES.ASTM_FRAME_BAD_CHECKSUM,
597
- message: "Frame checksum mismatch \u2014 surfaced untrusted, never merged into a record.",
597
+ message: "Frame checksum mismatch, surfaced untrusted, never merged into a record.",
598
598
  position
599
599
  };
600
600
  }
601
601
  function frameSequenceGap(position) {
602
602
  return {
603
603
  code: FRAME_WARNING_CODES.ASTM_FRAME_SEQUENCE_GAP,
604
- message: "Frame number out of sequence \u2014 possible dropped frame, never silently bridged.",
604
+ message: "Frame number out of sequence, possible dropped frame, never silently bridged.",
605
605
  position
606
606
  };
607
607
  }
608
608
  function frameUnterminated(position) {
609
609
  return {
610
610
  code: FRAME_WARNING_CODES.ASTM_FRAME_UNTERMINATED,
611
- message: "Unterminated frame \u2014 partial bytes surfaced untrusted, no partial record invented.",
611
+ message: "Unterminated frame, partial bytes surfaced untrusted, no partial record invented.",
612
612
  position
613
613
  };
614
614
  }
615
615
  function frameOversize(position) {
616
616
  return {
617
617
  code: FRAME_WARNING_CODES.ASTM_FRAME_OVERSIZE,
618
- message: "Frame text exceeded the 240-byte limit without a split \u2014 flagged, never dropped.",
618
+ message: "Frame text exceeded the 240-byte limit without a split, flagged, never dropped.",
619
619
  position
620
620
  };
621
621
  }
@@ -624,21 +624,21 @@ function frameOversize(position) {
624
624
  var LTP_WARNING_CODES = {
625
625
  /**
626
626
  * The transport detector could not tell a framed stream from a raw (unframed) one from its leading
627
- * byte — it was neither `STX`/`ENQ` nor a bare record letter. It **defaults to framed** and warns,
627
+ * byte: it was neither `STX`/`ENQ` nor a bare record letter. It **defaults to framed** and warns,
628
628
  * never guessing silently into data loss; a profile override forces the mode. (cobas b121 drops
629
- * framing over TCP; cobas 4800 / Iguana retain it — both realities exist, so an unrecognizable lead
629
+ * framing over TCP; cobas 4800 / Iguana retain it, both realities exist, so an unrecognizable lead
630
630
  * is defaulted, not assumed.)
631
631
  */
632
632
  ASTM_LTP_AMBIGUOUS_TRANSPORT: "ASTM_LTP_AMBIGUOUS_TRANSPORT",
633
633
  /**
634
- * A control event arrived in a protocol state that did not expect it — e.g. an inbound `ACK`/`NAK`
634
+ * A control event arrived in a protocol state that did not expect it: e.g. an inbound `ACK`/`NAK`
635
635
  * at a receiver (which sends, never receives, those), or an `ENQ` mid-transfer. The event is
636
636
  * surfaced and handled defensively (an unexpected `ACK`/`NAK` is **never** read as acceptance of
637
637
  * data); it never advances the transfer as if valid.
638
638
  */
639
639
  ASTM_LTP_UNEXPECTED_EVENT: "ASTM_LTP_UNEXPECTED_EVENT",
640
640
  /**
641
- * The receiver rejected a received frame with a `NAK` instead of accepting it — because its
641
+ * The receiver rejected a received frame with a `NAK` instead of accepting it: because its
642
642
  * checksum failed, it was unterminated, or its frame number was out of sequence. The frame's text
643
643
  * is **never** appended to the record and the transfer does **not** advance; the receiver awaits the
644
644
  * sender's retransmit. This is the protocol-level face of the frame codec's fail-safe: a bad frame
@@ -649,20 +649,20 @@ var LTP_WARNING_CODES = {
649
649
  function ltpAmbiguousTransport() {
650
650
  return {
651
651
  code: LTP_WARNING_CODES.ASTM_LTP_AMBIGUOUS_TRANSPORT,
652
- message: "Leading byte was neither a frame start (STX/ENQ) nor a record letter \u2014 defaulted to framed; override with a profile to force raw."
652
+ message: "Leading byte was neither a frame start (STX/ENQ) nor a record letter, defaulted to framed; override with a profile to force raw."
653
653
  };
654
654
  }
655
655
  function ltpUnexpectedEvent(frameNumber) {
656
656
  return {
657
657
  code: LTP_WARNING_CODES.ASTM_LTP_UNEXPECTED_EVENT,
658
- message: "Control event arrived in a state that did not expect it \u2014 handled defensively, never read as acceptance.",
658
+ message: "Control event arrived in a state that did not expect it, handled defensively, never read as acceptance.",
659
659
  ...frameNumber !== void 0 ? { frameNumber } : {}
660
660
  };
661
661
  }
662
662
  function ltpFrameRejected(frameNumber) {
663
663
  return {
664
664
  code: LTP_WARNING_CODES.ASTM_LTP_FRAME_REJECTED,
665
- message: "Frame rejected (bad checksum, unterminated, or out of sequence) \u2014 NAK sent, retransmit expected, never accepted.",
665
+ message: "Frame rejected (bad checksum, unterminated, or out of sequence), NAK sent, retransmit expected, never accepted.",
666
666
  ...frameNumber !== void 0 ? { frameNumber } : {}
667
667
  };
668
668
  }
@@ -770,7 +770,7 @@ function validateTolerations(tolerate, profileName) {
770
770
  }
771
771
  if (isSafetyCriticalCode(t.code)) {
772
772
  throw new AstmProfileDefinitionError(
773
- `Profile '${profileName}' may not tolerate '${t.code}' \u2014 it is a safety-critical warning code (a result value / flag / status / range / units, patient or comment context, message-kind ambiguity, code system, or a frame / LTP integrity warning). A profile quiets benign structural noise, never a deviation that could change a clinical reading or corrupt the wire \u2014 it can never make a bad checksum "ok" or a cancelled result read "final."`,
773
+ `Profile '${profileName}' may not tolerate '${t.code}': it is a safety-critical warning code (a result value / flag / status / range / units, patient or comment context, message-kind ambiguity, code system, or a frame / LTP integrity warning). A profile quiets benign structural noise, never a deviation that could change a clinical reading or corrupt the wire: it can never make a bad checksum "ok" or a cancelled result read "final."`,
774
774
  profileName
775
775
  );
776
776
  }
@@ -813,14 +813,14 @@ function defineAstmProfile(opts) {
813
813
  // src/profiles/default.ts
814
814
  var defaultProfile = defineAstmProfile({
815
815
  name: "default",
816
- description: "Conservative baseline \u2014 tolerates nothing; every deviation surfaces as a warning.",
816
+ description: "Conservative baseline: tolerates nothing; every deviation surfaces as a warning.",
817
817
  tolerate: []
818
818
  });
819
819
 
820
820
  // src/profiles/reference-corpus.ts
821
821
  var referenceCorpus = defineAstmProfile({
822
822
  name: "referenceCorpus",
823
- description: "Non-standard-escape tolerance grounded firsthand in the escape-agnostic OSS reference corpus (python-astm / senaite). Syntactic encoding noise only \u2014 the value is preserved verbatim, never a safety-critical value.",
823
+ description: "Non-standard-escape tolerance grounded firsthand in the escape-agnostic OSS reference corpus (python-astm / senaite). Syntactic encoding noise only: the value is preserved verbatim, never a safety-critical value.",
824
824
  provenance: {
825
825
  source: "kxepal/python-astm codec.py (BSD) + senaite.astm / senaite.lis2a",
826
826
  reference: "https://github.com/kxepal/python-astm/blob/master/astm/codec.py ; https://github.com/senaite/senaite.astm",
@@ -1084,7 +1084,7 @@ function buildRecord(line2, recordIndex, d, warnings) {
1084
1084
  case "Q":
1085
1085
  return buildQuery(recordIndex, fields, warnings);
1086
1086
  // `M` (manufacturer) and `S` (scientific) are vendor-defined free-form data surfaced VERBATIM and
1087
- // NEVER interpreted into typed clinical fields — the exact wire line is preserved for round-trip.
1087
+ // NEVER interpreted into typed clinical fields: the exact wire line is preserved for round-trip.
1088
1088
  case "M":
1089
1089
  return { type: "M", recordIndex, fields, rawLine: line2 };
1090
1090
  case "S":
@@ -1117,7 +1117,7 @@ function buildPatient(recordIndex, fields, warnings) {
1117
1117
  recordIndex,
1118
1118
  fields,
1119
1119
  ...definedString("seq", fieldScalar(astmField(fields, 2))),
1120
- // The three patient identifiers stay DISTINCT — practice-assigned (3), laboratory-assigned (4),
1120
+ // The three patient identifiers stay DISTINCT: practice-assigned (3), laboratory-assigned (4),
1121
1121
  // and a third ID (5) never collapse into one; conflating them is the primary misfiling path.
1122
1122
  ...definedString("practiceAssignedId", fieldScalar(astmField(fields, 3))),
1123
1123
  ...definedString("laboratoryAssignedId", fieldScalar(astmField(fields, 4))),
@@ -1140,7 +1140,7 @@ function buildOrder(recordIndex, fields) {
1140
1140
  ...hasContent(utidField) ? { universalTestId: recognizeUniversalTestId(utidField.components) } : {},
1141
1141
  // Priority (6), action code (~12), and report type (~26) are surfaced verbatim. The `~` field
1142
1142
  // indices and the code sets are `[OSS-derived]` (paywalled), so they are never mapped to a
1143
- // guessed meaning — see the JSDoc on `OrderRecord`.
1143
+ // guessed meaning: see the JSDoc on `OrderRecord`.
1144
1144
  ...definedString("priority", fieldScalar(astmField(fields, 6))),
1145
1145
  ...definedString("actionCode", fieldScalar(astmField(fields, 12))),
1146
1146
  ...definedString("reportType", fieldScalar(astmField(fields, 26)))
@@ -1539,7 +1539,7 @@ var AMBIGUOUS_CODES = {
1539
1539
  ASTM_AMBIGUOUS_MULTI_PATIENT: "ASTM_AMBIGUOUS_MULTI_PATIENT"
1540
1540
  };
1541
1541
  var AstmAmbiguousStreamError = class extends Error {
1542
- /** The stable discriminant — see {@link AMBIGUOUS_CODES}. */
1542
+ /** The stable discriminant: see {@link AMBIGUOUS_CODES}. */
1543
1543
  code;
1544
1544
  /** Where the ambiguity became visible: the second header, or the second `P`. Value-free. */
1545
1545
  position;
@@ -1684,14 +1684,14 @@ function defineLivdCatalog(entries) {
1684
1684
  var LIVD_WARNING_CODES = {
1685
1685
  /**
1686
1686
  * A record carried a vendor/local test code, but the consumer-supplied LIVD catalog held **no**
1687
- * entry for it. The code stays surfaced verbatim and the mapping is `unmapped` — a LOINC is
1687
+ * entry for it. The code stays surfaced verbatim and the mapping is `unmapped`: a LOINC is
1688
1688
  * **never** guessed. Purely advisory: the raw code and value are untouched.
1689
1689
  */
1690
1690
  ASTM_LIVD_UNMAPPED_CODE: "ASTM_LIVD_UNMAPPED_CODE",
1691
1691
  /**
1692
1692
  * A vendor/local test code matched **more than one distinct LOINC** in the catalog (e.g. the same
1693
1693
  * transmission code used by two devices for different analytes). The mapping is `ambiguous` and the
1694
- * candidate LOINCs are surfaced for inspection, but **none is chosen** — refusing to pick is the
1694
+ * candidate LOINCs are surfaced for inspection, but **none is chosen**: refusing to pick is the
1695
1695
  * fail-safe, since guessing wrong mis-identifies the test.
1696
1696
  */
1697
1697
  ASTM_LIVD_AMBIGUOUS_MAPPING: "ASTM_LIVD_AMBIGUOUS_MAPPING"
@@ -1699,14 +1699,14 @@ var LIVD_WARNING_CODES = {
1699
1699
  function livdUnmappedCode(position) {
1700
1700
  return {
1701
1701
  code: LIVD_WARNING_CODES.ASTM_LIVD_UNMAPPED_CODE,
1702
- message: "Reported test code had no LIVD mapping \u2014 surfaced unmapped, never a guessed LOINC.",
1702
+ message: "Reported test code had no LIVD mapping, surfaced unmapped, never a guessed LOINC.",
1703
1703
  position
1704
1704
  };
1705
1705
  }
1706
1706
  function livdAmbiguousMapping(position) {
1707
1707
  return {
1708
1708
  code: LIVD_WARNING_CODES.ASTM_LIVD_AMBIGUOUS_MAPPING,
1709
- message: "Reported test code mapped to multiple distinct LOINCs \u2014 surfaced ambiguous, never one guessed.",
1709
+ message: "Reported test code mapped to multiple distinct LOINCs, surfaced ambiguous, never one guessed.",
1710
1710
  position
1711
1711
  };
1712
1712
  }
@@ -2150,7 +2150,7 @@ function encodeFrame(text, frameNumber, isFinal) {
2150
2150
  }
2151
2151
  function composeAstmFrames(records, options = {}) {
2152
2152
  if (records.length === 0) {
2153
- throw new AstmFrameEncodeError("Cannot frame an empty record list \u2014 nothing to transmit.");
2153
+ throw new AstmFrameEncodeError("Cannot frame an empty record list: nothing to transmit.");
2154
2154
  }
2155
2155
  const out = [];
2156
2156
  let frameNumber = options.startFrameNumber ?? FIRST_FRAME_NUMBER;
@@ -2158,7 +2158,7 @@ function composeAstmFrames(records, options = {}) {
2158
2158
  const bytes = toBytes(record);
2159
2159
  if (bytes.length === 0) {
2160
2160
  throw new AstmFrameEncodeError(
2161
- "Cannot frame an empty record \u2014 a frame must carry record bytes.",
2161
+ "Cannot frame an empty record: a frame must carry record bytes.",
2162
2162
  recordIndex
2163
2163
  );
2164
2164
  }
@@ -2197,7 +2197,7 @@ function concatBytes3(chunks) {
2197
2197
  }
2198
2198
 
2199
2199
  // src/index.ts
2200
- var VERSION = "0.0.4";
2200
+ var VERSION = "0.0.5";
2201
2201
 
2202
2202
  export { ALL_ASTM_WARNING_CODES, AMBIGUOUS_CODES, ACK as ASTM_ACK, ENQ as ASTM_ENQ, EOT as ASTM_EOT, NAK as ASTM_NAK, AstmAmbiguousStreamError, AstmFrameEncodeError, AstmFrameStrictError, AstmParseError, AstmProfileDefinitionError, AstmSerializeError, AstmStrictError, CANONICAL_DELIMITERS, FATAL_CODES, FRAME_WARNING_CODES, LIVD_WARNING_CODES, LTP_WARNING_CODES, SAFETY_CRITICAL_CODES, TOLERABLE_CODES, VERSION, WARNING_CODES, ambiguousMessageKind, ambiguousValueSplit, applyAstmProfile, applyAstmProfileToWarnings, applyLivd, astmDateToLocalISO, astmProfiles, attachComments, buildAstmMessage, classifyMessage, comments, commentsFor, composeAstmFrames, computeChecksum, decodeAstmFrames, decodeEscapes, deepFreeze, defineAstmProfile, defineLivdCatalog, delimitersRedeclared, detectFraming, encodeComponent, fieldScalar, frameBadChecksum, frameOversize, frameSequenceGap, frameUnterminated, getAstmProfile, getDefaultAstmProfile, interpretAbnormalFlag, interpretResultStatus, isNonStandard, isSafetyCriticalCode, listAstmProfiles, livdAmbiguousMapping, livdUnmappedCode, lookupLivdForRecord, ltpAmbiguousTransport, ltpFrameRejected, ltpInitialState, ltpReduce, ltpUnexpectedEvent, messages, nonStandardDelimiters, orders, orphanComment, parseAstmDate, parseAstmRecords, parseChecksumHex, parseFramedAstm, parseReferenceRange, partialTimestamp, patient, primaryCode, profileQuirkApplied, query, readDelimiters, recognizeUniversalTestId, resolveProfileTransport, results, serializeAstmRecord, serializeAstmRecords, serializeField, serializeFramedAstm, setDefaultAstmProfile, splitEscapeAware, toChecksumHex, tokenizeHeader, tokenizeRecord, undefinedAbnormalFlag, undefinedResultStatus, uninterpretedQueryStatus, unitsAbsent, unknownEscapeSequence, unknownRecordType, unparseableReferenceRange, unreadableRedeclaration };
2203
2203
  //# sourceMappingURL=index.mjs.map