Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

js-otdr πŸ“‘

A lightweight, zero-dependency TypeScript/JavaScript library for parsing Telcordia SR-4731 Optical Time Domain Reflectometer (.sor) binary files.

NPM npm version License: MIT TypeScript


πŸš€ Features

  • ⚑ Fast & Lightweight: Zero runtime dependencies.
  • πŸ“¦ Dual Module Format: Works seamlessly in ESM and CommonJS environments (Node.js & Browsers).
  • 🧩 Object-Oriented Design: Encapsulated SorParser and SorData models.
  • πŸ“„ JSON Export: Export parsed OTDR traces directly to JSON strings using .toJson().
  • πŸ› οΈ Fully Typed: Written in TypeScript with complete type definitions included.

πŸ“¦ Installation

npm install @diolan12/js-otdr

or with yarn / pnpm / bun:

yarn add @diolan12/js-otdr
# or
pnpm add @diolan12/js-otdr
# or
bun add @diolan12/js-otdr

CDN (Browser <script> Tag)

You can also use @diolan12/js-otdr directly in the browser without a bundler via jsDelivr or unpkg:

Via IIFE (<script> tag with global JsOtdr):

<script src="https://cdn.jsdelivr.net/npm/@diolan12/js-otdr/dist/index.global.js"></script>
<script>
  // Access via global JsOtdr namespace
  const parser = new JsOtdr.SorParser(arrayBuffer);
  const sorData = parser.parse();
  console.log(sorData.toJson(true));
</script>

Via ES Module (<script type="module">):

<script type="module">
  import { SorParser } from 'https://cdn.jsdelivr.net/npm/@diolan12/js-otdr/+esm';

  const parser = new SorParser(arrayBuffer);
  const sorData = parser.parse();
</script>

πŸ’» Usage

1. Basic Parsing

Pass an ArrayBuffer to SorParser to extract structured OTDR metadata:

import { SorParser } from 'js-otdr';
import * as fs from 'node:fs';

// Read SOR binary file in Node.js
const fileBuffer = fs.readFileSync('trace.sor');
const arrayBuffer = fileBuffer.buffer.slice(
  fileBuffer.byteOffset,
  fileBuffer.byteOffset + fileBuffer.byteLength
);

// Instantiate parser and parse
const parser = new SorParser(arrayBuffer);
const sorData = parser.parse();

console.log(`Cable ID: ${sorData.cableId}`);
console.log(`Wavelength: ${sorData.wavelengthNm} nm`);
console.log(`Events Found: ${sorData.events.length}`);

2. Exporting to JSON (toJson)

Convert parsed OTDR data into a JSON string directly from SorParser or SorData:

import { SorParser } from 'js-otdr';

const parser = new SorParser(arrayBuffer);

// Format with 2-space indentation
const prettyJson = parser.toJson(true);
console.log(prettyJson);

// Compact JSON string
const compactJson = parser.toJson(false);

You can also call .toJson() on an existing SorData instance:

const sorData = parser.parse();
const jsonOutput = sorData.toJson(true);

3. Events Table (getEventsTable)

Build an OTDR-style events table β€” a launch row, a fiber-section row between consecutive events, and the last event rendered as end-of-fiber β€” ready to feed straight into a UI table:

const sorData = parser.parse();

for (const row of sorData.getEventsTable()) {
  console.log(row.type, row.distanceMeters, row.sectionLengthMeters, row.lossDb, row.reflectanceDb);
}
# distance section length type loss reflectance
0 0.000 km β€” launch β€” β€”
β€” β€” 16.066 km fiber-section β€” β€”
1 16.066 km β€” splice 0.193 dB β€”
β€” β€” 4.895 km fiber-section β€” β€”
2 20.961 km β€” splice 1.967 dB β€”
…
5 39.490 km β€” end-of-fiber β€” -49.298 dB

Each row is a SorEventsTableRow:

interface SorEventsTableRow {
  eventNumber: number | null;        // null for fiber-section rows, 0 for the launch row
  type: 'launch' | 'fiber-section' | 'splice' | 'connector' | 'saturated' | 'end-of-fiber' | 'unknown';
  distanceMeters: number | null;     // null for fiber-section rows
  sectionLengthMeters: number | null; // only set on fiber-section rows
  lossDb: number | null;
  reflectanceDb: number | null;
}

πŸ“š API Reference

SorParser

class SorParser {
  constructor(buffer: ArrayBuffer)
  
  // Parses the buffer and returns a SorData instance
  public parse(): SorData
  
  // Conveniently converts parsed SOR data directly into JSON
  public toJson(pretty?: boolean): string
}

SorData

class SorData implements SorMetadata {
  cableId: string;
  fiberId: string;
  wavelengthNm: number;
  pulseWidthNs: number;
  rangeMeters: number;
  refractiveIndex: number;
  endToEndLossDb: number;
  opticalReturnLossDb: number;
  events: SorEvent[];
  dataPoints: number[];

  // Formats data as JSON string
  public toJson(pretty?: boolean): string;

  // Returns plain JavaScript object clone
  public toObject(): SorMetadata;

  // Builds an OTDR-style events table (launch / fiber sections / events / end-of-fiber)
  public getEventsTable(): SorEventsTableRow[];
}

πŸ§ͺ Development & Unit Testing

We use Vitest for unit testing and tsup for TypeScript bundling.

Running Tests

# Run unit test suite once
npm test

# Run tests in watch mode during development
npm run test:watch

Test Directory Structure

tests/
β”œβ”€β”€ fixtures/
β”‚   └── Core-47.sor      # Sample .sor binary test files
└── parser.test.ts       # SorParser and SorData test suite

Adding New Test Cases

When contributing new features or parsing capabilities, add corresponding unit test cases in tests/parser.test.ts:

import { describe, it, expect } from 'vitest';
import { SorParser } from '../src/parser';

describe('My New Feature', () => {
  it('should parse custom SOR attributes', () => {
    // Write test expectations here
  });
});

πŸ› οΈ Building

To bundle ESM (dist/index.js), CommonJS (dist/index.cjs), and declaration files (dist/index.d.ts):

npm run build

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository.
  2. Create a feature branch (git checkout -b feature/my-feature).
  3. Write clean, readable TypeScript code following OOP principles.
  4. Add unit tests for your changes and verify with npm test.
  5. Open a Pull Request detailing your changes.

πŸ“„ License

This project is licensed under the MIT License.

Releases

Packages

Contributors

Languages