npm package: @longevity-tools/platform-sdk
Description: TypeScript SDK for Longevity Tools platform
Latest version: 1.2.0

# Longevity-tools Platform Integration SDK

A TypeScript SDK for integrating with the Longevity-tools platform.

Biomarker data for Longevity-tools interpretation is provided via the URL and this SDK simplifies the process of generating interpretation URL.

## Installation

```bash
npm install @longevity-tools/platform-sdk
```

This package has less than 5kB gzipped and has zero dependencies.

## Quick JavaScript example: how to get the URL with data

The SDK supports automatic biomarker matching using LOINC codes.

```javascript
import { getInterpretationUrl } from '@longevity-tools/platform-sdk';

const url = getInterpretationUrl({
  baseUrl: 'https://longevity-tools.com/...', // this URL will be provided after activating your partner platform account
  patientName: 'John Smith', // optional
  measurements: [
    { identifier: 'gender', value: 'male' },
    { identifier: 'age', value: 45, unit: 'years' },

    {
      // you can provide multiple identifiers, useful for providing also a LOINC code
      identifier: ['cholesterol (Total)', '2093-3'],
      value: 200,
      unit: 'mg/dL',
    },
    {
      // no LOINC... Requires entry in customIdMapping to map it
      identifier: 'your-id-for-glucose',
      value: 95,
      unit: 'mg/dL',
    },
    { identifier: ['some-niche-marker', '9999-9'], value: 4.2, unit: 'g/dL' }, // Markers we don't support will be ignored and not included in the URL
  ],

  // Optional: map your custom IDs to Longevity-tools biomarker IDs if you don't have LOINC codes
  customIdMapping: {
    // cholesterol will be auto paired by LOINC, no need to add it here
    'S-glucose': 'your-id-for-glucose',
  },
});

// console.log(url):
// https://...#gender=male&age=45_years&S-cholesterol=200_mg~dL&S-glucose=95_mg~dL

// Now you can use the URL in a button/link like this:
// <a href={url} target="_blank">Interpret</a>
```

## Detailed TypeScript example

```typescript
import { getInterpretationUrl } from '@longevity-tools/platform-sdk';
import type { Measurement, CustomIdMapping } from '@longevity-tools/platform-sdk';

const measurements: Measurement[] = [
  // Enum biomarkers require that you send only supported values
  // See Supported Biomarkers section below for valid options for enum biomarkers
  { identifier: 'gender', value: 'female' }, // Gender is always required and must be "male" | "female"

  // Numeric measurements must have units
  // You can send any unit, the platform will try to normalize them into one of the supported ones
  { identifier: 'age', value: 32, unit: 'years' }, // age must be in 'years'
  { identifier: 'weight', value: 65, unit: 'kg' },
  { identifier: 'height', value: 165, unit: 'cm' },

  // Now iterate all measurements from your database - unsupported ones will be ignored
  {
    // You can provide a string or an array of multiple IDs (e.g., internal ID + LOINC code)
    identifier: ['your-id-for-glucose', '2345-7'],
    value: 92,
    unit: 'mg/dL',
  },
  {
    // Or just use LOINC directly
    identifier: '1751-7',
    value: 4.3,
    unit: 'g/dL',
  },

  {
    // If you don't have LOINC codes, use your custom ID
    identifier: 'Albumin (Serum)',
    value: 4.3,
    unit: 'g/dL',
  },

  {
    // Or use Longevity-tools IDs directly - no mapping required
    identifier: 'S-insulin',
    value: 8.4,
    unit: 'µIU/mL',
  },

  // This marker will not be sent since we don't support it
  // But include it anyway - if we add support in the future, it will automatically work when you upgrade the SDK
  {
    identifier: ['Small LDL Particle Number', '43727-7'],
    value: 644,
    unit: 'nmol/L',
  },
];

// Optional: map your custom IDs to Longevity-tools biomarker IDs if you don't have LOINC codes
const customIdMapping: CustomIdMapping = {
  // Longevity-tools ID -> your custom ID(s)
  // Can be a single string or an array of strings (for multiple labs/systems)
  'S-albumin': ['Albumin (Serum)', 'lab-B-serum-albumin'],

  // Repeat for all biomarkers that don't have LOINC codes. Find our IDs here: https://www.longevity-tools.com/platform-integration-docs
};

// Generate the interpretation URL
const interpretationUrl = getInterpretationUrl({
  baseUrl: 'https://longevity-tools.com/...',
  patientName: 'John Smith', // Optional but highly recommended to avoid mixing up patient reports
  measurements,
  customIdMapping,
});
```

### Handling String Values and Edge Cases

The SDK automatically handles various input formats:

```typescript
const measurements: Measurement[] = [
  // String numeric values are accepted
  { identifier: 'S-glucose', value: '95.5', unit: 'mg/dL' },

  // Values with comparison operators are cleaned automatically
  { identifier: 'S-ferritin', value: '<5', unit: 'ng/mL' },

  // Whitespace is automatically trimmed
  { identifier: 'S-cholesterol', value: ' 200 ', unit: ' mg/dL ' },
];
```

#### Measurement Type

```typescript
type Measurement = {
  /** Biomarker identifier(s) - can be Longevity-tools ID, LOINC code, or your custom ID */
  identifier: string | string[];

  /** Measurement value
   * For numeric biomarkers: can be number or numeric string. Values like "<0.3" will be handled.
   * For enum biomarkers: must be one of the exact accepted values, like "male" | "female" for gender.
   */
  value: number | string;

  /** Unit of measurement
   * For numeric biomarkers: must be string like "mg/dL", "mmol/L", "years", etc.
   * For enum biomarkers: must be undefined (or omitted).
   */
  unit: string | undefined;
};
```

## Supported Biomarkers

You can find the list of supported biomarkers on this website: https://www.longevity-tools.com/platform-integration-docs

Supported biomarkers are also included in this repo. You can import the `biomarkers` array and `LtBiomarkerId` type to see all available options:

```typescript
import { biomarkers, LtBiomarkerId } from '@longevity-tools/platform-sdk';

// View all supported biomarker IDs
console.log(biomarkers);

// TypeScript will autocomplete valid biomarker IDs
const identifier: LtBiomarkerId = 'S-glucose'; // Type-safe!
```

## Error Handling

- In development mode (`NODE_ENV === 'development'`), the SDK throws errors for severe issues that are usually developer mistakes.
- In production mode, errors are logged to the console and the function continues execution with only valid measurements to avoid breaking your application.

### LOINC Priority and Matching Logic

When the SDK processes measurements, it follows this priority order for matching:

1. **Direct Longevity-tools biomarker ID match** (e.g., `'S-glucose'`) - highest priority
2. **Custom ID mapping** - matches your custom IDs via `customIdMapping`
3. **LOINC code matching** - automatic matching using standardized LOINC codes

**LOINC Priority Order**: We support multiple LOINC codes for each biomarker. If for some reason the test was done using via multiple measurement methods, we will map only the most precise measurement method.

## Privacy

All biomarker data is encoded in the URL hash (after the `#` symbol). Browsers don't send URL hash fragments to servers, so patient data never leaves the browser. This way, no personal or medical data is ever transferred to the longevity-tools server.

Learn more: [longevity-tools.com/privacy-policy](https://www.longevity-tools.com/privacy-policy)

## License

MIT