njs-modbus 3.0.2 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -113,6 +113,8 @@ declare enum ConformityLevel {
113
113
  REGULAR = 130,
114
114
  EXTENDED = 131
115
115
  }
116
+ /** Shared empty Buffer to avoid repeated allocations. */
117
+ declare const EMPTY_BUFFER: Buffer<ArrayBuffer>;
116
118
  /** Modbus V1.1b3 PDU quantity limits. */
117
119
  declare const LIMITS: {
118
120
  readonly READ_COILS_MIN: 1;
@@ -180,17 +182,16 @@ declare class SerialPhysicalLayer extends AbstractPhysicalLayer {
180
182
  private _serialportOpts;
181
183
  private _path;
182
184
  private _baudRate;
183
- private _openPromise;
184
- private _closePromise;
185
- private _resolveClose;
185
+ private _pendingOpenCbs;
186
+ private _pendingCloseCbs;
186
187
  private _cleanupFns;
187
188
  get state(): PhysicalState;
188
189
  get serialport(): SerialPort | null;
189
190
  get path(): string;
190
191
  get baudRate(): number;
191
192
  constructor(options: SerialPhysicalLayerOptions);
192
- open(): Promise<void>;
193
- close(): Promise<void>;
193
+ open(cb?: (err?: Error | null) => void): void;
194
+ close(cb?: (err?: Error | null) => void): void;
194
195
  }
195
196
 
196
197
  declare class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
@@ -199,15 +200,15 @@ declare class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
199
200
  private _connections;
200
201
  private _socket;
201
202
  private _socketOpts?;
202
- private _openPromise;
203
- private _closePromise;
204
- private _resolveClose;
203
+ private _pendingOpenCbs;
204
+ private _pendingCloseCbs;
205
205
  private _cleanupFns;
206
206
  get state(): PhysicalState;
207
207
  get socket(): Socket | null;
208
208
  constructor(options?: SocketConstructorOpts);
209
- open(options?: SocketConnectOpts): Promise<void>;
210
- close(): Promise<void>;
209
+ open(cb?: (err?: Error | null) => void): void;
210
+ open(options: SocketConnectOpts, cb?: (err?: Error | null) => void): void;
211
+ close(cb?: (err?: Error | null) => void): void;
211
212
  }
212
213
 
213
214
  interface TcpServerPhysicalLayerOptions {
@@ -226,15 +227,15 @@ declare class TcpServerPhysicalLayer extends AbstractPhysicalLayer {
226
227
  private _connections;
227
228
  private _server;
228
229
  private _opts;
229
- private _openPromise;
230
- private _closePromise;
231
- private _resolveClose;
230
+ private _pendingOpenCbs;
231
+ private _pendingCloseCbs;
232
232
  private _cleanupFns;
233
233
  get state(): PhysicalState;
234
234
  get server(): Server | null;
235
235
  constructor(options?: TcpServerPhysicalLayerOptions);
236
- open(options?: ListenOptions): Promise<void>;
237
- close(): Promise<void>;
236
+ open(cb?: (err?: Error | null) => void): void;
237
+ open(options: ListenOptions, cb?: (err?: Error | null) => void): void;
238
+ close(cb?: (err?: Error | null) => void): void;
238
239
  }
239
240
 
240
241
  declare class UdpClientPhysicalLayer extends AbstractPhysicalLayer {
@@ -243,18 +244,18 @@ declare class UdpClientPhysicalLayer extends AbstractPhysicalLayer {
243
244
  private _connections;
244
245
  private _socket;
245
246
  private _socketOpts;
246
- private _openPromise;
247
- private _closePromise;
248
- private _resolveClose;
247
+ private _pendingOpenCbs;
248
+ private _pendingCloseCbs;
249
249
  private _cleanupFns;
250
250
  get state(): PhysicalState;
251
251
  get socket(): Socket$1 | null;
252
252
  constructor(options?: Partial<SocketOptions>);
253
- open(remote?: {
253
+ open(cb?: (err?: Error | null) => void): void;
254
+ open(remote: {
254
255
  port?: number;
255
256
  address?: string;
256
- }): Promise<void>;
257
- close(): Promise<void>;
257
+ }, cb?: (err?: Error | null) => void): void;
258
+ close(cb?: (err?: Error | null) => void): void;
258
259
  }
259
260
 
260
261
  interface UdpServerPhysicalLayerOptions {
@@ -273,9 +274,8 @@ declare class UdpServerPhysicalLayer extends AbstractPhysicalLayer {
273
274
  private _connections;
274
275
  private _socket;
275
276
  private _opts;
276
- private _openPromise;
277
- private _closePromise;
278
- private _resolveClose;
277
+ private _pendingOpenCbs;
278
+ private _pendingCloseCbs;
279
279
  private _cleanupFns;
280
280
  get state(): PhysicalState;
281
281
  get socket(): Socket$1 | null;
@@ -284,13 +284,11 @@ declare class UdpServerPhysicalLayer extends AbstractPhysicalLayer {
284
284
  * Bind the UDP socket and start accepting datagrams.
285
285
  *
286
286
  * @param options Bind options (port, address, etc.). Defaults to port 502.
287
- * @param [idleTimeout=30000] Maximum idle time in milliseconds before an
288
- * inactive client connection is evicted. Pass `0` to disable eviction
289
- * (connections never time out). Disabling eviction may cause unbounded
290
- * memory growth if the server sees many unique clients.
287
+ * @param cb Callback invoked when binding completes or fails.
291
288
  */
292
- open(options?: BindOptions): Promise<void>;
293
- close(): Promise<void>;
289
+ open(cb?: (err?: Error | null) => void): void;
290
+ open(options: BindOptions, cb?: (err?: Error | null) => void): void;
291
+ close(cb?: (err?: Error | null) => void): void;
294
292
  }
295
293
 
296
294
  interface AbstractPhysicalConnectionEvents {
@@ -306,8 +304,8 @@ interface AbstractPhysicalConnectionEvents {
306
304
  declare abstract class AbstractPhysicalConnection extends EventEmitter<AbstractPhysicalConnectionEvents> {
307
305
  abstract readonly state: PhysicalConnectionState;
308
306
  abstract readonly physicalLayer: AbstractPhysicalLayer;
309
- abstract write(data: Buffer): Promise<void>;
310
- abstract destroy(): Promise<void>;
307
+ abstract write(data: Buffer, cb?: (err?: Error | null) => void): void;
308
+ abstract destroy(cb?: (err?: Error | null) => void): void;
311
309
  }
312
310
  interface AbstractPhysicalLayerEvents {
313
311
  open: [];
@@ -331,8 +329,9 @@ declare abstract class AbstractPhysicalLayer extends EventEmitter<AbstractPhysic
331
329
  is(type: 'UDP_CLIENT'): this is UdpClientPhysicalLayer;
332
330
  is(type: 'UDP_SERVER'): this is UdpServerPhysicalLayer;
333
331
  abstract readonly state: PhysicalState;
334
- abstract open(...args: any[]): Promise<void>;
335
- abstract close(): Promise<void>;
332
+ /** Last argument is the callback: `(err?: Error | null) => void`. Callback is optional. */
333
+ abstract open(...args: any[]): void;
334
+ abstract close(cb?: (err?: Error | null) => void): void;
336
335
  }
337
336
 
338
337
  type PhysicalConfig = {
@@ -387,7 +386,7 @@ declare abstract class AbstractApplicationLayer extends EventEmitter<AbstractApp
387
386
  flush(): void;
388
387
  addCustomFunctionCode(cfc: CustomFunctionCode): void;
389
388
  removeCustomFunctionCode(fc: number): void;
390
- abstract encode(data: ApplicationDataUnit): Buffer;
389
+ abstract encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
391
390
  }
392
391
 
393
392
  interface AsciiApplicationLayerOptions {
@@ -409,7 +408,7 @@ declare class AsciiApplicationLayer extends AbstractApplicationLayer {
409
408
  constructor(role: 'MASTER' | 'SLAVE', connection: AbstractPhysicalConnection, options?: AsciiApplicationLayerOptions);
410
409
  private framing;
411
410
  flush(): void;
412
- encode(data: ApplicationDataUnit): Buffer;
411
+ encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
413
412
  }
414
413
 
415
414
  interface RtuApplicationLayerOptions {
@@ -438,14 +437,10 @@ declare class RtuApplicationLayer extends AbstractApplicationLayer {
438
437
  constructor(role: 'MASTER' | 'SLAVE', connection: AbstractPhysicalConnection, options?: RtuApplicationLayerOptions);
439
438
  private clearStateTimers;
440
439
  private flushBuffer;
441
- private deliverFrame;
442
- private tryExtract;
443
- private checkExpected;
444
- private crcMatches;
445
440
  flush(): void;
446
441
  addCustomFunctionCode(cfc: CustomFunctionCode): void;
447
442
  removeCustomFunctionCode(fc: number): void;
448
- encode(data: ApplicationDataUnit): Buffer;
443
+ encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
449
444
  }
450
445
 
451
446
  declare class TcpApplicationLayer extends AbstractApplicationLayer {
@@ -460,35 +455,49 @@ declare class TcpApplicationLayer extends AbstractApplicationLayer {
460
455
  private tryExtract;
461
456
  private processFrame;
462
457
  flush(): void;
463
- encode(data: ApplicationDataUnit): Buffer;
458
+ encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
464
459
  }
465
460
 
461
+ /**
462
+ * RTU timing parameter — accepts either:
463
+ * - a bare `number` in milliseconds (`0` to disable the timer entirely)
464
+ * - `{ unit: 'ms', value: N }` — explicit milliseconds (equivalent to bare `N`)
465
+ * - `{ unit: 'bit', value: N }` — bit-time approximation, derived from `baudRate`
466
+ *
467
+ * The bare-number form is the recommended default; the object form exists for
468
+ * specs that quote bit-time. Pass `0` (or `{ unit: 'ms', value: 0 }`) to disable
469
+ * the timer; either form short-circuits the baudRate-derived fallback.
470
+ */
471
+ type RtuTimingValue = number | {
472
+ unit: 'bit' | 'ms';
473
+ value: number;
474
+ };
466
475
  /** User-facing RTU protocol options (supports both bit and ms units). */
467
476
  interface RtuProtocolOptions {
468
477
  /**
469
478
  * Inter-frame silence (Modbus RTU t3.5).
479
+ *
480
+ * - `20` or `{ unit: 'ms', value: 20 }` — 20 ms
470
481
  * - `{ unit: 'bit', value: 38.5 }` — spec bit-time approximation (default when `baudRate` is provided)
471
- * - `{ unit: 'ms', value: 20 }` explicit milliseconds
482
+ * - `0` disable t3.5 timing (immediate parse on every chunk; useful for
483
+ * lossless transports such as RTU-over-TCP or PTY-based tests where the
484
+ * wire's silence semantics do not apply)
472
485
  *
473
486
  * Per Modbus V1.02 §2.5.1.1, at baud rates > 19200 a fixed 1.75 ms is used
474
487
  * regardless of the bit value.
475
488
  */
476
- intervalBetweenFrames?: {
477
- unit: 'bit' | 'ms';
478
- value: number;
479
- };
489
+ intervalBetweenFrames?: RtuTimingValue;
480
490
  /**
481
491
  * Inter-character timeout (Modbus RTU t1.5). Opt-in; **disabled** by default.
492
+ *
493
+ * - `1` or `{ unit: 'ms', value: 1 }` — 1 ms
482
494
  * - `{ unit: 'bit', value: 21 }` — bit-time approximation (~1.5 char times)
483
- * - `{ unit: 'ms', value: 1 }` — explicit milliseconds
495
+ * - `0` — disable explicitly
484
496
  *
485
497
  * Per Modbus V1.02 §2.5.1.1, at baud rates > 19200 a fixed 0.75 ms is used
486
498
  * regardless of the bit value.
487
499
  */
488
- interCharTimeout?: {
489
- unit: 'bit' | 'ms';
490
- value: number;
491
- };
500
+ interCharTimeout?: RtuTimingValue;
492
501
  /**
493
502
  * Buffer pool size per connection (bytes). Defaults to `MAX_FRAME_LENGTH * 2`
494
503
  * (512 bytes). Increase this if you expect frames larger than 256 bytes or
@@ -532,7 +541,15 @@ declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions>
532
541
  private _protocol;
533
542
  private _appLayer?;
534
543
  private _customFunctionCodes;
535
- private _queue;
544
+ private _queueUnits;
545
+ private _queueFcs;
546
+ private _queueDatas;
547
+ private _queueTimeouts;
548
+ private _queueBroadcasts;
549
+ private _queueResolves;
550
+ private _queueRejects;
551
+ private _queueHead;
552
+ private _queueLen;
536
553
  private _draining;
537
554
  private _nextTid;
538
555
  private _cleanupFns;
@@ -543,6 +560,7 @@ declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions>
543
560
  private _createAppLayer;
544
561
  private send;
545
562
  private _drain;
563
+ private _processNext;
546
564
  private _exchange;
547
565
  private writeFC1Or2;
548
566
  writeFC1: this['readCoils'];
@@ -601,7 +619,6 @@ declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions>
601
619
  removeCustomFunctionCode(fc: number): void;
602
620
  sendCustomFC(unit: 0, fc: number, data: Buffer | number[], timeout?: number): Promise<void>;
603
621
  sendCustomFC(unit: number, fc: number, data: Buffer | number[], timeout?: number): Promise<Buffer>;
604
- private _clean;
605
622
  /**
606
623
  * Open the underlying physical layer and begin accepting connections.
607
624
  *
@@ -626,17 +643,17 @@ declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions>
626
643
  type Frame = ApplicationDataUnit & {
627
644
  buffer: Buffer;
628
645
  };
629
- type PreCheck = (frame: Frame) => boolean | number | undefined;
630
646
  type Callback = (error: Error | null, frame?: Frame) => void;
631
647
  declare class MasterSession {
632
648
  private _waiters;
633
- start(key: string | number, preCheck: PreCheck[], callback: Callback): void;
649
+ /** Register a callback for `key`. No timer timeout is managed by the caller. */
650
+ start(key: string | number, callback: Callback): void;
651
+ /** Cancel a pending waiter without firing its callback. */
634
652
  stop(key: string | number): void;
635
653
  stopAll(error: Error): void;
636
654
  has(key: string | number): boolean;
637
655
  handleFrame(frame: Frame): void;
638
656
  handleError(error: Error): void;
639
- private runPreChecks;
640
657
  }
641
658
 
642
659
  interface ModbusSlaveModel {
@@ -727,6 +744,7 @@ declare class ModbusSlave<T extends ModbusSlaveOptions = ModbusSlaveOptions> ext
727
744
  private _intercept;
728
745
  private _withAddressLock;
729
746
  private _handleFC;
747
+ private _handleCustomFC;
730
748
  add(model: ModbusSlaveModel): void;
731
749
  remove(unit: number): void;
732
750
  addCustomFunctionCode(cfc: CustomFunctionCode): void;
@@ -752,5 +770,5 @@ declare class ModbusSlave<T extends ModbusSlaveOptions = ModbusSlaveOptions> ext
752
770
  close(): Promise<void>;
753
771
  }
754
772
 
755
- export { AbstractApplicationLayer, AbstractPhysicalConnection, AbstractPhysicalLayer, AsciiApplicationLayer, COIL_OFF, COIL_ON, ConformityLevel, EXCEPTION_OFFSET, ErrorCode, FunctionCode, LIMITS, MEI_READ_DEVICE_ID, MasterSession, ModbusError, ModbusMaster, ModbusSlave, PhysicalConnectionState, PhysicalState, ReadDeviceIDCode, RtuApplicationLayer, SerialPhysicalLayer, TcpApplicationLayer, TcpClientPhysicalLayer, TcpServerPhysicalLayer, UdpClientPhysicalLayer, UdpServerPhysicalLayer, createPhysicalLayer, getCodeByError, getErrorByCode };
773
+ export { AbstractApplicationLayer, AbstractPhysicalConnection, AbstractPhysicalLayer, AsciiApplicationLayer, COIL_OFF, COIL_ON, ConformityLevel, EMPTY_BUFFER, EXCEPTION_OFFSET, ErrorCode, FunctionCode, LIMITS, MEI_READ_DEVICE_ID, MasterSession, ModbusError, ModbusMaster, ModbusSlave, PhysicalConnectionState, PhysicalState, ReadDeviceIDCode, RtuApplicationLayer, SerialPhysicalLayer, TcpApplicationLayer, TcpClientPhysicalLayer, TcpServerPhysicalLayer, UdpClientPhysicalLayer, UdpServerPhysicalLayer, createPhysicalLayer, getCodeByError, getErrorByCode };
756
774
  export type { AbstractPhysicalLayerEvents, ApplicationDataUnit, AsciiApplicationLayerOptions, Callback$1 as Callback, CustomFunctionCode, DeviceIdentification, MaybeAsyncFunction, ModbusMasterOptions, ModbusSlaveModel, ModbusSlaveOptions, OpenArgs, PhysicalConfig, RtuApplicationLayerOptions, ServerId, TcpServerPhysicalLayerOptions, UdpServerPhysicalLayerOptions };