Skip to content

Connection and configuration ​

SerialConfig ​

The constructor accepts the exact SerialConfig contract from serial-core.

OptionTypeRequiredBehavior
baudRatenumberyesSerial speed; match the device
autoConnectbooleannoDefault false; when true, connect in a microtask after construction
reconnectIntervalnumbernoInitial retry delay; default 2000 ms
autoReconnectbooleannoDefault true; enable automatic recovery
reconnectBackoffFactornumbernoDelay multiplier, at least 1; default 1
maxReconnectIntervalnumbernoDelay ceiling; default max(30000, reconnectInterval)
maxReconnectAttemptsnumbernoRetry budget excluding initial attempt; default Infinity
writeTimeoutnumbernoPhysical write/drain deadline; default 5000 ms
responseTimeoutnumbernoserial-core response wait deadline; default 5000 ms; distinct from JSD ACK timeout
maxQueueSizenumbernoActive plus pending command capacity; default 1000; also bounds JSD's backlog
pathstringnoExplicit port path
vendorIdstringnoUSB vendor filter when scanning
productIdstringnoUSB product filter when scanning
serialNumberstringnoExact serial number for discovery
parserNodeJS.ReadWriteStreamnoShared custom parser, mutually exclusive with parserFactory
parserFactory() => NodeJS.ReadWriteStreamnoFresh parser each session; JSD supplies a delimiter factory by default
handshakeJSDHandshakenoCustom handshake; JSD supplies a protocol handshake otherwise

Use autoConnect: false to attach all listeners before initiating a connection. The constructor preserves the caller's configuration and supplies defaults in a separate object. A fresh parser per session prevents partial frames surviving a reconnect.

Port paths and discovery ​

Typical paths are /dev/ttyUSB0 or /dev/ttyACM0 on Linux, /dev/cu.usbserial-* on macOS, and COM3 on Windows. Use your actual path.

ts
const ports = await JSD.listPorts({ availableOnly: true });
console.table(ports);

JSD exposes static and instance listPorts() / findPorts() methods. Filters combine with AND and do not open ports. availableOnly checks module-local reservations, not OS-wide availability. To connect through discovery, omit path and provide vendorId, productId, or serialNumber:

ts
const jsd = new JSD({
  vendorId: '0403',
  productId: '6001',
  baudRate: 9600,
  autoConnect: false,
  reconnectInterval: 1_000
});

Scanning belongs to serial-core. Its installed version selects the first matching unreserved port using normalized exact VID/PID matching and an exact serial number. An explicit path takes precedence. Enumeration errors reject; no match returns an empty list.

Readiness and reconnection ​

start(): void asks serial-core to connect. Observe DISCONNECTED, SCANNING, CONNECTING, CONNECTED, and RECONNECTING through serial:status. Failures are reported through serial:error and serial-core applies the configured retry budget and capped backoff. Observe serial:reconnecting with { attempt, delay } and serial:reconnectFailed with { attempts }. Counts exclude the initial connection attempt.

ts
import { once } from 'node:events';

const ready = once(jsd, 'serial:connected', {
  signal: AbortSignal.timeout(10_000)
});
jsd.start();
await ready;

The example bounds the readiness wait; it does not turn serial:error into a rejection. Keep an error listener and call stop() if your application abandons connection attempts.

Default handshake and parser ​

JSD sends its licensing connection frame and accepts a valid ACK or DATA frame. The default handshake timeout is 500 ms. Its delimiter parser splits at 0xC0 and excludes that delimiter. Invalid frames fail CRC or frame validation.

A supplied handshake replaces the default entirely:

ts
import type { JSDHandshake } from '@danidoble/serial-node-jsd';

const handshake: JSDHandshake = {
  command: Buffer.from([/* your device handshake bytes */]),
  pattern: /READY/,
  timeout: 1_000
};

command accepts string or Buffer, pattern string or RegExp, timeout milliseconds, hexPattern an optional boolean, and callback an optional (data: Buffer | string) => boolean. A callback, when supplied, determines success instead of the pattern. maxBufferSize bounds accumulated pattern input (default 65536 bytes). Callback mode receives individual chunks/frames. Both successful handshake transmission and validation are required. Use settings appropriate to the device.

Shutdown and retries ​

stop(): Promise<void> delegates to serial-core disconnect and cancels its reconnection scheduling. It also clears JSD commands, ACK timers, and delayed initial status queries. Lost session commands are never automatically replayed after reconnection. Late write callbacks from the old session cannot change a new session. Pending log reads, channel assignment, carts, and dispenses reject with JSD session ended; operation outcome may be unknown. Their polling timers are released and cached machine readiness is invalidated. This does not undo a physical operation. No per-operation cancellation handle is exposed; application deadlines are still needed if a device remains connected but never completes its response.

The JSD command queue waits for a matching ACK after physical write/drain. Its default interval is 500 ms, with the initial send plus up to three resends. NACK is exposed as an event and does not immediately remove the queued command.

Explicit protocol, typed events, isolated transport.