modbus-rs-wasm 0.14.1 → 0.15.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.
- package/README.md +131 -62
- package/dist/bundler/modbus-rs.d.ts +271 -681
- package/dist/bundler/modbus-rs.js +1 -1
- package/dist/bundler/modbus-rs_bg.js +527 -1189
- package/dist/bundler/modbus-rs_bg.wasm +0 -0
- package/dist/bundler/modbus-rs_bg.wasm.d.ts +62 -119
- package/package.json +15 -4
- package/dist/web/modbus-rs.d.ts +0 -875
- package/dist/web/modbus-rs.js +0 -2142
- package/dist/web/modbus-rs_bg.wasm +0 -0
- package/dist/web/modbus-rs_bg.wasm.d.ts +0 -140
package/README.md
CHANGED
|
@@ -12,13 +12,13 @@ npm install modbus-rs-wasm
|
|
|
12
12
|
|
|
13
13
|
## Integration & Frameworks (Vite, Svelte, React, etc.)
|
|
14
14
|
|
|
15
|
-
No custom resolver aliases
|
|
15
|
+
No custom resolver aliases are required. Standard package entry points are resolved automatically based on your builder/bundler targets.
|
|
16
16
|
|
|
17
17
|
### Web (Direct / HTML / Vanilla JS)
|
|
18
|
-
When loading the package in browser environments without a bundler, import the web entry point and await the initialization promise:
|
|
18
|
+
When loading the package in browser environments without a bundler (e.g. from CDNs like unpkg or jsDelivr), import the web entry point and await the initialization promise:
|
|
19
19
|
|
|
20
20
|
```javascript
|
|
21
|
-
import init, { WasmTcpTransport } from 'modbus-rs-wasm/
|
|
21
|
+
import init, { WasmTcpTransport } from 'modbus-rs-wasm/web';
|
|
22
22
|
|
|
23
23
|
await init();
|
|
24
24
|
const transport = new WasmTcpTransport('ws://localhost:8502', {
|
|
@@ -29,27 +29,87 @@ const transport = new WasmTcpTransport('ws://localhost:8502', {
|
|
|
29
29
|
const client = transport.create_client({ unitId: 1 });
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
### Bundlers & Frameworks
|
|
33
|
-
|
|
32
|
+
### Bundlers & Modern Frameworks
|
|
33
|
+
|
|
34
|
+
When using modern bundlers (Vite, Webpack, Next.js, etc.), the root import maps to the bundler target where WebAssembly is loaded automatically:
|
|
34
35
|
|
|
35
36
|
```javascript
|
|
36
37
|
import { WasmTcpTransport } from 'modbus-rs-wasm';
|
|
37
38
|
```
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
Because WASM is an asynchronous module dependency, you must configure your bundler to support WASM loader options:
|
|
41
|
+
|
|
42
|
+
#### 1. Vite (React, Svelte, Vue, SolidJS, etc. via Vite)
|
|
43
|
+
Vite requires helper plugins to support WebAssembly. Install `vite-plugin-wasm` and `vite-plugin-top-level-await`:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install -D vite-plugin-wasm vite-plugin-top-level-await
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
In your `vite.config.ts`, register the plugins and **exclude** `modbus-rs-wasm` from dependency pre-bundling (to prevent Esbuild from trying to optimize the WASM module):
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { defineConfig } from 'vite';
|
|
53
|
+
import wasm from 'vite-plugin-wasm';
|
|
54
|
+
import topLevelAwait from 'vite-plugin-top-level-await';
|
|
55
|
+
|
|
56
|
+
export default defineConfig({
|
|
57
|
+
plugins: [wasm(), topLevelAwait()],
|
|
58
|
+
optimizeDeps: {
|
|
59
|
+
exclude: ['modbus-rs-wasm']
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### 2. Webpack 5 (React, Angular, or custom Webpack setups)
|
|
65
|
+
Webpack 5 supports WebAssembly natively but it is disabled by default. You need to enable the `asyncWebAssembly` experiment in your `webpack.config.js`:
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
module.exports = {
|
|
69
|
+
// ...
|
|
70
|
+
experiments: {
|
|
71
|
+
asyncWebAssembly: true,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### 3. Next.js (Webpack mode)
|
|
77
|
+
Configure `next.config.js` to enable WebAssembly support inside Next.js's internal Webpack runner:
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
/** @type {import('next').NextConfig} */
|
|
81
|
+
const nextConfig = {
|
|
82
|
+
webpack(config) {
|
|
83
|
+
config.experiments = {
|
|
84
|
+
...config.experiments,
|
|
85
|
+
asyncWebAssembly: true,
|
|
86
|
+
};
|
|
87
|
+
return config;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
module.exports = nextConfig;
|
|
92
|
+
```
|
|
39
93
|
|
|
40
94
|
## Quick Start
|
|
41
95
|
|
|
42
96
|
### Examples
|
|
43
97
|
Ready-to-run HTML examples demonstrating both Modbus client and server functionality in the browser:
|
|
44
98
|
|
|
45
|
-
- **[wasm_client/network_smoke.html](
|
|
46
|
-
- **[wasm_client/serial_smoke.html](
|
|
47
|
-
- **[wasm_server/network_smoke.html](
|
|
48
|
-
- **[wasm_server/serial_smoke.html](
|
|
99
|
+
- **[wasm_client/network_smoke.html](https://github.com/Raghava-Ch/modbus-rs/blob/main/mbus-ffi/wasm/examples/wasm_client/network_smoke.html)**: WebSocket Modbus TCP client example.
|
|
100
|
+
- **[wasm_client/serial_smoke.html](https://github.com/Raghava-Ch/modbus-rs/blob/main/mbus-ffi/wasm/examples/wasm_client/serial_smoke.html)**: Web Serial Modbus RTU client example.
|
|
101
|
+
- **[wasm_server/network_smoke.html](https://github.com/Raghava-Ch/modbus-rs/blob/main/mbus-ffi/wasm/examples/wasm_server/network_smoke.html)**: WebSocket Modbus TCP server example.
|
|
102
|
+
- **[wasm_server/serial_smoke.html](https://github.com/Raghava-Ch/modbus-rs/blob/main/mbus-ffi/wasm/examples/wasm_server/serial_smoke.html)**: Web Serial Modbus RTU server example.
|
|
103
|
+
- **[Demo Application](https://modbus-lab.vercel.app)**: Live web application demonstrating modbus-rs-wasm in action. [modbus-lab.vercel.app](https://modbus-lab.vercel.app)
|
|
104
|
+
- **[Real-World Example Source Code](https://github.com/Raghava-Ch/modbus-lab)**: Repository containing the source code for the demo web client and Tauri-based desktop client/server simulators.
|
|
49
105
|
|
|
50
106
|
To run the examples locally:
|
|
51
107
|
```bash
|
|
52
|
-
|
|
108
|
+
# clone the repo
|
|
109
|
+
cd modbus-rs/mbus-ffi/wasm
|
|
110
|
+
npx serve ./
|
|
111
|
+
# Navigate to example folder with chromium based web browser run the examples.
|
|
112
|
+
# you can also use the tauri desktop client and server simulator.
|
|
53
113
|
```
|
|
54
114
|
|
|
55
115
|
### Modbus RTU via Web Serial
|
|
@@ -76,16 +136,15 @@ document.getElementById('connect-btn').addEventListener('click', async () => {
|
|
|
76
136
|
stopBits: 1,
|
|
77
137
|
parity: 'even',
|
|
78
138
|
responseTimeoutMs: 1000,
|
|
79
|
-
retryAttempts: 3
|
|
80
|
-
tickIntervalMs: 20
|
|
139
|
+
retryAttempts: 3
|
|
81
140
|
});
|
|
82
141
|
|
|
83
142
|
// 3. Spawn a client for a specific slave (Unit ID)
|
|
84
|
-
const client = transport.
|
|
143
|
+
const client = transport.createClient({ unitId: 10 });
|
|
85
144
|
|
|
86
145
|
// 4. Read coils
|
|
87
|
-
const coils = await client.
|
|
88
|
-
console.log('Coils:', coils); //
|
|
146
|
+
const coils = await client.readCoils({ address: 0, quantity: 8 });
|
|
147
|
+
console.log('Coils:', coils); // boolean[]
|
|
89
148
|
|
|
90
149
|
} catch (err) {
|
|
91
150
|
console.error('Serial error:', err);
|
|
@@ -101,18 +160,17 @@ import { WasmTcpTransport } from 'modbus-rs-wasm';
|
|
|
101
160
|
|
|
102
161
|
async function readRegisters() {
|
|
103
162
|
// 1. Connect to a WebSocket proxy that forwards to a Modbus TCP device
|
|
104
|
-
const transport =
|
|
163
|
+
const transport = await WasmTcpTransport.connect('ws://localhost:8502', {
|
|
105
164
|
responseTimeoutMs: 5000,
|
|
106
|
-
retryAttempts: 3
|
|
107
|
-
tickIntervalMs: 20
|
|
165
|
+
retryAttempts: 3
|
|
108
166
|
});
|
|
109
167
|
|
|
110
168
|
// 2. Spawn a client attached to Unit ID 1
|
|
111
|
-
const client = transport.
|
|
169
|
+
const client = transport.createClient({ unitId: 1 });
|
|
112
170
|
|
|
113
171
|
try {
|
|
114
172
|
// 3. Read 10 holding registers starting at address 0
|
|
115
|
-
const registers = await client.
|
|
173
|
+
const registers = await client.readHoldingRegisters({ address: 0, quantity: 10 });
|
|
116
174
|
console.log('Holding registers:', registers); // Uint16Array
|
|
117
175
|
} catch (error) {
|
|
118
176
|
console.error('Failed to read registers:', error);
|
|
@@ -122,36 +180,40 @@ async function readRegisters() {
|
|
|
122
180
|
|
|
123
181
|
### Modbus server demo with modbus-rs-wasm
|
|
124
182
|
|
|
125
|
-
The `modbus-rs-wasm` package also provides building blocks for server simulation inside the browser. You can
|
|
183
|
+
The `modbus-rs-wasm` package also provides building blocks for server simulation inside the browser. You can bind a `WasmTcpServer` or `WasmSerialServer` by providing configurations and an object implementing `ServerHandlers` callback methods.
|
|
126
184
|
|
|
127
185
|
Here is a quick example of setting up a simulated server via a WebSocket TCP gateway:
|
|
128
186
|
|
|
129
187
|
```javascript
|
|
130
|
-
import {
|
|
188
|
+
import { WasmTcpServer } from 'modbus-rs-wasm';
|
|
131
189
|
|
|
132
190
|
async function simulateServer() {
|
|
133
|
-
// 1.
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
191
|
+
// 1. Define the request handlers
|
|
192
|
+
const handlers = {
|
|
193
|
+
onReadHoldingRegisters: async (request) => {
|
|
194
|
+
console.log("Received Modbus request:", request);
|
|
195
|
+
|
|
196
|
+
// Callbacks can return values synchronously or as Promises
|
|
197
|
+
return [100, 200, 300];
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// 2. Bind the server
|
|
202
|
+
const server = await WasmTcpServer.bind(
|
|
203
|
+
{
|
|
204
|
+
wsUrl: "ws://localhost:8080",
|
|
205
|
+
unitId: 1
|
|
206
|
+
},
|
|
207
|
+
handlers
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
// 3. Start the event loop (runs asynchronously in background)
|
|
211
|
+
server.serve().catch(err => {
|
|
212
|
+
console.error("Server crashed:", err);
|
|
147
213
|
});
|
|
148
|
-
|
|
149
|
-
// 3. Start the server
|
|
150
|
-
server.start();
|
|
151
214
|
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
console.log("Server status:", server.status_snapshot());
|
|
215
|
+
// To stop the server later:
|
|
216
|
+
// await server.shutdown();
|
|
155
217
|
}
|
|
156
218
|
```
|
|
157
219
|
|
|
@@ -160,34 +222,41 @@ async function simulateServer() {
|
|
|
160
222
|
You can also create a simulated serial server (RTU or ASCII) and attach a browser `SerialPort` to it using the Web Serial API:
|
|
161
223
|
|
|
162
224
|
```javascript
|
|
163
|
-
import {
|
|
225
|
+
import { WasmSerialServer } from 'modbus-rs-wasm';
|
|
164
226
|
|
|
165
227
|
async function simulateSerialServer() {
|
|
166
228
|
// 1. Request a serial port from the user (requires user gesture)
|
|
167
229
|
const port = await navigator.serial.requestPort();
|
|
168
230
|
|
|
169
|
-
// 2.
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
231
|
+
// 2. Define the request handlers
|
|
232
|
+
const handlers = {
|
|
233
|
+
onReadHoldingRegisters: (request) => {
|
|
234
|
+
console.log("Received Modbus request via Serial:", request);
|
|
235
|
+
return [100, 200, 300];
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// 3. Bind the server for RTU mode
|
|
240
|
+
const server = await WasmSerialServer.bindRtu(
|
|
241
|
+
{
|
|
242
|
+
serialPort: port,
|
|
243
|
+
unitId: 1,
|
|
244
|
+
baudRate: 19200
|
|
245
|
+
},
|
|
246
|
+
handlers
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
// 4. Start the event loop
|
|
250
|
+
server.serve().catch(err => {
|
|
251
|
+
console.error("Serial Server crashed:", err);
|
|
179
252
|
});
|
|
180
|
-
|
|
181
|
-
// 4. Attach the browser serial port
|
|
182
|
-
server.attach_serial_port(port);
|
|
183
|
-
|
|
184
|
-
// 5. Start the server
|
|
185
|
-
server.start();
|
|
186
|
-
|
|
187
|
-
console.log("Serial Server running:", server.is_running());
|
|
188
253
|
}
|
|
189
254
|
```
|
|
190
255
|
|
|
256
|
+
## Migration Guide
|
|
257
|
+
|
|
258
|
+
Detailed step-by-step migration guides are available in the [Migration Guides](https://github.com/Raghava-Ch/modbus-rs/tree/main/documentation/migrations) directory.
|
|
259
|
+
|
|
191
260
|
## License
|
|
192
261
|
|
|
193
262
|
GPL-3.0-only — see [LICENSE](./LICENSE). A commercial license is available for proprietary use.
|