@flux-control/effect-modbus-rs 0.8.0 → 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.
- package/README.md +499 -832
- package/dist/index.d.ts +56 -113
- package/dist/index.js +234 -116
- package/dist/src/AsciiTransportService.d.ts +15 -14
- package/dist/src/RtuTransportService.d.ts +15 -14
- package/dist/src/SerialModbusServerService.d.ts +3 -2
- package/dist/src/SerialTransportService.d.ts +8 -2
- package/dist/src/TcpGatewayService.d.ts +2 -1
- package/dist/src/TcpModbusServerService.d.ts +2 -1
- package/dist/src/TcpTransportService.d.ts +6 -5
- package/dist/src/WasmAsciiTransportService.d.ts +13 -7
- package/dist/src/WasmRtuTransportService.d.ts +13 -7
- package/dist/src/WasmSerialModbusServerService.d.ts +4 -2
- package/dist/src/WasmSerialPort.d.ts +6 -4
- package/dist/src/WasmSerialTransportService.d.ts +9 -2
- package/dist/src/WasmTcpServerService.d.ts +2 -1
- package/dist/src/WasmWsTransportService.d.ts +9 -5
- package/dist/src/batching-client.d.ts +61 -28
- package/dist/src/connection.d.ts +6 -2
- package/dist/src/errors.d.ts +11 -12
- package/dist/src/mocks.d.ts +3 -2
- package/dist/src/modbus-client.d.ts +14 -10
- package/dist/src/read-debouncer.d.ts +8 -22
- package/dist/src/register-cache.d.ts +1 -7
- package/dist/src/register-plan.d.ts +2 -12
- package/dist/src/retry.d.ts +1 -0
- package/dist/src/serial-port-path.d.ts +21 -0
- package/dist/src/shared-transport.d.ts +25 -5
- package/dist/src/span-attributes.d.ts +1 -1
- package/dist/src/write-debouncer.d.ts +15 -49
- package/dist/test/native-transport.test.d.ts +1 -0
- package/dist/test/serial-port-path.test.d.ts +1 -0
- package/package.json +20 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,144 +1,86 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* # @flux-control/effect-modbus-rs
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Provides typed Effect services for native and browser Modbus transports and servers.
|
|
5
|
+
* Transport services use `Context.Service` and scoped layers. They open on first
|
|
6
|
+
* client access and close when the provided scope ends.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
+
* Build the package with `bun run build` before using package imports. The build
|
|
9
|
+
* creates `dist/`, which the package export map uses.
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* Native transports: {@link SerialTransportService}, {@link RtuTransportService},
|
|
12
|
+
* {@link AsciiTransportService}, and {@link TcpTransportService}. Browser
|
|
13
|
+
* transports: {@link WasmSerialTransportService}, {@link WasmRtuTransportService},
|
|
14
|
+
* {@link WasmAsciiTransportService}, and {@link WasmWsTransportService}.
|
|
15
|
+
* Call {@link requestSerialPort} from a user-gesture handler to request a Web Serial port.
|
|
13
16
|
*
|
|
14
|
-
*
|
|
17
|
+
* Server layers include {@link serialRtuServerLayer}, {@link serialAsciiServerLayer},
|
|
18
|
+
* {@link tcpServerLayer}, and {@link tcpGatewayLayer}. Browser server layers are
|
|
19
|
+
* experimental upstream surfaces.
|
|
15
20
|
*
|
|
16
|
-
*
|
|
17
|
-
* - {@link WasmRtuTransportService} — Web Serial RTU transport.
|
|
18
|
-
* - {@link WasmAsciiTransportService} — Web Serial ASCII transport.
|
|
19
|
-
* - {@link WasmWsTransportService} — TCP-over-WebSocket transport (Modbus/TCP via a WS gateway).
|
|
20
|
-
* - {@link requestSerialPort} — Requests a Web Serial port handle (user-gesture gated).
|
|
21
|
+
* ## Raw operations and result types
|
|
21
22
|
*
|
|
22
|
-
*
|
|
23
|
+
* `transport.withClient(unitId)` returns a typed client. Register reads return
|
|
24
|
+
* `Uint16Array`; coil and discrete-input reads return `CoilState[]`. Operations
|
|
25
|
+
* fail with a variant of {@link ModbusError}. Use `Effect.catchTags` to handle
|
|
26
|
+
* specific variants. The union has eight variants, including
|
|
27
|
+
* {@link ModbusCircuitOpenError}. The batching declaration error is separate.
|
|
23
28
|
*
|
|
24
|
-
*
|
|
29
|
+
* ## Register batching
|
|
25
30
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* - {@link serialRtuServerLayer} — Serial RTU server.
|
|
31
|
-
* - {@link serialAsciiServerLayer} — Serial ASCII server.
|
|
32
|
-
* - {@link tcpServerLayer} — TCP server.
|
|
33
|
-
* - {@link tcpGatewayLayer} — TCP gateway.
|
|
34
|
-
* - {@link wasmWsServerLayer} — Browser WS-gateway server (experimental upstream surface).
|
|
35
|
-
* - {@link wasmSerialRtuServerLayer} / {@link wasmSerialAsciiServerLayer} — Browser Web Serial servers (experimental).
|
|
36
|
-
*
|
|
37
|
-
* ## Transaction batching
|
|
38
|
-
*
|
|
39
|
-
* A caller that derives each register independently produces one transaction per
|
|
40
|
-
* register, which is the dominant cost on a half-duplex bus. Three pieces bring
|
|
41
|
-
* that count down, and each one is usable without the others.
|
|
42
|
-
*
|
|
43
|
-
* {@link planWrites} and {@link planReads} pack neighbouring addresses into the
|
|
44
|
-
* fewest transactions that cover them. They hold no state and run no I/O:
|
|
31
|
+
* {@link planWrites} and {@link planReads} plan the supplied registers without
|
|
32
|
+
* state or I/O. For example:
|
|
45
33
|
*
|
|
46
34
|
* ```ts
|
|
47
35
|
* planWrites([{ address: 2000, value: 10 }, { address: 2001, value: 20 }]);
|
|
48
|
-
* //
|
|
36
|
+
* // One multiple-register write step for addresses 2000 and 2001.
|
|
49
37
|
* ```
|
|
50
38
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* a
|
|
39
|
+
* {@link createWriteDebouncer} and {@link createReadDebouncer} collect separate
|
|
40
|
+
* calls only when configured with positive windows. Without a window, calls are
|
|
41
|
+
* not debounced. `writeAll` and `readAll` also collect when their windows are
|
|
42
|
+
* positive. Their `Now` variants flush the pending group immediately.
|
|
43
|
+
* Grouping does not make separate application operations atomic. A pending
|
|
44
|
+
* write can be superseded, and the cache can suppress a write based on its
|
|
45
|
+
* recorded value. Therefore, each call is not guaranteed to produce a separate
|
|
46
|
+
* device write. The cache records acknowledged writes from this process; it
|
|
47
|
+
* does not answer reads.
|
|
48
|
+
*
|
|
49
|
+
* `withBatchingClient` combines planning, optional collection, and optional
|
|
50
|
+
* caching. It is separate from `withClient`, which exposes raw Modbus operations.
|
|
51
|
+
* Once a batching client exists for a unit, raw FC06, FC16, and FC23 operations
|
|
52
|
+
* for that unit fail. Raw reads, coil operations, and other operations remain
|
|
53
|
+
* available. A batching client does not extend {@link ModbusOperations}.
|
|
64
54
|
*
|
|
65
55
|
* ```ts
|
|
66
|
-
* const
|
|
67
|
-
* yield*
|
|
56
|
+
* const raw = yield* transport.withClient(3);
|
|
57
|
+
* const registers = yield* raw.readHoldingRegisters({ address: 2000, quantity: 2 });
|
|
58
|
+
* // registers is Uint16Array.
|
|
68
59
|
*
|
|
69
|
-
* const
|
|
70
|
-
* debounce: { writes: { window:
|
|
60
|
+
* const batch = yield* transport.withBatchingClient(3, {
|
|
61
|
+
* debounce: { writes: { window: '250 millis', maxHold: '1 second' } },
|
|
71
62
|
* });
|
|
72
|
-
* yield*
|
|
73
|
-
* yield*
|
|
74
|
-
* ```
|
|
75
|
-
*
|
|
76
|
-
* A {@link BatchingModbusClient} deliberately does not extend
|
|
77
|
-
* {@link ModbusOperations}: a raw write on the same object would go around the
|
|
78
|
-
* cache and around the batch. Once a batching client exists for a unit, raw
|
|
79
|
-
* FC06, FC16, and FC23 operations on that unit fail. The raw client remains
|
|
80
|
-
* available for exact reads, coils, and other non-register-write operations.
|
|
81
|
-
*
|
|
82
|
-
* Nothing is debounced unless `debounce` asks for it, matching the rest of this
|
|
83
|
-
* package. `writeAll` and `readAll` still plan, so a caller that holds a group of
|
|
84
|
-
* registers gets packed transactions with no window at all.
|
|
85
|
-
*
|
|
86
|
-
* ## Errors
|
|
87
|
-
*
|
|
88
|
-
* All Modbus operations fail with a {@link ModbusError} discriminated union.
|
|
89
|
-
* Use `Effect.catchTags` to handle specific variants:
|
|
90
|
-
*
|
|
91
|
-
* ```ts
|
|
92
|
-
* Effect.catchTags(effect, {
|
|
93
|
-
* ModbusTimeoutError: ...,
|
|
94
|
-
* ModbusTransportError: ...,
|
|
95
|
-
* })
|
|
63
|
+
* yield* batch.write({ address: 2000, value: 512 });
|
|
64
|
+
* yield* batch.readAll([0, 1, 32]);
|
|
96
65
|
* ```
|
|
97
66
|
*
|
|
98
|
-
* ##
|
|
67
|
+
* ## Retry and reconnection
|
|
99
68
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* default. Resilience is configured on the **transport**, which owns it for
|
|
103
|
-
* every client derived from it:
|
|
104
|
-
*
|
|
105
|
-
* ```ts
|
|
106
|
-
* TcpTransportService.make({
|
|
107
|
-
* host, port,
|
|
108
|
-
* retry: RetryPolicies.tcp(), // applied to every operation
|
|
109
|
-
* reconnect: {}, // supervised reconnect + circuit breaker
|
|
110
|
-
* })
|
|
111
|
-
* ```
|
|
112
|
-
*
|
|
113
|
-
* Policies are error-aware: transient failures (timeouts, framing errors, a
|
|
114
|
-
* busy device) back off exponentially with jitter (on by default), while
|
|
115
|
-
* deterministic ones (illegal address, invalid argument) fail immediately.
|
|
116
|
-
*
|
|
117
|
-
* Override per client — one bus, several device types — or per operation.
|
|
118
|
-
* Both replace the policy rather than composing with it:
|
|
69
|
+
* Retry and reconnection are opt-in. A transport retry policy applies to its
|
|
70
|
+
* clients. Client and operation overrides replace that policy. For example:
|
|
119
71
|
*
|
|
120
72
|
* ```ts
|
|
73
|
+
* TcpTransportService.make({ host, port, retry: RetryPolicies.tcp(), reconnect: {} });
|
|
121
74
|
* const meter = yield* transport.withClient(1, { retry: RetryPolicies.serial() });
|
|
122
75
|
* yield* meter.withRetry(RetryPolicies.none()).writeSingleCoil({ address: 0, value });
|
|
123
76
|
* ```
|
|
124
77
|
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* {@link
|
|
131
|
-
* read-modify-write driven as a unit — over a `RetryPolicies.none()` client.
|
|
132
|
-
* Note that it **wraps** rather than replaces: unlike the two overrides above,
|
|
133
|
-
* it is piped around an effect the client has already wrapped in its own retry,
|
|
134
|
-
* so over a policied client the two nest and attempt counts multiply.
|
|
135
|
-
*
|
|
136
|
-
* Resilience lives at this layer and only at this layer. `modbus-rs`'s own
|
|
137
|
-
* transport-level `retryAttempts` / `retryDelayMs` / `retryBackoffStrategy` are
|
|
138
|
-
* **not accepted** by any transport constructor here: they retry beneath the
|
|
139
|
-
* Effect boundary where neither the policy, the circuit breaker, nor the logs
|
|
140
|
-
* can see them, and they reconnect inline, racing the supervisor fiber that
|
|
141
|
-
* owns reconnection. See {@link UpstreamRetryOptionKey}.
|
|
78
|
+
* A configured reconnect supervisor owns reconnection for the transport and
|
|
79
|
+
* guards operations while the connection is down. Watch {@link ConnectionState}
|
|
80
|
+
* through `transport.connectionState`. {@link retryModbus} wraps an Effect; use
|
|
81
|
+
* it with a `RetryPolicies.none()` client for a compound operation. It does not
|
|
82
|
+
* replace a client's policy. Upstream transport retry options are excluded;
|
|
83
|
+
* see {@link UpstreamRetryOptionKey}.
|
|
142
84
|
*
|
|
143
85
|
* @module @flux-control/effect-modbus-rs
|
|
144
86
|
*/
|
|
@@ -169,6 +111,7 @@ export { TcpTransportService } from './src/TcpTransportService';
|
|
|
169
111
|
export type { TcpTransportOpenOptions } from './src/TcpTransportService';
|
|
170
112
|
export { RtuTransportService } from './src/RtuTransportService';
|
|
171
113
|
export type { RtuTransportOpenOptions } from './src/RtuTransportService';
|
|
114
|
+
export { MAX_SERIAL_PORT_PATH, resolveSerialPortPath } from './src/serial-port-path';
|
|
172
115
|
export { serialRtuServerLayer, serialAsciiServerLayer } from './src/SerialModbusServerService';
|
|
173
116
|
export { tcpServerLayer } from './src/TcpModbusServerService';
|
|
174
117
|
export { tcpGatewayLayer } from './src/TcpGatewayService';
|