@flux-control/effect-modbus-rs 0.8.0 → 0.8.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.
Files changed (33) hide show
  1. package/README.md +498 -831
  2. package/dist/index.d.ts +56 -113
  3. package/dist/index.js +234 -116
  4. package/dist/src/AsciiTransportService.d.ts +15 -14
  5. package/dist/src/RtuTransportService.d.ts +15 -14
  6. package/dist/src/SerialModbusServerService.d.ts +3 -2
  7. package/dist/src/SerialTransportService.d.ts +8 -2
  8. package/dist/src/TcpGatewayService.d.ts +2 -1
  9. package/dist/src/TcpModbusServerService.d.ts +2 -1
  10. package/dist/src/TcpTransportService.d.ts +6 -5
  11. package/dist/src/WasmAsciiTransportService.d.ts +13 -7
  12. package/dist/src/WasmRtuTransportService.d.ts +13 -7
  13. package/dist/src/WasmSerialModbusServerService.d.ts +4 -2
  14. package/dist/src/WasmSerialPort.d.ts +6 -4
  15. package/dist/src/WasmSerialTransportService.d.ts +9 -2
  16. package/dist/src/WasmTcpServerService.d.ts +2 -1
  17. package/dist/src/WasmWsTransportService.d.ts +9 -5
  18. package/dist/src/batching-client.d.ts +61 -28
  19. package/dist/src/connection.d.ts +6 -2
  20. package/dist/src/errors.d.ts +11 -12
  21. package/dist/src/mocks.d.ts +3 -2
  22. package/dist/src/modbus-client.d.ts +14 -10
  23. package/dist/src/read-debouncer.d.ts +8 -22
  24. package/dist/src/register-cache.d.ts +1 -7
  25. package/dist/src/register-plan.d.ts +2 -12
  26. package/dist/src/retry.d.ts +1 -0
  27. package/dist/src/serial-port-path.d.ts +21 -0
  28. package/dist/src/shared-transport.d.ts +25 -5
  29. package/dist/src/span-attributes.d.ts +1 -1
  30. package/dist/src/write-debouncer.d.ts +15 -49
  31. package/dist/test/native-transport.test.d.ts +1 -0
  32. package/dist/test/serial-port-path.test.d.ts +1 -0
  33. package/package.json +2 -2
@@ -1,4 +1,5 @@
1
- import { Context, Layer } from 'effect';
1
+ /** Provides scoped ASCII Modbus transport layers and an in-memory mock layer. */
2
+ import { Context, Effect, Layer } from 'effect';
2
3
  import type { AsciiTransportOptions } from 'modbus-rs';
3
4
  import { type MockFaultOptions, type SlaveDeviceDefinitions } from './mocks';
4
5
  import type { TransportResilienceOptions, WithoutUpstreamRetry, TransportServiceApi } from './shared-transport';
@@ -15,7 +16,7 @@ declare const AsciiTransportService_base: Context.ServiceClass<AsciiTransportSer
15
16
  *
16
17
  * The transport connection is opened lazily on the first call to
17
18
  * `withClient(unitId)` and automatically closed when the consuming
18
- * {@link Effect.Scope | Scope} finalizes.
19
+ * scope finalizes.
19
20
  *
20
21
  * Clients are created per `unitId` via
21
22
  * {@link AsyncAsciiTransport.createClient} and cached, so repeated
@@ -30,7 +31,7 @@ export declare class AsciiTransportService extends AsciiTransportService_base {
30
31
  * Scoped constructor effect for the service. v4 does not auto-generate a
31
32
  * layer from this, so {@link AsciiTransportService.make} builds one explicitly.
32
33
  */
33
- static readonly makeScoped: (options: AsciiTransportOpenOptions & TransportResilienceOptions) => import("effect/Effect").Effect<{
34
+ static readonly makeScoped: (options: AsciiTransportOpenOptions & TransportResilienceOptions) => Effect.Effect<{
34
35
  connectionState: import("effect/SubscriptionRef").SubscriptionRef<{
35
36
  readonly _tag: "Connected";
36
37
  } | {
@@ -44,34 +45,34 @@ export declare class AsciiTransportService extends AsciiTransportService_base {
44
45
  }>;
45
46
  withClient: (unitId: number, clientOptions?: {
46
47
  readonly retry?: import("./retry").ModbusRetryPolicy;
47
- } | undefined) => import("effect/Effect").Effect<import("./modbus-client").EffectModbusClient, import("./errors").ModbusError, never>;
48
- setRequestTimeout: (timeoutMs: number) => import("effect/Effect").Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
49
- clearRequestTimeout: () => import("effect/Effect").Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
50
- reconnect: () => import("effect/Effect").Effect<undefined, import("./errors").ModbusError, never>;
51
- close: (scope: import("effect/Scope").Closeable) => import("effect/Effect").Effect<void, import("./errors").ModbusError, never>;
48
+ } | undefined) => Effect.Effect<import("./modbus-client").EffectModbusClient, import("./errors").ModbusError, never>;
49
+ setRequestTimeout: (timeoutMs: number) => Effect.Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
50
+ clearRequestTimeout: () => Effect.Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
51
+ reconnect: () => Effect.Effect<undefined, import("./errors").ModbusError, never>;
52
+ close: (scope: import("effect/Scope").Closeable) => Effect.Effect<void, import("./errors").ModbusError, never>;
52
53
  withBatchingClient: (unitId: number, options?: import("./batching-client").BatchingClientOptions & {
53
54
  readonly retry?: import("./retry").ModbusRetryPolicy;
54
- }) => import("effect/Effect").Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError | import("./errors").ModbusUnitAlreadyDeclaredError>;
55
- batchingClient: (unitId: number) => import("effect/Effect").Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError>;
55
+ }) => Effect.Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError | import("./errors").ModbusUnitAlreadyDeclaredError>;
56
+ batchingClient: (unitId: number) => Effect.Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError>;
56
57
  readonly touchedUnits: Set<number>;
57
58
  hasPendingRequests: () => boolean;
58
59
  }, never, import("effect/Scope").Scope>;
59
60
  /**
60
61
  * Creates a {@link Layer} providing a live {@link AsciiTransportService}.
61
62
  *
62
- * @param options - Connection and resilience options for the transport.
63
+ * @param options - Serial ASCII options and optional retry, reconnect, and connect-timeout settings.
64
+ * @returns A layer whose scope opens the connection on first use and closes it on finalization.
63
65
  */
64
66
  static readonly make: (options: AsciiTransportOpenOptions & TransportResilienceOptions) => Layer.Layer<AsciiTransportService>;
65
67
  /**
66
68
  * Creates a {@link Layer} providing an in-memory mock
67
69
  * {@link AsciiTransportService} for testing or development.
68
70
  *
69
- * Accepts an array of {@link SlaveDeviceDefinition} describing the
71
+ * Accepts an array of {@link SlaveDeviceDefinition} values describing the
70
72
  * simulated Modbus slaves and their register/coil maps.
71
73
  *
72
74
  * @param devices - Slave device definitions for the mock.
73
- * @returns A function that takes {@link AsciiTransportOpenOptions} and
74
- * returns a scoped {@link Layer} providing the mock service.
75
+ * @returns A factory that accepts transport, resilience, and mock-fault options and returns a layer for the mock service.
75
76
  *
76
77
  * @see makeMockTransport — The underlying mock factory.
77
78
  */
@@ -1,4 +1,5 @@
1
- import { Context, Layer } from 'effect';
1
+ /** Provides scoped RTU Modbus transport layers and an in-memory mock layer. */
2
+ import { Context, Effect, Layer } from 'effect';
2
3
  import type { RtuTransportOptions } from 'modbus-rs';
3
4
  import { type MockFaultOptions, type SlaveDeviceDefinitions } from './mocks';
4
5
  import type { TransportResilienceOptions, WithoutUpstreamRetry, TransportServiceApi } from './shared-transport';
@@ -15,7 +16,7 @@ declare const RtuTransportService_base: Context.ServiceClass<RtuTransportService
15
16
  *
16
17
  * The transport connection is opened lazily on the first call to
17
18
  * `withClient(unitId)` and automatically closed when the consuming
18
- * {@link Effect.Scope | Scope} finalizes.
19
+ * scope finalizes.
19
20
  *
20
21
  * Clients are created per `unitId` via
21
22
  * {@link AsyncRtuTransport.createClient} and cached, so repeated
@@ -30,7 +31,7 @@ export declare class RtuTransportService extends RtuTransportService_base {
30
31
  * Scoped constructor effect for the service. v4 does not auto-generate a
31
32
  * layer from this, so {@link RtuTransportService.make} builds one explicitly.
32
33
  */
33
- static readonly makeScoped: (options: RtuTransportOpenOptions & TransportResilienceOptions) => import("effect/Effect").Effect<{
34
+ static readonly makeScoped: (options: RtuTransportOpenOptions & TransportResilienceOptions) => Effect.Effect<{
34
35
  connectionState: import("effect/SubscriptionRef").SubscriptionRef<{
35
36
  readonly _tag: "Connected";
36
37
  } | {
@@ -44,34 +45,34 @@ export declare class RtuTransportService extends RtuTransportService_base {
44
45
  }>;
45
46
  withClient: (unitId: number, clientOptions?: {
46
47
  readonly retry?: import("./retry").ModbusRetryPolicy;
47
- } | undefined) => import("effect/Effect").Effect<import("./modbus-client").EffectModbusClient, import("./errors").ModbusError, never>;
48
- setRequestTimeout: (timeoutMs: number) => import("effect/Effect").Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
49
- clearRequestTimeout: () => import("effect/Effect").Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
50
- reconnect: () => import("effect/Effect").Effect<undefined, import("./errors").ModbusError, never>;
51
- close: (scope: import("effect/Scope").Closeable) => import("effect/Effect").Effect<void, import("./errors").ModbusError, never>;
48
+ } | undefined) => Effect.Effect<import("./modbus-client").EffectModbusClient, import("./errors").ModbusError, never>;
49
+ setRequestTimeout: (timeoutMs: number) => Effect.Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
50
+ clearRequestTimeout: () => Effect.Effect<undefined, import("./errors").ModbusNotConnectedError, never>;
51
+ reconnect: () => Effect.Effect<undefined, import("./errors").ModbusError, never>;
52
+ close: (scope: import("effect/Scope").Closeable) => Effect.Effect<void, import("./errors").ModbusError, never>;
52
53
  withBatchingClient: (unitId: number, options?: import("./batching-client").BatchingClientOptions & {
53
54
  readonly retry?: import("./retry").ModbusRetryPolicy;
54
- }) => import("effect/Effect").Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError | import("./errors").ModbusUnitAlreadyDeclaredError>;
55
- batchingClient: (unitId: number) => import("effect/Effect").Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError>;
55
+ }) => Effect.Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError | import("./errors").ModbusUnitAlreadyDeclaredError>;
56
+ batchingClient: (unitId: number) => Effect.Effect<import("./batching-client").BatchingModbusClient, import("./errors").ModbusError>;
56
57
  readonly touchedUnits: Set<number>;
57
58
  hasPendingRequests: () => boolean;
58
59
  }, never, import("effect/Scope").Scope>;
59
60
  /**
60
61
  * Creates a {@link Layer} providing a live {@link RtuTransportService}.
61
62
  *
62
- * @param options - Connection and resilience options for the transport.
63
+ * @param options - Serial RTU options and optional retry, reconnect, and connect-timeout settings.
64
+ * @returns A layer whose scope opens the connection on first use and closes it on finalization.
63
65
  */
64
66
  static readonly make: (options: RtuTransportOpenOptions & TransportResilienceOptions) => Layer.Layer<RtuTransportService>;
65
67
  /**
66
68
  * Creates a {@link Layer} providing an in-memory mock
67
69
  * {@link RtuTransportService} for testing or development.
68
70
  *
69
- * Accepts an array of {@link SlaveDeviceDefinition} describing the
71
+ * Accepts an array of {@link SlaveDeviceDefinition} values describing the
70
72
  * simulated Modbus slaves and their register/coil maps.
71
73
  *
72
74
  * @param devices - Slave device definitions for the mock.
73
- * @returns A function that takes {@link RtuTransportOpenOptions} and
74
- * returns a scoped {@link Layer} providing the mock service.
75
+ * @returns A factory that accepts transport, resilience, and mock-fault options and returns a layer for the mock service.
75
76
  *
76
77
  * @see makeMockTransport — The underlying mock factory.
77
78
  */
@@ -1,3 +1,4 @@
1
+ /** Defines scoped RTU and ASCII Modbus serial server layers. */
1
2
  import { Layer } from 'effect';
2
3
  import type { SerialServerOptions, ServerHandlers } from 'modbus-rs';
3
4
  import type { ModbusError } from './errors';
@@ -6,7 +7,7 @@ import type { ModbusError } from './errors';
6
7
  *
7
8
  * @param options - Serial port options (path, baud rate, unit ID, etc.).
8
9
  * @param handlers - Callback functions that handle incoming Modbus requests.
9
- * @returns A `Layer` that fails with {@link ModbusError} on bind failure.
10
+ * @returns A layer that starts the server; bind failures enter the `ModbusError` channel. Scope finalization shuts it down, and shutdown failures are ignored.
10
11
  *
11
12
  * @example
12
13
  * ```ts
@@ -30,7 +31,7 @@ export declare const serialRtuServerLayer: (options: SerialServerOptions, handle
30
31
  *
31
32
  * @param options - Serial port options (path, baud rate, unit ID, etc.).
32
33
  * @param handlers - Callback functions that handle incoming Modbus requests.
33
- * @returns A `Layer` that fails with {@link ModbusError} on bind failure.
34
+ * @returns A layer that starts the server; bind failures enter the `ModbusError` channel. Scope finalization shuts it down, and shutdown failures are ignored.
34
35
  *
35
36
  * @example
36
37
  * ```ts
@@ -1,3 +1,4 @@
1
+ /** Exposes one serial transport tag that can use RTU, ASCII, or mock framing. */
1
2
  import { Context, Layer } from 'effect';
2
3
  import { type AsciiTransportOpenOptions } from './AsciiTransportService';
3
4
  import { type MockFaultOptions, type SlaveDeviceDefinitions } from './mocks';
@@ -27,11 +28,17 @@ export declare class SerialTransportService extends SerialTransportService_base
27
28
  /**
28
29
  * Creates a {@link Layer} providing {@link SerialTransportService}
29
30
  * backed by an ASCII transport.
31
+ *
32
+ * @param options - ASCII transport and optional resilience settings.
33
+ * @returns A layer that opens the transport on first use and closes it when its scope ends.
30
34
  */
31
35
  static fromAscii(options: AsciiTransportOpenOptions & TransportResilienceOptions): Layer.Layer<SerialTransportService>;
32
36
  /**
33
37
  * Creates a {@link Layer} providing {@link SerialTransportService}
34
38
  * backed by an RTU transport.
39
+ *
40
+ * @param options - RTU transport and optional resilience settings.
41
+ * @returns A layer that opens the transport on first use and closes it when its scope ends.
35
42
  */
36
43
  static fromRtu(options: RtuTransportOpenOptions & TransportResilienceOptions): Layer.Layer<SerialTransportService>;
37
44
  /**
@@ -46,8 +53,7 @@ export declare class SerialTransportService extends SerialTransportService_base
46
53
  * `fault`, and `reconnectFault`.
47
54
  *
48
55
  * @param devices - The slave device definitions for the mock.
49
- * @returns A function that takes the mock options and gives a scoped
50
- * {@link Layer} that provides the mock service.
56
+ * @returns A factory that accepts either framing's transport options, resilience settings, and mock-fault settings, then provides a scoped mock layer.
51
57
  * @see MockFaultOptions — The `fault` hook and the `reconnectFault` hook.
52
58
  * @see makeMockTransport — The mock factory that this method uses.
53
59
  */
@@ -1,3 +1,4 @@
1
+ /** Defines a scoped layer for a Modbus TCP gateway. */
1
2
  import { Layer } from 'effect';
2
3
  import type { GatewayBindOptions, GatewayConfig } from 'modbus-rs';
3
4
  import type { ModbusError } from './errors';
@@ -12,7 +13,7 @@ import type { ModbusError } from './errors';
12
13
  * @param options - Gateway bind options (host, port).
13
14
  * @param gatewayConfig - Routing configuration with downstream server
14
15
  * definitions and a unit-ID-to-channel route table.
15
- * @returns A `Layer` that fails with {@link ModbusError} on bind failure.
16
+ * @returns A layer that starts the gateway; bind failures enter the `ModbusError` channel. Scope finalization shuts it down, and shutdown failures are ignored.
16
17
  *
17
18
  * @example
18
19
  * ```ts
@@ -1,3 +1,4 @@
1
+ /** Defines a scoped layer for a Modbus TCP server. */
1
2
  import { Layer } from 'effect';
2
3
  import type { ServerHandlers, TcpServerOptions } from 'modbus-rs';
3
4
  import type { ModbusError } from './errors';
@@ -10,7 +11,7 @@ import type { ModbusError } from './errors';
10
11
  *
11
12
  * @param options - Server bind options (host, port, unit ID).
12
13
  * @param handlers - Callback functions that handle incoming Modbus requests.
13
- * @returns A `Layer` that fails with {@link ModbusError} on bind failure.
14
+ * @returns A layer that starts the server; bind failures enter the `ModbusError` channel. Scope finalization shuts it down, and shutdown failures are ignored.
14
15
  *
15
16
  * @example
16
17
  * ```ts
@@ -1,3 +1,4 @@
1
+ /** Provides scoped TCP Modbus transport layers and an in-memory mock layer. */
1
2
  import { Context, Layer } from 'effect';
2
3
  import type { TcpTransportOptions } from 'modbus-rs';
3
4
  import { type MockFaultOptions, type SlaveDeviceDefinitions } from './mocks';
@@ -15,7 +16,7 @@ declare const TcpTransportService_base: Context.ServiceClass<TcpTransportService
15
16
  *
16
17
  * The transport connection is opened lazily on the first call to
17
18
  * `withClient(unitId)` and automatically closed when the consuming
18
- * {@link Effect.Scope | Scope} finalizes.
19
+ * scope finalizes.
19
20
  *
20
21
  * Clients are created per `unitId` via
21
22
  * {@link AsyncTcpTransport.createClient} and cached, so repeated
@@ -59,19 +60,19 @@ export declare class TcpTransportService extends TcpTransportService_base {
59
60
  /**
60
61
  * Creates a {@link Layer} providing a live {@link TcpTransportService}.
61
62
  *
62
- * @param options - Connection and resilience options for the TCP transport.
63
+ * @param options - TCP connection options and optional retry, reconnect, and connect-timeout settings.
64
+ * @returns A layer whose scope opens the connection on first use and closes it on finalization.
63
65
  */
64
66
  static readonly make: (options: TcpTransportOpenOptions & TransportResilienceOptions) => Layer.Layer<TcpTransportService>;
65
67
  /**
66
68
  * Creates a {@link Layer} providing an in-memory mock
67
69
  * {@link TcpTransportService} for testing or development.
68
70
  *
69
- * Accepts an array of {@link SlaveDeviceDefinition} describing the
71
+ * Accepts an array of {@link SlaveDeviceDefinition} values describing the
70
72
  * simulated Modbus slaves and their register/coil maps.
71
73
  *
72
74
  * @param devices - Slave device definitions for the mock.
73
- * @returns A function that takes {@link TcpTransportOpenOptions} and
74
- * returns a scoped {@link Layer} providing the mock service.
75
+ * @returns A factory that accepts transport, resilience, and mock-fault options and returns a layer for the mock service.
75
76
  *
76
77
  * @see makeMockTransport — The underlying mock factory.
77
78
  */
@@ -8,7 +8,8 @@ import type { TransportResilienceOptions, TransportServiceApi } from './shared-t
8
8
  * combines them into one object so it fits {@link createTransportScoped}'s single-options
9
9
  * shape, with `port` destructured back out inside the service's `openMethod`.
10
10
  *
11
- * @see requestSerialPort — Obtains the `port` handle (must be called from a user gesture).
11
+ * Obtain the `port` handle with {@link requestSerialPort}. Call it from a browser
12
+ * user-gesture handler because the browser may require transient user activation.
12
13
  */
13
14
  export type WasmAsciiTransportOpenOptions = WasmSerialTransportOptions & {
14
15
  port: WasmSerialPortHandle;
@@ -16,11 +17,12 @@ export type WasmAsciiTransportOpenOptions = WasmSerialTransportOptions & {
16
17
  declare const WasmAsciiTransportService_base: Context.ServiceClass<WasmAsciiTransportService, "WasmAsciiTransportService", TransportServiceApi>;
17
18
  /**
18
19
  * Scoped Effect service wrapping `modbus-rs`'s browser {@link WasmAsciiTransport}
19
- * for Modbus ASCII over the Web Serial API.
20
+ * for Modbus ASCII over the Web Serial API. The caller obtains the port handle;
21
+ * this service does not request browser permission.
20
22
  *
21
23
  * The transport connection is opened lazily on the first call to
22
24
  * `withClient(unitId)` and automatically closed when the consuming
23
- * {@link Effect.Scope | Scope} finalizes.
25
+ * scope finalizes.
24
26
  *
25
27
  * Clients are created per `unitId` via {@link WasmAsciiTransport.createClient} and
26
28
  * cached, so repeated requests for the same unit ID reuse the same client.
@@ -31,8 +33,10 @@ declare const WasmAsciiTransportService_base: Context.ServiceClass<WasmAsciiTran
31
33
  */
32
34
  export declare class WasmAsciiTransportService extends WasmAsciiTransportService_base {
33
35
  /**
34
- * Scoped constructor effect for the service. v4 does not auto-generate a
35
- * layer from this, so {@link WasmAsciiTransportService.make} builds one explicitly.
36
+ * Builds the scoped transport service effect. The transport opens on first use
37
+ * and its connection closes when the consuming scope ends.
38
+ *
39
+ * @returns An effect that provides the service for the lifetime of its scope.
36
40
  */
37
41
  static readonly makeScoped: (options: WasmSerialTransportOptions & {
38
42
  port: WasmSerialPortHandle;
@@ -66,18 +70,20 @@ export declare class WasmAsciiTransportService extends WasmAsciiTransportService
66
70
  * Creates a {@link Layer} providing a live {@link WasmAsciiTransportService}.
67
71
  *
68
72
  * @param options - Connection and resilience options for the transport.
73
+ * @returns A layer that provides the scoped service.
69
74
  */
70
75
  static readonly make: (options: WasmAsciiTransportOpenOptions & TransportResilienceOptions) => Layer.Layer<WasmAsciiTransportService>;
71
76
  /**
72
77
  * Creates a {@link Layer} providing an in-memory mock
73
78
  * {@link WasmAsciiTransportService} for testing or development.
74
79
  *
75
- * Accepts an array of {@link SlaveDeviceDefinition} describing the
80
+ * Accepts an array of {@link SlaveDeviceDefinitions} describing the
76
81
  * simulated Modbus slaves and their register/coil maps.
77
82
  *
78
83
  * @param devices - Slave device definitions for the mock.
79
84
  * @returns A function that takes {@link WasmAsciiTransportOpenOptions} and
80
- * returns a scoped {@link Layer} providing the mock service.
85
+ * returns a scoped {@link Layer} providing the mock service. The mock
86
+ * uses device definitions and fault hooks instead of browser I/O.
81
87
  *
82
88
  * @see makeMockTransport — The underlying mock factory.
83
89
  */
@@ -8,7 +8,8 @@ import type { TransportResilienceOptions, TransportServiceApi } from './shared-t
8
8
  * combines them into one object so it fits {@link createTransportScoped}'s single-options
9
9
  * shape, with `port` destructured back out inside the service's `openMethod`.
10
10
  *
11
- * @see requestSerialPort — Obtains the `port` handle (must be called from a user gesture).
11
+ * Obtain the `port` handle with {@link requestSerialPort}. Call it from a browser
12
+ * user-gesture handler because the browser may require transient user activation.
12
13
  */
13
14
  export type WasmRtuTransportOpenOptions = WasmSerialTransportOptions & {
14
15
  port: WasmSerialPortHandle;
@@ -16,11 +17,12 @@ export type WasmRtuTransportOpenOptions = WasmSerialTransportOptions & {
16
17
  declare const WasmRtuTransportService_base: Context.ServiceClass<WasmRtuTransportService, "WasmRtuTransportService", TransportServiceApi>;
17
18
  /**
18
19
  * Scoped Effect service wrapping `modbus-rs`'s browser {@link WasmRtuTransport}
19
- * for Modbus RTU over the Web Serial API.
20
+ * for Modbus RTU over the Web Serial API. The caller obtains the port handle;
21
+ * this service does not request browser permission.
20
22
  *
21
23
  * The transport connection is opened lazily on the first call to
22
24
  * `withClient(unitId)` and automatically closed when the consuming
23
- * {@link Effect.Scope | Scope} finalizes.
25
+ * scope finalizes.
24
26
  *
25
27
  * Clients are created per `unitId` via {@link WasmRtuTransport.createClient} and
26
28
  * cached, so repeated requests for the same unit ID reuse the same client.
@@ -31,8 +33,10 @@ declare const WasmRtuTransportService_base: Context.ServiceClass<WasmRtuTranspor
31
33
  */
32
34
  export declare class WasmRtuTransportService extends WasmRtuTransportService_base {
33
35
  /**
34
- * Scoped constructor effect for the service. v4 does not auto-generate a
35
- * layer from this, so {@link WasmRtuTransportService.make} builds one explicitly.
36
+ * Builds the scoped transport service effect. The transport opens on first use
37
+ * and its connection closes when the consuming scope ends.
38
+ *
39
+ * @returns An effect that provides the service for the lifetime of its scope.
36
40
  */
37
41
  static readonly makeScoped: (options: WasmSerialTransportOptions & {
38
42
  port: WasmSerialPortHandle;
@@ -66,18 +70,20 @@ export declare class WasmRtuTransportService extends WasmRtuTransportService_bas
66
70
  * Creates a {@link Layer} providing a live {@link WasmRtuTransportService}.
67
71
  *
68
72
  * @param options - Connection and resilience options for the transport.
73
+ * @returns A layer that provides the scoped service.
69
74
  */
70
75
  static readonly make: (options: WasmRtuTransportOpenOptions & TransportResilienceOptions) => Layer.Layer<WasmRtuTransportService>;
71
76
  /**
72
77
  * Creates a {@link Layer} providing an in-memory mock
73
78
  * {@link WasmRtuTransportService} for testing or development.
74
79
  *
75
- * Accepts an array of {@link SlaveDeviceDefinition} describing the
80
+ * Accepts an array of {@link SlaveDeviceDefinitions} describing the
76
81
  * simulated Modbus slaves and their register/coil maps.
77
82
  *
78
83
  * @param devices - Slave device definitions for the mock.
79
84
  * @returns A function that takes {@link WasmRtuTransportOpenOptions} and
80
- * returns a scoped {@link Layer} providing the mock service.
85
+ * returns a scoped {@link Layer} providing the mock service. The mock
86
+ * uses device definitions and fault hooks instead of browser I/O.
81
87
  *
82
88
  * @see makeMockTransport — The underlying mock factory.
83
89
  */
@@ -19,7 +19,8 @@ import type { ModbusError } from './errors';
19
19
  * @param options - Serial port, baud rate, unit ID, etc.
20
20
  * @param handlers - Callback functions that handle incoming Modbus requests
21
21
  * (same {@link ServerHandlers} shape as the native TCP/serial servers).
22
- * @returns A `Layer` that fails with {@link ModbusError} on bind failure.
22
+ * @returns A layer that binds the server and runs its request loop within the
23
+ * layer scope. Binding errors fail with {@link ModbusError}; loop errors are logged.
23
24
  *
24
25
  * @example
25
26
  * ```ts
@@ -46,7 +47,8 @@ export declare const wasmSerialRtuServerLayer: (options: WasmSerialServerOptions
46
47
  *
47
48
  * @param options - Serial port, baud rate, unit ID, etc.
48
49
  * @param handlers - Callback functions that handle incoming Modbus requests.
49
- * @returns A `Layer` that fails with {@link ModbusError} on bind failure.
50
+ * @returns A layer that binds the server and runs its request loop within the
51
+ * layer scope. Binding errors fail with {@link ModbusError}; loop errors are logged.
50
52
  *
51
53
  * @see WasmSerialServerOptions — Options accepted by the upstream WASM serial server.
52
54
  * @see ServerHandlers — Interface for request handler callbacks.
@@ -6,10 +6,10 @@ import type { ModbusError } from './errors';
6
6
  * {@link WasmSerialTransportService.fromRtu} / `.fromAscii` (or
7
7
  * `WasmRtuTransportService.make` / `WasmAsciiTransportService.make` directly).
8
8
  *
9
- * **Must be called synchronously from within a user-gesture event handler**
10
- * (e.g. a `click` listener) — this is a hard Web Serial API / browser security
11
- * constraint (`navigator.serial.requestPort()` semantics), not a library-imposed
12
- * restriction. Calling it outside a gesture will reject.
9
+ * Call this from a browser user-gesture handler, such as a click handler, because
10
+ * the Web Serial API may require transient user activation to show its chooser.
11
+ * The helper loads the browser binding before requesting the port, so it does not
12
+ * itself call the browser API synchronously in the handler.
13
13
  *
14
14
  * @example
15
15
  * ```ts
@@ -22,6 +22,8 @@ import type { ModbusError } from './errors';
22
22
  * });
23
23
  * ```
24
24
  *
25
+ * @returns An effect that succeeds with the selected opaque port handle or fails
26
+ * with {@link ModbusError} when the browser request or binding fails.
25
27
  * @see WasmSerialPortHandle — Opaque handle returned by `modbus-rs`'s WASM bindings.
26
28
  */
27
29
  export declare const requestSerialPort: () => Effect.Effect<WasmSerialPortHandle, ModbusError>;
@@ -5,7 +5,7 @@ import { type WasmAsciiTransportOpenOptions } from './WasmAsciiTransportService'
5
5
  import { type WasmRtuTransportOpenOptions } from './WasmRtuTransportService';
6
6
  declare const WasmSerialTransportService_base: Context.ServiceClass<WasmSerialTransportService, "WasmSerialTransportService", TransportServiceApi>;
7
7
  /**
8
- * Abstract browser (WASM) serial Modbus transport service tag.
8
+ * Abstract browser serial Modbus transport service tag.
9
9
  *
10
10
  * Represents a Web Serial-based Modbus transport backed by either ASCII or RTU
11
11
  * framing. Use this tag when you need a browser serial transport but don't care
@@ -23,17 +23,24 @@ declare const WasmSerialTransportService_base: Context.ServiceClass<WasmSerialTr
23
23
  * Layer.provide(WasmSerialTransportService.fromRtu({ port, baudRate: 9600 }))
24
24
  * ```
25
25
  *
26
- * @see requestSerialPort — Obtains the `port` handle both providers need (must be called from a user gesture).
26
+ * Obtain the serial port handle with {@link requestSerialPort}. Call it from a
27
+ * browser user-gesture handler because the browser may require transient activation.
27
28
  */
28
29
  export declare class WasmSerialTransportService extends WasmSerialTransportService_base {
29
30
  /**
30
31
  * Creates a {@link Layer} providing {@link WasmSerialTransportService}
31
32
  * backed by an ASCII transport.
33
+ *
34
+ * @param options - Serial connection and resilience options.
35
+ * @returns A layer that provides the ASCII transport through the abstract service tag.
32
36
  */
33
37
  static fromAscii(options: WasmAsciiTransportOpenOptions & TransportResilienceOptions): Layer.Layer<WasmSerialTransportService>;
34
38
  /**
35
39
  * Creates a {@link Layer} providing {@link WasmSerialTransportService}
36
40
  * backed by an RTU transport.
41
+ *
42
+ * @param options - Serial connection and resilience options.
43
+ * @returns A layer that provides the RTU transport through the abstract service tag.
37
44
  */
38
45
  static fromRtu(options: WasmRtuTransportOpenOptions & TransportResilienceOptions): Layer.Layer<WasmSerialTransportService>;
39
46
  /**
@@ -17,7 +17,8 @@ import type { ModbusError } from './errors';
17
17
  * @param options - WebSocket gateway URL and unit ID.
18
18
  * @param handlers - Callback functions that handle incoming Modbus requests
19
19
  * (same {@link ServerHandlers} shape as the native TCP/serial servers).
20
- * @returns A `Layer` that fails with {@link ModbusError} on bind failure.
20
+ * @returns A layer that binds the server and runs its request loop within the
21
+ * layer scope. Binding errors fail with {@link ModbusError}; loop errors are logged.
21
22
  *
22
23
  * @example
23
24
  * ```ts
@@ -9,7 +9,7 @@ declare const WasmWsTransportService_base: Context.ServiceClass<WasmWsTransportS
9
9
  *
10
10
  * The transport connection is opened lazily on the first call to
11
11
  * `withClient(unitId)` and automatically closed when the consuming
12
- * {@link Effect.Scope | Scope} finalizes.
12
+ * scope finalizes.
13
13
  *
14
14
  * Clients are created per `unitId` via {@link WasmWsTransport.createClient} and
15
15
  * cached, so repeated requests for the same unit ID reuse the same client.
@@ -20,8 +20,10 @@ declare const WasmWsTransportService_base: Context.ServiceClass<WasmWsTransportS
20
20
  */
21
21
  export declare class WasmWsTransportService extends WasmWsTransportService_base {
22
22
  /**
23
- * Scoped constructor effect for the service. v4 does not auto-generate a
24
- * layer from this, so {@link WasmWsTransportService.make} builds one explicitly.
23
+ * Builds the scoped transport service effect. The transport opens on first use
24
+ * and its connection closes when the consuming scope ends.
25
+ *
26
+ * @returns An effect that provides the service for the lifetime of its scope.
25
27
  */
26
28
  static readonly makeScoped: (options: WasmWsTransportOptions & TransportResilienceOptions) => import("effect/Effect").Effect<{
27
29
  connectionState: import("effect/SubscriptionRef").SubscriptionRef<{
@@ -53,18 +55,20 @@ export declare class WasmWsTransportService extends WasmWsTransportService_base
53
55
  * Creates a {@link Layer} providing a live {@link WasmWsTransportService}.
54
56
  *
55
57
  * @param options - Connection and resilience options for the transport.
58
+ * @returns A layer that provides the scoped service.
56
59
  */
57
60
  static readonly make: (options: WasmWsTransportOptions & TransportResilienceOptions) => Layer.Layer<WasmWsTransportService>;
58
61
  /**
59
62
  * Creates a {@link Layer} providing an in-memory mock
60
63
  * {@link WasmWsTransportService} for testing or development.
61
64
  *
62
- * Accepts an array of {@link SlaveDeviceDefinition} describing the
65
+ * Accepts an array of {@link SlaveDeviceDefinitions} describing the
63
66
  * simulated Modbus slaves and their register/coil maps.
64
67
  *
65
68
  * @param devices - Slave device definitions for the mock.
66
69
  * @returns A function that takes {@link WasmWsTransportOptions} and
67
- * returns a scoped {@link Layer} providing the mock service.
70
+ * returns a scoped {@link Layer} providing the mock service. The mock
71
+ * uses device definitions and fault hooks instead of network I/O.
68
72
  *
69
73
  * @see makeMockTransport — The underlying mock factory.
70
74
  */