@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
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Coalesces register writes
|
|
3
|
-
*
|
|
4
|
-
* `planWrites` packs the writes a caller holds at one moment. A caller that
|
|
5
|
-
* derives each register independently — one fiber per output, each settling at
|
|
6
|
-
* its own pace — never holds two values at the same moment, so a planner alone
|
|
7
|
-
* never sees a run longer than one. Batching those would need a collection point
|
|
8
|
-
* upstream that the caller does not have.
|
|
9
|
-
*
|
|
10
|
-
* This module is that collection point, and it collects on time rather than on
|
|
11
|
-
* structure. A write is held for `window`, each new arrival restarts the window,
|
|
12
|
-
* and `maxHold` caps the total hold so a register that updates without a pause
|
|
13
|
-
* still reaches the wire.
|
|
14
|
-
*
|
|
15
|
-
* Callers still await their own write. Each caller gets its own `Deferred`,
|
|
16
|
-
* completed with the exit of the flush that carried its value, so a write that
|
|
17
|
-
* fails still fails for the caller that issued it. That keeps "the effect
|
|
18
|
-
* succeeded" meaning "the value reached the device", which is the invariant a
|
|
19
|
-
* caller uses to decide whether it may report an actuation.
|
|
2
|
+
* @fileoverview Coalesces register writes by address and flushes them after a debounce window.
|
|
3
|
+
* New arrivals restart the window; `maxHold` limits the total delay.
|
|
20
4
|
*
|
|
21
5
|
* @module
|
|
22
6
|
*/
|
|
@@ -67,8 +51,8 @@ export interface WriteDebouncer {
|
|
|
67
51
|
/**
|
|
68
52
|
* Holds a write for the window, then issues it with whatever else arrived.
|
|
69
53
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
54
|
+
* Completes with the flush result for its address. A later write can supersede
|
|
55
|
+
* its value, and a downstream cache can suppress the physical write.
|
|
72
56
|
*/
|
|
73
57
|
write(write: RegisterWrite, attributes?: ModbusSpanAttributes): Effect.Effect<void, ModbusError>;
|
|
74
58
|
/**
|
|
@@ -85,8 +69,8 @@ export interface WriteDebouncer {
|
|
|
85
69
|
*
|
|
86
70
|
* A caller that already holds every value does not need a collection point,
|
|
87
71
|
* but it still must not go around the batch: a write held for one of these
|
|
88
|
-
* addresses would otherwise reach the device after the newer value. The
|
|
89
|
-
*
|
|
72
|
+
* addresses would otherwise reach the device after the newer value. The result
|
|
73
|
+
* covers the flush, but separate bus transactions are not atomic.
|
|
90
74
|
*
|
|
91
75
|
* With a window of zero the group is issued at once, so a caller of this
|
|
92
76
|
* method gets packed transactions with no debouncer at all.
|
|
@@ -104,33 +88,6 @@ export interface WriteDebouncer {
|
|
|
104
88
|
/** Addresses currently held. Intended for tests. */
|
|
105
89
|
readonly pending: number;
|
|
106
90
|
}
|
|
107
|
-
/**
|
|
108
|
-
* Creates a write debouncer bound to the current scope.
|
|
109
|
-
*
|
|
110
|
-
* The flush runs in that scope, not in the caller's. A caller interrupted while
|
|
111
|
-
* waiting — an output recomputed before its write landed — must not take the
|
|
112
|
-
* pending batch down with it, and a caller must not have to carry a `Scope` to
|
|
113
|
-
* issue a write.
|
|
114
|
-
*
|
|
115
|
-
* When the scope closes, callers still waiting are interrupted and the batch is
|
|
116
|
-
* discarded. Their writes never reached the device, and reporting success for
|
|
117
|
-
* them would break the invariant the `Deferred` exists to hold.
|
|
118
|
-
*
|
|
119
|
-
* @param options - The window, the ceiling, and the callback that issues a batch.
|
|
120
|
-
* @returns The debouncer.
|
|
121
|
-
*
|
|
122
|
-
* @example
|
|
123
|
-
* const debouncer = yield* createWriteDebouncer({
|
|
124
|
-
* window: '250 millis',
|
|
125
|
-
* maxHold: '1 second',
|
|
126
|
-
* flush: (batch) => issue(batch),
|
|
127
|
-
* });
|
|
128
|
-
* // Two callers that never meet, one transaction:
|
|
129
|
-
* yield* Effect.all([
|
|
130
|
-
* debouncer.write({ address: 2000, value: 10 }),
|
|
131
|
-
* debouncer.write({ address: 2001, value: 20 }),
|
|
132
|
-
* ], { concurrency: 'unbounded' });
|
|
133
|
-
*/
|
|
134
91
|
/**
|
|
135
92
|
* Resolves the window and the hold limit that a write debouncer applies.
|
|
136
93
|
*
|
|
@@ -144,4 +101,13 @@ export declare const resolveWriteHold: (window: Duration.Input, maxHold: Duratio
|
|
|
144
101
|
windowMs: number;
|
|
145
102
|
maxHoldMs: number;
|
|
146
103
|
};
|
|
104
|
+
/**
|
|
105
|
+
* Creates a write debouncer bound to the current scope.
|
|
106
|
+
*
|
|
107
|
+
* Waiting callers do not control the flush fiber. Closing the scope discards
|
|
108
|
+
* pending writes and interrupts their waiters.
|
|
109
|
+
*
|
|
110
|
+
* @param options - The collection window, hold limit, and flush callback.
|
|
111
|
+
* @returns The debouncer, which requires the current scope.
|
|
112
|
+
*/
|
|
147
113
|
export declare const createWriteDebouncer: (options: WriteDebouncerOptions) => Effect.Effect<WriteDebouncer, never, Scope.Scope>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flux-control/effect-modbus-rs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Type-safe Modbus communication via Effect-TS, wrapping the modbus-rs npm bindings.",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"repository": {
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"format:fix": "oxfmt",
|
|
31
31
|
"lint": "oxlint",
|
|
32
32
|
"lint:fix": "oxlint --fix",
|
|
33
|
+
"lint:staged": "lint-staged --config package.json",
|
|
33
34
|
"lock": "bash tools/refresh-lockfile.sh",
|
|
34
35
|
"prepare": "husky",
|
|
35
36
|
"release": "changeset publish",
|
|
@@ -39,22 +40,30 @@
|
|
|
39
40
|
"version": "changeset version"
|
|
40
41
|
},
|
|
41
42
|
"dependencies": {
|
|
42
|
-
"modbus-rs": "0.16.
|
|
43
|
+
"modbus-rs": "0.16.3"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@changesets/cli": "^
|
|
46
|
-
"@effect/language-service": "0.87.
|
|
47
|
-
"@effect/platform-bun": "
|
|
48
|
-
"@oxlint/plugins": "1.
|
|
46
|
+
"@changesets/cli": "^3.0.3",
|
|
47
|
+
"@effect/language-service": "0.87.4",
|
|
48
|
+
"@effect/platform-bun": "4.0.3",
|
|
49
|
+
"@oxlint/plugins": "1.87.0",
|
|
49
50
|
"@types/bun": "latest",
|
|
50
|
-
"effect": "4.0.
|
|
51
|
-
"fallow": "^
|
|
51
|
+
"effect": "4.0.3",
|
|
52
|
+
"fallow": "^3.33.1",
|
|
52
53
|
"husky": "^9.1.7",
|
|
53
|
-
"
|
|
54
|
-
"
|
|
54
|
+
"lint-staged": "^17.6.0",
|
|
55
|
+
"oxfmt": "^0.72.0",
|
|
56
|
+
"oxlint": "1.87.0",
|
|
55
57
|
"typescript": "^7.0.2"
|
|
56
58
|
},
|
|
57
59
|
"peerDependencies": {
|
|
58
|
-
"effect": "^4.0.
|
|
60
|
+
"effect": "^4.0.3"
|
|
61
|
+
},
|
|
62
|
+
"lint-staged": {
|
|
63
|
+
"*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}": [
|
|
64
|
+
"oxlint --fix",
|
|
65
|
+
"oxfmt"
|
|
66
|
+
],
|
|
67
|
+
"*.{json,jsonc,md,mdx,css,scss,html,yaml,yml}": "oxfmt"
|
|
59
68
|
}
|
|
60
69
|
}
|