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

@m-scan/device-kit-agent

v0.0.3

Published

Local native agent (Node.js) exposing network/USB/Bluetooth device access to the browser over WebSocket/HTTP

Readme

@m-scan/device-kit-agent

Agent local (Node.js) qui donne à une application web (@m-scan/device-kit) l'accès au réseau, aux queues d'impression USB et aux ports série Bluetooth — des accès qu'un navigateur ne peut pas atteindre directement.

Doit tourner en permanence sur le poste de caisse, sur le même réseau local que les imprimantes. Un hébergement cloud externe ne peut pas atteindre du matériel sur un réseau privé de magasin.

Installation et lancement

npx m-scan-device-agent

Ou installé globalement :

npm install -g @m-scan/device-kit-agent
m-scan-device-agent

Écoute par défaut sur http://localhost:4310. Changer le port :

M_SCAN_AGENT_PORT=4400 npx m-scan-device-agent

Plateformes supportées

| Transport | Plateforme | |---|---| | Réseau (TCP) | Windows, Linux, macOS | | USB | Windows, Linux, macOS (queue d'impression système : winspool.drv ou CUPS) | | Bluetooth | Windows, Linux, macOS (port série, l'imprimante doit être appairée dans les paramètres Bluetooth de l'OS) |

Android/iOS ne sont pas supportés par l'agent (pas d'environnement Node.js persistant sur mobile) — sur tablette/téléphone, la voie prévue est une PWA qui parle directement à l'imprimante via Web Bluetooth/WebUSB dans le navigateur, sans agent (encore à implémenter).

API

Toutes les routes acceptent/répondent en JSON. { receipt: Receipt } (voir @m-scan/device-kit-escpos) est préféré à { lines: string[] } pour un ticket correctement formaté (colonnes alignées).

Réseau

| Route | Méthode | Body | Rôle | |---|---|---|---| | /api/scan | GET | ?port=9100 | Scanne le /24 local, identifie les imprimantes (SNMP/mDNS best-effort) | | /api/connect | POST | { host, port? } | Ouvre une connexion TCP réutilisable | | /api/print | POST | { receipt } ou { host?, port?, receipt } | Imprime (réutilise la connexion active si host omis) | | /api/cash-drawer | POST | { host?, port? } | Pulse le tiroir-caisse | | /api/disconnect | POST | — | Ferme toutes les connexions actives (tous transports) |

USB (préfixe /api/usb/)

Mêmes routes, avec printerName (nom de la queue d'impression système — Get-Printer sur Windows, lpstat -v sur Linux/macOS) à la place de host/port.

Bluetooth (préfixe /api/bluetooth/)

Mêmes routes, avec comPort (ex. "COM5") à la place de host/port.

Exemple complet

const AGENT = 'http://localhost:4310'

// Découvrir les imprimantes réseau
const { devices } = await fetch(`${AGENT}/api/scan`).then((r) => r.json())

// Se connecter à la première trouvée
await fetch(`${AGENT}/api/connect`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ host: devices[0].address, port: devices[0].meta.port }),
})

// Imprimer
await fetch(`${AGENT}/api/print`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ receipt: myReceipt }),
})

Utilisation programmatique (sans CLI)

import { AgentServer } from '@m-scan/device-kit-agent'

const server = new AgentServer({ port: 4310 })
await server.start()
// ...
await server.stop()

Pourquoi pas d'accès USB/Bluetooth bas niveau (WebUSB/libusb) ?

Testé et abandonné en pratique : dès qu'un pilote imprimante est installé sur un périphérique USB, l'OS verrouille l'accès USB direct (sur Windows, claimInterface échoue avec "incompatible driver is installed for this device"). Passer par la queue d'impression système (winspool.drv sur Windows, CUPS sur Linux/macOS) évite ce conflit et fonctionne avec le pilote déjà en place.

Licence

MIT