@glion/parser 0.27.1 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,9 +33,10 @@ Register the parser as the reader for a `unified` processor. The parser reads fr
33
33
 
34
34
  ### Options
35
35
 
36
- | Option | Type | Description |
37
- | ------------ | --------------------- | ---------------------------------------------------------------------------------------- |
38
- | `delimiters` | `Partial<Delimiters>` | Override one or more delimiters. The parser merges with MSH-derived values and defaults. |
36
+ | Option | Type | Description |
37
+ | --------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | `decodeEscapes` | `boolean` | Whether a subcomponent value holds the characters its escape sequences stand for (`true`, the default) or the escape sequences as written. The encoding characters in MSH-2 are never decoded. |
39
+ | `delimiters` | `Partial<Delimiters>` | Override one or more delimiters. The parser merges with MSH-derived values and defaults. |
39
40
 
40
41
  The default delimiters are `|` (field), `^` (component), `~` (repetition), `&` (subcomponent), `\` (escape), and `\r` (segment).
41
42
 
@@ -60,6 +61,25 @@ const customTree = unified()
60
61
 
61
62
  Options accept a partial `Delimiters` object, so only the characters you want to override need to be provided.
62
63
 
64
+ ### Escape sequences
65
+
66
+ A value's escape sequences are decoded while the message is tokenized. `\F\`, `\S\`, `\R\`, `\T\`, and `\E\` become the field, component, repetition, subcomponent, and escape delimiters the message declares, `\.br\` becomes the segment delimiter, and `\Xdd\` becomes the characters its bytes, named by pairs of hexadecimal digits, encode in UTF-8. A formatting command such as `\H\`, `\N\`, or `\.sp 2\`, a locally defined sequence (`\Z…\`), a character set switch (`\Cxxyy\`, `\Mxxyyzz\`), and any other sequence stay as written.
67
+
68
+ ```ts
69
+ import { unified } from "unified";
70
+ import { hl7v2Parser } from "@glion/parser";
71
+
72
+ unified().use(hl7v2Parser).parse("PID|1||DOE\\T\\SMITH");
73
+ // PID-3 subcomponent value: "DOE&SMITH"
74
+
75
+ unified()
76
+ .use(hl7v2Parser, { decodeEscapes: false })
77
+ .parse("PID|1||DOE\\T\\SMITH");
78
+ // PID-3 subcomponent value: "DOE\\T\\SMITH"
79
+ ```
80
+
81
+ A node's `position` is the span of the source text, so a decoded value is shorter than its span.
82
+
63
83
  ### `Hl7v2Processor`
64
84
 
65
85
  The `unified` `Processor<Root, Root | undefined, Root | undefined>` type every HL7v2 pipeline satisfies — head and tail admit `undefined` so the bare `unified().use(hl7v2Parser).freeze()` is assignable. Use it to type a processor built with `unified().use(hl7v2Parser)` regardless of which transformer or compiler plugins are added. `@glion/mllp` re-exports it unchanged.
@@ -74,6 +94,7 @@ const processor: Hl7v2Processor = unified().use(hl7v2Parser).freeze();
74
94
 
75
95
  - **Pull-based tokenizer.** Single pass, minimal object allocations — suitable for high-throughput ingestion.
76
96
  - **Delimiter auto-detection.** MSH-1 and MSH-2 are read before the rest of the message is tokenized so custom delimiter sets are honored without configuration.
97
+ - **Escape sequences decoded in the same pass.** A text run that holds the escape character is decoded as it is tokenized; a run without one is taken as it is.
77
98
  - **`unist`-compatible output.** Nodes follow the `@glion/ast` spec and integrate with `unist-util-visit`, `unist-builder`, and the wider Glion plugin ecosystem.
78
99
  - **Streaming-friendly.** The pull-based design is ready for streaming ingestion even though the current public API takes a complete string.
79
100
 
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { DEFAULT_DELIMITERS, isEmptyNode } from "@glion/utils";
1
+ import { DEFAULT_DELIMITERS, decodeEscapes, isEmptyNode } from "@glion/utils";
2
2
  //#region src/preprocessor.ts
3
3
  /**
4
4
  * Step: strip UTF-8 BOM.
@@ -365,6 +365,7 @@ const MSH_FIELD_SEPERATOR_END = 4;
365
365
  const MSH_FIELD_DELIMITER_START = 4;
366
366
  const MSH_FIELD_DELIMITER_END = 8;
367
367
  var HL7v2Tokenizer = class {
368
+ decodeEscapes;
368
369
  input = "";
369
370
  i = 0;
370
371
  line = 1;
@@ -372,6 +373,9 @@ var HL7v2Tokenizer = class {
372
373
  delims;
373
374
  didMshBootstrap = false;
374
375
  pendingBootstrap = null;
376
+ constructor(options = {}) {
377
+ this.decodeEscapes = options.decodeEscapes ?? true;
378
+ }
375
379
  reset(ctx) {
376
380
  this.input = ctx.input;
377
381
  this.delims = ctx.delimiters;
@@ -464,14 +468,17 @@ var HL7v2Tokenizer = class {
464
468
  return this._tok("SUBCOMP_DELIM", void 0, start);
465
469
  }
466
470
  let j = this.i;
467
- const cmp = this.delims.component, fld = this.delims.field, rep = this.delims.repetition, seg = this.delims.segment, sub = this.delims.subcomponent;
471
+ const cmp = this.delims.component, esc = this.delims.escape, fld = this.delims.field, rep = this.delims.repetition, seg = this.delims.segment, sub = this.delims.subcomponent;
472
+ let escaped = false;
468
473
  while (j < s.length) {
469
474
  const c = s.charAt(j);
470
475
  if (c === seg || c === fld || c === rep || c === cmp || c === sub) break;
476
+ if (c === esc) escaped = true;
471
477
  j += 1;
472
478
  }
473
- const val = s.slice(this.i, j);
474
- this._fastAdvance(val);
479
+ const raw = s.slice(this.i, j);
480
+ this._fastAdvance(raw);
481
+ const val = escaped && this.decodeEscapes ? decodeEscapes(raw, this.delims) : raw;
475
482
  return this._tok("TEXT", val, start);
476
483
  }
477
484
  _slice(start, end) {
@@ -534,7 +541,7 @@ function parseHL7v2(input, opts = {}, settings) {
534
541
  input
535
542
  };
536
543
  ctx = runPreprocessors(ctx, opts.preprocess || defaultPreprocessors);
537
- const tokenizer = new HL7v2Tokenizer();
544
+ const tokenizer = new HL7v2Tokenizer({ decodeEscapes: opts.decodeEscapes });
538
545
  tokenizer.reset(ctx);
539
546
  return parseHL7v2FromIterator(iterateTokenizerSync(tokenizer));
540
547
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/preprocessor.ts","../src/processor.ts","../src/tokenizer.ts","../src/parser.ts"],"sourcesContent":["import { DEFAULT_DELIMITERS } from \"@glion/utils\";\n\nimport type { ParserContext, PreprocessorStep } from \"./types\";\n\n// PreprocessorStep is declared in `types.ts` to avoid circular imports\n\n/**\n * Step: strip UTF-8 BOM.\n */\nexport const stripBOM: PreprocessorStep = (ctx) => {\n if (ctx.input.codePointAt(0) === 0xfe_ff) {\n ctx.input = ctx.input.slice(1);\n }\n return ctx;\n};\n\n/**\n * Step: normalize newlines to the default delimiters.\n */\nexport const normalizeNewlines: PreprocessorStep = (ctx) => {\n ctx.input = ctx.input.replaceAll(/\\r?\\n/g, ctx.delimiters.segment);\n return ctx;\n};\n\n/**\n * Step: auto-detect delimiters from MSH.\n */\nexport const detectDelimiters: PreprocessorStep = (ctx) => {\n if (ctx.input.startsWith(\"MSH\")) {\n const field = ctx.input.charAt(3) || DEFAULT_DELIMITERS.field;\n const enc = ctx.input.slice(4, 8);\n const component = enc.charAt(0) || DEFAULT_DELIMITERS.component;\n const repetition = enc.charAt(1) || DEFAULT_DELIMITERS.repetition;\n const _escape = enc.charAt(2) || DEFAULT_DELIMITERS.escape;\n const subcomponent = enc.charAt(3) || DEFAULT_DELIMITERS.subcomponent;\n const { segment } = DEFAULT_DELIMITERS;\n\n ctx.delimiters = {\n component,\n escape: _escape,\n field,\n repetition,\n segment,\n subcomponent,\n };\n }\n return ctx;\n};\n\n/**\n * Default preprocessing pipeline.\n */\nexport const defaultPreprocessors: PreprocessorStep[] = [\n stripBOM,\n normalizeNewlines,\n detectDelimiters,\n];\n\n/**\n * Run the pipeline to initialize ParserContext.\n */\nexport function runPreprocessors(\n ctx: ParserContext,\n steps: PreprocessorStep[]\n): ParserContext {\n for (const step of steps) {\n // oxlint-disable-next-line no-param-reassign\n ctx = step(ctx);\n }\n\n return ctx;\n}\n","import type {\n Component,\n Field,\n FieldRepetition,\n Root,\n Segment,\n Subcomponent,\n} from \"@glion/ast\";\nimport { isEmptyNode } from \"@glion/utils\";\nimport type { Position } from \"unist\";\n\nimport type { Token } from \"./types\";\n\n/**\n * Check if a field has structural content beyond a single empty value.\n * A field with multiple repetitions, multiple components, or multiple\n * subcomponents has structural content even if all values are empty.\n * This is used to prevent dropping trailing fields like |^| or |&|\n * that have meaningful delimiter structure.\n */\nfunction hasStructuralContent(field: Field): boolean {\n if (field.children.length > 1) {\n return true;\n }\n const rep = field.children[0];\n if (rep && rep.children.length > 1) {\n return true;\n }\n const comp = rep?.children[0];\n return comp !== undefined && comp.children.length > 1;\n}\n\nfunction createSubcomponent(start: Position[\"start\"]): Subcomponent {\n return {\n position: { end: start, start },\n type: \"subcomponent\",\n value: \"\",\n };\n}\n\nfunction createComponent(start: Position[\"start\"]): Component {\n return {\n children: [],\n position: { end: start, start },\n type: \"component\",\n };\n}\n\nfunction createFieldRepetition(start: Position[\"start\"]): FieldRepetition {\n return {\n children: [],\n position: { end: start, start },\n type: \"field-repetition\",\n };\n}\n\nfunction createField(start: Position[\"start\"]): Field {\n return {\n children: [],\n position: { end: start, start },\n type: \"field\",\n };\n}\n\n// Shared core: process a single token into mutable parse state\nfunction createParserCore() {\n const root: Root = {\n children: [],\n type: \"root\",\n };\n\n let seg: Segment | null = null;\n let field: Field | null = null;\n let rep: FieldRepetition | null = null;\n let comp: Component | null = null;\n let currentSub: Subcomponent | null = null;\n let segmentHasContent = false;\n let lastContentEnd: Position[\"end\"] | null = null;\n let documentEnd: Position[\"end\"] | null = null; // Track document-level end position\n let expectingSegmentName = true; // Start expecting a segment name\n let justSetSegmentName = false; // Track if we just set the segment name\n let rootStartSet = false; // Track if we've set the root start position\n\n const resetState = () => {\n seg = null;\n field = null;\n rep = null;\n comp = null;\n currentSub = null;\n segmentHasContent = false;\n lastContentEnd = null;\n expectingSegmentName = true;\n };\n\n const openSegment = (name: string, position: Position) => {\n seg = {\n children: [],\n name,\n position: { end: position.end, start: position.start },\n type: \"segment\",\n };\n root.children.push(seg);\n field = null;\n rep = null;\n comp = null;\n currentSub = null;\n segmentHasContent = false;\n justSetSegmentName = true;\n expectingSegmentName = false;\n };\n\n /**\n * Ensure there is an active segment. If delimiter tokens arrive before\n * any segment name, lazily open a segment with an empty name.\n */\n const ensureSegment = (start: Position[\"start\"]) => {\n if (!seg) {\n openSegment(\"\", { end: start, start });\n // Reset justSetSegmentName so the first FIELD_DELIM isn't skipped\n // (there's no real segment name to separate from fields)\n justSetSegmentName = false;\n }\n };\n\n const openField = (start: Position[\"start\"]) => {\n ensureSegment(start);\n field = createField(start);\n seg!.children.push(field);\n rep = null;\n comp = null;\n currentSub = null;\n segmentHasContent = true;\n };\n\n const openRepetition = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n // Add an empty first repetition before the delimiter\n const emptyRep = createFieldRepetition(start);\n field!.children.push(emptyRep);\n }\n // If field has no children yet, add empty first rep\n if (field!.children.length === 0) {\n const emptyRep = createFieldRepetition(start);\n field!.children.push(emptyRep);\n }\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n comp = null;\n currentSub = null;\n segmentHasContent = true;\n };\n\n // Ensure there's a component to add subcomponents to (for SUBCOMP_DELIM)\n // Does NOT add empty sibling components.\n const ensureComponent = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n }\n if (!rep) {\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n }\n if (!comp) {\n comp = createComponent(start);\n rep.children.push(comp);\n }\n segmentHasContent = true;\n };\n\n const openComponent = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n // Build out a rep + empty first component before the delimiter\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n const emptyComp = createComponent(start);\n rep.children.push(emptyComp);\n }\n if (!rep) {\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n const emptyComp = createComponent(start);\n rep.children.push(emptyComp);\n } else if (rep.children.length === 0) {\n const emptyComp = createComponent(start);\n rep.children.push(emptyComp);\n }\n comp = createComponent(start);\n rep.children.push(comp);\n currentSub = null;\n segmentHasContent = true;\n };\n\n const ensureForText = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n }\n if (!rep) {\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n }\n if (!comp) {\n comp = createComponent(start);\n rep.children.push(comp);\n }\n if (!currentSub) {\n currentSub = createSubcomponent(start);\n comp.children.push(currentSub);\n segmentHasContent = true;\n }\n };\n\n const updatePositionsToEnd = (endPos: Position[\"end\"]) => {\n if (currentSub?.position) {\n currentSub.position.end = endPos;\n }\n if (comp?.position) {\n comp.position.end = endPos;\n }\n if (rep?.position) {\n rep.position.end = endPos;\n }\n if (field?.position) {\n field.position.end = endPos;\n }\n if (seg?.position) {\n seg.position.end = endPos;\n }\n };\n\n const processToken = (tok: Token) => {\n switch (tok.type) {\n case \"SEGMENT_END\": {\n const endPos = lastContentEnd || tok.position.start;\n updatePositionsToEnd(endPos);\n dropTrailingEmptyFieldIfPresent();\n resetState();\n return;\n }\n case \"FIELD_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n // Skip the first field delimiter after setting segment name\n if (justSetSegmentName) {\n justSetSegmentName = false;\n return;\n }\n // Leading field delimiter implies an empty first field\n if (!field) {\n openField(tok.position.start);\n }\n openField(tok.position.end);\n return;\n }\n case \"REPETITION_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n if (!field) {\n openField(tok.position.start);\n }\n openRepetition(tok.position.end);\n return;\n }\n case \"COMPONENT_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n openComponent(tok.position.end);\n return;\n }\n case \"SUBCOMP_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n ensureComponent(tok.position.start);\n // If comp has no children yet, add empty first subcomponent\n if (comp!.children.length === 0) {\n const emptySub = createSubcomponent(tok.position.start);\n comp!.children.push(emptySub);\n }\n currentSub = createSubcomponent(tok.position.end);\n comp?.children.push(currentSub);\n segmentHasContent = true;\n return;\n }\n case \"TEXT\": {\n const val = tok.value ?? \"\";\n\n // Set root start position on first token\n if (!rootStartSet) {\n root.position = {\n end: tok.position.start,\n start: tok.position.start,\n };\n rootStartSet = true;\n }\n\n // If we're expecting a segment name, this TEXT is the segment name\n if (expectingSegmentName) {\n openSegment(val, tok.position);\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n return;\n }\n\n // Otherwise, it's regular field content\n ensureForText(tok.position.start);\n if (currentSub) {\n currentSub.value += val;\n }\n updatePositionsToEnd(tok.position.end);\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n segmentHasContent = true;\n return;\n }\n default: {\n throw new Error(`Unexpected token type: ${tok.type}`);\n }\n }\n };\n\n // Do not pre-open a segment; lazily open upon first non-SEGMENT_END token.\n\n const finalize = () => {\n if (lastContentEnd && seg) {\n updatePositionsToEnd(lastContentEnd);\n }\n dropTrailingEmptyFieldIfPresent();\n if (seg && !segmentHasContent && !seg.name) {\n // Drop trailing empty segment only when it was lazily opened by\n // `ensureSegment` (no name, no content). A segment that arrived\n // with a name carries information — even if no fields followed —\n // and dropping it would break round-trip idempotency: the\n // serializer re-emits the name, the next parse would drop it\n // again, and any sibling segment immediately preceding it would\n // shift into the trailing position and get dropped on the\n // following parse.\n root.children.pop();\n }\n\n // Set root end position once at finalization using document-level end\n if (root.position && documentEnd) {\n root.position.end = documentEnd;\n } else if (!root.position) {\n root.position = {\n end: { column: 1, line: 1, offset: 0 },\n start: { column: 1, line: 1, offset: 0 },\n };\n }\n\n return root;\n };\n\n /**\n * Drop only the phantom trailing empty field created by a terminal field\n * delimiter (e.g. the last `|` in `PID|foo|`). Without this, every segment\n * ending with `|` would gain an extra empty field on each parse cycle.\n */\n function dropTrailingEmptyFieldIfPresent() {\n if (!seg || seg.children.length === 0) {\n return;\n }\n const lastChild = seg.children.at(-1);\n if (lastChild?.type !== \"field\") {\n return;\n }\n const lastField = lastChild as Field;\n // A field like `|^|` is isEmpty (no leaf data) but has structural content\n // (component separators) and must be preserved.\n if (isEmptyNode(lastField) && !hasStructuralContent(lastField)) {\n seg.children.pop();\n }\n }\n\n return { finalize, processToken, root };\n}\n\nexport function parseHL7v2FromIterator(tokens: Iterable<Token>): Root {\n const core = createParserCore();\n for (const tok of tokens) {\n core.processToken(tok);\n }\n return core.finalize();\n}\n","// src/tokenizer.ts\nimport type { Delimiters } from \"@glion/ast\";\nimport type { Position } from \"unist\";\n\nimport type { ParserContext, Token, Tokenizer, TokenType } from \"./types\";\n\nconst MSH_SEGMENT_START = 0;\nconst MSH_SEGMENT_END = 3;\nconst MSH_FIELD_SEPERATOR_START = 3;\nconst MSH_FIELD_SEPERATOR_END = 4;\nconst MSH_FIELD_DELIMITER_START = 4;\nconst MSH_FIELD_DELIMITER_END = 8;\n\nexport class HL7v2Tokenizer implements Tokenizer, Iterable<Token> {\n private input = \"\";\n private i = 0;\n private line = 1;\n private col = 1;\n private delims!: Delimiters;\n\n // Only-run-once MSH bootstrap at the start of the file\n private didMshBootstrap = false;\n private pendingBootstrap: null | Array<\n | { kind: \"TEXT\"; value: string; advance: number }\n | { kind: \"FIELD_DELIM\"; advance: number }\n > = null; // queue to emit TEXT('MSH'), FIELD_DELIM, TEXT('^~\\\\&')\n\n reset(ctx: ParserContext) {\n this.input = ctx.input;\n this.delims = ctx.delimiters;\n this.i = 0;\n this.line = 1;\n this.col = 1;\n this.didMshBootstrap = false;\n this.pendingBootstrap = null;\n\n // Prepare a one-time bootstrap if file starts with MSH\n if (this.input.startsWith(\"MSH\")) {\n // Precompute MSH and MSH.2; MSH.1 is the field delimiter char at index 3\n const msh = this._slice(MSH_SEGMENT_START, MSH_SEGMENT_END);\n const msh1 = this._slice(\n MSH_FIELD_SEPERATOR_START,\n MSH_FIELD_SEPERATOR_END\n ); // the field delimiter char at index 3\n const msh2 = this._slice(\n MSH_FIELD_DELIMITER_START,\n MSH_FIELD_DELIMITER_END\n ); // may be shorter than 4 if truncated\n this.pendingBootstrap = [\n { advance: msh.length, kind: \"TEXT\", value: msh },\n { advance: 0, kind: \"FIELD_DELIM\" },\n { advance: msh1.length, kind: \"TEXT\", value: msh1 },\n { advance: 0, kind: \"FIELD_DELIM\" },\n { advance: msh2.length, kind: \"TEXT\", value: msh2 },\n ];\n // NOTE: we have not advanced indices yet; we will as we emit tokens\n }\n }\n\n // oxlint-disable-next-line complexity/complexity -- tokenizer hot path: one branch per delimiter class, kept flat for speed\n next(): Token | null {\n const s = this.input;\n const n = s.length;\n if (this.i >= n && !this.pendingBootstrap?.length) {\n return null;\n }\n\n const start = { column: this.col, line: this.line, offset: this.i };\n\n // ---- One-time MSH bootstrap at file start ----\n if (!this.didMshBootstrap && this.pendingBootstrap) {\n const step = this.pendingBootstrap.shift();\n if (step) {\n if (step.kind === \"TEXT\") {\n const take = Math.min(step.advance, n - this.i);\n const out = step.value.slice(0, take);\n this._fastAdvance(out);\n if (this.pendingBootstrap.length === 0) {\n this.pendingBootstrap = null;\n this.didMshBootstrap = true;\n }\n return this._tok(\"TEXT\", out, start);\n }\n // FIELD_DELIM: advance exactly one char (the delimiter) and emit a FIELD_DELIM token\n this._advance(Math.min(step.advance, n - this.i));\n if (this.pendingBootstrap.length === 0) {\n this.pendingBootstrap = null;\n this.didMshBootstrap = true;\n }\n return this._tok(\"FIELD_DELIM\", undefined, start);\n }\n }\n\n // ---- Normal tokenization (delimiters + text) ----\n if (this.i >= n) {\n return null;\n }\n const ch = s.charAt(this.i);\n\n if (ch === this.delims.segment) {\n this._advance(1, true);\n return this._tok(\"SEGMENT_END\", undefined, start);\n }\n if (ch === this.delims.field) {\n this._advance(1);\n return this._tok(\"FIELD_DELIM\", undefined, start);\n }\n if (ch === this.delims.repetition) {\n this._advance(1);\n return this._tok(\"REPETITION_DELIM\", undefined, start);\n }\n if (ch === this.delims.component) {\n this._advance(1);\n return this._tok(\"COMPONENT_DELIM\", undefined, start);\n }\n if (ch === this.delims.subcomponent) {\n this._advance(1);\n return this._tok(\"SUBCOMP_DELIM\", undefined, start);\n }\n\n // TEXT until next delimiter or end\n let j = this.i;\n const cmp = this.delims.component,\n fld = this.delims.field,\n rep = this.delims.repetition,\n seg = this.delims.segment,\n sub = this.delims.subcomponent;\n\n while (j < s.length) {\n const c = s.charAt(j);\n if (c === seg || c === fld || c === rep || c === cmp || c === sub) {\n break;\n }\n j += 1;\n }\n\n const val = s.slice(this.i, j);\n this._fastAdvance(val);\n return this._tok(\"TEXT\", val, start);\n }\n\n // ---- helpers ----\n private _slice(start: number, end: number): string {\n return this.input.slice(start, Math.min(end, this.input.length));\n }\n\n private _advance(n: number, isNewline = false) {\n this.i += n;\n if (isNewline) {\n this.line += 1;\n this.col = 1;\n } else {\n this.col += n;\n }\n }\n\n private _fastAdvance(chunk: string) {\n const parts = chunk.split(this.delims.segment);\n if (parts.length > 1) {\n this.line += parts.length - 1;\n this.col = (parts.at(-1)?.length ?? 0) + 1;\n } else {\n this.col += chunk.length;\n }\n this.i += chunk.length;\n }\n\n private _tok(\n type: TokenType,\n value: string | undefined,\n start: Position[\"start\"]\n ): Token {\n const end = { column: this.col, line: this.line, offset: this.i };\n return { position: { end, start }, type, value };\n }\n\n // Iterable protocol (sync)\n [Symbol.iterator](): Iterator<Token> {\n return {\n next: () => {\n const t = this.next();\n if (!t) {\n return { done: true, value: undefined as unknown as Token };\n }\n return { done: false, value: t };\n },\n };\n }\n}\n","import type { Root } from \"@glion/ast\";\nimport type { HL7v2Settings } from \"@glion/config\";\nimport { DEFAULT_DELIMITERS } from \"@glion/utils\";\nimport type { Plugin, Processor } from \"unified\";\n\nimport { defaultPreprocessors, runPreprocessors } from \"./preprocessor\";\nimport { parseHL7v2FromIterator } from \"./processor\";\nimport { HL7v2Tokenizer } from \"./tokenizer\";\nimport type { ParseOptions, ParserContext, Token, Tokenizer } from \"./types\";\n\nfunction* iterateTokenizerSync(t: Tokenizer): Iterable<Token> {\n for (let tok = t.next(); tok; tok = t.next()) {\n yield tok;\n }\n}\n\nexport function parseHL7v2(\n input: string,\n opts: ParseOptions = {},\n settings?: HL7v2Settings\n): Root {\n // Merge settings: defaults < provided settings\n // Note: MSH auto-detection (via detectDelimiters preprocessor) runs after this\n // and will override delimiters if the message starts with MSH\n\n let ctx: ParserContext = {\n delimiters: {\n ...DEFAULT_DELIMITERS,\n ...(settings?.delimiters ?? {}),\n },\n input,\n };\n // Run preprocessing\n ctx = runPreprocessors(ctx, opts.preprocess || defaultPreprocessors);\n // Run tokenizer\n const tokenizer = new HL7v2Tokenizer();\n // Reset tokenizer.\n tokenizer.reset(ctx);\n // Parse\n return parseHL7v2FromIterator(iterateTokenizerSync(tokenizer));\n}\n\nconst hl7v2Parser: Plugin<[ParseOptions?], string, Root> = function hl7v2Parser(\n this: Processor,\n options = {}\n) {\n this.parser = (document: string) => {\n // Get settings from processor (populated by unified-args from config)\n const settings = this.data(\"settings\");\n\n return parseHL7v2(document, options, settings);\n };\n};\n\nexport default hl7v2Parser;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/preprocessor.ts","../src/processor.ts","../src/tokenizer.ts","../src/parser.ts"],"sourcesContent":["import { DEFAULT_DELIMITERS } from \"@glion/utils\";\n\nimport type { ParserContext, PreprocessorStep } from \"./types\";\n\n// PreprocessorStep is declared in `types.ts` to avoid circular imports\n\n/**\n * Step: strip UTF-8 BOM.\n */\nexport const stripBOM: PreprocessorStep = (ctx) => {\n if (ctx.input.codePointAt(0) === 0xfe_ff) {\n ctx.input = ctx.input.slice(1);\n }\n return ctx;\n};\n\n/**\n * Step: normalize newlines to the default delimiters.\n */\nexport const normalizeNewlines: PreprocessorStep = (ctx) => {\n ctx.input = ctx.input.replaceAll(/\\r?\\n/g, ctx.delimiters.segment);\n return ctx;\n};\n\n/**\n * Step: auto-detect delimiters from MSH.\n */\nexport const detectDelimiters: PreprocessorStep = (ctx) => {\n if (ctx.input.startsWith(\"MSH\")) {\n const field = ctx.input.charAt(3) || DEFAULT_DELIMITERS.field;\n const enc = ctx.input.slice(4, 8);\n const component = enc.charAt(0) || DEFAULT_DELIMITERS.component;\n const repetition = enc.charAt(1) || DEFAULT_DELIMITERS.repetition;\n const _escape = enc.charAt(2) || DEFAULT_DELIMITERS.escape;\n const subcomponent = enc.charAt(3) || DEFAULT_DELIMITERS.subcomponent;\n const { segment } = DEFAULT_DELIMITERS;\n\n ctx.delimiters = {\n component,\n escape: _escape,\n field,\n repetition,\n segment,\n subcomponent,\n };\n }\n return ctx;\n};\n\n/**\n * Default preprocessing pipeline.\n */\nexport const defaultPreprocessors: PreprocessorStep[] = [\n stripBOM,\n normalizeNewlines,\n detectDelimiters,\n];\n\n/**\n * Run the pipeline to initialize ParserContext.\n */\nexport function runPreprocessors(\n ctx: ParserContext,\n steps: PreprocessorStep[]\n): ParserContext {\n for (const step of steps) {\n // oxlint-disable-next-line no-param-reassign\n ctx = step(ctx);\n }\n\n return ctx;\n}\n","import type {\n Component,\n Field,\n FieldRepetition,\n Root,\n Segment,\n Subcomponent,\n} from \"@glion/ast\";\nimport { isEmptyNode } from \"@glion/utils\";\nimport type { Position } from \"unist\";\n\nimport type { Token } from \"./types\";\n\n/**\n * Check if a field has structural content beyond a single empty value.\n * A field with multiple repetitions, multiple components, or multiple\n * subcomponents has structural content even if all values are empty.\n * This is used to prevent dropping trailing fields like |^| or |&|\n * that have meaningful delimiter structure.\n */\nfunction hasStructuralContent(field: Field): boolean {\n if (field.children.length > 1) {\n return true;\n }\n const rep = field.children[0];\n if (rep && rep.children.length > 1) {\n return true;\n }\n const comp = rep?.children[0];\n return comp !== undefined && comp.children.length > 1;\n}\n\nfunction createSubcomponent(start: Position[\"start\"]): Subcomponent {\n return {\n position: { end: start, start },\n type: \"subcomponent\",\n value: \"\",\n };\n}\n\nfunction createComponent(start: Position[\"start\"]): Component {\n return {\n children: [],\n position: { end: start, start },\n type: \"component\",\n };\n}\n\nfunction createFieldRepetition(start: Position[\"start\"]): FieldRepetition {\n return {\n children: [],\n position: { end: start, start },\n type: \"field-repetition\",\n };\n}\n\nfunction createField(start: Position[\"start\"]): Field {\n return {\n children: [],\n position: { end: start, start },\n type: \"field\",\n };\n}\n\n// Shared core: process a single token into mutable parse state\nfunction createParserCore() {\n const root: Root = {\n children: [],\n type: \"root\",\n };\n\n let seg: Segment | null = null;\n let field: Field | null = null;\n let rep: FieldRepetition | null = null;\n let comp: Component | null = null;\n let currentSub: Subcomponent | null = null;\n let segmentHasContent = false;\n let lastContentEnd: Position[\"end\"] | null = null;\n let documentEnd: Position[\"end\"] | null = null; // Track document-level end position\n let expectingSegmentName = true; // Start expecting a segment name\n let justSetSegmentName = false; // Track if we just set the segment name\n let rootStartSet = false; // Track if we've set the root start position\n\n const resetState = () => {\n seg = null;\n field = null;\n rep = null;\n comp = null;\n currentSub = null;\n segmentHasContent = false;\n lastContentEnd = null;\n expectingSegmentName = true;\n };\n\n const openSegment = (name: string, position: Position) => {\n seg = {\n children: [],\n name,\n position: { end: position.end, start: position.start },\n type: \"segment\",\n };\n root.children.push(seg);\n field = null;\n rep = null;\n comp = null;\n currentSub = null;\n segmentHasContent = false;\n justSetSegmentName = true;\n expectingSegmentName = false;\n };\n\n /**\n * Ensure there is an active segment. If delimiter tokens arrive before\n * any segment name, lazily open a segment with an empty name.\n */\n const ensureSegment = (start: Position[\"start\"]) => {\n if (!seg) {\n openSegment(\"\", { end: start, start });\n // Reset justSetSegmentName so the first FIELD_DELIM isn't skipped\n // (there's no real segment name to separate from fields)\n justSetSegmentName = false;\n }\n };\n\n const openField = (start: Position[\"start\"]) => {\n ensureSegment(start);\n field = createField(start);\n seg!.children.push(field);\n rep = null;\n comp = null;\n currentSub = null;\n segmentHasContent = true;\n };\n\n const openRepetition = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n // Add an empty first repetition before the delimiter\n const emptyRep = createFieldRepetition(start);\n field!.children.push(emptyRep);\n }\n // If field has no children yet, add empty first rep\n if (field!.children.length === 0) {\n const emptyRep = createFieldRepetition(start);\n field!.children.push(emptyRep);\n }\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n comp = null;\n currentSub = null;\n segmentHasContent = true;\n };\n\n // Ensure there's a component to add subcomponents to (for SUBCOMP_DELIM)\n // Does NOT add empty sibling components.\n const ensureComponent = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n }\n if (!rep) {\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n }\n if (!comp) {\n comp = createComponent(start);\n rep.children.push(comp);\n }\n segmentHasContent = true;\n };\n\n const openComponent = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n // Build out a rep + empty first component before the delimiter\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n const emptyComp = createComponent(start);\n rep.children.push(emptyComp);\n }\n if (!rep) {\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n const emptyComp = createComponent(start);\n rep.children.push(emptyComp);\n } else if (rep.children.length === 0) {\n const emptyComp = createComponent(start);\n rep.children.push(emptyComp);\n }\n comp = createComponent(start);\n rep.children.push(comp);\n currentSub = null;\n segmentHasContent = true;\n };\n\n const ensureForText = (start: Position[\"start\"]) => {\n if (!field) {\n openField(start);\n }\n if (!rep) {\n rep = createFieldRepetition(start);\n field!.children.push(rep);\n }\n if (!comp) {\n comp = createComponent(start);\n rep.children.push(comp);\n }\n if (!currentSub) {\n currentSub = createSubcomponent(start);\n comp.children.push(currentSub);\n segmentHasContent = true;\n }\n };\n\n const updatePositionsToEnd = (endPos: Position[\"end\"]) => {\n if (currentSub?.position) {\n currentSub.position.end = endPos;\n }\n if (comp?.position) {\n comp.position.end = endPos;\n }\n if (rep?.position) {\n rep.position.end = endPos;\n }\n if (field?.position) {\n field.position.end = endPos;\n }\n if (seg?.position) {\n seg.position.end = endPos;\n }\n };\n\n const processToken = (tok: Token) => {\n switch (tok.type) {\n case \"SEGMENT_END\": {\n const endPos = lastContentEnd || tok.position.start;\n updatePositionsToEnd(endPos);\n dropTrailingEmptyFieldIfPresent();\n resetState();\n return;\n }\n case \"FIELD_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n // Skip the first field delimiter after setting segment name\n if (justSetSegmentName) {\n justSetSegmentName = false;\n return;\n }\n // Leading field delimiter implies an empty first field\n if (!field) {\n openField(tok.position.start);\n }\n openField(tok.position.end);\n return;\n }\n case \"REPETITION_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n if (!field) {\n openField(tok.position.start);\n }\n openRepetition(tok.position.end);\n return;\n }\n case \"COMPONENT_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n openComponent(tok.position.end);\n return;\n }\n case \"SUBCOMP_DELIM\": {\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n ensureComponent(tok.position.start);\n // If comp has no children yet, add empty first subcomponent\n if (comp!.children.length === 0) {\n const emptySub = createSubcomponent(tok.position.start);\n comp!.children.push(emptySub);\n }\n currentSub = createSubcomponent(tok.position.end);\n comp?.children.push(currentSub);\n segmentHasContent = true;\n return;\n }\n case \"TEXT\": {\n const val = tok.value ?? \"\";\n\n // Set root start position on first token\n if (!rootStartSet) {\n root.position = {\n end: tok.position.start,\n start: tok.position.start,\n };\n rootStartSet = true;\n }\n\n // If we're expecting a segment name, this TEXT is the segment name\n if (expectingSegmentName) {\n openSegment(val, tok.position);\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n return;\n }\n\n // Otherwise, it's regular field content\n ensureForText(tok.position.start);\n if (currentSub) {\n currentSub.value += val;\n }\n updatePositionsToEnd(tok.position.end);\n lastContentEnd = tok.position.end;\n documentEnd = tok.position.end;\n segmentHasContent = true;\n return;\n }\n default: {\n throw new Error(`Unexpected token type: ${tok.type}`);\n }\n }\n };\n\n // Do not pre-open a segment; lazily open upon first non-SEGMENT_END token.\n\n const finalize = () => {\n if (lastContentEnd && seg) {\n updatePositionsToEnd(lastContentEnd);\n }\n dropTrailingEmptyFieldIfPresent();\n if (seg && !segmentHasContent && !seg.name) {\n // Drop trailing empty segment only when it was lazily opened by\n // `ensureSegment` (no name, no content). A segment that arrived\n // with a name carries information — even if no fields followed —\n // and dropping it would break round-trip idempotency: the\n // serializer re-emits the name, the next parse would drop it\n // again, and any sibling segment immediately preceding it would\n // shift into the trailing position and get dropped on the\n // following parse.\n root.children.pop();\n }\n\n // Set root end position once at finalization using document-level end\n if (root.position && documentEnd) {\n root.position.end = documentEnd;\n } else if (!root.position) {\n root.position = {\n end: { column: 1, line: 1, offset: 0 },\n start: { column: 1, line: 1, offset: 0 },\n };\n }\n\n return root;\n };\n\n /**\n * Drop only the phantom trailing empty field created by a terminal field\n * delimiter (e.g. the last `|` in `PID|foo|`). Without this, every segment\n * ending with `|` would gain an extra empty field on each parse cycle.\n */\n function dropTrailingEmptyFieldIfPresent() {\n if (!seg || seg.children.length === 0) {\n return;\n }\n const lastChild = seg.children.at(-1);\n if (lastChild?.type !== \"field\") {\n return;\n }\n const lastField = lastChild as Field;\n // A field like `|^|` is isEmpty (no leaf data) but has structural content\n // (component separators) and must be preserved.\n if (isEmptyNode(lastField) && !hasStructuralContent(lastField)) {\n seg.children.pop();\n }\n }\n\n return { finalize, processToken, root };\n}\n\nexport function parseHL7v2FromIterator(tokens: Iterable<Token>): Root {\n const core = createParserCore();\n for (const tok of tokens) {\n core.processToken(tok);\n }\n return core.finalize();\n}\n","// src/tokenizer.ts\nimport type { Delimiters } from \"@glion/ast\";\nimport { decodeEscapes } from \"@glion/utils\";\nimport type { Position } from \"unist\";\n\nimport type { ParserContext, Token, Tokenizer, TokenType } from \"./types\";\n\nconst MSH_SEGMENT_START = 0;\nconst MSH_SEGMENT_END = 3;\nconst MSH_FIELD_SEPERATOR_START = 3;\nconst MSH_FIELD_SEPERATOR_END = 4;\nconst MSH_FIELD_DELIMITER_START = 4;\nconst MSH_FIELD_DELIMITER_END = 8;\n\nexport interface TokenizerOptions {\n /**\n * Whether a TEXT token holds the characters its escape sequences stand for\n * (`true`, the default) or the escape sequences as they are on the wire\n * (`false`). The encoding characters MSH-2 declares are never decoded.\n */\n decodeEscapes?: boolean;\n}\n\nexport class HL7v2Tokenizer implements Tokenizer, Iterable<Token> {\n private readonly decodeEscapes: boolean;\n private input = \"\";\n private i = 0;\n private line = 1;\n private col = 1;\n private delims!: Delimiters;\n\n // Only-run-once MSH bootstrap at the start of the file\n private didMshBootstrap = false;\n private pendingBootstrap: null | Array<\n | { kind: \"TEXT\"; value: string; advance: number }\n | { kind: \"FIELD_DELIM\"; advance: number }\n > = null; // queue to emit TEXT('MSH'), FIELD_DELIM, TEXT('^~\\\\&')\n\n constructor(options: TokenizerOptions = {}) {\n this.decodeEscapes = options.decodeEscapes ?? true;\n }\n\n reset(ctx: ParserContext) {\n this.input = ctx.input;\n this.delims = ctx.delimiters;\n this.i = 0;\n this.line = 1;\n this.col = 1;\n this.didMshBootstrap = false;\n this.pendingBootstrap = null;\n\n // Prepare a one-time bootstrap if file starts with MSH\n if (this.input.startsWith(\"MSH\")) {\n // Precompute MSH and MSH.2; MSH.1 is the field delimiter char at index 3\n const msh = this._slice(MSH_SEGMENT_START, MSH_SEGMENT_END);\n const msh1 = this._slice(\n MSH_FIELD_SEPERATOR_START,\n MSH_FIELD_SEPERATOR_END\n ); // the field delimiter char at index 3\n const msh2 = this._slice(\n MSH_FIELD_DELIMITER_START,\n MSH_FIELD_DELIMITER_END\n ); // may be shorter than 4 if truncated\n this.pendingBootstrap = [\n { advance: msh.length, kind: \"TEXT\", value: msh },\n { advance: 0, kind: \"FIELD_DELIM\" },\n { advance: msh1.length, kind: \"TEXT\", value: msh1 },\n { advance: 0, kind: \"FIELD_DELIM\" },\n { advance: msh2.length, kind: \"TEXT\", value: msh2 },\n ];\n // NOTE: we have not advanced indices yet; we will as we emit tokens\n }\n }\n\n // oxlint-disable-next-line complexity/complexity -- tokenizer hot path: one branch per delimiter class, kept flat for speed\n next(): Token | null {\n const s = this.input;\n const n = s.length;\n if (this.i >= n && !this.pendingBootstrap?.length) {\n return null;\n }\n\n const start = { column: this.col, line: this.line, offset: this.i };\n\n // ---- One-time MSH bootstrap at file start ----\n if (!this.didMshBootstrap && this.pendingBootstrap) {\n const step = this.pendingBootstrap.shift();\n if (step) {\n if (step.kind === \"TEXT\") {\n const take = Math.min(step.advance, n - this.i);\n const out = step.value.slice(0, take);\n this._fastAdvance(out);\n if (this.pendingBootstrap.length === 0) {\n this.pendingBootstrap = null;\n this.didMshBootstrap = true;\n }\n return this._tok(\"TEXT\", out, start);\n }\n // FIELD_DELIM: advance exactly one char (the delimiter) and emit a FIELD_DELIM token\n this._advance(Math.min(step.advance, n - this.i));\n if (this.pendingBootstrap.length === 0) {\n this.pendingBootstrap = null;\n this.didMshBootstrap = true;\n }\n return this._tok(\"FIELD_DELIM\", undefined, start);\n }\n }\n\n // ---- Normal tokenization (delimiters + text) ----\n if (this.i >= n) {\n return null;\n }\n const ch = s.charAt(this.i);\n\n if (ch === this.delims.segment) {\n this._advance(1, true);\n return this._tok(\"SEGMENT_END\", undefined, start);\n }\n if (ch === this.delims.field) {\n this._advance(1);\n return this._tok(\"FIELD_DELIM\", undefined, start);\n }\n if (ch === this.delims.repetition) {\n this._advance(1);\n return this._tok(\"REPETITION_DELIM\", undefined, start);\n }\n if (ch === this.delims.component) {\n this._advance(1);\n return this._tok(\"COMPONENT_DELIM\", undefined, start);\n }\n if (ch === this.delims.subcomponent) {\n this._advance(1);\n return this._tok(\"SUBCOMP_DELIM\", undefined, start);\n }\n\n // TEXT until next delimiter or end\n let j = this.i;\n const cmp = this.delims.component,\n esc = this.delims.escape,\n fld = this.delims.field,\n rep = this.delims.repetition,\n seg = this.delims.segment,\n sub = this.delims.subcomponent;\n let escaped = false;\n\n while (j < s.length) {\n const c = s.charAt(j);\n if (c === seg || c === fld || c === rep || c === cmp || c === sub) {\n break;\n }\n // Stryker disable next-line ConditionalExpression, EqualityOperator: the flag only skips decoding a run without the escape character, which decodes to itself\n if (c === esc) {\n escaped = true;\n }\n j += 1;\n }\n\n // Positions and line counts follow the source, so the raw slice advances.\n const raw = s.slice(this.i, j);\n this._fastAdvance(raw);\n const val =\n escaped && this.decodeEscapes ? decodeEscapes(raw, this.delims) : raw;\n return this._tok(\"TEXT\", val, start);\n }\n\n // ---- helpers ----\n private _slice(start: number, end: number): string {\n return this.input.slice(start, Math.min(end, this.input.length));\n }\n\n private _advance(n: number, isNewline = false) {\n this.i += n;\n if (isNewline) {\n this.line += 1;\n this.col = 1;\n } else {\n this.col += n;\n }\n }\n\n private _fastAdvance(chunk: string) {\n const parts = chunk.split(this.delims.segment);\n if (parts.length > 1) {\n this.line += parts.length - 1;\n this.col = (parts.at(-1)?.length ?? 0) + 1;\n } else {\n this.col += chunk.length;\n }\n this.i += chunk.length;\n }\n\n private _tok(\n type: TokenType,\n value: string | undefined,\n start: Position[\"start\"]\n ): Token {\n const end = { column: this.col, line: this.line, offset: this.i };\n return { position: { end, start }, type, value };\n }\n\n // Iterable protocol (sync)\n [Symbol.iterator](): Iterator<Token> {\n return {\n next: () => {\n const t = this.next();\n if (!t) {\n return { done: true, value: undefined as unknown as Token };\n }\n return { done: false, value: t };\n },\n };\n }\n}\n","import type { Root } from \"@glion/ast\";\nimport type { HL7v2Settings } from \"@glion/config\";\nimport { DEFAULT_DELIMITERS } from \"@glion/utils\";\nimport type { Plugin, Processor } from \"unified\";\n\nimport { defaultPreprocessors, runPreprocessors } from \"./preprocessor\";\nimport { parseHL7v2FromIterator } from \"./processor\";\nimport { HL7v2Tokenizer } from \"./tokenizer\";\nimport type { ParseOptions, ParserContext, Token, Tokenizer } from \"./types\";\n\nfunction* iterateTokenizerSync(t: Tokenizer): Iterable<Token> {\n for (let tok = t.next(); tok; tok = t.next()) {\n yield tok;\n }\n}\n\nexport function parseHL7v2(\n input: string,\n opts: ParseOptions = {},\n settings?: HL7v2Settings\n): Root {\n // Merge settings: defaults < provided settings\n // Note: MSH auto-detection (via detectDelimiters preprocessor) runs after this\n // and will override delimiters if the message starts with MSH\n\n let ctx: ParserContext = {\n delimiters: {\n ...DEFAULT_DELIMITERS,\n ...(settings?.delimiters ?? {}),\n },\n input,\n };\n // Run preprocessing\n ctx = runPreprocessors(ctx, opts.preprocess || defaultPreprocessors);\n // Run tokenizer\n const tokenizer = new HL7v2Tokenizer({ decodeEscapes: opts.decodeEscapes });\n // Reset tokenizer.\n tokenizer.reset(ctx);\n // Parse\n return parseHL7v2FromIterator(iterateTokenizerSync(tokenizer));\n}\n\nconst hl7v2Parser: Plugin<[ParseOptions?], string, Root> = function hl7v2Parser(\n this: Processor,\n options = {}\n) {\n this.parser = (document: string) => {\n // Get settings from processor (populated by unified-args from config)\n const settings = this.data(\"settings\");\n\n return parseHL7v2(document, options, settings);\n };\n};\n\nexport default hl7v2Parser;\n"],"mappings":"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"}
@@ -1,5 +1,14 @@
1
1
  import type { ParserContext, Token, Tokenizer } from "./types";
2
+ export interface TokenizerOptions {
3
+ /**
4
+ * Whether a TEXT token holds the characters its escape sequences stand for
5
+ * (`true`, the default) or the escape sequences as they are on the wire
6
+ * (`false`). The encoding characters MSH-2 declares are never decoded.
7
+ */
8
+ decodeEscapes?: boolean;
9
+ }
2
10
  export declare class HL7v2Tokenizer implements Tokenizer, Iterable<Token> {
11
+ private readonly decodeEscapes;
3
12
  private input;
4
13
  private i;
5
14
  private line;
@@ -7,6 +16,7 @@ export declare class HL7v2Tokenizer implements Tokenizer, Iterable<Token> {
7
16
  private delims;
8
17
  private didMshBootstrap;
9
18
  private pendingBootstrap;
19
+ constructor(options?: TokenizerOptions);
10
20
  reset(ctx: ParserContext): void;
11
21
  next(): Token | null;
12
22
  private _slice;
@@ -1 +1 @@
1
- {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAa,MAAM,SAAS,CAAC;AAS1E,qBAAa,cAAe,YAAW,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC/D,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,CAAC,CAAK;IACd,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,MAAM,CAAc;IAG5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAGf;IAET,KAAK,CAAC,GAAG,EAAE,aAAa;IAiCxB,IAAI,IAAI,KAAK,GAAG,IAAI;IAkFpB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,IAAI;IAUZ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC;CAWrC"}
1
+ {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAa,MAAM,SAAS,CAAC;AAS1E,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,qBAAa,cAAe,YAAW,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC/D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,CAAC,CAAK;IACd,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,MAAM,CAAc;IAG5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAGf;gBAEG,OAAO,GAAE,gBAAqB;IAI1C,KAAK,CAAC,GAAG,EAAE,aAAa;IAiCxB,IAAI,IAAI,KAAK,GAAG,IAAI;IA2FpB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,IAAI;IAUZ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC;CAWrC"}
package/dist/types.d.ts CHANGED
@@ -12,6 +12,12 @@ import type { Position } from "unist";
12
12
  export type Hl7v2Processor = Processor<Root, Root | undefined, Root | undefined>;
13
13
  export type PreprocessorStep = (ctx: ParserContext) => ParserContext;
14
14
  export interface ParseOptions {
15
+ /**
16
+ * Whether a subcomponent value holds the characters its escape sequences
17
+ * stand for (`true`, the default) or the escape sequences as they are on
18
+ * the wire (`false`).
19
+ */
20
+ decodeEscapes?: boolean;
15
21
  /**
16
22
  * Optional preprocessing steps to apply to the input before parsing.
17
23
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,CACpC,IAAI,EACJ,IAAI,GAAG,SAAS,EAChB,IAAI,GAAG,SAAS,CACjB,CAAC;AAIF,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,aAAa,CAAC;AAErE,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAGD,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAGD,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,aAAa,GACb,kBAAkB,GAClB,iBAAiB,GACjB,eAAe,GACf,MAAM,CAAC;AAEX,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,CACpC,IAAI,EACJ,IAAI,GAAG,SAAS,EAChB,IAAI,GAAG,SAAS,CACjB,CAAC;AAIF,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,aAAa,CAAC;AAErE,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAGD,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAGD,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,aAAa,GACb,kBAAkB,GAClB,iBAAiB,GACjB,eAAe,GACf,MAAM,CAAC;AAEX,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC;CACtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glion/parser",
3
- "version": "0.27.1",
3
+ "version": "0.28.0",
4
4
  "description": "hl7v2 plugin to parse hl7v2 messages",
5
5
  "keywords": [
6
6
  "health",
@@ -35,9 +35,9 @@
35
35
  "dependencies": {
36
36
  "@types/unist": "3.0.3",
37
37
  "unified": "11.0.5",
38
- "@glion/ast": "0.27.1",
39
- "@glion/config": "0.27.1",
40
- "@glion/utils": "0.27.1"
38
+ "@glion/ast": "0.28.0",
39
+ "@glion/config": "0.28.0",
40
+ "@glion/utils": "0.28.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@stryker-mutator/core": "10.0.0",