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

@onion-party/spacepackets

v1.0.0

Published

Encode and decode CCSDS Space Packets for ground station and spacecraft software.

Readme

spacepackets

spacepackets

CI

A TypeScript library for encoding and decoding CCSDS Space Packets — the standard packet format used in spacecraft telemetry and telecommand systems (CCSDS 133.0-B-2).

Install

npm install @onion-party/spacepackets
# or
pnpm add @onion-party/spacepackets

Quick start

Decode a telemetry packet

import { decode, PacketType } from "@onion-party/spacepackets";

const bytes = new Uint8Array([/* raw packet bytes from socket or file */]);
const packet = decode(bytes);

console.log(packet.header.apid);          // Application Process ID
console.log(packet.header.sequenceCount); // For gap detection
console.log(packet.header.packetType);    // PacketType.Telemetry or PacketType.Telecommand
console.log(packet.dataField);            // Uint8Array — secondary header + user data

Encode a telecommand

import { encode, PacketType, SequenceFlags } from "@onion-party/spacepackets";

const packet = {
  header: {
    packetVersionNumber: 0,
    packetType: PacketType.Telecommand,
    secondaryHeaderFlag: false,
    apid: 100,
    sequenceFlags: SequenceFlags.Standalone,
    sequenceCount: 0,
    dataLength: 2, // dataField.byteLength - 1
  },
  dataField: new Uint8Array([0x01, 0x02, 0x03]),
};

const bytes = encode(packet); // Uint8Array ready for transmission

Assemble packets from a byte stream

Packets often arrive in chunks — split across frame boundaries or delivered over a socket. PacketAssembler buffers incoming bytes and emits complete packets.

import { PacketAssembler } from "@onion-party/spacepackets";

const assembler = new PacketAssembler();

// Feed raw bytes as they arrive (e.g. from a UDP socket)
socket.on("data", (chunk: Buffer) => {
  const packets = assembler.onChunk(chunk);
  for (const packet of packets) {
    console.log("received packet", packet.header.apid);
  }
});

Full pipeline (Node.js streams)

All three stream classes compose via .pipe() for a fully declarative receive pipeline:

import {
  PacketAssemblerStream,
  GapDetectorStream,
  SegmentationReassemblerStream,
  type ReassembledAdu,
} from "@onion-party/spacepackets";

socket
  .pipe(new PacketAssemblerStream({ maxBufferBytes: 1_000_000 }))
  .pipe(new GapDetectorStream({
    onGap: (gap) => console.warn(`APID ${gap.apid}: ${gap.missing} packet(s) missing`),
  }))
  .pipe(new SegmentationReassemblerStream({
    onError: (err) => console.warn(`APID ${err.apid}: ${err.kind}`),
  }))
  .on("data", (adu: ReassembledAdu) => {
    console.log(`APID ${adu.apid}: ${adu.data.byteLength} bytes`);
  });

Detect gaps in the packet stream

GapDetector tracks the sequence count per APID and fires a callback whenever packets are missing.

import { GapDetector, PacketAssembler } from "@onion-party/spacepackets";

const assembler = new PacketAssembler();
const detector = new GapDetector({
  onGap: (gap) => {
    console.warn(`APID ${gap.apid}: expected ${gap.expected}, got ${gap.received} — ${gap.missing} packet(s) missing`);
  },
});

socket.on("data", (chunk: Buffer) => {
  const packets = assembler.onChunk(chunk);
  for (const packet of packets) {
    detector.onPacket(packet.header);
  }
});

Reassemble segmented ADUs

Large application data units (ADUs) are sometimes split across multiple packets using First/Continuation/Last sequence flags. SegmentationReassembler buffers segments per APID and emits the fully concatenated data when the final segment arrives.

import { PacketAssembler, SegmentationReassembler } from "@onion-party/spacepackets";

const assembler = new PacketAssembler();
const reassembler = new SegmentationReassembler({
  onAdu: (adu) => {
    console.log(`APID ${adu.apid}: reassembled ${adu.data.byteLength} bytes`);
  },
  onError: (err) => {
    if (err.kind === 'ORPHANED_SEGMENT') {
      console.warn(`APID ${err.apid}: segment arrived with no matching First packet`);
    } else {
      console.warn(`APID ${err.apid}: new First arrived while ADU was in-progress — abandoned`);
    }
  },
});

socket.on("data", (chunk: Buffer) => {
  const packets = assembler.onChunk(chunk);
  for (const packet of packets) {
    reassembler.onPacket(packet);
  }
});

Error handling

All errors thrown by this library are instances of SpacePacketError. Use the code field to branch programmatically without parsing message strings.

import { decode, SpacePacketError } from "@onion-party/spacepackets";

try {
  const packet = decode(bytes);
} catch (err) {
  if (err instanceof SpacePacketError) {
    switch (err.code) {
      case "BUFFER_TOO_SHORT":
        // Not enough bytes yet — wait for more data
        break;
      case "INVALID_VERSION":
        // Packet version number is non-zero — malformed or unsupported
        break;
    }
  }
}

API

Functions

| Function | Description | |---|---| | encode(packet) | Serialize a SpacePacket to a Uint8Array | | decode(bytes) | Parse a Uint8Array into a SpacePacket | | decodeHeader(bytes) | Parse only the 6-byte primary header — useful in streaming contexts to learn the full packet length before the payload has arrived | | getPacketLength(header) | Returns the total byte length of a packet given its header (6 + header.dataLength + 1) | | isIdlePacket(header) | Returns true if the packet's APID is 0x7FF (the reserved idle/fill APID); idle packets carry no mission data and should be discarded |

Classes

| Class | Description | |---|---| | PacketAssembler | Stateful buffer that accepts raw byte chunks via onChunk(chunk) and returns complete SpacePacket[]. Handles packets split across chunk boundaries. | | GapDetector | Tracks sequence counts per APID and calls onGap whenever packets are missing. Handles 14-bit wrap-around and ignores idle packets. | | SegmentationReassembler | Reassembles segmented ADUs from First/Continuation/Last packet sequences. Calls onAdu when complete, onError on out-of-order or orphaned segments. | | PacketAssemblerStream | Node.js Transform stream wrapping PacketAssembler. Accepts raw byte chunks on the writable side, emits decoded SpacePacket objects on the readable side. Emits INCOMPLETE_PACKET if the stream ends mid-packet. | | GapDetectorStream | Passthrough Transform stream wrapping GapDetector. Accepts and re-emits SpacePacket objects; calls onGap as a side effect for any detected sequence gaps. | | SegmentationReassemblerStream | Transform stream wrapping SegmentationReassembler. Accepts SpacePacket objects, emits ReassembledAdu objects when a complete ADU is assembled. | | SpacePacketError | Thrown by encode/decode on malformed input, or emitted by PacketAssemblerStream. Has a code field: BUFFER_TOO_SHORT, INVALID_VERSION, APID_OUT_OF_RANGE, DATA_FIELD_EMPTY, DATA_LENGTH_MISMATCH, SEQUENCE_COUNT_OUT_OF_RANGE, PACKET_TOO_LARGE, BUFFER_OVERFLOW, INCOMPLETE_PACKET. |

Specification

This library implements CCSDS 133.0-B-2 — Space Packet Protocol, published by the Consultative Committee for Space Data Systems (CCSDS).

License

MIT