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

@maustec/slip

v0.1.0

Published

SLIP protocol library for Maus-Tec devices

Readme

@maustec/slip

TypeScript client for the Maus-Tec SLIP protocol. This is a base module to be consumed by product-specific SDKs. It provides all framing, request/ response correlation, ACK handling, chunked-message reassembly, and typed wrappers for every SLIP command exposed by the firmware.

npm install @maustec/slip

Quick start

This package is byte-source agnostic and can be used with any transport library pointed at your connected device. SlipTransport expects an async write callback, and bytes are written to it with receive(). Everything else (nonce allocation, timeouts, response correlation, ACKs) is handled internally.

Node (serialport)

import { SerialPort } from 'serialport';
import { SlipTransport } from '@maustec/slip';

const port = new SerialPort({ path: '/dev/ttyUSB0', baudRate: 115200 });

const transport = new SlipTransport({
  write: (data) =>
    new Promise((resolve, reject) =>
      port.write(Buffer.from(data), (err) => (err ? reject(err) : resolve())),
    ),
  onEvent: (pkt) => console.log('event', pkt),
});

port.on('data', (buf: Buffer) => transport.receive(new Uint8Array(buf)));

const info = await transport.system.deviceInfo();
console.log(`${info.vendor} ${info.productName} (fw ${info.fwVersion})`);

Browser (WebSerial)

const port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
const writer = port.writable!.getWriter();
const reader = port.readable!.getReader();

const transport = new SlipTransport({
  write: (data) => writer.write(data),
});

(async () => {
  for (;;) {
    const { value, done } = await reader.read();
    if (done) break;
    if (value) transport.receive(value);
  }
})();

Built-in operation modules

Operations are grouped by module on the transport instance. Each method returns a typed result and throws SlipError on a non-SUCCESS device status.

await transport.system.ping(new TextEncoder().encode('hello'));
await transport.system.firmwareVersion();      // => '1.4.2'
await transport.system.health();               // => { framesOk, errCrc, ... }

await transport.file.list('/sdcard');          // => FileEntry[]
await transport.file.read('/sdcard/log.txt');  // chunked download
await transport.file.write('/sdcard/cfg.json', bytes);

await transport.events.subscribe([0x42]);
await transport.log.tail();

Extending for a product SDK

Product firmware adds its own SLIP command interfaces. Codegen emits raw wrappers under generated/<module>/commands.ts. The developer is expected to build a thin facade on top to expose a more developer-friendly interface.

import { SlipTransport, type SendOptions } from '@maustec/slip';
import { setSpeed, getStatus } from './generated/motor/commands.js';

export class MotorOps {
  constructor(private transport: SlipTransport) {}

  setSpeed(value: number, opts?: SendOptions) {
    return setSpeed(this.transport, { value }, opts);
  }

  status(opts?: SendOptions) {
    return getStatus(this.transport, opts);
  }
}

export class MyDevice {
  readonly motor: MotorOps;

  constructor(private readonly transport: SlipTransport) {
    this.motor = new MotorOps(transport);
  }

  // Built-in modules remain reachable through the transport.
  get system() { return this.transport.system; }
}

For direct access to the raw command wrappers, import them directly from the codegen output:

import * as motor from './generated/motor/commands.js';
await motor.setSpeed(transport, { value: 128 });

Error handling

import { SlipError, SlipStatus } from '@maustec/slip';

try {
  await transport.file.read('/missing');
} catch (err) {
  if (err instanceof SlipError && err.status === SlipStatus.ERR_NOT_FOUND) {
    // handle missing file
  } else {
    throw err;
  }
}

Development

npm install
npm test          # vitest
npm run lint
npm run build
npm run smoke -- /dev/ttyUSB0   # exercise a real device (smoke is not literal, we hope)

License

MIT