modbus-rs 0.9.0

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.
Files changed (5) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +239 -0
  3. package/index.d.ts +440 -0
  4. package/index.js +582 -0
  5. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,6 @@
1
+ ## License
2
+
3
+ This crate is dual-licensed under GPLv3 and a commercial license. If you require a commercial license to use this crate in a proprietary project, please contact [ch.raghava44@gmail.com](mailto:ch.raghava44@gmail.com) to purchase a license.
4
+
5
+
6
+ This project is licensed under the **GNU General Public License v3.0 (GPLv3)** — see [GPL v3.0](https://www.gnu.org/licenses/gpl-3.0.html).
package/README.md ADDED
@@ -0,0 +1,239 @@
1
+ # modbus-rs
2
+
3
+ High-performance Modbus TCP/RTU/ASCII client, server, and gateway for Node.js, powered by Rust.
4
+
5
+ ## Features
6
+
7
+ - **Async/Promise-based API** - All operations return Promises
8
+ - **TCP Client** - Full Modbus TCP/IP client implementation
9
+ - **Serial Client** - Modbus RTU and ASCII over serial port
10
+ - **TCP Server** - Build Modbus TCP servers with JavaScript handlers
11
+ - **TCP Gateway** - Route requests to multiple downstream servers based on unit ID
12
+ - **High Performance** - Native Rust core with napi-rs bindings
13
+ - **Type Safe** - Full TypeScript definitions included
14
+ - **Cross Platform** - Pre-built binaries for Linux, macOS, and Windows
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install modbus-rs
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### TCP Client
25
+
26
+ ```javascript
27
+ const { AsyncTcpModbusClient } = require('modbus-rs');
28
+
29
+ async function main() {
30
+ const client = await AsyncTcpModbusClient.connect({
31
+ host: '127.0.0.1',
32
+ port: 502,
33
+ unitId: 1,
34
+ timeoutMs: 5000,
35
+ });
36
+
37
+ try {
38
+ // Read holding registers (FC03)
39
+ const registers = await client.readHoldingRegisters({
40
+ address: 0,
41
+ quantity: 10,
42
+ });
43
+ console.log('Registers:', registers);
44
+
45
+ // Write single register (FC06)
46
+ await client.writeSingleRegister({
47
+ address: 0,
48
+ value: 12345,
49
+ });
50
+ } finally {
51
+ await client.close();
52
+ }
53
+ }
54
+
55
+ main().catch(console.error);
56
+ ```
57
+
58
+ ### Serial RTU Client
59
+
60
+ ```javascript
61
+ const { AsyncSerialModbusClient } = require('modbus-rs');
62
+
63
+ async function main() {
64
+ const client = await AsyncSerialModbusClient.connectRtu({
65
+ portPath: '/dev/ttyUSB0',
66
+ unitId: 1,
67
+ baudRate: 19200,
68
+ dataBits: 8,
69
+ stopBits: 1,
70
+ parity: 'even',
71
+ });
72
+
73
+ try {
74
+ const registers = await client.readHoldingRegisters({
75
+ address: 0,
76
+ quantity: 10,
77
+ });
78
+ console.log('Registers:', registers);
79
+ } finally {
80
+ await client.close();
81
+ }
82
+ }
83
+
84
+ main().catch(console.error);
85
+ ```
86
+
87
+ ### TCP Server
88
+
89
+ ```javascript
90
+ const { AsyncTcpModbusServer } = require('modbus-rs');
91
+
92
+ const holdingRegisters = new Array(1000).fill(0);
93
+
94
+ async function main() {
95
+ const server = await AsyncTcpModbusServer.bind(
96
+ { host: '0.0.0.0', port: 502 },
97
+ {
98
+ onReadHoldingRegisters: (req) => {
99
+ return holdingRegisters.slice(req.address, req.address + req.count);
100
+ },
101
+ onWriteSingleRegister: (req) => {
102
+ holdingRegisters[req.address] = req.value;
103
+ return true;
104
+ },
105
+ }
106
+ );
107
+
108
+ console.log('Server listening on port 502');
109
+
110
+ process.on('SIGINT', async () => {
111
+ await server.shutdown();
112
+ process.exit(0);
113
+ });
114
+ }
115
+
116
+ main().catch(console.error);
117
+ ```
118
+
119
+ ### TCP Gateway
120
+
121
+ ```javascript
122
+ const { AsyncTcpGateway } = require('modbus-rs');
123
+
124
+ async function main() {
125
+ const gateway = await AsyncTcpGateway.bind(
126
+ { host: '0.0.0.0', port: 502 },
127
+ {
128
+ downstreams: [
129
+ { host: '192.168.1.10', port: 502 },
130
+ { host: '192.168.1.11', port: 502 },
131
+ ],
132
+ routes: [
133
+ { unitId: 1, channel: 0 },
134
+ { unitId: 2, channel: 1 },
135
+ ],
136
+ }
137
+ );
138
+
139
+ console.log('Gateway listening on port 502');
140
+
141
+ process.on('SIGINT', async () => {
142
+ await gateway.shutdown();
143
+ process.exit(0);
144
+ });
145
+ }
146
+
147
+ main().catch(console.error);
148
+ ```
149
+
150
+ ## API Reference
151
+
152
+ ### AsyncTcpModbusClient
153
+
154
+ - `connect(opts: TcpClientOptions)` - Connect to a Modbus TCP server
155
+ - `close()` - Close the connection
156
+ - `readCoils(opts)` - FC01: Read Coils
157
+ - `readDiscreteInputs(opts)` - FC02: Read Discrete Inputs
158
+ - `readHoldingRegisters(opts)` - FC03: Read Holding Registers
159
+ - `readInputRegisters(opts)` - FC04: Read Input Registers
160
+ - `writeSingleCoil(opts)` - FC05: Write Single Coil
161
+ - `writeSingleRegister(opts)` - FC06: Write Single Register
162
+ - `writeMultipleCoils(opts)` - FC15: Write Multiple Coils
163
+ - `writeMultipleRegisters(opts)` - FC16: Write Multiple Registers
164
+ - `readWriteMultipleRegisters(opts)` - FC23: Read/Write Multiple Registers
165
+ - `readFileRecord(opts)` - FC20: Read File Record
166
+ - `writeFileRecord(opts)` - FC21: Write File Record
167
+ - `readFifoQueue(opts)` - FC24: Read FIFO Queue
168
+ - `readExceptionStatus()` - FC07: Read Exception Status
169
+ - `diagnostics(opts)` - FC08: Diagnostics
170
+ - `readDeviceIdentification(opts)` - FC43/14: Read Device Identification
171
+
172
+ ### AsyncSerialModbusClient
173
+
174
+ Same methods as `AsyncTcpModbusClient`, with different connection options:
175
+
176
+ - `connectRtu(opts: SerialClientOptions)` - Connect using Modbus RTU
177
+ - `connectAscii(opts: SerialClientOptions)` - Connect using Modbus ASCII
178
+
179
+ ### AsyncTcpModbusServer
180
+
181
+ - `bind(opts, handlers)` - Create and start a TCP server
182
+ - `shutdown()` - Stop the server
183
+
184
+ ### AsyncTcpGateway
185
+
186
+ - `bind(opts, config)` - Create and start a gateway
187
+ - `shutdown()` - Stop the gateway
188
+
189
+ ## Error Handling
190
+
191
+ All errors are thrown as JavaScript Error objects with descriptive messages:
192
+
193
+ ```javascript
194
+ try {
195
+ await client.readHoldingRegisters({ address: 0, count: 10 });
196
+ } catch (err) {
197
+ if (err.message.includes('MODBUS_EXCEPTION')) {
198
+ console.error('Modbus exception:', err.message);
199
+ } else if (err.message.includes('MODBUS_TIMEOUT')) {
200
+ console.error('Request timed out');
201
+ } else {
202
+ console.error('Error:', err.message);
203
+ }
204
+ }
205
+ ```
206
+
207
+ ## Status & known limitations (v0.8)
208
+
209
+ The Node.js bindings are an **early release**. The following work is planned
210
+ for v0.9 and beyond:
211
+
212
+ * **Server JS handler dispatch** — `AsyncTcpModbusServer.bind()` accepts a
213
+ handlers object today, but only the lifecycle (`bind` / `shutdown`) and
214
+ write-request echo are wired up. JS handler callbacks for read requests
215
+ are not yet invoked; the server returns `IllegalFunction` for reads. The
216
+ client API is fully functional — use it against any third-party Modbus
217
+ server today.
218
+ * **`AsyncSerialModbusServer`** — not yet exposed in the JS API. Use the
219
+ Rust `mbus-async` crate directly for serial servers.
220
+ * **`AbortSignal`** support on per-request methods. Use `timeoutMs` at
221
+ connect time as a workaround.
222
+ * A separate **browser/WASM npm package** built on the existing `wasm`
223
+ feature.
224
+
225
+ ## Supported platforms
226
+
227
+ Pre-built binaries are published for:
228
+
229
+ - Linux x64 (glibc), Linux arm64 (glibc)
230
+ - macOS x64, macOS arm64
231
+ - Windows x64 (MSVC)
232
+
233
+ Other targets can be built locally via `cargo build -p mbus-ffi --features nodejs,full`
234
+ followed by `npm run build`.
235
+
236
+ ## License
237
+
238
+ GPL-3.0-only — see [LICENSE](./LICENSE). A commercial license is available
239
+ for proprietary use; contact ch.raghava44@gmail.com.
package/index.d.ts ADDED
@@ -0,0 +1,440 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+ /** Async Modbus Serial client supporting RTU and ASCII transports. */
4
+ export declare class AsyncSerialModbusClient {
5
+ /** Creates and connects a new Serial RTU client. */
6
+ static connectRtu(opts: SerialClientOptions): Promise<AsyncSerialModbusClient>
7
+ /** Creates and connects a new Serial ASCII client. */
8
+ static connectAscii(opts: SerialClientOptions): Promise<AsyncSerialModbusClient>
9
+ /** Sets the per-request timeout in milliseconds. */
10
+ setRequestTimeout(timeoutMs: number): void
11
+ /** Clears the per-request timeout. */
12
+ clearRequestTimeout(): void
13
+ /** Returns whether there are pending requests. */
14
+ get pendingRequests(): boolean
15
+ /** Closes the client connection. */
16
+ close(): Promise<void>
17
+ /** Reconnects the client after a disconnect. */
18
+ reconnect(): Promise<void>
19
+ /** Reads holding registers (FC03). */
20
+ readHoldingRegisters(opts: ReadRegistersOptions): Promise<Array<number>>
21
+ /** Reads input registers (FC04). */
22
+ readInputRegisters(opts: ReadRegistersOptions): Promise<Array<number>>
23
+ /** Writes a single register (FC06). */
24
+ writeSingleRegister(opts: WriteSingleRegisterOptions): Promise<void>
25
+ /** Writes multiple registers (FC16). */
26
+ writeMultipleRegisters(opts: WriteMultipleRegistersOptions): Promise<void>
27
+ /** Reads and writes multiple registers atomically (FC23). */
28
+ readWriteMultipleRegisters(opts: ReadWriteMultipleRegistersOptions): Promise<Array<number>>
29
+ /** Reads coils (FC01). */
30
+ readCoils(opts: ReadBitsOptions): Promise<Array<boolean>>
31
+ /** Writes a single coil (FC05). */
32
+ writeSingleCoil(opts: WriteSingleCoilOptions): Promise<void>
33
+ /** Writes multiple coils (FC15). */
34
+ writeMultipleCoils(opts: WriteMultipleCoilsOptions): Promise<void>
35
+ /** Reads discrete inputs (FC02). */
36
+ readDiscreteInputs(opts: ReadBitsOptions): Promise<Array<boolean>>
37
+ /** Reads FIFO queue (FC24). */
38
+ readFifoQueue(opts: ReadFifoQueueOptions): Promise<FifoQueueResponse>
39
+ /** Reads file records (FC20). */
40
+ readFileRecord(opts: ReadFileRecordOptions): Promise<Array<Array<number>>>
41
+ /** Writes file records (FC21). */
42
+ writeFileRecord(opts: WriteFileRecordOptions): Promise<void>
43
+ /** Reads exception status (FC07). */
44
+ readExceptionStatus(): Promise<number>
45
+ /** Sends a diagnostics request (FC08). */
46
+ diagnostics(opts: DiagnosticsOptions): Promise<DiagnosticsResponse>
47
+ /** Reads device identification (FC43/MEI14). */
48
+ readDeviceIdentification(opts: ReadDeviceIdentificationOptions): Promise<DeviceIdentificationResponse>
49
+ }
50
+
51
+ /**
52
+ * Async Modbus TCP gateway.
53
+ *
54
+ * Forwards incoming Modbus requests to downstream servers based on unit ID routing.
55
+ */
56
+ export declare class AsyncTcpGateway {
57
+ /**
58
+ * Creates and starts a new TCP gateway.
59
+ *
60
+ * @param opts - Gateway bind options.
61
+ * @param config - Gateway configuration including downstreams and routes.
62
+ * @returns A running gateway instance.
63
+ */
64
+ static bind(opts: GatewayBindOptions, config: GatewayConfig): Promise<AsyncTcpGateway>
65
+ /** Stops the gateway. */
66
+ shutdown(): Promise<void>
67
+ }
68
+
69
+ /**
70
+ * Async Modbus TCP client.
71
+ *
72
+ * All methods are async and return Promises. The client must be connected
73
+ * before issuing Modbus requests.
74
+ */
75
+ export declare class AsyncTcpModbusClient {
76
+ /**
77
+ * Creates and connects a new TCP client.
78
+ *
79
+ * @param opts - Connection options including host, port, unitId, and optional timeout.
80
+ * @returns A connected client instance.
81
+ */
82
+ static connect(opts: TcpClientOptions): Promise<AsyncTcpModbusClient>
83
+ /** Sets the per-request timeout in milliseconds. */
84
+ setRequestTimeout(timeoutMs: number): void
85
+ /** Clears the per-request timeout. */
86
+ clearRequestTimeout(): void
87
+ /** Returns whether there are pending requests. */
88
+ get pendingRequests(): boolean
89
+ /** Closes the client connection. */
90
+ close(): Promise<void>
91
+ /** Reconnects the client after a disconnect. */
92
+ reconnect(): Promise<void>
93
+ /** Reads holding registers (FC03). */
94
+ readHoldingRegisters(opts: ReadRegistersOptions): Promise<Array<number>>
95
+ /** Reads input registers (FC04). */
96
+ readInputRegisters(opts: ReadRegistersOptions): Promise<Array<number>>
97
+ /** Writes a single register (FC06). */
98
+ writeSingleRegister(opts: WriteSingleRegisterOptions): Promise<void>
99
+ /** Writes multiple registers (FC16). */
100
+ writeMultipleRegisters(opts: WriteMultipleRegistersOptions): Promise<void>
101
+ /** Reads and writes multiple registers atomically (FC23). */
102
+ readWriteMultipleRegisters(opts: ReadWriteMultipleRegistersOptions): Promise<Array<number>>
103
+ /** Reads coils (FC01). */
104
+ readCoils(opts: ReadBitsOptions): Promise<Array<boolean>>
105
+ /** Writes a single coil (FC05). */
106
+ writeSingleCoil(opts: WriteSingleCoilOptions): Promise<void>
107
+ /** Writes multiple coils (FC15). */
108
+ writeMultipleCoils(opts: WriteMultipleCoilsOptions): Promise<void>
109
+ /** Reads discrete inputs (FC02). */
110
+ readDiscreteInputs(opts: ReadBitsOptions): Promise<Array<boolean>>
111
+ /** Reads FIFO queue (FC24). */
112
+ readFifoQueue(opts: ReadFifoQueueOptions): Promise<FifoQueueResponse>
113
+ /** Reads file records (FC20). */
114
+ readFileRecord(opts: ReadFileRecordOptions): Promise<Array<Array<number>>>
115
+ /** Writes file records (FC21). */
116
+ writeFileRecord(opts: WriteFileRecordOptions): Promise<void>
117
+ /** Reads exception status (FC07). */
118
+ readExceptionStatus(): Promise<number>
119
+ /** Sends a diagnostics request (FC08). */
120
+ diagnostics(opts: DiagnosticsOptions): Promise<DiagnosticsResponse>
121
+ /** Reads device identification (FC43/MEI14). */
122
+ readDeviceIdentification(opts: ReadDeviceIdentificationOptions): Promise<DeviceIdentificationResponse>
123
+ }
124
+
125
+ /**
126
+ * Async Modbus TCP server.
127
+ *
128
+ * Binds to a TCP port and handles incoming Modbus requests using JS callbacks.
129
+ */
130
+ export declare class AsyncTcpModbusServer {
131
+ /**
132
+ * Creates and starts a new TCP server.
133
+ *
134
+ * @param opts - Server bind options.
135
+ * @param handlers - Object containing handler functions for each Modbus operation.
136
+ * @returns A running server instance.
137
+ */
138
+ static bind(opts: TcpServerOptions, handlers: object): AsyncTcpModbusServer
139
+ /** Stops the server. */
140
+ shutdown(): Promise<void>
141
+ }
142
+
143
+ /** Device identification object. */
144
+ export interface DeviceIdentificationObject {
145
+ /** Object ID. */
146
+ id: number
147
+ /** Object value as string. */
148
+ value: string
149
+ }
150
+
151
+ /** Response from device identification request. */
152
+ export interface DeviceIdentificationResponse {
153
+ /** Conformity level. */
154
+ conformityLevel: number
155
+ /** Whether more objects follow. */
156
+ moreFollows: boolean
157
+ /** Next object ID if more follows. */
158
+ nextObjectId: number
159
+ /** Retrieved objects. */
160
+ objects: Array<DeviceIdentificationObject>
161
+ }
162
+
163
+ /** Options for diagnostics request. */
164
+ export interface DiagnosticsOptions {
165
+ /** Diagnostic sub-function code. */
166
+ subFunction: number
167
+ /** Data words for the request. */
168
+ data: Array<number>
169
+ }
170
+
171
+ /** Handler request for diagnostics. */
172
+ export interface DiagnosticsRequest {
173
+ unitId: number
174
+ subFunction: number
175
+ data: Array<number>
176
+ }
177
+
178
+ /** Response from diagnostics request. */
179
+ export interface DiagnosticsResponse {
180
+ /** Echoed sub-function code. */
181
+ subFunction: number
182
+ /** Response data words. */
183
+ data: Array<number>
184
+ }
185
+
186
+ /** Downstream server configuration. */
187
+ export interface DownstreamConfig {
188
+ /** Downstream server host. */
189
+ host: string
190
+ /** Downstream server port. */
191
+ port: number
192
+ }
193
+
194
+ /** Response from reading FIFO queue. */
195
+ export interface FifoQueueResponse {
196
+ /** Number of values in the queue. */
197
+ count: number
198
+ /** Queue values. */
199
+ values: Array<number>
200
+ }
201
+
202
+ /** A single file record read sub-request. */
203
+ export interface FileRecordReadRequest {
204
+ /** File number (1-65535). */
205
+ fileNumber: number
206
+ /** Starting record number. */
207
+ recordNumber: number
208
+ /** Number of records to read. */
209
+ recordLength: number
210
+ }
211
+
212
+ /** A single file record write sub-request. */
213
+ export interface FileRecordWriteRequest {
214
+ /** File number (1-65535). */
215
+ fileNumber: number
216
+ /** Starting record number. */
217
+ recordNumber: number
218
+ /** Record data to write. */
219
+ recordData: Array<number>
220
+ }
221
+
222
+ /** Gateway bind options. */
223
+ export interface GatewayBindOptions {
224
+ /** Bind host address (e.g., "0.0.0.0"). */
225
+ host: string
226
+ /** Bind port. */
227
+ port: number
228
+ }
229
+
230
+ /** Gateway configuration. */
231
+ export interface GatewayConfig {
232
+ /** List of downstream servers. */
233
+ downstreams: Array<DownstreamConfig>
234
+ /** Routing table mapping unit IDs to downstream channels. */
235
+ routes: Array<RouteEntry>
236
+ }
237
+
238
+ /** Options for reading coils or discrete inputs. */
239
+ export interface ReadBitsOptions {
240
+ /** Starting address. */
241
+ address: number
242
+ /** Number of bits to read. */
243
+ quantity: number
244
+ }
245
+
246
+ /** Handler request for reading coils. */
247
+ export interface ReadCoilsRequest {
248
+ unitId: number
249
+ address: number
250
+ quantity: number
251
+ }
252
+
253
+ /** Options for device identification. */
254
+ export interface ReadDeviceIdentificationOptions {
255
+ /** Read device ID code (1=basic, 2=regular, 3=extended, 4=individual). */
256
+ readDeviceIdCode: number
257
+ /** Starting object ID. */
258
+ objectId: number
259
+ }
260
+
261
+ /** Handler request for reading discrete inputs. */
262
+ export interface ReadDiscreteInputsRequest {
263
+ unitId: number
264
+ address: number
265
+ quantity: number
266
+ }
267
+
268
+ /** Options for reading FIFO queue. */
269
+ export interface ReadFifoQueueOptions {
270
+ /** FIFO pointer address. */
271
+ address: number
272
+ }
273
+
274
+ /** Handler request for reading FIFO queue. */
275
+ export interface ReadFifoQueueRequest {
276
+ unitId: number
277
+ address: number
278
+ }
279
+
280
+ /** Options for reading file records. */
281
+ export interface ReadFileRecordOptions {
282
+ /** Array of sub-requests. */
283
+ requests: Array<FileRecordReadRequest>
284
+ }
285
+
286
+ /** Handler request for reading holding registers. */
287
+ export interface ReadHoldingRegistersRequest {
288
+ unitId: number
289
+ address: number
290
+ quantity: number
291
+ }
292
+
293
+ /** Handler request for reading input registers. */
294
+ export interface ReadInputRegistersRequest {
295
+ unitId: number
296
+ address: number
297
+ quantity: number
298
+ }
299
+
300
+ /** Options for reading registers. */
301
+ export interface ReadRegistersOptions {
302
+ /** Starting register address. */
303
+ address: number
304
+ /** Number of registers to read. */
305
+ quantity: number
306
+ }
307
+
308
+ /** Options for read/write multiple registers (FC23). */
309
+ export interface ReadWriteMultipleRegistersOptions {
310
+ /** Starting address for read operation. */
311
+ readAddress: number
312
+ /** Number of registers to read. */
313
+ readQuantity: number
314
+ /** Starting address for write operation. */
315
+ writeAddress: number
316
+ /** Values to write. */
317
+ writeValues: Array<number>
318
+ }
319
+
320
+ /** Route entry mapping unit ID to a downstream channel. */
321
+ export interface RouteEntry {
322
+ /** Modbus unit ID (1-247). */
323
+ unitId: number
324
+ /** Index into the downstreams array. */
325
+ channel: number
326
+ }
327
+
328
+ /** Connection options for the serial client. */
329
+ export interface SerialClientOptions {
330
+ /** Serial port path (e.g., "/dev/ttyUSB0", "COM3"). */
331
+ portPath: string
332
+ /** Baud rate (e.g., 9600, 19200, 38400, 57600, 115200). */
333
+ baudRate: number
334
+ /** Data bits (5, 6, 7, or 8). */
335
+ dataBits?: number
336
+ /** Parity ("none", "even", "odd"). */
337
+ parity?: string
338
+ /** Stop bits (1 or 2). */
339
+ stopBits?: number
340
+ /** Modbus unit ID (1-247). */
341
+ unitId: number
342
+ /** Response timeout in milliseconds. */
343
+ responseTimeoutMs?: number
344
+ /** Per-request timeout in milliseconds. */
345
+ requestTimeoutMs?: number
346
+ }
347
+
348
+ /** Response that may include an exception code. */
349
+ export interface ServerExceptionResponse {
350
+ /** Modbus exception code if this is an error response. */
351
+ exception?: number
352
+ }
353
+
354
+ /** Connection options for the TCP client. */
355
+ export interface TcpClientOptions {
356
+ /** Target host address (IP or hostname). */
357
+ host: string
358
+ /** Target TCP port (typically 502). */
359
+ port: number
360
+ /** Modbus unit ID (1-247). */
361
+ unitId: number
362
+ /** Per-request timeout in milliseconds (optional). */
363
+ timeoutMs?: number
364
+ }
365
+
366
+ /** Server bind options. */
367
+ export interface TcpServerOptions {
368
+ /** Bind host address (e.g., "0.0.0.0"). */
369
+ host: string
370
+ /** Bind port. */
371
+ port: number
372
+ /** Modbus unit ID to respond to. */
373
+ unitId: number
374
+ }
375
+
376
+ /** Options for writing file records. */
377
+ export interface WriteFileRecordOptions {
378
+ /** Array of sub-requests. */
379
+ requests: Array<FileRecordWriteRequest>
380
+ }
381
+
382
+ /** Options for writing multiple coils. */
383
+ export interface WriteMultipleCoilsOptions {
384
+ /** Starting coil address. */
385
+ address: number
386
+ /** Values to write. */
387
+ values: Array<boolean>
388
+ }
389
+
390
+ /** Handler request for writing multiple coils. */
391
+ export interface WriteMultipleCoilsRequest {
392
+ unitId: number
393
+ address: number
394
+ values: Array<boolean>
395
+ }
396
+
397
+ /** Options for writing multiple registers. */
398
+ export interface WriteMultipleRegistersOptions {
399
+ /** Starting register address. */
400
+ address: number
401
+ /** Values to write. */
402
+ values: Array<number>
403
+ }
404
+
405
+ /** Handler request for writing multiple registers. */
406
+ export interface WriteMultipleRegistersRequest {
407
+ unitId: number
408
+ address: number
409
+ values: Array<number>
410
+ }
411
+
412
+ /** Options for writing a single coil. */
413
+ export interface WriteSingleCoilOptions {
414
+ /** Coil address. */
415
+ address: number
416
+ /** Value to write. */
417
+ value: boolean
418
+ }
419
+
420
+ /** Handler request for writing a single coil. */
421
+ export interface WriteSingleCoilRequest {
422
+ unitId: number
423
+ address: number
424
+ value: boolean
425
+ }
426
+
427
+ /** Options for writing a single register. */
428
+ export interface WriteSingleRegisterOptions {
429
+ /** Register address. */
430
+ address: number
431
+ /** Value to write. */
432
+ value: number
433
+ }
434
+
435
+ /** Handler request for writing a single register. */
436
+ export interface WriteSingleRegisterRequest {
437
+ unitId: number
438
+ address: number
439
+ value: number
440
+ }
package/index.js ADDED
@@ -0,0 +1,582 @@
1
+ // prettier-ignore
2
+ /* eslint-disable */
3
+ // @ts-nocheck
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ const { readFileSync } = require('node:fs')
7
+ let nativeBinding = null
8
+ const loadErrors = []
9
+
10
+ const isMusl = () => {
11
+ let musl = false
12
+ if (process.platform === 'linux') {
13
+ musl = isMuslFromFilesystem()
14
+ if (musl === null) {
15
+ musl = isMuslFromReport()
16
+ }
17
+ if (musl === null) {
18
+ musl = isMuslFromChildProcess()
19
+ }
20
+ }
21
+ return musl
22
+ }
23
+
24
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
25
+
26
+ const isMuslFromFilesystem = () => {
27
+ try {
28
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
29
+ } catch {
30
+ return null
31
+ }
32
+ }
33
+
34
+ const isMuslFromReport = () => {
35
+ let report = null
36
+ if (typeof process.report?.getReport === 'function') {
37
+ process.report.excludeNetwork = true
38
+ report = process.report.getReport()
39
+ }
40
+ if (!report) {
41
+ return null
42
+ }
43
+ if (report.header && report.header.glibcVersionRuntime) {
44
+ return false
45
+ }
46
+ if (Array.isArray(report.sharedObjects)) {
47
+ if (report.sharedObjects.some(isFileMusl)) {
48
+ return true
49
+ }
50
+ }
51
+ return false
52
+ }
53
+
54
+ const isMuslFromChildProcess = () => {
55
+ try {
56
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
57
+ } catch (e) {
58
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
59
+ return false
60
+ }
61
+ }
62
+
63
+ function requireNative() {
64
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
65
+ try {
66
+ return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
67
+ } catch (err) {
68
+ loadErrors.push(err)
69
+ }
70
+ } else if (process.platform === 'android') {
71
+ if (process.arch === 'arm64') {
72
+ try {
73
+ return require('./modbus-rs.android-arm64.node')
74
+ } catch (e) {
75
+ loadErrors.push(e)
76
+ }
77
+ try {
78
+ const binding = require('modbus-rs-android-arm64')
79
+ const bindingPackageVersion = require('modbus-rs-android-arm64/package.json').version
80
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
81
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
82
+ }
83
+ return binding
84
+ } catch (e) {
85
+ loadErrors.push(e)
86
+ }
87
+ } else if (process.arch === 'arm') {
88
+ try {
89
+ return require('./modbus-rs.android-arm-eabi.node')
90
+ } catch (e) {
91
+ loadErrors.push(e)
92
+ }
93
+ try {
94
+ const binding = require('modbus-rs-android-arm-eabi')
95
+ const bindingPackageVersion = require('modbus-rs-android-arm-eabi/package.json').version
96
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
97
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
98
+ }
99
+ return binding
100
+ } catch (e) {
101
+ loadErrors.push(e)
102
+ }
103
+ } else {
104
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
105
+ }
106
+ } else if (process.platform === 'win32') {
107
+ if (process.arch === 'x64') {
108
+ if (process.config?.variables?.shlib_suffix === 'dll.a' || process.config?.variables?.node_target_type === 'shared_library') {
109
+ try {
110
+ return require('./modbus-rs.win32-x64-gnu.node')
111
+ } catch (e) {
112
+ loadErrors.push(e)
113
+ }
114
+ try {
115
+ const binding = require('modbus-rs-win32-x64-gnu')
116
+ const bindingPackageVersion = require('modbus-rs-win32-x64-gnu/package.json').version
117
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
118
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
119
+ }
120
+ return binding
121
+ } catch (e) {
122
+ loadErrors.push(e)
123
+ }
124
+ } else {
125
+ try {
126
+ return require('./modbus-rs.win32-x64-msvc.node')
127
+ } catch (e) {
128
+ loadErrors.push(e)
129
+ }
130
+ try {
131
+ const binding = require('modbus-rs-win32-x64-msvc')
132
+ const bindingPackageVersion = require('modbus-rs-win32-x64-msvc/package.json').version
133
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
134
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
135
+ }
136
+ return binding
137
+ } catch (e) {
138
+ loadErrors.push(e)
139
+ }
140
+ }
141
+ } else if (process.arch === 'ia32') {
142
+ try {
143
+ return require('./modbus-rs.win32-ia32-msvc.node')
144
+ } catch (e) {
145
+ loadErrors.push(e)
146
+ }
147
+ try {
148
+ const binding = require('modbus-rs-win32-ia32-msvc')
149
+ const bindingPackageVersion = require('modbus-rs-win32-ia32-msvc/package.json').version
150
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
151
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
152
+ }
153
+ return binding
154
+ } catch (e) {
155
+ loadErrors.push(e)
156
+ }
157
+ } else if (process.arch === 'arm64') {
158
+ try {
159
+ return require('./modbus-rs.win32-arm64-msvc.node')
160
+ } catch (e) {
161
+ loadErrors.push(e)
162
+ }
163
+ try {
164
+ const binding = require('modbus-rs-win32-arm64-msvc')
165
+ const bindingPackageVersion = require('modbus-rs-win32-arm64-msvc/package.json').version
166
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
167
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
168
+ }
169
+ return binding
170
+ } catch (e) {
171
+ loadErrors.push(e)
172
+ }
173
+ } else {
174
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
175
+ }
176
+ } else if (process.platform === 'darwin') {
177
+ try {
178
+ return require('./modbus-rs.darwin-universal.node')
179
+ } catch (e) {
180
+ loadErrors.push(e)
181
+ }
182
+ try {
183
+ const binding = require('modbus-rs-darwin-universal')
184
+ const bindingPackageVersion = require('modbus-rs-darwin-universal/package.json').version
185
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
186
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
187
+ }
188
+ return binding
189
+ } catch (e) {
190
+ loadErrors.push(e)
191
+ }
192
+ if (process.arch === 'x64') {
193
+ try {
194
+ return require('./modbus-rs.darwin-x64.node')
195
+ } catch (e) {
196
+ loadErrors.push(e)
197
+ }
198
+ try {
199
+ const binding = require('modbus-rs-darwin-x64')
200
+ const bindingPackageVersion = require('modbus-rs-darwin-x64/package.json').version
201
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
202
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
203
+ }
204
+ return binding
205
+ } catch (e) {
206
+ loadErrors.push(e)
207
+ }
208
+ } else if (process.arch === 'arm64') {
209
+ try {
210
+ return require('./modbus-rs.darwin-arm64.node')
211
+ } catch (e) {
212
+ loadErrors.push(e)
213
+ }
214
+ try {
215
+ const binding = require('modbus-rs-darwin-arm64')
216
+ const bindingPackageVersion = require('modbus-rs-darwin-arm64/package.json').version
217
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
218
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
219
+ }
220
+ return binding
221
+ } catch (e) {
222
+ loadErrors.push(e)
223
+ }
224
+ } else {
225
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
226
+ }
227
+ } else if (process.platform === 'freebsd') {
228
+ if (process.arch === 'x64') {
229
+ try {
230
+ return require('./modbus-rs.freebsd-x64.node')
231
+ } catch (e) {
232
+ loadErrors.push(e)
233
+ }
234
+ try {
235
+ const binding = require('modbus-rs-freebsd-x64')
236
+ const bindingPackageVersion = require('modbus-rs-freebsd-x64/package.json').version
237
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
239
+ }
240
+ return binding
241
+ } catch (e) {
242
+ loadErrors.push(e)
243
+ }
244
+ } else if (process.arch === 'arm64') {
245
+ try {
246
+ return require('./modbus-rs.freebsd-arm64.node')
247
+ } catch (e) {
248
+ loadErrors.push(e)
249
+ }
250
+ try {
251
+ const binding = require('modbus-rs-freebsd-arm64')
252
+ const bindingPackageVersion = require('modbus-rs-freebsd-arm64/package.json').version
253
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
254
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
255
+ }
256
+ return binding
257
+ } catch (e) {
258
+ loadErrors.push(e)
259
+ }
260
+ } else {
261
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
262
+ }
263
+ } else if (process.platform === 'linux') {
264
+ if (process.arch === 'x64') {
265
+ if (isMusl()) {
266
+ try {
267
+ return require('./modbus-rs.linux-x64-musl.node')
268
+ } catch (e) {
269
+ loadErrors.push(e)
270
+ }
271
+ try {
272
+ const binding = require('modbus-rs-linux-x64-musl')
273
+ const bindingPackageVersion = require('modbus-rs-linux-x64-musl/package.json').version
274
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
275
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
276
+ }
277
+ return binding
278
+ } catch (e) {
279
+ loadErrors.push(e)
280
+ }
281
+ } else {
282
+ try {
283
+ return require('./modbus-rs.linux-x64-gnu.node')
284
+ } catch (e) {
285
+ loadErrors.push(e)
286
+ }
287
+ try {
288
+ const binding = require('modbus-rs-linux-x64-gnu')
289
+ const bindingPackageVersion = require('modbus-rs-linux-x64-gnu/package.json').version
290
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
291
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
292
+ }
293
+ return binding
294
+ } catch (e) {
295
+ loadErrors.push(e)
296
+ }
297
+ }
298
+ } else if (process.arch === 'arm64') {
299
+ if (isMusl()) {
300
+ try {
301
+ return require('./modbus-rs.linux-arm64-musl.node')
302
+ } catch (e) {
303
+ loadErrors.push(e)
304
+ }
305
+ try {
306
+ const binding = require('modbus-rs-linux-arm64-musl')
307
+ const bindingPackageVersion = require('modbus-rs-linux-arm64-musl/package.json').version
308
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
309
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
310
+ }
311
+ return binding
312
+ } catch (e) {
313
+ loadErrors.push(e)
314
+ }
315
+ } else {
316
+ try {
317
+ return require('./modbus-rs.linux-arm64-gnu.node')
318
+ } catch (e) {
319
+ loadErrors.push(e)
320
+ }
321
+ try {
322
+ const binding = require('modbus-rs-linux-arm64-gnu')
323
+ const bindingPackageVersion = require('modbus-rs-linux-arm64-gnu/package.json').version
324
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
325
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
326
+ }
327
+ return binding
328
+ } catch (e) {
329
+ loadErrors.push(e)
330
+ }
331
+ }
332
+ } else if (process.arch === 'arm') {
333
+ if (isMusl()) {
334
+ try {
335
+ return require('./modbus-rs.linux-arm-musleabihf.node')
336
+ } catch (e) {
337
+ loadErrors.push(e)
338
+ }
339
+ try {
340
+ const binding = require('modbus-rs-linux-arm-musleabihf')
341
+ const bindingPackageVersion = require('modbus-rs-linux-arm-musleabihf/package.json').version
342
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
343
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
344
+ }
345
+ return binding
346
+ } catch (e) {
347
+ loadErrors.push(e)
348
+ }
349
+ } else {
350
+ try {
351
+ return require('./modbus-rs.linux-arm-gnueabihf.node')
352
+ } catch (e) {
353
+ loadErrors.push(e)
354
+ }
355
+ try {
356
+ const binding = require('modbus-rs-linux-arm-gnueabihf')
357
+ const bindingPackageVersion = require('modbus-rs-linux-arm-gnueabihf/package.json').version
358
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
359
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
360
+ }
361
+ return binding
362
+ } catch (e) {
363
+ loadErrors.push(e)
364
+ }
365
+ }
366
+ } else if (process.arch === 'loong64') {
367
+ if (isMusl()) {
368
+ try {
369
+ return require('./modbus-rs.linux-loong64-musl.node')
370
+ } catch (e) {
371
+ loadErrors.push(e)
372
+ }
373
+ try {
374
+ const binding = require('modbus-rs-linux-loong64-musl')
375
+ const bindingPackageVersion = require('modbus-rs-linux-loong64-musl/package.json').version
376
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
377
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
378
+ }
379
+ return binding
380
+ } catch (e) {
381
+ loadErrors.push(e)
382
+ }
383
+ } else {
384
+ try {
385
+ return require('./modbus-rs.linux-loong64-gnu.node')
386
+ } catch (e) {
387
+ loadErrors.push(e)
388
+ }
389
+ try {
390
+ const binding = require('modbus-rs-linux-loong64-gnu')
391
+ const bindingPackageVersion = require('modbus-rs-linux-loong64-gnu/package.json').version
392
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
393
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
394
+ }
395
+ return binding
396
+ } catch (e) {
397
+ loadErrors.push(e)
398
+ }
399
+ }
400
+ } else if (process.arch === 'riscv64') {
401
+ if (isMusl()) {
402
+ try {
403
+ return require('./modbus-rs.linux-riscv64-musl.node')
404
+ } catch (e) {
405
+ loadErrors.push(e)
406
+ }
407
+ try {
408
+ const binding = require('modbus-rs-linux-riscv64-musl')
409
+ const bindingPackageVersion = require('modbus-rs-linux-riscv64-musl/package.json').version
410
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
411
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
412
+ }
413
+ return binding
414
+ } catch (e) {
415
+ loadErrors.push(e)
416
+ }
417
+ } else {
418
+ try {
419
+ return require('./modbus-rs.linux-riscv64-gnu.node')
420
+ } catch (e) {
421
+ loadErrors.push(e)
422
+ }
423
+ try {
424
+ const binding = require('modbus-rs-linux-riscv64-gnu')
425
+ const bindingPackageVersion = require('modbus-rs-linux-riscv64-gnu/package.json').version
426
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
427
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
428
+ }
429
+ return binding
430
+ } catch (e) {
431
+ loadErrors.push(e)
432
+ }
433
+ }
434
+ } else if (process.arch === 'ppc64') {
435
+ try {
436
+ return require('./modbus-rs.linux-ppc64-gnu.node')
437
+ } catch (e) {
438
+ loadErrors.push(e)
439
+ }
440
+ try {
441
+ const binding = require('modbus-rs-linux-ppc64-gnu')
442
+ const bindingPackageVersion = require('modbus-rs-linux-ppc64-gnu/package.json').version
443
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
444
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
445
+ }
446
+ return binding
447
+ } catch (e) {
448
+ loadErrors.push(e)
449
+ }
450
+ } else if (process.arch === 's390x') {
451
+ try {
452
+ return require('./modbus-rs.linux-s390x-gnu.node')
453
+ } catch (e) {
454
+ loadErrors.push(e)
455
+ }
456
+ try {
457
+ const binding = require('modbus-rs-linux-s390x-gnu')
458
+ const bindingPackageVersion = require('modbus-rs-linux-s390x-gnu/package.json').version
459
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
460
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
461
+ }
462
+ return binding
463
+ } catch (e) {
464
+ loadErrors.push(e)
465
+ }
466
+ } else {
467
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
468
+ }
469
+ } else if (process.platform === 'openharmony') {
470
+ if (process.arch === 'arm64') {
471
+ try {
472
+ return require('./modbus-rs.openharmony-arm64.node')
473
+ } catch (e) {
474
+ loadErrors.push(e)
475
+ }
476
+ try {
477
+ const binding = require('modbus-rs-openharmony-arm64')
478
+ const bindingPackageVersion = require('modbus-rs-openharmony-arm64/package.json').version
479
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
481
+ }
482
+ return binding
483
+ } catch (e) {
484
+ loadErrors.push(e)
485
+ }
486
+ } else if (process.arch === 'x64') {
487
+ try {
488
+ return require('./modbus-rs.openharmony-x64.node')
489
+ } catch (e) {
490
+ loadErrors.push(e)
491
+ }
492
+ try {
493
+ const binding = require('modbus-rs-openharmony-x64')
494
+ const bindingPackageVersion = require('modbus-rs-openharmony-x64/package.json').version
495
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
497
+ }
498
+ return binding
499
+ } catch (e) {
500
+ loadErrors.push(e)
501
+ }
502
+ } else if (process.arch === 'arm') {
503
+ try {
504
+ return require('./modbus-rs.openharmony-arm.node')
505
+ } catch (e) {
506
+ loadErrors.push(e)
507
+ }
508
+ try {
509
+ const binding = require('modbus-rs-openharmony-arm')
510
+ const bindingPackageVersion = require('modbus-rs-openharmony-arm/package.json').version
511
+ if (bindingPackageVersion !== '0.9.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
512
+ throw new Error(`Native binding package version mismatch, expected 0.9.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
513
+ }
514
+ return binding
515
+ } catch (e) {
516
+ loadErrors.push(e)
517
+ }
518
+ } else {
519
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
520
+ }
521
+ } else {
522
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
523
+ }
524
+ }
525
+
526
+ nativeBinding = requireNative()
527
+
528
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
529
+ let wasiBinding = null
530
+ let wasiBindingError = null
531
+ try {
532
+ wasiBinding = require('./modbus-rs.wasi.cjs')
533
+ nativeBinding = wasiBinding
534
+ } catch (err) {
535
+ if (process.env.NAPI_RS_FORCE_WASI) {
536
+ wasiBindingError = err
537
+ }
538
+ }
539
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
540
+ try {
541
+ wasiBinding = require('modbus-rs-wasm32-wasi')
542
+ nativeBinding = wasiBinding
543
+ } catch (err) {
544
+ if (process.env.NAPI_RS_FORCE_WASI) {
545
+ if (!wasiBindingError) {
546
+ wasiBindingError = err
547
+ } else {
548
+ wasiBindingError.cause = err
549
+ }
550
+ loadErrors.push(err)
551
+ }
552
+ }
553
+ }
554
+ if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) {
555
+ const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error')
556
+ error.cause = wasiBindingError
557
+ throw error
558
+ }
559
+ }
560
+
561
+ if (!nativeBinding) {
562
+ if (loadErrors.length > 0) {
563
+ throw new Error(
564
+ `Cannot find native binding. ` +
565
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
566
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
567
+ {
568
+ cause: loadErrors.reduce((err, cur) => {
569
+ cur.cause = err
570
+ return cur
571
+ }),
572
+ },
573
+ )
574
+ }
575
+ throw new Error(`Failed to load native binding`)
576
+ }
577
+
578
+ module.exports = nativeBinding
579
+ module.exports.AsyncSerialModbusClient = nativeBinding.AsyncSerialModbusClient
580
+ module.exports.AsyncTcpGateway = nativeBinding.AsyncTcpGateway
581
+ module.exports.AsyncTcpModbusClient = nativeBinding.AsyncTcpModbusClient
582
+ module.exports.AsyncTcpModbusServer = nativeBinding.AsyncTcpModbusServer
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "modbus-rs",
3
+ "version": "0.9.0",
4
+ "description": "High-performance Modbus TCP/RTU/ASCII client, server and gateway for Node.js, powered by Rust",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "scripts": {
8
+ "build": "napi build --platform --release --features nodejs,full --js index.js --dts index.d.ts --output-dir . --manifest-path ../Cargo.toml",
9
+ "build:debug": "napi build --platform --features nodejs,full --js index.js --dts index.d.ts --output-dir . --manifest-path ../Cargo.toml",
10
+ "test": "node --test __test__/",
11
+ "prepublishOnly": "napi prepublish -t npm",
12
+ "artifacts": "napi artifacts",
13
+ "universal": "napi universal",
14
+ "version": "napi version"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/Raghava-Ch/modbus-rs.git"
19
+ },
20
+ "keywords": [
21
+ "modbus",
22
+ "modbus-tcp",
23
+ "modbus-rtu",
24
+ "modbus-ascii",
25
+ "scada",
26
+ "plc",
27
+ "industrial",
28
+ "automation",
29
+ "napi-rs",
30
+ "rust"
31
+ ],
32
+ "author": "Raghava-Ch",
33
+ "license": "GPL-3.0-only",
34
+ "bugs": {
35
+ "url": "https://github.com/Raghava-Ch/modbus-rs/issues"
36
+ },
37
+ "homepage": "https://github.com/Raghava-Ch/modbus-rs#readme",
38
+ "engines": {
39
+ "node": ">=20"
40
+ },
41
+ "napi": {
42
+ "binaryName": "modbus-rs",
43
+ "targets": [
44
+ "x86_64-pc-windows-msvc",
45
+ "x86_64-unknown-linux-gnu",
46
+ "x86_64-apple-darwin",
47
+ "aarch64-apple-darwin",
48
+ "aarch64-unknown-linux-gnu"
49
+ ]
50
+ },
51
+ "devDependencies": {
52
+ "@napi-rs/cli": "^3.6.2",
53
+ "@types/node": "^25.6.0",
54
+ "typescript": "^6.0.3"
55
+ },
56
+ "files": [
57
+ "index.js",
58
+ "index.d.ts",
59
+ "README.md",
60
+ "LICENSE"
61
+ ],
62
+ "dependencies": {},
63
+ "optionalDependencies": {
64
+ "modbus-rs-win32-x64-msvc": "0.9.0",
65
+ "modbus-rs-linux-x64-gnu": "0.9.0",
66
+ "modbus-rs-darwin-x64": "0.9.0",
67
+ "modbus-rs-darwin-arm64": "0.9.0",
68
+ "modbus-rs-linux-arm64-gnu": "0.9.0"
69
+ }
70
+ }