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

sor-reader

v1.0.0

Published

Zero-dependency TypeScript parser for OTDR SOR (Standard OTDR Record) files. Supports Bellcore/Telcordia SR-4731 v1.x and v2.x. Works in Node.js and browsers.

Readme

sor-reader

Zero-dependency TypeScript parser for OTDR SOR files (Standard OTDR Record, Bellcore/Telcordia SR-4731 v1.x and v2.x).

Works in Node.js ≥ 18 and modern browsers (via Uint8Array — no Buffer required).


Features

  • Full SOR v1 and v2 support
  • Parses all standard blocks: MapBlock, GenParams, SupParams, FxdParams, KeyEvents, DataPts, Cksum
  • CRC16-CCITT checksum verification
  • Trace data export as tab-separated .dat (identical to pyOTDR output)
  • JSON output matching pyOTDR (sorted keys, 8-space indent)
  • Browser-safe entry point (sor-reader/browser) — no Node.js APIs in the core
  • CLI tool for quick file processing
  • Full TypeScript types and JSDoc

Installation

npm install sor-reader

Quick Start

Node.js

import { parseSorFile, toJSON, traceToString } from "sor-reader";

const result = await parseSorFile("measurement.sor");

console.log(`Format: v${result.format}`);
console.log(`Data points: ${result.FxdParams["num data points"]}`);
console.log(`Wavelength: ${result.FxdParams.wavelength}`);
console.log(`Checksum OK: ${result.Cksum.match}`);

// Write pyOTDR-compatible JSON
import { writeFileSync } from "fs";
writeFileSync("measurement-dump.json", toJSON(result));

// Write trace data
writeFileSync("measurement-trace.dat", traceToString(result.trace));

Browser / Bundler

import { parseSor, toJSON, traceToString } from "sor-reader/browser";

// From a file input or fetch response
const response = await fetch("measurement.sor");
const buffer = await response.arrayBuffer();
const data = new Uint8Array(buffer);

const result = parseSor(data, "measurement.sor");
console.log(toJSON(result));

CommonJS

const { parseSorFile, toJSON } = require("sor-reader");

CLI

# Parse a single file (writes measurement-dump.json + measurement-trace.dat)
npx sor-reader measurement.sor

# Multiple files
npx sor-reader *.sor

# Print JSON to stdout only
npx sor-reader --stdout --no-trace measurement.sor

# Skip JSON output
npx sor-reader --no-json measurement.sor

CLI Options

| Option | Description | |---|---| | --json / --no-json | Write JSON dump (default: enabled) | | --trace / --no-trace | Write trace .dat file (default: enabled) | | --stdout | Print JSON to stdout instead of file | | --help, -h | Show help | | --version, -v | Print version |


API Reference

parseSor(data, filename?, options?)

Parse a SOR file from a Uint8Array.

function parseSor(
  data: Uint8Array,
  filename?: string,
  options?: ParseOptions,
): SorResult

parseSorFile(filepath, options?) (Node.js only)

Parse a SOR file from a filesystem path.

async function parseSorFile(
  filepath: string,
  options?: ParseOptions,
): Promise<SorResult>

toJSON(result)

Serialize a SorResult to a JSON string compatible with pyOTDR output (sorted keys, 8-space indent).

function toJSON(result: SorResult): string

traceToString(trace)

Convert trace data to a tab-separated string (distance\tpower\n per line).

function traceToString(trace: TracePoint[]): string

SorResult Structure

interface SorResult {
  filename: string;
  format: 1 | 2;           // SOR version
  version: string;          // e.g. "2.00"
  mapblock: MapBlockInfo;
  blocks: Record<string, BlockInfo>;
  GenParams: GenParamsRaw;  // General parameters
  SupParams: SupParamsRaw;  // Supplier parameters
  FxdParams: FxdParamsRaw;  // Fixed parameters (wavelength, range, etc.)
  KeyEvents: KeyEventsRaw;  // Detected events and summary
  DataPts: DataPtsRaw;      // Trace metadata
  Cksum: CksumRaw;          // Checksum verification
  trace: TracePoint[];      // [{distance, power}, ...] in km / dB
}

Key fields

| Field | Type | Description | |---|---|---| | FxdParams["wavelength"] | string | e.g. "1310 nm" | | FxdParams["num data points"] | number | Number of trace samples | | FxdParams["range"] | number | Measurement range in km | | FxdParams["resolution"] | number | Sample resolution in m | | FxdParams["index"] | number | Group index of refraction | | FxdParams["date/time"] | string | Human-readable timestamp | | KeyEvents["num events"] | number | Number of detected events | | Cksum.match | boolean | Whether checksum is valid | | trace[i].distance | number | Distance in km | | trace[i].power | number | Signal level in dB |


Compatibility

| Environment | Support | |---|---| | Node.js ≥ 18 | Full (including parseSorFile) | | Node.js 16 | Core parseSor only (no parseArgs for CLI) | | Browsers (modern) | sor-reader/browser entry — all features except parseSorFile | | Deno | Use parseSor with Uint8Array from Deno.readFile | | Bun | Full support |


Comparison with pyOTDR

| Feature | pyOTDR (Python) | sor-reader (TS) | |---|---|---| | SOR v1 | ✅ | ✅ | | SOR v2 | ✅ | ✅ | | CRC16 checksum | ✅ | ✅ | | Trace output | ✅ | ✅ (byte-identical) | | JSON output | ✅ | ✅ (byte-identical) | | Browser support | ❌ | ✅ | | TypeScript types | ❌ | ✅ | | Zero dependencies | ❌ (crc pkg) | ✅ | | CLI | ✅ | ✅ |


SOR File Format

SOR files follow the Bellcore/Telcordia SR-4731 standard for OTDR (Optical Time-Domain Reflectometer) measurements. The format stores:

  • General parameters: fiber type, cable ID, operator, location
  • Supplier parameters: OTDR make/model, firmware version
  • Fixed parameters: wavelength, pulse width, measurement range, IOR
  • Key events: detected splices, reflections, and end-of-fiber
  • Data points: raw backscatter trace samples
  • Checksum: CRC16-CCITT over all preceding bytes

License

MIT — see LICENSE.

Ported from pyOTDR (GPL-3.0) by Sidney Li. The port is a clean-room reimplementation in TypeScript, licensed under MIT.