npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@rethinkhealth/hl7v2-utils

v0.4.2

Published

hl7v2 utilities

Downloads

477

Readme

@rethinkhealth/hl7v2-utils

A utility package for working with HL7v2 messages, most commonly used within the @rethinkhealth/hl7v2 ecosystem — a unist-inspired collection of plugins and utilities designed to parse, transform, validate, and manipulate HL7v2 messages.

This package provides core utilities including:

  • Diagnostic reporting system for linters, validators, and transformers
  • Standard HL7v2 delimiters
  • AST node utility functions
  • Conformance validation utilities (cardinality, length, optionality)

Installation

npm install @rethinkhealth/hl7v2-utils

API

report(file, rule, options?)

Report a diagnostic to a VFile. This function is the standard way to report issues in the HL7v2 ecosystem.

Parameters

  • file (VFile | null | undefined) - The VFile to report to
  • rule (Diagnostic) - The diagnostic rule definition
  • options (ReportOptions, optional)
    • node (Node, optional) - The AST node related to the diagnostic
    • context (Record<string, unknown>, optional) - Context data passed to the diagnostic's message function

Example

import { report } from '@rethinkhealth/hl7v2-utils';
import type { Diagnostic } from '@rethinkhealth/hl7v2-utils';
import { VFile } from 'vfile';

// Define a diagnostic rule
const requiredFieldRule: Diagnostic = {
  type: 'lint',
  namespace: 'field',
  code: 'required',
  title: 'Required Field Missing',
  description: 'A required field is missing from the segment.',
  severity: 'error',
  message: (ctx) => `Field '${ctx.fieldPath}' is required`,
  helpUrl: 'https://example.com/docs/required-field'
};

// Report the diagnostic
const file = new VFile();
report(file, requiredFieldRule, {
  context: { fieldPath: 'PID-5' },
  node: segmentNode
});

getByteLength(node)

Calculate the byte length of any HL7v2 AST node. This utility efficiently computes the total serialized length including all children and separators (assumed to be 1 byte each).

Parameters

  • node (Nodes | null | undefined) - The AST node to measure

Returns

number - The total byte length when the node is serialized

Algorithm

  • For literal nodes (Subcomponent, SegmentHeader): returns the byte length of the value using UTF-8 encoding (i.e., Buffer.byteLength(value, 'utf8'))
  • For parent nodes: recursively sums the byte length of all children plus 1 byte per separator between children
  • Handles all node types: Root, Segment, Group, Field, FieldRepetition, Component, Subcomponent

Performance

The function is optimized for performance with O(n) time complexity where n is the total number of nodes in the tree. It uses a simple recursive approach with minimal overhead.

Example

import { getByteLength } from '@rethinkhealth/hl7v2-utils';
import type { Field } from '@rethinkhealth/hl7v2-ast';

const field: Field = {
  type: 'field',
  children: [
    {
      type: 'field-repetition',
      children: [
        {
          type: 'component',
          children: [
            { type: 'subcomponent', value: 'SMITH' },
            { type: 'subcomponent', value: 'JOHN' }
          ]
        }
      ]
    }
  ]
};

// Calculate: SMITH&JOHN = 5 + 1 + 4 = 10 bytes
const length = getByteLength(field); // Returns: 10

Use Cases

  • Validating field or message size constraints
  • Memory allocation planning
  • Message size reporting and analytics
  • Performance optimization by avoiding full serialization

getLength(node)

Calculate the string length of any HL7v2 AST node. This utility efficiently computes the total serialized character length including all children and separators (assumed to be 1 character each).

Parameters

  • node (Nodes | null | undefined) - The AST node to measure

Returns

number - The total string length when the node is serialized

Algorithm

  • For literal nodes (Subcomponent, SegmentHeader): returns value.length (JavaScript string length)
  • For parent nodes: recursively sums the string length of all children plus 1 character per separator between children
  • Handles all node types: Root, Segment, Group, Field, FieldRepetition, Component, Subcomponent

Important Note

Returns JavaScript string length (UTF-16 code units). For UTF-8 byte length (e.g., for wire protocol or size constraints), use getByteLength instead. These values differ for characters outside the ASCII range.

Performance

The function is optimized for performance with O(n) time complexity where n is the total number of nodes in the tree. It uses a simple recursive approach with minimal overhead.

Example

import { getLength } from '@rethinkhealth/hl7v2-utils';
import type { Field } from '@rethinkhealth/hl7v2-ast';

const field: Field = {
  type: 'field',
  children: [
    {
      type: 'field-repetition',
      children: [
        {
          type: 'component',
          children: [
            { type: 'subcomponent', value: 'SMITH' },
            { type: 'subcomponent', value: 'JOHN' }
          ]
        }
      ]
    }
  ]
};

// Calculate: SMITH&JOHN = 5 + 1 + 4 = 10 characters
const length = getLength(field); // Returns: 10

Use Cases

  • UI display and text formatting
  • Character-based validation rules
  • String manipulation operations
  • Quick length checks where byte-level precision is not required

Comparison with getByteLength

import { getLength, getByteLength } from '@rethinkhealth/hl7v2-utils';

const subcomponent = { type: 'subcomponent', value: 'café' };

getLength(subcomponent);     // Returns: 4 (4 characters)
getByteLength(subcomponent); // Returns: 5 (5 bytes in UTF-8: c-a-f-C3-A9)

Conformance Utilities

The package provides stateless, composable functions to validate HL7v2 AST nodes against constraints like optionality (usage), cardinality, and length.

ValidationResult

All conformance functions return a ValidationResult object:

type ValidationResult = 
  | { ok: true }
  | { 
      ok: false; 
      error: { 
        code: string; 
        message: string;
        expected?: string | number | Array<string | number>;
        actual?: string | number | Array<string | number>;
      } 
    };

checkOptionality(node, optionality)

Checks if a node satisfies the optionality (usage) constraint.

  • node: Nodes | undefined - The AST node to check.
  • optionality: string - The usage code (e.g., 'R', 'O', 'X').
  • Returns: ValidationResult
import { checkOptionality } from '@rethinkhealth/hl7v2-utils';

// 'R' (Required), 'RE' (Required or Empty), 'O' (Optional), 'X' (Not Supported)
const result = checkOptionality(myFieldNode, 'R');

if (!result.ok) {
  console.error(result.error.message); // "is required but missing"
}

checkCardinality(node, min, max)

Checks if a field has the correct number of repetitions.

  • node: Field | undefined - The field node to check.
  • min: number - Minimum repetitions.
  • max: number | '*' - Maximum repetitions.
  • Returns: ValidationResult
import { checkCardinality } from '@rethinkhealth/hl7v2-utils';

// Field must repeat between 1 and 5 times
const result = checkCardinality(myFieldNode, 1, 5);

checkLength(node, max, min?)

Checks if the content of a node falls within the minimum and maximum length.

  • node: Nodes | undefined - The node to check (length is calculated recursively).
  • max: number - Maximum length.
  • min: number (optional, default: 0) - Minimum length.
  • Returns: ValidationResult
import { checkLength } from '@rethinkhealth/hl7v2-utils';

// Content length must be between 1 and 10 characters
const result = checkLength(myNode, 10, 1);

// Content length must be at most 10 characters (min defaults to 0)
const result2 = checkLength(myNode, 10);

Contributing

We welcome contributions! Please see our Contributing Guide for more details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Code of Conduct

To ensure a welcoming and positive environment, we have a Code of Conduct that all contributors and participants are expected to adhere to.

License

Copyright 2025 Rethink Health, SUARL. All rights reserved.

This program is licensed to you under the terms of the MIT License. This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file for details.