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

@dpup/meshcore-sim

v0.2.0

Published

A deterministic, behavioral MeshCore network simulator for testing meshcore.js / @dpup/meshcore-ts apps without radios. The grown-up form of a hand-written connection stub.

Readme

meshcore-sim

A deterministic, behavioral MeshCore network simulator for testing your apps without radios.

License: MIT Types: included Node Module: ESM

meshcore-sim simulates a MeshCore network so you can test @dpup/meshcore-ts / @liamcottle/meshcore.js apps with no radios attached — in CI, deterministically, including the failure and adversarial cases hardware can't stage.

It is deliberately not a digital twin. It models the observable behavior of a mesh — message arrival, ordering, loss, signal metadata, node state, channel and decrypt outcomes — not RF physics. SimConnection is a drop-in for a meshcore.js Connection: inject it where an app would use a real TCP/serial connection, drive a virtual clock, and assert on what the app observed. It is the grown-up form of a hand-written connection stub — the same interface, a simulated world behind it instead of canned returns.

import { MeshCoreClient } from "@dpup/meshcore-ts";
import { SimConnection, defineWorld, SimClock, node, contact, traffic } from "@dpup/meshcore-sim";

const world = defineWorld({
  homeNodeId: "home",
  nodes: [node("home"), node("alice")],
  contacts: [contact("Alice", "alice")],
});
const clock = new SimClock();
const sim = new SimConnection({
  world,
  clock,
  scenario: traffic.burst({ from: "alice", count: 3, within: "10s" }),
});

const client = new MeshCoreClient(sim.asConnection(), { autoSync: true });
client.on("contactMessage", (m) => console.log(m.text));

await client.connect();
clock.advance("10s"); // 3 messages arrive in compressed virtual time

The three messages arrive in their (seeded, jittered) order — instantly, no real seconds spent:

msg 0
msg 2
msg 1

Why

The most logic-dense, bug-prone parts of a MeshCore app are barely testable any other way: time-domain debounce/coalescing (a controllable clock, not real seconds), admin-channel gates (adversarial inputs you shouldn't produce on hardware), and failure modes (offline nodes, packet loss, reconnection). This is a development/test dependency, never shipped in production.

Install

npm install -D @dpup/meshcore-sim      # or: bun add -d / pnpm add -D

ESM-only, Node.js ≥ 18. Bring your own @dpup/meshcore-ts and @liamcottle/meshcore.js (peer dependencies).

Documentation

See it in action

examples/demo.ts is a guided tour — it builds a world, drives it through a real MeshCoreClient, and walks the whole feature set. No hardware, fully deterministic:

bun examples/demo.ts          # or --seed <n> / a positional seed
meshcore-sim — guided tour
a real MeshCoreClient driven over a simulated Connection (seed 42)

1. Build a world
────────────────────────────────────────────────────────────
   4 nodes (3 reachable, 1 offline), 2 channels, 3 contacts
     • Home Base    home       online
     • Rocky Ridge  repeater   online
     • Cedar Creek  companion  online
     • Silent Peak  repeater   offline
     # ch0 public   public
     # ch1 ops      private

2. Connect
────────────────────────────────────────────────────────────
   connected to "Home Base" d54ca596335b… freq=910525kHz sf=10
   a MeshCoreClient cannot tell this from a real radio.

3. Static reads
────────────────────────────────────────────────────────────
   3 contacts:
     • Rocky Ridge  3f997cdbe620…
     • Cedar Creek  3d4098fbaa16…
     • Silent Peak  ba14fa6ded11…
   2 channels:
     # ch0 public
     # ch1 ops
   ✓ status Rocky Ridge: battery=4.20V uptime=0s rx=0 tx=0
   ✗ status Silent Peak: unreachable (Device error: not found)

4. Dynamic traffic in virtual time
────────────────────────────────────────────────────────────
   scheduled a 4-message burst across a 10s window…
   t+04.482s  MESSAGE 3f997cdbe620 "msg 1"
   t+06.011s  MESSAGE 3f997cdbe620 "msg 0"
   t+06.697s  MESSAGE 3f997cdbe620 "msg 3"
   t+08.524s  MESSAGE 3f997cdbe620 "msg 2"
   ↑ 4 messages spanning 8.52s of mesh time replayed in zero real seconds — that is the virtual clock.

5. Provenance: verified vs. unverified
────────────────────────────────────────────────────────────
   t+03.000s  ✓ VERIFIED   decrypt-verified on ch1 (ops): "status: all green"
   t+03.000s  ⚠ UNVERIFIED raw datagram on admin ch7: 10 bytes (snr 7), never decoded
   the admin-gate point: the unverified datagram surfaces only as raw bytes — it
   can never arrive as a verified channelMessage, so a gate keyed on verification
   correctly rejects it.

6. Determinism & freezing
────────────────────────────────────────────────────────────
   ✓ two generateWorld(42) runs are identical — deterministic, byte for byte.
   ✓ loadWorld() round-trips the snapshot exactly — freeze once, replay forever.

✓ tour complete — a full mesh app workflow, no radio, fully reproducible.

In a real terminal the tour is ANSI-colored; re-run it with any --seed and the output is identical every time.

Development

bun install
bun run typecheck   # tsc --noEmit (strict)
bun run test        # vitest unit + integration tests (no hardware needed)
bun run build       # emit dist/ (ESM + .d.ts)
bun run docs        # regenerate docs/api.md from the source

See AGENTS.md for architecture and contribution notes.

License

MIT © Dan Pupius