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

isa-sdk

v1.0.8

Published

Unified TypeScript SDK for the ISA platform APIs (zyins, rapidsign, proxy).

Readme

isa-sdk

Unified TypeScript SDK for the Best Plan Pro API — powered by the ZyINS engine.

Install

npm install isa-sdk

Hello world

import { Isa } from 'isa-sdk';

const isa = Isa.withBearer();                   // reads ISA_TOKEN
const { data } = await isa.zyins.prequalify(req);  // v3 by default
console.log(data.plans[0].carrier.name);

Three bootstrap factories cover all auth contexts:

| Factory | Audience | Env defaults | |---|---|---| | Isa.withBearer() | Server-to-server | ISA_TOKEN | | Isa.withLicense({ deviceId, orderId }) | BPP agent tools | ISA_LICENSE_KEYCODE, ISA_LICENSE_EMAIL | | Isa.withSession() | Embedded forms | ISA_SESSION_ID, ISA_SESSION_SECRET |

First call in <15 lines

import {
  Isa,
  Sex,
  State,
  Height,
  Weight,
  NicotineDuration,
  Coverage,
  ProductSelection,
  Products,
} from 'isa-sdk';

const isa = await Isa.withKeycode({
  keycode: 'ABC-123-XYZ',
  email:   '[email protected]',
});

// The bare `isa.zyins.prequalify` facade routes to v3 by default and
// resolves to an envelope; destructure `data` to read the flat plans[].
const { data } = await isa.zyins.prequalify({
  applicant: {
    dob:         '1962-04-18',
    sex:         Sex.Male,
    state:       State.NorthCarolina,
    height:      Height.fromFeetInches(5, 10),
    weight:      Weight.fromPounds(195),
    nicotineUse: { lastUsed: NicotineDuration.Never },
  },
  coverage: Coverage.faceValue(25_000),
  products: ProductSelection.of([Products.Term.FidelityLifeInstabrainTerm]),
});

for (const offer of data.plans) {
  const headline = offer.pricing.find(row => row.primary);
  console.log(`${offer.carrier.name} ${offer.product.name}: ${headline?.premium?.amount.display}`);
}

Per-surface API versions

The ISA API is a federation of independently versioned surfaces. There is no single "current" version; the SDK exposes no global shorthand. Every release ships a frozen BundledApiVersions table recording which /vN each surface targets:

import { BundledApiVersions } from 'isa-sdk';

console.log(BundledApiVersions);
// {
//   prequalify: 'v3',
//   quote:      'v3',
//   datasets:   'v3',
//   reference:  'v3',
//   sessions:   'v1',
//   branding:   'v1',
//   cases:      'v1',
// }

To pin a single surface without disturbing the rest, pass a per-surface apiVersion override map. There is no default key and no string shorthand — resolution is apiVersion[surface] ?? BundledApiVersions[surface]:

import { Isa } from 'isa-sdk';

const isa = await Isa.withKeycode(
  {
    keycode: 'ABC-123-XYZ',
    email:   '[email protected]',
  },
  undefined,                       // env reader — defaults to process.env
  { apiVersion: { quote: 'v2' } }, // pin only quote; everything else bundled
);

prequalify / quote / datasets / reference default to v3 — the flat plans[] shape, the Money primitive, and the reference adapters all work out of the box. Pin apiVersion: { prequalify: 'v2' } only when a consumer still needs the legacy v2 shape. See SDK syntax proposal §2.7.

Reference adapters

Three SDK adapters consume the /v3/datasets catalog: Autocorrect (typo correction), Match (text → single canonical concept), and Autocomplete (text → ranked suggestions). Each one ships a default implementation and accepts a wholesale replacement at SDK construction. Each one has a canonical guide on docs.isaapi.com; the README only shows the 30-second tour.

| Adapter | Default impl | Guide | |---|---|---| | Autocorrector | DefaultAutocorrector (typo-map driven) | Autocorrect | | MatchAlgorithm | DefaultMatchAlgorithm (_makeKey + exact lookup) | Match | | AutocompleteAlgorithm | DefaultAutocompleteAlgorithm (6-bucket priority) | Autocomplete |

Wire-shape reference for the catalog the adapters consume: Reference catalog shape. Standalone-licensable terms: Licensing the datasets.

Autocorrect

isa.zyins.autocorrector is pre-wired against the ZyINS spelling corrections. The mode option chooses between mid-typing guards (keyup) and anti-duplication guards (submit).

import { Isa } from 'isa-sdk';

const isa = await Isa.withKeycode({
  keycode: 'ABC-123-XYZ',
  email:   '[email protected]',
});

const corrected = isa.zyins.autocorrector.correct('hyprtension and losartn', {
  mode: 'submit',
});
// → 'HYPERTENSION and LOSARTAN'

For a custom typo corpus, use the generic kernel:

const myCorrector = isa.autocorrector.create({
  typoMap: new Map([['ASMA', 'ASTHMA'], ['DIABEETUS', 'DIABETES']]),
});
myCorrector.correct('asma flare', { mode: 'submit' });
// → 'ASTHMA flare'

Match

isa.zyins.{conditions,medications,concepts}.match() resolves free text to a single canonical Concept. Unknown text never rejects — it returns an UnknownConcept with inputText preserved, safe to send straight to /v3/prequalify.

const hbp = isa.zyins.conditions.match('High Blood Pressure');
console.log(hbp.id, hbp.name, hbp.isKnown);
// cond_01KSR2XVXS8F3PQRJGFG91W51G  High Blood Pressure  true

const novel = isa.zyins.medications.match('NewExperimental XR 2026');
console.log(novel.isKnown, novel.inputText);
// false  'NewExperimental XR 2026'

Autocomplete

isa.zyins.{conditions,medications,concepts}.autocomplete(text, opts) returns ranked Suggestion[] using the 6-bucket priority algorithm with within-bucket frequency boost. frequencies and kinds come from the cached datasets bundle automatically.

const suggestions = await isa.zyins.conditions.autocomplete('high b', {
  limit: 5,
});
suggestions.forEach(s => console.log(s.bucket, s.concept.name, s.score));
// 1  High Blood Pressure  12480
// 1  High Blood Sugar      3200

Extending the default

Each Default* implementation is immutable and exposes a clone(overrides) method plus a versionTag getter. Use clone() to swap one field without restating the others:

import { DefaultAutocorrector } from 'isa-sdk';

// Start from the SDK-bundled corrector, override the typo map, keep
// the rest of the wiring (mode, onApplied sink, etc.) intact:
const tenant = isa.zyins.autocorrector.clone({
  typoMap:    new Map([['HBP', 'HIGH BLOOD PRESSURE']]),
  versionTag: '2026.05.29-acme',
  onApplied:  (event) => analytics.track('autocorrect', event),
});

tenant.versionTag;  // '2026.05.29-acme'  — surfaces stale-corpus detection

DefaultAutocorrector.onApplied fires once per correction with the input text, the corrected text, and the mode. Use it to surface telemetry without subclassing.

DefaultMatchAlgorithm and DefaultAutocompleteAlgorithm follow the same clone(overrides) + versionTag pattern.

Wholesale replacement

When the bundled algorithm is the wrong shape (e.g. fuzzy edit-distance, hosted-LLM lookup), implement the interface directly and pass it on the constructor. The minimal MatchAlgorithm is two lines:

import type { MatchAlgorithm, Concept } from 'isa-sdk';

// Exact-string match against `concept.name`, no key normalization.
class ExactNameMatch implements MatchAlgorithm {
  match(text: string, candidates: readonly Concept[]): Concept | null {
    return candidates.find((c) => c.name === text) ?? null;
  }
}

const isa = await Isa.withKeycode({
  keycode: 'ABC-123-XYZ',
  email:   '[email protected]',
  autocorrector:         new MyAutocorrector(),         // Autocorrector
  matchAlgorithm:        new ExactNameMatch(),          // MatchAlgorithm
  autocompleteAlgorithm: new MyAutocompleteAlgorithm(), // AutocompleteAlgorithm
});

The injected implementation replaces the default everywhere — pre-wired facades (isa.zyins.conditions.match, isa.zyins.medications.autocomplete) route through it. Same wholesale + decorator + composition pattern as CaseStorage.

BundledApiVersions and the adapter wire

The default adapters consume the reference catalog. The /datasets surface is pinned in BundledApiVersions:

import { BundledApiVersions } from 'isa-sdk';

BundledApiVersions.datasets;    // 'v3' as of this SDK release
BundledApiVersions.prequalify;  // 'v3' as of this SDK release

Override per-surface via the apiVersion map on Isa.withKeycode. The adapters always read whichever /vN/datasets you pinned — no separate adapter version. See api-version-pinning.

Case storage — bring your own

isa.zyins.cases.* routes through a CaseStorage adapter. The default is the zero-knowledge store — ISA's servers only hold ciphertext and an opaque ID. To plug a carrier-controlled store, pass your adapter at construction:

// `CarrierCaseStorage` is a placeholder for a consumer-supplied
// implementation of the `CaseStorage` interface — see the cases guide.
import { Isa, LicenseAuth, type CaseStorage } from 'isa-sdk';
declare const CarrierCaseStorage: new () => CaseStorage;

const isa = await Isa.create({
  auth: LicenseAuth.fromEnv(),
  caseStorage: new CarrierCaseStorage(),  // optional; default = ZeroKnowledgeCaseStorage
});

See cases guide for the full bring-your-own pattern.

Sub-namespaces

| Namespace | Access | Status | |---|---|---| | isa.zyins.* | isa.zyins.prequalify(req) | Live (license mode) | | isa.rapidsign.* | isa.rapidsign.webhooks.verify(...) | Verifier stub (issue #38) | | isa.proxy.* | internal | Phase 3 | | isa.webhooks.* | top-level alias | Verifier stub |

Raw response variant

Every product method has a .withRawResponse sibling returning { data, response } with status, headers, and url:

// Continued from "First call in <15 lines" — `isa` and `req` are
// the ones defined there.
const { data, response } = await isa.zyins.prequalifyRaw(req);
console.log(response.headers['x-isa-request-id']);

Debug logging

Set ISA_LOG=debug to stream request/response pairs to stderr. Sensitive headers (Authorization, X-Device-Signature, X-Session-Signature) and body fields (license, licenseKey, keycode, password, secret, token) are redacted.

Concurrency safety

A single Isa instance carries no shared mutable state. Multiple concurrent in-flight calls on one instance are safe — there's no need to construct one client per request.

Tree-shaking

The package is annotated sideEffects: false. Modern bundlers (esbuild, Rollup, Webpack) will drop unused product namespaces from your bundle when you import only the names you use.

Migration from per-product packages

@isa-sdk/core, @isa-sdk/zyins, @isa-sdk/rapidsign, and @isa-sdk/proxy (all 0.0.0) are retired in favor of this unified package. See MIGRATION.md for the codemod and a mapping table.

License lifecycle

License activation, check, and deactivation hang off isa.zyins.license (singular — a device carries exactly one license). The facade fills keycode/email/deviceId from the credential state used to construct isa, so the common call is argument-free:

import { Isa } from 'isa-sdk';

const isa = await Isa.withKeycode({
  keycode: 'ABC-123-XYZ',
  email:   '[email protected]',
});

const status = await isa.zyins.license.check();
// status.status: 'valid' | 'invalid' | 'inactive'