@cosyte/astm 0.1.3 → 0.1.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/CHANGELOG.md +18 -0
- package/dist/index.cjs +7 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -31
- package/dist/index.d.ts +56 -31
- package/dist/index.mjs +7 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +31 -32
package/dist/index.d.cts
CHANGED
|
@@ -515,9 +515,12 @@ declare const WARNING_CODES: {
|
|
|
515
515
|
*/
|
|
516
516
|
readonly ASTM_RECORD_UNINTERPRETED_QUERY_STATUS: "ASTM_RECORD_UNINTERPRETED_QUERY_STATUS";
|
|
517
517
|
/**
|
|
518
|
-
*
|
|
519
|
-
*
|
|
518
|
+
* The stream carried **both** a `Q` (request) and an `R` (result) record: a contradictory shape. The
|
|
519
|
+
* stream is classified `host-query` (the `Q` **dominates**, so it is never read as a result set) and
|
|
520
520
|
* this warning flags the anomaly. Positional context only; no field value.
|
|
521
|
+
*
|
|
522
|
+
* Classification is folded over the whole stream, so a `Q` in one message and an `R` in another
|
|
523
|
+
* raise it too. `classifyMessage(m.records)` over `messages()` says which message carried which.
|
|
521
524
|
*/
|
|
522
525
|
readonly ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND: "ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND";
|
|
523
526
|
/**
|
|
@@ -941,10 +944,10 @@ declare function partialTimestamp(position: AstmPosition): AstmRecordWarning;
|
|
|
941
944
|
*/
|
|
942
945
|
declare function uninterpretedQueryStatus(position: AstmPosition): AstmRecordWarning;
|
|
943
946
|
/**
|
|
944
|
-
* Build an `ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND` warning. Emitted when a
|
|
945
|
-
* carries both a `Q` (request) and an `R` (result) record
|
|
946
|
-
* classified as a host-query request (the `Q`
|
|
947
|
-
* flagged.
|
|
947
|
+
* Build an `ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND` warning. Emitted when a parsed
|
|
948
|
+
* stream carries both a `Q` (request) and an `R` (result) record, in one message
|
|
949
|
+
* or across several; the stream is classified as a host-query request (the `Q`
|
|
950
|
+
* dominates) and the anomaly is flagged.
|
|
948
951
|
*
|
|
949
952
|
* @example
|
|
950
953
|
* ```ts
|
|
@@ -2487,8 +2490,11 @@ interface CommentRecord extends RecordBase {
|
|
|
2487
2490
|
* The `Q` (Request Information) record: the host-query request.
|
|
2488
2491
|
*
|
|
2489
2492
|
* A `Q` record asks the LIS for information (e.g. outstanding orders for a
|
|
2490
|
-
* specimen); its **presence classifies the
|
|
2491
|
-
* result set
|
|
2493
|
+
* specimen); its **presence classifies the records it arrives in as a request,
|
|
2494
|
+
* never a result set**. {@link AstmMessage.classification} is folded over the
|
|
2495
|
+
* whole parsed stream, so a `Q` in any one message makes the whole stream read as
|
|
2496
|
+
* a host query; `classifyMessage(m.records)` classifies one message from
|
|
2497
|
+
* `messages()` on its own. Its safety-relevant
|
|
2492
2498
|
* fields, the starting/ending range ID and the request-information status, are
|
|
2493
2499
|
* surfaced **verbatim**; the field *positions* are the public ASTM E1394 layout,
|
|
2494
2500
|
* but their internal structure and code meanings are **`[OSS-derived / paywalled]`**
|
|
@@ -2589,10 +2595,11 @@ interface TerminatorRecord extends RecordBase {
|
|
|
2589
2595
|
* arrives here instead, opens no message, and the messages either side of it are
|
|
2590
2596
|
* grouped as one. Check `rawType` before trusting a split.
|
|
2591
2597
|
*
|
|
2592
|
-
* **And one of these may be a `Q`.**
|
|
2593
|
-
*
|
|
2594
|
-
*
|
|
2595
|
-
*
|
|
2598
|
+
* **And one of these may be a `Q`.** Classification counts type letters too, so
|
|
2599
|
+
* records that include an unsupported one are classified `indeterminate` unless a
|
|
2600
|
+
* `Q` was read outright. On {@link AstmMessage.classification} that is every
|
|
2601
|
+
* record in the stream, so one unsupported record in any message withholds the
|
|
2602
|
+
* kind for the whole stream: see {@link AstmMessageClassification.hasUnrecognized}.
|
|
2596
2603
|
*
|
|
2597
2604
|
* **A header that arrives here also failed to re-scope the delimiters.** The
|
|
2598
2605
|
* records after it are read with the set already in force, and where that set is
|
|
@@ -2607,12 +2614,13 @@ interface UnsupportedRecord extends RecordBase {
|
|
|
2607
2614
|
/** The discriminated union of every parsed record. */
|
|
2608
2615
|
type AstmRecord = HeaderRecord | PatientRecord | OrderRecord | ResultRecord | CommentRecord | QueryRecord | ManufacturerRecord | ScientificRecord | TerminatorRecord | UnsupportedRecord;
|
|
2609
2616
|
/**
|
|
2610
|
-
* How a
|
|
2617
|
+
* How the host-query flow classifies a set of records: one message's under
|
|
2618
|
+
* `classifyMessage(m.records)`, the whole stream's on {@link AstmMessage.classification}.
|
|
2611
2619
|
*
|
|
2612
|
-
* - `host-query` (the
|
|
2620
|
+
* - `host-query` (the records include at least one `Q`): it is a **request
|
|
2613
2621
|
* for information**, and **must never be read as a result set** (the load-bearing
|
|
2614
2622
|
* safety distinction of this layer). `Q` **dominates**: a `Q` present classifies
|
|
2615
|
-
* the
|
|
2623
|
+
* the records as a request even if a result record is also present (an anomaly,
|
|
2616
2624
|
* separately warned), so a `Q`-bearing message is never silently treated as a
|
|
2617
2625
|
* result upload.
|
|
2618
2626
|
* - `results` (no `Q`, at least one `R` result record): a result upload / response.
|
|
@@ -2623,9 +2631,16 @@ type AstmRecord = HeaderRecord | PatientRecord | OrderRecord | ResultRecord | Co
|
|
|
2623
2631
|
*/
|
|
2624
2632
|
type AstmMessageKind = "host-query" | "results" | "orders" | "indeterminate";
|
|
2625
2633
|
/**
|
|
2626
|
-
* The
|
|
2627
|
-
*
|
|
2628
|
-
*
|
|
2634
|
+
* The host-query classification of a set of records. `isHostQueryRequest` is the
|
|
2635
|
+
* single boolean a consumer should gate on before treating records as results: it
|
|
2636
|
+
* is `true` **iff** a `Q` record is present among the records classified.
|
|
2637
|
+
*
|
|
2638
|
+
* Which records those are depends on where it comes from. On
|
|
2639
|
+
* {@link AstmMessage.classification} it is folded over **every record in the
|
|
2640
|
+
* stream**, not one message: a stream carrying several `H` … `L` messages gets one
|
|
2641
|
+
* classification, so a `Q` in any message makes the whole stream read as a host
|
|
2642
|
+
* query. `classifyMessage(m.records)`, on a message from `messages()`, gives
|
|
2643
|
+
* that one message's classification.
|
|
2629
2644
|
*
|
|
2630
2645
|
* @example
|
|
2631
2646
|
* ```ts
|
|
@@ -2637,9 +2652,9 @@ type AstmMessageKind = "host-query" | "results" | "orders" | "indeterminate";
|
|
|
2637
2652
|
*/
|
|
2638
2653
|
interface AstmMessageClassification {
|
|
2639
2654
|
/**
|
|
2640
|
-
* The
|
|
2655
|
+
* The kind of the records classified.
|
|
2641
2656
|
*
|
|
2642
|
-
* `indeterminate` also covers
|
|
2657
|
+
* `indeterminate` also covers records the reader declines to classify: when
|
|
2643
2658
|
* {@link AstmMessageClassification.hasUnrecognized} is `true` and no `Q` was read, the kind is
|
|
2644
2659
|
* withheld rather than guessed, because the unreadable letter may have been that `Q`. The `has*`
|
|
2645
2660
|
* flags below stay truthful in that case, so a caller that wants the raw counts still has them.
|
|
@@ -2655,7 +2670,7 @@ interface AstmMessageClassification {
|
|
|
2655
2670
|
* At least one record's type letter was **not recognized** (an
|
|
2656
2671
|
* {@link UnsupportedRecord}), so the letter counts above are known to be incomplete.
|
|
2657
2672
|
*
|
|
2658
|
-
* Any of them may have been a `Q`, which is why
|
|
2673
|
+
* Any of them may have been a `Q`, which is why records that include one are classified
|
|
2659
2674
|
* `indeterminate` unless a `Q` was read outright. `ASTM_RECORD_UNKNOWN_TYPE` reports the same
|
|
2660
2675
|
* condition on {@link AstmMessage.warnings}.
|
|
2661
2676
|
*/
|
|
@@ -2664,7 +2679,7 @@ interface AstmMessageClassification {
|
|
|
2664
2679
|
* `true` **iff** `kind === "host-query"` (a `Q` record was read), the safety surface: gate on this
|
|
2665
2680
|
* before treating records as results, so a query is never misread as a result upload.
|
|
2666
2681
|
*
|
|
2667
|
-
* `false` is **not** a warrant that the
|
|
2682
|
+
* `false` is **not** a warrant that the records are a result set. Read `kind` for that: it is
|
|
2668
2683
|
* `indeterminate` whenever the reader could not account for every type letter.
|
|
2669
2684
|
*/
|
|
2670
2685
|
readonly isHostQueryRequest: boolean;
|
|
@@ -2695,10 +2710,14 @@ interface AstmMessage {
|
|
|
2695
2710
|
*/
|
|
2696
2711
|
readonly delimiters: Delimiters;
|
|
2697
2712
|
/**
|
|
2698
|
-
* The host-query classification of
|
|
2699
|
-
* present), a result upload, an order download, or indeterminate. Gate on
|
|
2700
|
-
* {@link AstmMessageClassification.isHostQueryRequest} before reading records as
|
|
2701
|
-
*
|
|
2713
|
+
* The host-query classification of the **whole stream**: whether its records make a request
|
|
2714
|
+
* (`Q` present), a result upload, an order download, or indeterminate. Gate on
|
|
2715
|
+
* {@link AstmMessageClassification.isHostQueryRequest} before reading records as results.
|
|
2716
|
+
*
|
|
2717
|
+
* It is folded over every record, not per message, and it does not throw on a multi-message
|
|
2718
|
+
* stream. A `Q` in one message makes the whole stream read as a host query, and a stream that
|
|
2719
|
+
* also carries results anywhere raises `ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND`. Classify each
|
|
2720
|
+
* message on its own with `classifyMessage(m.records)` over `messages()`.
|
|
2702
2721
|
*/
|
|
2703
2722
|
readonly classification: AstmMessageClassification;
|
|
2704
2723
|
readonly warnings: readonly AstmRecordWarning[];
|
|
@@ -3662,8 +3681,8 @@ declare function messages(msg: AstmMessage): readonly AstmStreamMessage[];
|
|
|
3662
3681
|
* Classify a record stream by the host-query flow. Pure and total: it only reads
|
|
3663
3682
|
* the record type letters, never a field value.
|
|
3664
3683
|
*
|
|
3665
|
-
* `Q` dominates:
|
|
3666
|
-
* a result (`R`) record is also present, so a query is never misread as a result
|
|
3684
|
+
* `Q` dominates: records with any `Q` among them are a `host-query` request even
|
|
3685
|
+
* when a result (`R`) record is also present, so a query is never misread as a result
|
|
3667
3686
|
* upload. (The `Q`+`R` anomaly is separately warned at parse time.)
|
|
3668
3687
|
*
|
|
3669
3688
|
* An **unsupported** record letter with no `Q` alongside it yields `indeterminate`,
|
|
@@ -3672,8 +3691,13 @@ declare function messages(msg: AstmMessage): readonly AstmStreamMessage[];
|
|
|
3672
3691
|
* {@link AstmMessageClassification.hasUnrecognized} reports why the answer is
|
|
3673
3692
|
* withheld, and the `has*` counts stay truthful throughout.
|
|
3674
3693
|
*
|
|
3694
|
+
* `parseAstmRecords` applies this to every record in the stream, so
|
|
3695
|
+
* its `classification` answers for the whole stream, not per message.
|
|
3696
|
+
* Pass one message's records (`m.records` for `m` of `messages()`) to classify that
|
|
3697
|
+
* message on its own.
|
|
3698
|
+
*
|
|
3675
3699
|
* @param records - The parsed records, in wire order.
|
|
3676
|
-
* @returns The
|
|
3700
|
+
* @returns The classification of exactly those records.
|
|
3677
3701
|
* @example
|
|
3678
3702
|
* ```ts
|
|
3679
3703
|
* import { classifyMessage, parseAstmRecords } from "@cosyte/astm";
|
|
@@ -7136,7 +7160,7 @@ declare class AstmFrameStrictError extends Error {
|
|
|
7136
7160
|
* Library version string, kept in lockstep with `package.json#version`.
|
|
7137
7161
|
*
|
|
7138
7162
|
* Changesets owns the bump and rewrites `package.json` only, so the release `version` script runs
|
|
7139
|
-
* `
|
|
7163
|
+
* `cosyte-process sync-version` to rewrite this declaration in the same commit, and
|
|
7140
7164
|
* `test/sanity.test.ts` compares the two so a skipped sync goes red instead of shipping a version
|
|
7141
7165
|
* string that lies.
|
|
7142
7166
|
*
|
|
@@ -7148,4 +7172,5 @@ declare class AstmFrameStrictError extends Error {
|
|
|
7148
7172
|
*/
|
|
7149
7173
|
declare const VERSION: string;
|
|
7150
7174
|
|
|
7151
|
-
export { ABNORMAL_FLAG_CODES, ABNORMAL_FLAG_VOCABULARY, ALL_ASTM_WARNING_CODES, AMBIGUOUS_CODES, ACK as ASTM_ACK, ENQ as ASTM_ENQ, EOT as ASTM_EOT, NAK as ASTM_NAK,
|
|
7175
|
+
export { ABNORMAL_FLAG_CODES, ABNORMAL_FLAG_VOCABULARY, 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_CATALOG_IDENTITY_UNDECLARED, LIVD_WARNING_CODES, LTP_WARNING_CODES, RESULT_STATUS_VOCABULARY, SAFETY_CRITICAL_CODES, TOLERABLE_CODES, VERSION, WARNING_CODES, alignmentShiftedComponents, alignmentShiftedFields, alignmentTruncatedField, ambiguousEscapeAlignment, ambiguousMessageKind, ambiguousValueSplit, applyAstmProfile, applyAstmProfileToWarnings, applyLivd, astmDateToLocalISO, astmProfiles, attachComments, buildAstmMessage, classifyMessage, comments, commentsFor, composeAstmFrames, computeChecksum, decodeAstmFrames, decodeEscapes, deepFreeze, defineAstmProfile, defineLivdCatalog, delimiterRoleCollision, delimiterSwallowedByEscape, delimitersRedeclared, describeVocabulary, detectFraming, encodeComponent, fieldScalar, fieldsUnseparated, frameBadChecksum, frameOversize, frameSequenceGap, frameUnterminated, getAstmProfile, getDefaultAstmProfile, hasCollidingRoles, interpretAbnormalFlag, interpretResultStatus, isNonStandard, isSafetyCriticalCode, listAstmProfiles, livdAmbiguousMapping, livdCatalogMissingLoincVersion, livdUnmappedCode, lookupLivdForRecord, ltpAmbiguousTransport, ltpFrameRejected, ltpInitialState, ltpReduce, ltpUnexpectedEvent, messages, nonStandardDelimiters, orders, orphanComment, parseAstmDate, parseAstmRecords, parseChecksumHex, parseFramedAstm, parseReferenceRange, partialTimestamp, patient, primaryCode, profileQuirkApplied, query, readDelimiterDeclaration, readDelimiters, recognizeUniversalTestId, resolveProfileTransport, results, serializeAstmRecord, serializeAstmRecords, serializeField, serializeFramedAstm, setDefaultAstmProfile, splitEscapeAware, toChecksumHex, toDate, toISO, toObject, tokenizeHeader, tokenizeRecord, undefinedAbnormalFlag, undefinedResultStatus, uninterpretedQueryStatus, unitsAbsent, unknownEscapeSequence, unknownRecordType, unpairedEscapeCharacter, unparseableReferenceRange, unreadableRedeclaration };
|
|
7176
|
+
export type { AbnormalFlag, AbnormalFlagCode, AbnormalFlagMeaning, AmbiguousAlignmentSink, AmbiguousCode, AnyAstmWarningCode, AstmDate, AstmDatePrecision, AstmField, AstmFrame, AstmFrameEncodeErrorCode, AstmFramePosition, AstmFrameWarning, AstmFraming, AstmLivdCatalogWarning, AstmLivdWarning, AstmLtpWarning, AstmMessage, AstmMessageClassification, AstmMessageKind, AstmParseOptions, AstmPosition, AstmProfile, AstmProfileProvenance, AstmQuirkMatch, AstmQuirkTolerance, AstmRecord, AstmRecordInput, AstmRecordWarning, AstmSerializeErrorCode, AstmStreamMessage, CommentInput, CommentRecord, ComposeFramesOptions, DateParts, DecodeAstmFramesResult, DefineAstmProfileOptions, DelimiterDeclarationFault, DelimiterReadResult, Delimiters, DetectFramingOptions, DetectFramingResult, FatalCode, FrameChecksum, FrameOptions, FrameTerminator, FrameWarningCode, FramedAstmResult, HeaderInput, HeaderRecord, LivdAmbiguityReason, LivdAnnotation, LivdCandidate, LivdCatalog, LivdCatalogIdentity, LivdEntry, LivdLookup, LivdMapping, LivdPublication, LivdResult, LivdUnitComparison, LivdWarningCode, LtpAction, LtpEvent, LtpPhase, LtpState, LtpTransition, LtpWarningCode, ManufacturerRecord, MessageInput, NamedVocabulary, OrderInput, OrderRecord, PatientInput, PatientName, PatientNameInput, PatientRecord, QueryInput, QueryRecord, ReferenceRange, ReferenceRangeKind, ResultInput, ResultRecord, ResultStatus, ResultStatusCode, ResultStatusMeaning, ScientificRecord, ShiftedComponentsSink, ShiftedFieldsSink, SwallowedDelimiterSink, TerminatorRecord, ToDateOptions, TruncatedFieldSink, UnattributedVocabulary, UniversalTestId, UniversalTestIdProvenance, UnknownEscapeSink, UnpairedEscapeSink, UnsupportedRecord, VerbatimInput, VocabularyAttribution, WarningCode };
|
package/dist/index.d.ts
CHANGED
|
@@ -515,9 +515,12 @@ declare const WARNING_CODES: {
|
|
|
515
515
|
*/
|
|
516
516
|
readonly ASTM_RECORD_UNINTERPRETED_QUERY_STATUS: "ASTM_RECORD_UNINTERPRETED_QUERY_STATUS";
|
|
517
517
|
/**
|
|
518
|
-
*
|
|
519
|
-
*
|
|
518
|
+
* The stream carried **both** a `Q` (request) and an `R` (result) record: a contradictory shape. The
|
|
519
|
+
* stream is classified `host-query` (the `Q` **dominates**, so it is never read as a result set) and
|
|
520
520
|
* this warning flags the anomaly. Positional context only; no field value.
|
|
521
|
+
*
|
|
522
|
+
* Classification is folded over the whole stream, so a `Q` in one message and an `R` in another
|
|
523
|
+
* raise it too. `classifyMessage(m.records)` over `messages()` says which message carried which.
|
|
521
524
|
*/
|
|
522
525
|
readonly ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND: "ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND";
|
|
523
526
|
/**
|
|
@@ -941,10 +944,10 @@ declare function partialTimestamp(position: AstmPosition): AstmRecordWarning;
|
|
|
941
944
|
*/
|
|
942
945
|
declare function uninterpretedQueryStatus(position: AstmPosition): AstmRecordWarning;
|
|
943
946
|
/**
|
|
944
|
-
* Build an `ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND` warning. Emitted when a
|
|
945
|
-
* carries both a `Q` (request) and an `R` (result) record
|
|
946
|
-
* classified as a host-query request (the `Q`
|
|
947
|
-
* flagged.
|
|
947
|
+
* Build an `ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND` warning. Emitted when a parsed
|
|
948
|
+
* stream carries both a `Q` (request) and an `R` (result) record, in one message
|
|
949
|
+
* or across several; the stream is classified as a host-query request (the `Q`
|
|
950
|
+
* dominates) and the anomaly is flagged.
|
|
948
951
|
*
|
|
949
952
|
* @example
|
|
950
953
|
* ```ts
|
|
@@ -2487,8 +2490,11 @@ interface CommentRecord extends RecordBase {
|
|
|
2487
2490
|
* The `Q` (Request Information) record: the host-query request.
|
|
2488
2491
|
*
|
|
2489
2492
|
* A `Q` record asks the LIS for information (e.g. outstanding orders for a
|
|
2490
|
-
* specimen); its **presence classifies the
|
|
2491
|
-
* result set
|
|
2493
|
+
* specimen); its **presence classifies the records it arrives in as a request,
|
|
2494
|
+
* never a result set**. {@link AstmMessage.classification} is folded over the
|
|
2495
|
+
* whole parsed stream, so a `Q` in any one message makes the whole stream read as
|
|
2496
|
+
* a host query; `classifyMessage(m.records)` classifies one message from
|
|
2497
|
+
* `messages()` on its own. Its safety-relevant
|
|
2492
2498
|
* fields, the starting/ending range ID and the request-information status, are
|
|
2493
2499
|
* surfaced **verbatim**; the field *positions* are the public ASTM E1394 layout,
|
|
2494
2500
|
* but their internal structure and code meanings are **`[OSS-derived / paywalled]`**
|
|
@@ -2589,10 +2595,11 @@ interface TerminatorRecord extends RecordBase {
|
|
|
2589
2595
|
* arrives here instead, opens no message, and the messages either side of it are
|
|
2590
2596
|
* grouped as one. Check `rawType` before trusting a split.
|
|
2591
2597
|
*
|
|
2592
|
-
* **And one of these may be a `Q`.**
|
|
2593
|
-
*
|
|
2594
|
-
*
|
|
2595
|
-
*
|
|
2598
|
+
* **And one of these may be a `Q`.** Classification counts type letters too, so
|
|
2599
|
+
* records that include an unsupported one are classified `indeterminate` unless a
|
|
2600
|
+
* `Q` was read outright. On {@link AstmMessage.classification} that is every
|
|
2601
|
+
* record in the stream, so one unsupported record in any message withholds the
|
|
2602
|
+
* kind for the whole stream: see {@link AstmMessageClassification.hasUnrecognized}.
|
|
2596
2603
|
*
|
|
2597
2604
|
* **A header that arrives here also failed to re-scope the delimiters.** The
|
|
2598
2605
|
* records after it are read with the set already in force, and where that set is
|
|
@@ -2607,12 +2614,13 @@ interface UnsupportedRecord extends RecordBase {
|
|
|
2607
2614
|
/** The discriminated union of every parsed record. */
|
|
2608
2615
|
type AstmRecord = HeaderRecord | PatientRecord | OrderRecord | ResultRecord | CommentRecord | QueryRecord | ManufacturerRecord | ScientificRecord | TerminatorRecord | UnsupportedRecord;
|
|
2609
2616
|
/**
|
|
2610
|
-
* How a
|
|
2617
|
+
* How the host-query flow classifies a set of records: one message's under
|
|
2618
|
+
* `classifyMessage(m.records)`, the whole stream's on {@link AstmMessage.classification}.
|
|
2611
2619
|
*
|
|
2612
|
-
* - `host-query` (the
|
|
2620
|
+
* - `host-query` (the records include at least one `Q`): it is a **request
|
|
2613
2621
|
* for information**, and **must never be read as a result set** (the load-bearing
|
|
2614
2622
|
* safety distinction of this layer). `Q` **dominates**: a `Q` present classifies
|
|
2615
|
-
* the
|
|
2623
|
+
* the records as a request even if a result record is also present (an anomaly,
|
|
2616
2624
|
* separately warned), so a `Q`-bearing message is never silently treated as a
|
|
2617
2625
|
* result upload.
|
|
2618
2626
|
* - `results` (no `Q`, at least one `R` result record): a result upload / response.
|
|
@@ -2623,9 +2631,16 @@ type AstmRecord = HeaderRecord | PatientRecord | OrderRecord | ResultRecord | Co
|
|
|
2623
2631
|
*/
|
|
2624
2632
|
type AstmMessageKind = "host-query" | "results" | "orders" | "indeterminate";
|
|
2625
2633
|
/**
|
|
2626
|
-
* The
|
|
2627
|
-
*
|
|
2628
|
-
*
|
|
2634
|
+
* The host-query classification of a set of records. `isHostQueryRequest` is the
|
|
2635
|
+
* single boolean a consumer should gate on before treating records as results: it
|
|
2636
|
+
* is `true` **iff** a `Q` record is present among the records classified.
|
|
2637
|
+
*
|
|
2638
|
+
* Which records those are depends on where it comes from. On
|
|
2639
|
+
* {@link AstmMessage.classification} it is folded over **every record in the
|
|
2640
|
+
* stream**, not one message: a stream carrying several `H` … `L` messages gets one
|
|
2641
|
+
* classification, so a `Q` in any message makes the whole stream read as a host
|
|
2642
|
+
* query. `classifyMessage(m.records)`, on a message from `messages()`, gives
|
|
2643
|
+
* that one message's classification.
|
|
2629
2644
|
*
|
|
2630
2645
|
* @example
|
|
2631
2646
|
* ```ts
|
|
@@ -2637,9 +2652,9 @@ type AstmMessageKind = "host-query" | "results" | "orders" | "indeterminate";
|
|
|
2637
2652
|
*/
|
|
2638
2653
|
interface AstmMessageClassification {
|
|
2639
2654
|
/**
|
|
2640
|
-
* The
|
|
2655
|
+
* The kind of the records classified.
|
|
2641
2656
|
*
|
|
2642
|
-
* `indeterminate` also covers
|
|
2657
|
+
* `indeterminate` also covers records the reader declines to classify: when
|
|
2643
2658
|
* {@link AstmMessageClassification.hasUnrecognized} is `true` and no `Q` was read, the kind is
|
|
2644
2659
|
* withheld rather than guessed, because the unreadable letter may have been that `Q`. The `has*`
|
|
2645
2660
|
* flags below stay truthful in that case, so a caller that wants the raw counts still has them.
|
|
@@ -2655,7 +2670,7 @@ interface AstmMessageClassification {
|
|
|
2655
2670
|
* At least one record's type letter was **not recognized** (an
|
|
2656
2671
|
* {@link UnsupportedRecord}), so the letter counts above are known to be incomplete.
|
|
2657
2672
|
*
|
|
2658
|
-
* Any of them may have been a `Q`, which is why
|
|
2673
|
+
* Any of them may have been a `Q`, which is why records that include one are classified
|
|
2659
2674
|
* `indeterminate` unless a `Q` was read outright. `ASTM_RECORD_UNKNOWN_TYPE` reports the same
|
|
2660
2675
|
* condition on {@link AstmMessage.warnings}.
|
|
2661
2676
|
*/
|
|
@@ -2664,7 +2679,7 @@ interface AstmMessageClassification {
|
|
|
2664
2679
|
* `true` **iff** `kind === "host-query"` (a `Q` record was read), the safety surface: gate on this
|
|
2665
2680
|
* before treating records as results, so a query is never misread as a result upload.
|
|
2666
2681
|
*
|
|
2667
|
-
* `false` is **not** a warrant that the
|
|
2682
|
+
* `false` is **not** a warrant that the records are a result set. Read `kind` for that: it is
|
|
2668
2683
|
* `indeterminate` whenever the reader could not account for every type letter.
|
|
2669
2684
|
*/
|
|
2670
2685
|
readonly isHostQueryRequest: boolean;
|
|
@@ -2695,10 +2710,14 @@ interface AstmMessage {
|
|
|
2695
2710
|
*/
|
|
2696
2711
|
readonly delimiters: Delimiters;
|
|
2697
2712
|
/**
|
|
2698
|
-
* The host-query classification of
|
|
2699
|
-
* present), a result upload, an order download, or indeterminate. Gate on
|
|
2700
|
-
* {@link AstmMessageClassification.isHostQueryRequest} before reading records as
|
|
2701
|
-
*
|
|
2713
|
+
* The host-query classification of the **whole stream**: whether its records make a request
|
|
2714
|
+
* (`Q` present), a result upload, an order download, or indeterminate. Gate on
|
|
2715
|
+
* {@link AstmMessageClassification.isHostQueryRequest} before reading records as results.
|
|
2716
|
+
*
|
|
2717
|
+
* It is folded over every record, not per message, and it does not throw on a multi-message
|
|
2718
|
+
* stream. A `Q` in one message makes the whole stream read as a host query, and a stream that
|
|
2719
|
+
* also carries results anywhere raises `ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND`. Classify each
|
|
2720
|
+
* message on its own with `classifyMessage(m.records)` over `messages()`.
|
|
2702
2721
|
*/
|
|
2703
2722
|
readonly classification: AstmMessageClassification;
|
|
2704
2723
|
readonly warnings: readonly AstmRecordWarning[];
|
|
@@ -3662,8 +3681,8 @@ declare function messages(msg: AstmMessage): readonly AstmStreamMessage[];
|
|
|
3662
3681
|
* Classify a record stream by the host-query flow. Pure and total: it only reads
|
|
3663
3682
|
* the record type letters, never a field value.
|
|
3664
3683
|
*
|
|
3665
|
-
* `Q` dominates:
|
|
3666
|
-
* a result (`R`) record is also present, so a query is never misread as a result
|
|
3684
|
+
* `Q` dominates: records with any `Q` among them are a `host-query` request even
|
|
3685
|
+
* when a result (`R`) record is also present, so a query is never misread as a result
|
|
3667
3686
|
* upload. (The `Q`+`R` anomaly is separately warned at parse time.)
|
|
3668
3687
|
*
|
|
3669
3688
|
* An **unsupported** record letter with no `Q` alongside it yields `indeterminate`,
|
|
@@ -3672,8 +3691,13 @@ declare function messages(msg: AstmMessage): readonly AstmStreamMessage[];
|
|
|
3672
3691
|
* {@link AstmMessageClassification.hasUnrecognized} reports why the answer is
|
|
3673
3692
|
* withheld, and the `has*` counts stay truthful throughout.
|
|
3674
3693
|
*
|
|
3694
|
+
* `parseAstmRecords` applies this to every record in the stream, so
|
|
3695
|
+
* its `classification` answers for the whole stream, not per message.
|
|
3696
|
+
* Pass one message's records (`m.records` for `m` of `messages()`) to classify that
|
|
3697
|
+
* message on its own.
|
|
3698
|
+
*
|
|
3675
3699
|
* @param records - The parsed records, in wire order.
|
|
3676
|
-
* @returns The
|
|
3700
|
+
* @returns The classification of exactly those records.
|
|
3677
3701
|
* @example
|
|
3678
3702
|
* ```ts
|
|
3679
3703
|
* import { classifyMessage, parseAstmRecords } from "@cosyte/astm";
|
|
@@ -7136,7 +7160,7 @@ declare class AstmFrameStrictError extends Error {
|
|
|
7136
7160
|
* Library version string, kept in lockstep with `package.json#version`.
|
|
7137
7161
|
*
|
|
7138
7162
|
* Changesets owns the bump and rewrites `package.json` only, so the release `version` script runs
|
|
7139
|
-
* `
|
|
7163
|
+
* `cosyte-process sync-version` to rewrite this declaration in the same commit, and
|
|
7140
7164
|
* `test/sanity.test.ts` compares the two so a skipped sync goes red instead of shipping a version
|
|
7141
7165
|
* string that lies.
|
|
7142
7166
|
*
|
|
@@ -7148,4 +7172,5 @@ declare class AstmFrameStrictError extends Error {
|
|
|
7148
7172
|
*/
|
|
7149
7173
|
declare const VERSION: string;
|
|
7150
7174
|
|
|
7151
|
-
export { ABNORMAL_FLAG_CODES, ABNORMAL_FLAG_VOCABULARY, ALL_ASTM_WARNING_CODES, AMBIGUOUS_CODES, ACK as ASTM_ACK, ENQ as ASTM_ENQ, EOT as ASTM_EOT, NAK as ASTM_NAK,
|
|
7175
|
+
export { ABNORMAL_FLAG_CODES, ABNORMAL_FLAG_VOCABULARY, 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_CATALOG_IDENTITY_UNDECLARED, LIVD_WARNING_CODES, LTP_WARNING_CODES, RESULT_STATUS_VOCABULARY, SAFETY_CRITICAL_CODES, TOLERABLE_CODES, VERSION, WARNING_CODES, alignmentShiftedComponents, alignmentShiftedFields, alignmentTruncatedField, ambiguousEscapeAlignment, ambiguousMessageKind, ambiguousValueSplit, applyAstmProfile, applyAstmProfileToWarnings, applyLivd, astmDateToLocalISO, astmProfiles, attachComments, buildAstmMessage, classifyMessage, comments, commentsFor, composeAstmFrames, computeChecksum, decodeAstmFrames, decodeEscapes, deepFreeze, defineAstmProfile, defineLivdCatalog, delimiterRoleCollision, delimiterSwallowedByEscape, delimitersRedeclared, describeVocabulary, detectFraming, encodeComponent, fieldScalar, fieldsUnseparated, frameBadChecksum, frameOversize, frameSequenceGap, frameUnterminated, getAstmProfile, getDefaultAstmProfile, hasCollidingRoles, interpretAbnormalFlag, interpretResultStatus, isNonStandard, isSafetyCriticalCode, listAstmProfiles, livdAmbiguousMapping, livdCatalogMissingLoincVersion, livdUnmappedCode, lookupLivdForRecord, ltpAmbiguousTransport, ltpFrameRejected, ltpInitialState, ltpReduce, ltpUnexpectedEvent, messages, nonStandardDelimiters, orders, orphanComment, parseAstmDate, parseAstmRecords, parseChecksumHex, parseFramedAstm, parseReferenceRange, partialTimestamp, patient, primaryCode, profileQuirkApplied, query, readDelimiterDeclaration, readDelimiters, recognizeUniversalTestId, resolveProfileTransport, results, serializeAstmRecord, serializeAstmRecords, serializeField, serializeFramedAstm, setDefaultAstmProfile, splitEscapeAware, toChecksumHex, toDate, toISO, toObject, tokenizeHeader, tokenizeRecord, undefinedAbnormalFlag, undefinedResultStatus, uninterpretedQueryStatus, unitsAbsent, unknownEscapeSequence, unknownRecordType, unpairedEscapeCharacter, unparseableReferenceRange, unreadableRedeclaration };
|
|
7176
|
+
export type { AbnormalFlag, AbnormalFlagCode, AbnormalFlagMeaning, AmbiguousAlignmentSink, AmbiguousCode, AnyAstmWarningCode, AstmDate, AstmDatePrecision, AstmField, AstmFrame, AstmFrameEncodeErrorCode, AstmFramePosition, AstmFrameWarning, AstmFraming, AstmLivdCatalogWarning, AstmLivdWarning, AstmLtpWarning, AstmMessage, AstmMessageClassification, AstmMessageKind, AstmParseOptions, AstmPosition, AstmProfile, AstmProfileProvenance, AstmQuirkMatch, AstmQuirkTolerance, AstmRecord, AstmRecordInput, AstmRecordWarning, AstmSerializeErrorCode, AstmStreamMessage, CommentInput, CommentRecord, ComposeFramesOptions, DateParts, DecodeAstmFramesResult, DefineAstmProfileOptions, DelimiterDeclarationFault, DelimiterReadResult, Delimiters, DetectFramingOptions, DetectFramingResult, FatalCode, FrameChecksum, FrameOptions, FrameTerminator, FrameWarningCode, FramedAstmResult, HeaderInput, HeaderRecord, LivdAmbiguityReason, LivdAnnotation, LivdCandidate, LivdCatalog, LivdCatalogIdentity, LivdEntry, LivdLookup, LivdMapping, LivdPublication, LivdResult, LivdUnitComparison, LivdWarningCode, LtpAction, LtpEvent, LtpPhase, LtpState, LtpTransition, LtpWarningCode, ManufacturerRecord, MessageInput, NamedVocabulary, OrderInput, OrderRecord, PatientInput, PatientName, PatientNameInput, PatientRecord, QueryInput, QueryRecord, ReferenceRange, ReferenceRangeKind, ResultInput, ResultRecord, ResultStatus, ResultStatusCode, ResultStatusMeaning, ScientificRecord, ShiftedComponentsSink, ShiftedFieldsSink, SwallowedDelimiterSink, TerminatorRecord, ToDateOptions, TruncatedFieldSink, UnattributedVocabulary, UniversalTestId, UniversalTestIdProvenance, UnknownEscapeSink, UnpairedEscapeSink, UnsupportedRecord, VerbatimInput, VocabularyAttribution, WarningCode };
|
package/dist/index.mjs
CHANGED
|
@@ -618,9 +618,12 @@ var WARNING_CODES = {
|
|
|
618
618
|
*/
|
|
619
619
|
ASTM_RECORD_UNINTERPRETED_QUERY_STATUS: "ASTM_RECORD_UNINTERPRETED_QUERY_STATUS",
|
|
620
620
|
/**
|
|
621
|
-
*
|
|
622
|
-
*
|
|
621
|
+
* The stream carried **both** a `Q` (request) and an `R` (result) record: a contradictory shape. The
|
|
622
|
+
* stream is classified `host-query` (the `Q` **dominates**, so it is never read as a result set) and
|
|
623
623
|
* this warning flags the anomaly. Positional context only; no field value.
|
|
624
|
+
*
|
|
625
|
+
* Classification is folded over the whole stream, so a `Q` in one message and an `R` in another
|
|
626
|
+
* raise it too. `classifyMessage(m.records)` over `messages()` says which message carried which.
|
|
624
627
|
*/
|
|
625
628
|
ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND: "ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND",
|
|
626
629
|
/**
|
|
@@ -808,7 +811,7 @@ function uninterpretedQueryStatus(position) {
|
|
|
808
811
|
function ambiguousMessageKind(position) {
|
|
809
812
|
return {
|
|
810
813
|
code: WARNING_CODES.ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND,
|
|
811
|
-
message: "
|
|
814
|
+
message: "Stream carried both a Q (request) and an R (result) record, classified host-query; Q dominates.",
|
|
812
815
|
position
|
|
813
816
|
};
|
|
814
817
|
}
|
|
@@ -3142,7 +3145,7 @@ function concatBytes3(chunks) {
|
|
|
3142
3145
|
}
|
|
3143
3146
|
|
|
3144
3147
|
// src/index.ts
|
|
3145
|
-
var VERSION = "0.1.
|
|
3148
|
+
var VERSION = "0.1.5";
|
|
3146
3149
|
|
|
3147
3150
|
export { ABNORMAL_FLAG_CODES, ABNORMAL_FLAG_VOCABULARY, 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_CATALOG_IDENTITY_UNDECLARED, LIVD_WARNING_CODES, LTP_WARNING_CODES, RESULT_STATUS_VOCABULARY, SAFETY_CRITICAL_CODES, TOLERABLE_CODES, VERSION, WARNING_CODES, alignmentShiftedComponents, alignmentShiftedFields, alignmentTruncatedField, ambiguousEscapeAlignment, ambiguousMessageKind, ambiguousValueSplit, applyAstmProfile, applyAstmProfileToWarnings, applyLivd, astmDateToLocalISO, astmProfiles, attachComments, buildAstmMessage, classifyMessage, comments, commentsFor, composeAstmFrames, computeChecksum, decodeAstmFrames, decodeEscapes, deepFreeze, defineAstmProfile, defineLivdCatalog, delimiterRoleCollision, delimiterSwallowedByEscape, delimitersRedeclared, describeVocabulary, detectFraming, encodeComponent, fieldScalar, fieldsUnseparated, frameBadChecksum, frameOversize, frameSequenceGap, frameUnterminated, getAstmProfile, getDefaultAstmProfile, hasCollidingRoles, interpretAbnormalFlag, interpretResultStatus, isNonStandard, isSafetyCriticalCode, listAstmProfiles, livdAmbiguousMapping, livdCatalogMissingLoincVersion, livdUnmappedCode, lookupLivdForRecord, ltpAmbiguousTransport, ltpFrameRejected, ltpInitialState, ltpReduce, ltpUnexpectedEvent, messages, nonStandardDelimiters, orders, orphanComment, parseAstmDate, parseAstmRecords, parseChecksumHex, parseFramedAstm, parseReferenceRange, partialTimestamp, patient, primaryCode, profileQuirkApplied, query, readDelimiterDeclaration, readDelimiters, recognizeUniversalTestId, resolveProfileTransport, results, serializeAstmRecord, serializeAstmRecords, serializeField, serializeFramedAstm, setDefaultAstmProfile, splitEscapeAware, toChecksumHex, toDate, toISO, toObject, tokenizeHeader, tokenizeRecord, undefinedAbnormalFlag, undefinedResultStatus, uninterpretedQueryStatus, unitsAbsent, unknownEscapeSequence, unknownRecordType, unpairedEscapeCharacter, unparseableReferenceRange, unreadableRedeclaration };
|
|
3148
3151
|
//# sourceMappingURL=index.mjs.map
|