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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@synanetics/syn-utils

v6.0.1

Published

synanetics util functionality

Readme

@synanetics/syn-utils

A collection of common utility functions used across multiple Synanetics repositories

Usage

const {
  getPrefix, removePrefix
} = require('@synanetics/syn-utils');
// or
import {
  getPrefix, removePrefix
} from '@synanetics/syn-utils';

API

Paging

Function: pageBuilder

The pageBuilder function takes in an array of sorted sourceBundles and pageConfig, and returns a bundle page with those with the combined resources from all the bundles.

Arguments

function pageBuilder(sourceBundles: SourceBundle[], config: PageConfig) => PageOutput

interface SourceBundle {
  sourceId: string;
  bundle: Bundle; 
}

interface SortConfig {
  fhirSorter: FhirSorter;
  sortTerms: string[];
  allowChainedSort?: boolean;
}

interface FhirIncluderConfig {
  searchParameters: URLSearchParams;
  includer: FhirIncluder | {
    model: Model;
    searchParameters: (InvariantSearchParameter | CompiledInvariantSearchParameter)[];
  };
}

interface PageConfig {
  pagingBaseUrl: URL;
  pageSize?: number;
  sortConfig?: SortConfig;
  currentPageNum?: number;
  partialPage?: Bundle;
  includeConfig?: FhirIncluderConfig;
}

interface PageOutput {
  completePage: boolean;
  page: Bundle;
  sourceBundles: SourceBundle[];
  bundleToReplace?: string;
}
  • sourceBundles
    • The Bundles to combine into a single page
    • All Bundles must have a 'Total'
    • At least one Bundle must have entries
  • config
    • The config defines how the page is to be built
    • pagingBaseUrl
      • The url to which the paging links can be appended
      • e.g https://fhir.store.nhs.uk/patient?_queryId=uuid ->
        • {relation: 'self', url: 'https://fhir.store.nhs.uk/patient?_queryId=uuid&_page=4'}
        • {relation: 'first', url: 'https://fhir.store.nhs.uk/patient?_queryId=uuid&_page=1'}
        • {relation: 'last', url: 'https://fhir.store.nhs.uk/patient?_queryId=uuid&_page=9'}
        • {relation: 'previous', url: 'https://fhir.store.nhs.uk/patient?_queryId=uuid&_page=3'}
        • {relation: 'next', url: 'https://fhir.store.nhs.uk/patient?_queryId=uuid&_page=5'}
    • pageSize
      • The desired maximum page size
      • Must be a positive integer
      • Will default to 100 if not provided
    • sortConfig?
      • This is an optional parameter, if it is not provided the pageBuilder will iterate over each source to build the page
      • fhirSorter
        • An instance of the FhirSorter from the @synanetics/fhir-sort package
      • sortTerms
        • An array of strings that will be used to sort the resources in the Bundles
        • e.g ['family', '_lastUpdated']
      • allowChainedSort
        • A boolean to allow/disallow chained sorting
        • For details on chained sorting see the @synanetics/fhir-sort package README
        • This parameter is optional and will default to false if not provided
    • currentPageNum?
      • The number of the page being built
      • e.g If you are calling the pageBuilder to build the 3rd page in a set of 5, this value should be 3
      • This value will default to 1 if not provided
    • partialPage?
      • This is an optional parameter
      • This parameter should only be provided when the pageBuilder previously returned an incomplete page
      • This happens when the pageBuilder has emptied an input bundle and requires a replacement
      • When you recall pageBuilder with the new bundle, you will pass in the incomplete page in partialPage returned by the first call
    • includeConfig?
      • This is an optional parameter that configures how included resources are handled
      • If not provided, no included resources will be present in the final Bundle
      • searchParameters
        • The URLSearchParams that were used to create the original Bundle includes
        • e.g. for a search with _include=Patient:organization, these search parameters would contain that include parameter
      • includer
        • Configuration for calculating the necessary includes for a given page
        • Can be either:
          • An instance of FhirIncluder from the @synanetics/syn-utils package, or
          • An object containing:
            • model: A fhirpath Model instance
            • searchParameters: An array of InvariantSearchParameter or CompiledInvariantSearchParameter objects
        • These will be used to determine which included resources are referenced by the matches on the page

Return Values

  • completePage
    • This is a boolean
    • This is true when:
      • The pageBuilder was able to build a page of the desired maximum size
      • The page builder has emptied all the bundles and built the final page
    • This is false when:
      • The page builder emptied one of the input bundles before completing the page and has determined it needs a replacement
  • page
    • This is a FHIR Bundle
    • Its total will be the combined total of all bundles
    • It will have paging links
    • Its entries will be populated from the input bundles
      • Outcomes come first
        • Any outcomes from all input bundles will appear first on the page
        • These can be in any order
      • Matches come second
        • A sorted, if sortTerms are provided, subset of the matches from all the input bundles will come after the outcomes
        • This will most often not contain all the matches from all the inputs, as the page size will likely be smaller than the number of matches provided
      • Includes come third
        • Any includes referenced in the matches will come after the matches
        • Each include will be referenced at least once by at least one match
        • Each include will only appear once
  • sourceBundles
    • The sourceBundles outputted by the page builder are similar to the ones inputted
    • The key difference is the output bundles will not contain any matches or outcomes already put into a page
    • e.g If we have input bundles with 5 matches each for 5 sources, and a page size of 10, the output bundles may contain 3 matches each for 5 sources.
    • Bundles that are emptied of matches will be returned by the pageBuilder, they are passed back to the pageBuilder as part of sourceBundles in future calls to keep accurate totals for subsequent pages.
  • bundleToReplace?
    • If the pageBuilder empties a paginated Bundle that is not on its last page, it needs to request a new bundle
    • When this occurs it populates this optional string with the source id of the bundle to be replaced

Usage

This is an example flow where the first call returns a complete page, and the second call requires a replacement bundle.

First Call:

  1. FHIR query received requiring pagination
  2. Gather the sorted Bundles from each source
  3. Call the pageBuilder with the source Bundles, and desired config for page 1
  4. pageBuilder returns completed page, and partially consumed input bundles
  5. Cache the page, and partially consumed input bundles
  6. Return the page

Second Call (with emptied Bundle):

  1. Second page requested
  2. Retrieve partially consumed input bundles from cache
  3. Call the pageBuilder with the partially consumed Bundles, and desired config for page 2
  4. pageBuilder responds with an incomplete page, partially consumed Bundles, and requests a replacement Bundle from "source1"
  5. Retrieve the next Bundle from "source1"
  6. Call the pageBuilder with the partially consumed Bundles, the fresh Bundle from "source1", desired config for page 2 and the incomplete page previously returned
  7. pageBuilder returns completed page, and partially consumed input bundles
  8. Cache the page, and partially consumed input bundles
  9. Return the page

Includes

Class: FhirIncluder

The FhirIncluder class is used to calculate which included resources should be present in a paginated Bundle based on the matches in that page. It evaluates FHIR search parameters to determine which included resources are referenced by the match resources.

Constructor

class FhirIncluder {
  constructor(
    model: Model,
    searchParameters: (InvariantSearchParameter | CompiledInvariantSearchParameter)[]
  )
}

interface InvariantSearchParameter {
  id?: string;
  expression?: string;
  code: string;
  base?: string[];
  target?: string[];
}

interface CompiledInvariantSearchParameter extends InvariantSearchParameter {
  compiledExpression: Compile<{ async: false }>;
}
  • model
    • A fhirpath Model instance for evaluating FHIRPath expressions
    • This is used to evaluate search parameter expressions against FHIR resources
  • searchParameters
    • An array of search parameter definitions
    • Each search parameter should include:
      • code: The search parameter code (e.g., 'organization', 'patient')
      • expression: The FHIRPath expression for extracting references (e.g., 'Patient.managingOrganization')
      • base: An array of resource types this parameter applies to (e.g., ['Patient'])
      • target: An array of resource types this parameter can reference (e.g., ['Organization'])
      • id: Optional unique identifier for the search parameter
      • compiledExpression: Optional precompiled fhirpath expression for the search parameter

Method: include

include(request: IncludeRequest): IncludeResult

interface IncludeRequest {
  query: URLSearchParams;
  matches: InvariantBundleEntry[];
  includes: InvariantBundleEntry[];
}

interface IncludeResult {
  included: InvariantBundleEntry[];
}

interface InvariantBundleEntry {
  resource?: { resourceType: string; id?: string };
}
  • request
    • The request object containing:
      • query: URLSearchParams containing _include, _revinclude, _include:iterate, and _revinclude:iterate parameters
      • matches: Array of bundle entries with search.mode='match' from the page
      • includes: Array of all available bundle entries with search.mode='include' to choose from
  • returns
    • An object containing the included array of bundle entries that should be included in the page
    • The result will only contain unique entries (duplicates are removed)
    • Supports:
      • _include=(* | [resource]:* | [resource]:[parameter] | [resource]:[parameter]:[target]): Include resources referenced by match resources
      • _revinclude=(* | [resource]:* | [resource]:[parameter] | [resource]:[parameter]:[target]): Include resources that reference the match resources
      • _include:iterate or _include:recurse = (* | [resource]:* | [resource]:[parameter] | [resource]:[parameter]:[target]): Include resources referenced by the first level of includes
      • _revinclude:iterate or _revinclude:recurse = (* | [resource]:* | [resource]:[parameter] | [resource]:[parameter]:[target]): Include resources that reference the first level of includes

Usage

import { FhirIncluder } from '@synanetics/syn-utils';
import { compile } from 'fhirpath';
// model to use when compiling fhirpath expressions
import model from 'fhirpath/fhir-context/r4/index.js'

// Define search parameters
const searchParameters = [
  {
    code: 'organization',
    expression: 'Patient.managingOrganization',
    base: ['Patient'],
    target: ['Organization'],
  },
  {
    code: 'patient',
    expression: 'Observation.subject',
    base: ['Observation'],
    target: ['Patient'],
  }
];

// Create the includer
const includer = new FhirIncluder(model, searchParameters);

// Use it to calculate includes for a page
const result = includer.include({
  query: new URLSearchParams('_include=Patient:organization'),
  matches: [
    { resource: { resourceType: 'Patient', id: '123', managingOrganization: { reference: 'Organization/abc' } } }
  ],
  includes: [
    { resource: { resourceType: 'Organization', id: 'abc' } },
    { resource: { resourceType: 'Organization', id: 'xyz' } }
  ]
});

// result.included will contain only the Organization/abc entry
// since it's the only one referenced by the matches

The FhirIncluder is written such that once it has compiled a particular search parameter (determined by the id property) it will not need to compile it again if the FhirIncluder is reused.

The FhirIncluder can currently resolve Literal references in both absolute and relative forms, including references to specific versions of resources. It cannot resolve Logical or Canonical references at present.

Where absolute references are used the FhirIncluder will find the target resource by the fullUrl of the Bundle entries, which must match the reference (excluding any _history component).

e.g. the absolute reference

{
    "reference": "https://some-url/Patient/123"
}

will be matched by the Bundle.entry

{
    "fullUrl": "https://some-url/Patient/123",
    "resource": {
        "resourceType": "Patient",
        "id": "123"
    } 
}

only when the fullUrl is present for the Bundle.entry

Similarly where a reference, either absolute or relative, refers to a specific version of a resource, the FhirIncluder will find the target resource by the meta.versionId present on the resource.

e.g. the absolute reference

{
    "reference": "https://some-url/Patient/123/_history/2"
}

will be matched by the Bundle.entry

{
    "fullUrl": "https://some-url/Patient/123",
    "resource": {
        "resourceType": "Patient",
        "id": "123",
        "meta": {
            "versionId": "2"
        }
    } 
}

only when the fullUrl is present for the Bundle.entry and matches the reference, (ignoring the _history section of the reference) and the resource.meta.versionId property is present and matches the _history component of the reference.

The FhirIncluder will make the best effort attempt to maintain only unique includes in the final output. Uniquness of entries is determined by the entry.fullUrl, entry.resource.resourceType, entry.resource.id and entry.resource.meta.versionId properties only. Any entries that do not have a fullUrl and/or a resourceType and id at a minimum cannot be determined to be unique or not and will not be included in the final output.

Prefix

Defaults

The prefix functions have default configuration values/functions which are as below.

const defaultPrefixDelimiter: string = '.';
const defaultEscapeRegex = (string: string): string => string.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
const defaultPrefixRegex: string = `^(?:.*/)?(?<prefix>.*?)${defaultEsc
apeRegex(defaultPrefixDelimiter)}.*`;

Function: getPrefix

The get prefix function takes in a string and returns a prefix that matches the provided arguments.

Arguments

function getPrefix(value: string, validPrefixes?: string[], prefixRegex: string = defaultPrefixRegex) => string
  • value
    • The string to retrieve the prefix from
    • If no value is provided an error will be thrown
  • validPrefixes
    • An array of valid prefix strings
    • If this is not provided, all prefixes are considered valid
  • dpPrefixRegex
    • Defaults to defaultDpPrefixRegex
    • This regex is used to find the prefix in value

Usage

//Expect value: wow
getPrefix('wow.theRest');

//Expect value: apple
getPrefix('apple.pie', ['apple', 'pear']);

// Expect error: No value provided 
getPrefix();

//Expect Error: No valid prefixes found
getPrefix('this has no prefix');

//Expect Error: No valid prefixes found
getPrefix('tomato.pie', ['apple', 'pear']);

Function: removePrefix

The get prefix function takes in a string and returns a prefix that matches the provided arguments.

Arguments

function removePrefix(value: string, prefix: string, prefixDelimiter: string = defaultPrefixDelimiter, escapeRegex: (string: string) => string = defaultEscapeRegex) => string 
  • value
    • The string to remove the prefix from
    • If no value is provided an error will be thrown
  • prefix
    • The prefix to remove
    • If no prefix is provided an error will be thrown
  • prefixDelimiter
    • Defaults to defaultPrefixDelimiter
    • This string is used to split prefix from value
  • escapeRegex
    • Defaults to defaultEscapeRegex
    • This regex is applied to the prefixDelimiter to escape protected characters

Usage

//Expect value: theRest
removePrefix('wow.theRest', 'wow');

//Expect value: apple.pie
removePrefix('apple.pie', 'pear');

// Expect error: No value provided 
removePrefix();

// Expect error: No prefix provided 
removePrefix('wow');

Function: removePrefixFromFhirObj

The removePrefixFromFhirObj function removes a prefix string from all ids and reference ids in a FHIR object

function removePrefixFromFhirObj<T extends (fhir3.FhirResource | fhir4.FhirResource)>(  
    input: T,
    prefix: string,
    prefixDelimiter?: string,
    maxDepth?: number,
  ) => T

Arguments

  • input is a FHIR stu3/r4 resource as defined in the @types/fhir package such as a Patient resource
  • prefix is a string such as 'HUB' that should be removed from all ids and reference ids
  • prefixDelimiter is a string that is used to delimit where a prefix ends and an id begins, this defaults to '.'
  • maxDepth is a number that represents the maximum recursion depth that is allowed before an error is thrown, this defaults to 15

Usage

//Input resource: 
const patient: Patient = {
    id: 'HUB.pat1',
    resourceType: 'Patient',
    generalPractitioner: [
    {
        reference: '#contained',
    },
    {
        reference: 'Organization/HUB.org1',
    },
    {
        reference: 'Organization/HUB.org1',
    },
    {
        reference: 'Practitioner/HUB.DDCR.pra1',
    },
    {
        reference: 'Practitioner/HUB.pra2/_history/4',
    },
    ],
    managingOrganization: {
    reference: 'url/fhir/Organization/HUB.DDCR.org2',
    },
};

const unprefixedPatient: Patient = removePrefixFromFhirObj(patient, 'HUB');

// expect unprefixedPatient to equal expectedPatient
const expectedPatient: Patient = {
    id: 'pat1',
    resourceType: 'Patient',
    generalPractitioner: [
    {
        reference: '#contained',
    },
    {
        reference: 'Organization/org1',
    },
    {
        reference: 'Organization/org1',
    },
    {
        reference: 'Practitioner/DDCR.pra1',
    },
    {
        reference: 'Practitioner/pra2/_history/4',
    },
    ],
    managingOrganization: {
    reference: 'url/fhir/Organization/DDCR.org2',
    },
};

Reference

Interface: ReferenceDetails

interface ReferenceDetails {
  original: string;
  contained: boolean;
  version: number;
  id?: string;
  type?: string;
  criteria?: string;
  url?: string;
  relative?: string;
}

Function: getReferenceDetails

The get getReferenceDetails function takes in a reference string and extracts the details into a ReferenceDetails object

Arguments

function getReferenceDetails(referenceString: string) => ReferenceDetails
  • referenceString
    • The string to extract the details from
    • If no referenceString is provided an error will be thrown

Usage

//Expect value: 
const expectedValue = {
    original: '#p1',
    contained: true,
    version: 1,
    id: 'p1'
}
getReferenceDetails('#p1');

//Expect value: 
const expectedValue = {
      original: 'ValueSet?url=http://hl7.org/fhir/ValueSet/my-valueset&version=0.8',
      contained: false,
      version: 1,
      type: 'ValueSet',
      criteria: 'url=http://hl7.org/fhir/ValueSet/my-valueset&version=0.8',
}
getReferenceDetails('ValueSet?url=http://hl7.org/fhir/ValueSet/my-valueset&version=0.8');

//Expect value: 
const expectedValue = {
      original: 'url/fhir/r4/Patient/12345',
      contained: false,
      version: 1,
      type: 'Patient',
      id: '12345',
      url: 'url/fhir/r4/Patient/12345',
      relative: 'Patient/12345',
}
getReferenceDetails('url/fhir/r4/Patient/12345');

//Expect value: 
const expectedValue = {
      original: 'Patient/12345/_history/5',
      contained: false,
      version: 5,
      type: 'Patient',
      id: '12345',
      relative: 'Patient/12345',
}
getReferenceDetails('Patient/12345/_history/5');

Function: getUniqueRelativeReferences

The get getUniqueRelativeReferences function takes in a fhir resource and extracts unique relative reference strings

function getUniqueRelativeReferences(
    input: Record<any, any>,  
    relativeRefs?: Set<string>,
    maxDepth?: string,
) => Set<string>

Arguments

  • input is a FHIR resource as defined in the @types/fhir package such as a Patient resource
  • relativeRefs is a set of unique relative reference strings, e.g Patient/12345, this defaults to an empty set
  • maxDepth is a number that represents the maximum recursion depth that is allowed before an error is thrown, this defaults to 15

Usage

//Input resource: 
const patient: Patient = {
    resourceType: 'Patient',
    generalPractitioner: [
    {
        reference: '#notRelative',
    },
    {
        reference: 'Organization/1',
    },
    {
        reference: 'Organization/1',
    },
    {
        reference: 'Practitioner/1',
    },
    {
        reference: 'Practitioner/2/_history/4',
    },
    ],
    managingOrganization: {
    reference: 'url/fhir/Organization/2',
    },
};

//Expect set to contain 'Organization/1', 'Practitioner/1', 'Practitioner/2', 'Organization/2' 
getUniqueRelativeReferences(patient);

Rebase References

Function: rebaseReferences

A function to prefix any identifiers or relative references with the supplied string.

Usage:

const resource = {
    id: 'DEF.123',
    subject: {
        reference: 'Patient/DEF.456',
    },
};

const rebasedResource = rebaseReferences(resource, 'ABC');
expect(resource).toEqual({
    id: 'ABC.DEF.123',
    subject: {
        reference: 'Patient/ABC.DEF.456',
    },
})