@flux-control/effect-modbus-rs 0.3.1 → 0.4.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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  For the complete API reference, see the [GitHub Pages documentation](https://flux-control-solutions.github.io/Effect-modbus-rs/).
6
6
 
7
- Provides scoped [`Effect.Service`](https://effect.website) constructors for RTU (serial), TCP, and ASCII Modbus transports. Clients expose a typed `Effect`-based API for all standard Modbus function codes.
7
+ Provides scoped [`Context.Service`](https://effect.website) constructors for RTU (serial), TCP, and ASCII Modbus transports. Clients expose a typed `Effect`-based API for all standard Modbus function codes.
8
8
 
9
9
  > This project is under active development. Its API may change before the 1.0 release.
10
10
 
@@ -44,7 +44,7 @@ program.pipe(
44
44
  ModbusInvalidArgumentError: (err) => Console.log(`Invalid argument: ${err.message}`),
45
45
  }),
46
46
  Effect.catchAll((err) => Console.log(`Unhandled error: ${err.message}`)),
47
- Effect.provide(RtuTransportService.Default({ portPath: '/dev/ttyUSB0', baudRate: 9600 })),
47
+ Effect.provide(RtuTransportService.make({ portPath: '/dev/ttyUSB0', baudRate: 9600 })),
48
48
  Effect.scoped,
49
49
  Effect.runPromise,
50
50
  );
@@ -64,7 +64,7 @@ const program = Effect.gen(function* () {
64
64
  });
65
65
 
66
66
  program.pipe(
67
- Effect.provide(TcpTransportService.Default({ host: '192.168.1.100', port: 502 })),
67
+ Effect.provide(TcpTransportService.make({ host: '192.168.1.100', port: 502 })),
68
68
  Effect.scoped,
69
69
  Effect.runPromise,
70
70
  );
@@ -87,7 +87,7 @@ const program = Effect.gen(function* () {
87
87
  });
88
88
 
89
89
  program.pipe(
90
- Effect.provide(AsciiTransportService.Default({ portPath: '/dev/ttyUSB0', baudRate: 9600 })),
90
+ Effect.provide(AsciiTransportService.make({ portPath: '/dev/ttyUSB0', baudRate: 9600 })),
91
91
  Effect.scoped,
92
92
  Effect.runPromise,
93
93
  );
@@ -112,7 +112,7 @@ const program = Effect.gen(function* () {
112
112
  });
113
113
 
114
114
  program.pipe(
115
- Effect.provide(WasmWsTransportService.Default({ wsUrl: 'ws://localhost:8080' })),
115
+ Effect.provide(WasmWsTransportService.make({ wsUrl: 'ws://localhost:8080' })),
116
116
  Effect.scoped,
117
117
  Effect.runPromise,
118
118
  );
@@ -129,7 +129,7 @@ connectButton.addEventListener('click', () => {
129
129
  Effect.gen(function* () {
130
130
  const port = yield* requestSerialPort();
131
131
  yield* program.pipe(
132
- Effect.provide(WasmRtuTransportService.Default({ port, baudRate: 19200 })),
132
+ Effect.provide(WasmRtuTransportService.make({ port, baudRate: 19200 })),
133
133
  Effect.scoped,
134
134
  );
135
135
  }),
@@ -150,7 +150,7 @@ Not demonstrated in `examples/wasm/` (see that app's README) — the same `impor
150
150
 
151
151
  ## Transports
152
152
 
153
- Each transport is a scoped `Effect.Service`. You provide it with `Effect.provide`, and the connection is opened on service access and closed when the scope ends.
153
+ Each transport is a scoped `Context.Service`. You provide it with `Effect.provide`, and the connection is opened on service access and closed when the scope ends.
154
154
 
155
155
  | Service | Options | Connection |
156
156
  | ------------------------------------- | ------------------------------ | ----------------------------- |
@@ -279,7 +279,7 @@ Handle with `Effect.catchTags`. The `ModbusError` union type covers all seven va
279
279
  Resilience belongs to the **transport**, not to call sites. Attach a policy where the transport is created and every client derived from it carries it:
280
280
 
281
281
  ```ts
282
- const layer = TcpTransportService.Default({
282
+ const layer = TcpTransportService.make({
283
283
  host: '192.168.1.50',
284
284
  port: 502,
285
285
  retry: RetryPolicies.tcp(), // applied to every operation
@@ -393,7 +393,7 @@ So `RetryPolicies.tcp()` waits roughly 80–120 ms before its first retry, not e
393
393
  Passing `reconnect` hands reconnection to a supervisor fiber owned by the transport — **one reconnect for the whole application**, however many fibers were in flight when the link dropped:
394
394
 
395
395
  ```ts
396
- TcpTransportService.Default({
396
+ TcpTransportService.make({
397
397
  host,
398
398
  port,
399
399
  reconnect: {
@@ -445,7 +445,7 @@ See `examples/retry-policies.ts` for a runnable walkthrough.
445
445
  `modbus-rs` exposes `retryAttempts`, `retryDelayMs`, and `retryBackoffStrategy` on its transport options. This package removes all three from every transport constructor, so setting one is a compile error rather than a documented hazard:
446
446
 
447
447
  ```ts
448
- TcpTransportService.Default({ host, port, retryAttempts: 3 });
448
+ TcpTransportService.make({ host, port, retryAttempts: 3 });
449
449
  // ^^^^^^^^^^^^^ Object literal may only specify
450
450
  // known properties, and 'retryAttempts' does not
451
451
  // exist in type 'TcpTransportOpenOptions & …'
@@ -568,17 +568,17 @@ src/
568
568
  connection.ts — Connection state machine, reconnect supervisor, circuit breaker
569
569
  retry.ts — Opt-in retry policies (backoff, jitter, per-error rules)
570
570
  shared-transport.ts — Generic scoped transport lifecycle management, WithoutUpstreamRetry
571
- RtuTransportService.ts — Scoped Effect.Service wrapping AsyncRtuTransport
572
- TcpTransportService.ts — Scoped Effect.Service wrapping AsyncTcpTransport
573
- AsciiTransportService.ts — Scoped Effect.Service wrapping AsyncAsciiTransport
571
+ RtuTransportService.ts — Scoped Context.Service wrapping AsyncRtuTransport
572
+ TcpTransportService.ts — Scoped Context.Service wrapping AsyncTcpTransport
573
+ AsciiTransportService.ts — Scoped Context.Service wrapping AsyncAsciiTransport
574
574
  SerialTransportService.ts — Abstract serial transport (RTU/ASCII) tag
575
575
  TcpModbusServerService.ts — tcpServerLayer
576
576
  SerialModbusServerService.ts — serialRtuServerLayer / serialAsciiServerLayer
577
577
  TcpGatewayService.ts — tcpGatewayLayer
578
578
  WasmSerialPort.ts — requestSerialPort() Effect helper (browser, user-gesture gated)
579
- WasmWsTransportService.ts — Scoped Effect.Service wrapping WasmWsTransport (browser, WS gateway)
580
- WasmRtuTransportService.ts — Scoped Effect.Service wrapping WasmRtuTransport (browser, Web Serial RTU)
581
- WasmAsciiTransportService.ts — Scoped Effect.Service wrapping WasmAsciiTransport (browser, Web Serial ASCII)
579
+ WasmWsTransportService.ts — Scoped Context.Service wrapping WasmWsTransport (browser, WS gateway)
580
+ WasmRtuTransportService.ts — Scoped Context.Service wrapping WasmRtuTransport (browser, Web Serial RTU)
581
+ WasmAsciiTransportService.ts — Scoped Context.Service wrapping WasmAsciiTransport (browser, Web Serial ASCII)
582
582
  WasmSerialTransportService.ts — Abstract browser serial transport (RTU/ASCII) tag
583
583
  WasmTcpServerService.ts — wasmWsServerLayer (experimental)
584
584
  WasmSerialModbusServerService.ts — wasmSerialRtuServerLayer / wasmSerialAsciiServerLayer (experimental)
package/dist/index.d.ts CHANGED
@@ -54,7 +54,7 @@
54
54
  * every client derived from it:
55
55
  *
56
56
  * ```ts
57
- * TcpTransportService.Default({
57
+ * TcpTransportService.make({
58
58
  * host, port,
59
59
  * retry: RetryPolicies.tcp(), // applied to every operation
60
60
  * reconnect: {}, // supervised reconnect + circuit breaker
package/dist/index.js CHANGED
@@ -55,7 +55,7 @@ var toModbusError = (cause) => {
55
55
  }
56
56
  };
57
57
  // src/retry.ts
58
- import { Duration, Effect, Schedule } from "effect";
58
+ import { Duration, Effect, Random, Schedule } from "effect";
59
59
  var retryableExceptionCodes = [5, 6, 10, 11];
60
60
  var defaultRetryableTags = {
61
61
  ModbusTimeoutError: true,
@@ -68,7 +68,7 @@ var defaultRetryableTags = {
68
68
  ModbusInternalError: false
69
69
  };
70
70
  var allTags = Object.keys(defaultRetryableTags);
71
- var toMillis = (input) => Duration.toMillis(Duration.decode(input));
71
+ var toMillis = (input) => Duration.toMillis(Duration.fromInputUnsafe(input));
72
72
  var resolveRetryableTags = (options) => {
73
73
  const retryable = {};
74
74
  for (const tag of allTags) {
@@ -112,10 +112,14 @@ var makeRetryPolicy = (options = {}) => {
112
112
  const { baseMs, factor, maxMs } = delays[error._tag];
113
113
  return Duration.millis(Math.min(maxMs, baseMs * factor ** retryIndex));
114
114
  };
115
- const base = Schedule.recurs(options.maxRetries ?? 3).pipe(Schedule.intersect(Schedule.identity()), Schedule.modifyDelay(([retryIndex, error]) => delayFor(error, retryIndex)), Schedule.whileInput(isRetryable));
115
+ const base = Schedule.recurs(options.maxRetries ?? 3).pipe(Schedule.setInputType(), Schedule.modifyDelay((metadata) => Effect.succeed(delayFor(metadata.input, metadata.attempt - 1))), Schedule.while((metadata) => Effect.succeed(isRetryable(metadata.input))));
116
116
  const jitter = options.jitter ?? true;
117
- const jittered = jitter === false ? base : Schedule.jitteredWith(base, jitter === true ? {} : jitter);
118
- const schedule = options.maxElapsed === undefined ? jittered : Schedule.upTo(jittered, options.maxElapsed);
117
+ const jittered = jitter === false ? base : jitter === true ? Schedule.jittered(base) : Schedule.modifyDelay(base, (metadata) => Effect.map(Random.next, (r) => {
118
+ const min = jitter.min ?? 0.8;
119
+ const max = jitter.max ?? 1.2;
120
+ return Duration.millis(Duration.toMillis(metadata.duration) * (min + r * (max - min)));
121
+ }));
122
+ const schedule = options.maxElapsed === undefined ? jittered : Schedule.upTo(jittered, { duration: options.maxElapsed });
119
123
  return { schedule, isRetryable };
120
124
  };
121
125
  var RetryPolicies = {
@@ -146,7 +150,7 @@ var RetryPolicies = {
146
150
  };
147
151
  var retryModbus = (policy) => (self) => Effect.retry(self, policy.schedule);
148
152
  // src/connection.ts
149
- import { Data as Data2, Duration as Duration2, Effect as Effect2, Either, SubscriptionRef } from "effect";
153
+ import { Data as Data2, Duration as Duration2, Effect as Effect2, Result, SubscriptionRef } from "effect";
150
154
  var ConnectionState = Data2.taggedEnum();
151
155
  var defaultReconnectPolicy = makeRetryPolicy({
152
156
  maxRetries: 5,
@@ -162,7 +166,7 @@ var resolveReconnect = (options) => {
162
166
  const triggerTags = options.triggerOn ?? defaultTriggers;
163
167
  return {
164
168
  policy: options.policy ?? defaultReconnectPolicy,
165
- resetAfter: Duration2.decode(options.resetAfter ?? "30 seconds"),
169
+ resetAfter: Duration2.fromInputUnsafe(options.resetAfter ?? "30 seconds"),
166
170
  triggers: (error) => triggerTags.includes(error._tag)
167
171
  };
168
172
  };
@@ -181,13 +185,13 @@ var guardCircuit = (state) => Effect2.flatMap(SubscriptionRef.get(state), (curre
181
185
  var superviseReconnect = (reconnect, state, resolved) => Effect2.gen(function* () {
182
186
  while (true) {
183
187
  const attempt = reconnect.pipe(Effect2.tapError(() => SubscriptionRef.update(state, (current) => ConnectionState.$is("Reconnecting")(current) ? ConnectionState.Reconnecting({ attempt: current.attempt + 1 }) : current)), retryModbus(resolved.policy));
184
- const result = yield* Effect2.either(attempt);
185
- if (Either.isRight(result)) {
188
+ const result = yield* Effect2.result(attempt);
189
+ if (Result.isSuccess(result)) {
186
190
  yield* SubscriptionRef.set(state, ConnectionState.Connected());
187
191
  return;
188
192
  }
189
- yield* Effect2.logDebug(`Reconnect attempts exhausted: ${result.left.message}`);
190
- yield* SubscriptionRef.set(state, ConnectionState.Down({ cause: result.left }));
193
+ yield* Effect2.logDebug(`Reconnect attempts exhausted: ${result.failure.message}`);
194
+ yield* SubscriptionRef.set(state, ConnectionState.Down({ cause: result.failure }));
191
195
  yield* Effect2.sleep(resolved.resetAfter);
192
196
  const probe = yield* SubscriptionRef.modify(state, (current) => ConnectionState.$is("Down")(current) ? [true, ConnectionState.Reconnecting({ attempt: 0 })] : [false, current]);
193
197
  if (!probe)
@@ -195,7 +199,7 @@ var superviseReconnect = (reconnect, state, resolved) => Effect2.gen(function* (
195
199
  }
196
200
  });
197
201
  // src/AsciiTransportService.ts
198
- import { Effect as Effect6, Layer } from "effect";
202
+ import { Context, Layer } from "effect";
199
203
 
200
204
  // src/mocks.ts
201
205
  import { Effect as Effect4, Schema, SubscriptionRef as SubscriptionRef2 } from "effect";
@@ -228,7 +232,7 @@ var makeEffectModbusClient = (client) => ({
228
232
  });
229
233
  var withResilience = (operations, resilience) => {
230
234
  const run = (operation) => {
231
- const attempt = Effect3.zipRight(resilience.guard, Effect3.suspend(operation)).pipe(Effect3.tapError((error) => resilience.report(error)));
235
+ const attempt = Effect3.andThen(resilience.guard, Effect3.suspend(operation)).pipe(Effect3.tapError((error) => resilience.report(error)));
232
236
  return resilience.policy ? retryModbus(resilience.policy)(attempt) : attempt;
233
237
  };
234
238
  return {
@@ -266,18 +270,10 @@ var RegisterDefinition = Schema.Struct({
266
270
  });
267
271
  var SlaveDeviceDefinition = Schema.Struct({
268
272
  unitId: Schema.Number,
269
- coils: Schema.optionalWith(Schema.Array(CoilDefinition), {
270
- default: () => []
271
- }),
272
- discreteInputs: Schema.optionalWith(Schema.Array(DiscreteInputDefinition), {
273
- default: () => []
274
- }),
275
- holdingRegisters: Schema.optionalWith(Schema.Array(RegisterDefinition), {
276
- default: () => []
277
- }),
278
- inputRegisters: Schema.optionalWith(Schema.Array(RegisterDefinition), {
279
- default: () => []
280
- })
273
+ coils: Schema.Array(CoilDefinition).pipe(Schema.withDecodingDefaultType(Effect4.succeed([]))),
274
+ discreteInputs: Schema.Array(DiscreteInputDefinition).pipe(Schema.withDecodingDefaultType(Effect4.succeed([]))),
275
+ holdingRegisters: Schema.Array(RegisterDefinition).pipe(Schema.withDecodingDefaultType(Effect4.succeed([]))),
276
+ inputRegisters: Schema.Array(RegisterDefinition).pipe(Schema.withDecodingDefaultType(Effect4.succeed([])))
281
277
  });
282
278
  var SlaveDeviceDefinitions = Schema.Array(SlaveDeviceDefinition);
283
279
  var buildCoils = (defs) => {
@@ -458,7 +454,7 @@ var makeMockTransport = (devices) => {
458
454
  const connectionState = yield* SubscriptionRef2.make(ConnectionState.Connected());
459
455
  const supervised = options.reconnect ? resolveReconnect(options.reconnect) : null;
460
456
  const serviceScope = yield* Effect4.scope;
461
- const reconnectOnce = Effect4.zipRight(Effect4.logDebug("Mock: reconnecting"), Effect4.suspend(() => {
457
+ const reconnectOnce = Effect4.andThen(Effect4.logDebug("Mock: reconnecting"), Effect4.suspend(() => {
462
458
  const injected = options.reconnectFault?.();
463
459
  return injected ? Effect4.fail(injected) : Effect4.void;
464
460
  }));
@@ -472,7 +468,7 @@ var makeMockTransport = (devices) => {
472
468
  yield* Effect4.forkIn(superviseReconnect(reconnectOnce, connectionState, supervised), serviceScope);
473
469
  });
474
470
  };
475
- const guard = Effect4.zipRight(supervised ? guardCircuit(connectionState) : Effect4.void, Effect4.suspend(() => {
471
+ const guard = Effect4.andThen(supervised ? guardCircuit(connectionState) : Effect4.void, Effect4.suspend(() => {
476
472
  const injected = options.fault?.();
477
473
  return injected ? Effect4.fail(injected) : Effect4.void;
478
474
  }));
@@ -494,8 +490,8 @@ var makeMockTransport = (devices) => {
494
490
  }),
495
491
  setRequestTimeout: (_timeoutMs) => Effect4.void,
496
492
  clearRequestTimeout: () => Effect4.void,
497
- reconnect: () => Effect4.zipRight(reconnectOnce, SubscriptionRef2.set(connectionState, ConnectionState.Connected())),
498
- close: () => Effect4.zipRight(Effect4.logDebug("Mock: closing transport"), SubscriptionRef2.set(connectionState, ConnectionState.Disconnected())),
493
+ reconnect: () => Effect4.andThen(reconnectOnce, SubscriptionRef2.set(connectionState, ConnectionState.Connected())),
494
+ close: () => Effect4.andThen(Effect4.logDebug("Mock: closing transport"), SubscriptionRef2.set(connectionState, ConnectionState.Disconnected())),
499
495
  hasPendingRequests: () => false
500
496
  };
501
497
  });
@@ -511,7 +507,7 @@ var singleFlight = (inFlight, work) => Effect5.uninterruptibleMask((restore) =>
511
507
  onNone: () => [[fresh, true], Option.some(fresh)]
512
508
  }));
513
509
  if (isLeader) {
514
- yield* Effect5.forkDaemon(Effect5.interruptible(work).pipe(Effect5.onExit((exit) => Effect5.zipRight(Ref.set(inFlight, Option.none()), Deferred.done(deferred, exit)))));
510
+ yield* Effect5.forkDetach(Effect5.interruptible(work).pipe(Effect5.onExit((exit) => Effect5.andThen(Ref.set(inFlight, Option.none()), Deferred.done(deferred, exit)))));
515
511
  }
516
512
  return yield* restore(Deferred.await(deferred));
517
513
  }));
@@ -533,11 +529,11 @@ function makeTransportScoped(transportKey, openMethod, serviceName, config) {
533
529
  cause: new Error("Transport has been closed"),
534
530
  message: "Transport has been closed"
535
531
  });
536
- const closeOrphan = (t) => Effect5.forkDaemon(Effect5.ignore(Effect5.tryPromise(() => t.close())));
532
+ const closeOrphan = (t) => Effect5.forkDetach(Effect5.ignore(Effect5.tryPromise(() => t.close())));
537
533
  const openTransport = Effect5.tryPromise({
538
534
  try: () => openMethod(TC, openOptions),
539
535
  catch: (error) => toModbusError(error)
540
- }).pipe(Effect5.tap((t) => closed ? closeOrphan(t) : Effect5.zipRight(Effect5.sync(() => {
536
+ }).pipe(Effect5.tap((t) => closed ? closeOrphan(t) : Effect5.andThen(Effect5.sync(() => {
541
537
  transport = t;
542
538
  }), SubscriptionRef3.set(connectionState, ConnectionState.Connected()))));
543
539
  const ensureOpen = Effect5.fnUntraced(function* () {
@@ -557,7 +553,7 @@ function makeTransportScoped(transportKey, openMethod, serviceName, config) {
557
553
  const t = transport;
558
554
  if (!t)
559
555
  return SubscriptionRef3.set(connectionState, ConnectionState.Disconnected());
560
- return Effect5.andThen(Effect5.logDebug(`Closing ${serviceName}`), Effect5.zipRight(Effect5.promise(() => t.close()), SubscriptionRef3.set(connectionState, ConnectionState.Disconnected())));
556
+ return Effect5.andThen(Effect5.logDebug(`Closing ${serviceName}`), Effect5.andThen(Effect5.promise(() => t.close()), SubscriptionRef3.set(connectionState, ConnectionState.Disconnected())));
561
557
  });
562
558
  const notConnectedMsg = "Transport is not connected. Call withClient() first.";
563
559
  const reconnectOnce = Effect5.suspend(() => {
@@ -665,54 +661,54 @@ function makeTransportScoped(transportKey, openMethod, serviceName, config) {
665
661
  }
666
662
 
667
663
  // src/AsciiTransportService.ts
668
- class AsciiTransportService extends Effect6.Service()("AsciiTransportService", {
669
- scoped: makeTransportScoped("AsyncAsciiTransport", (TC, options) => TC.open(options), "AsciiTransportService")
670
- }) {
664
+ class AsciiTransportService extends Context.Service()("AsciiTransportService") {
665
+ static makeScoped = makeTransportScoped("AsyncAsciiTransport", (TC, options) => TC.open(options), "AsciiTransportService");
666
+ static make = (options) => Layer.effect(AsciiTransportService, AsciiTransportService.makeScoped(options));
671
667
  static makeMockTransport = (devices) => {
672
668
  const factory = makeMockTransport(devices);
673
- return (options) => Layer.scoped(AsciiTransportService, factory(options));
669
+ return (options) => Layer.effect(AsciiTransportService, factory(options));
674
670
  };
675
671
  }
676
672
  // src/SerialTransportService.ts
677
- import { Context, Layer as Layer3 } from "effect";
673
+ import { Context as Context3, Layer as Layer3 } from "effect";
678
674
 
679
675
  // src/RtuTransportService.ts
680
- import { Effect as Effect7, Layer as Layer2 } from "effect";
681
- class RtuTransportService extends Effect7.Service()("RtuTransportService", {
682
- scoped: makeTransportScoped("AsyncRtuTransport", (TC, options) => TC.open(options), "RtuTransportService")
683
- }) {
676
+ import { Context as Context2, Layer as Layer2 } from "effect";
677
+ class RtuTransportService extends Context2.Service()("RtuTransportService") {
678
+ static makeScoped = makeTransportScoped("AsyncRtuTransport", (TC, options) => TC.open(options), "RtuTransportService");
679
+ static make = (options) => Layer2.effect(RtuTransportService, RtuTransportService.makeScoped(options));
684
680
  static makeMockTransport = (devices) => {
685
681
  const factory = makeMockTransport(devices);
686
- return (options) => Layer2.scoped(RtuTransportService, factory(options));
682
+ return (options) => Layer2.effect(RtuTransportService, factory(options));
687
683
  };
688
684
  }
689
685
 
690
686
  // src/SerialTransportService.ts
691
- class SerialTransportService extends Context.Tag("SerialTransportService")() {
687
+ class SerialTransportService extends Context3.Service()("SerialTransportService") {
692
688
  static fromAscii(options) {
693
- return Layer3.project(AsciiTransportService, SerialTransportService, (ascii) => ascii)(AsciiTransportService.Default(options));
689
+ return Layer3.flatMap(AsciiTransportService.make(options), (context) => Layer3.succeed(SerialTransportService, Context3.get(context, AsciiTransportService)));
694
690
  }
695
691
  static fromRtu(options) {
696
- return Layer3.project(RtuTransportService, SerialTransportService, (rtu) => rtu)(RtuTransportService.Default(options));
692
+ return Layer3.flatMap(RtuTransportService.make(options), (context) => Layer3.succeed(SerialTransportService, Context3.get(context, RtuTransportService)));
697
693
  }
698
694
  static makeMockTransport = (devices) => {
699
695
  const factory = makeMockTransport(devices);
700
- return (options) => Layer3.scoped(SerialTransportService, factory(options));
696
+ return (options) => Layer3.effect(SerialTransportService, factory(options));
701
697
  };
702
698
  }
703
699
  // src/TcpTransportService.ts
704
- import { Effect as Effect8, Layer as Layer4 } from "effect";
705
- class TcpTransportService extends Effect8.Service()("TcpTransportService", {
706
- scoped: makeTransportScoped("AsyncTcpTransport", (TC, options) => TC.connect(options), "TcpTransportService")
707
- }) {
700
+ import { Context as Context4, Layer as Layer4 } from "effect";
701
+ class TcpTransportService extends Context4.Service()("TcpTransportService") {
702
+ static makeScoped = makeTransportScoped("AsyncTcpTransport", (TC, options) => TC.connect(options), "TcpTransportService");
703
+ static make = (options) => Layer4.effect(TcpTransportService, TcpTransportService.makeScoped(options));
708
704
  static makeMockTransport = (devices) => {
709
705
  const factory = makeMockTransport(devices);
710
- return (options) => Layer4.scoped(TcpTransportService, factory(options));
706
+ return (options) => Layer4.effect(TcpTransportService, factory(options));
711
707
  };
712
708
  }
713
709
  // src/SerialModbusServerService.ts
714
710
  import { Effect as Effect9, Layer as Layer5 } from "effect";
715
- var serialRtuServerLayer = (options, handlers) => Layer5.scopedDiscard(Effect9.gen(function* () {
711
+ var serialRtuServerLayer = (options, handlers) => Layer5.effectDiscard(Effect9.gen(function* () {
716
712
  const { AsyncSerialModbusServer } = yield* Effect9.promise(() => import("modbus-rs"));
717
713
  const server = yield* Effect9.tryPromise({
718
714
  try: () => AsyncSerialModbusServer.bindRtu(options, handlers),
@@ -722,9 +718,9 @@ var serialRtuServerLayer = (options, handlers) => Layer5.scopedDiscard(Effect9.g
722
718
  yield* Effect9.addFinalizer(() => Effect9.logDebug("Serial RTU server shutting down").pipe(Effect9.andThen(Effect9.tryPromise({
723
719
  try: () => server.shutdown(),
724
720
  catch: (error) => toModbusError(error)
725
- })), Effect9.catchAll(() => Effect9.void)));
721
+ })), Effect9.catch(() => Effect9.void)));
726
722
  }));
727
- var serialAsciiServerLayer = (options, handlers) => Layer5.scopedDiscard(Effect9.gen(function* () {
723
+ var serialAsciiServerLayer = (options, handlers) => Layer5.effectDiscard(Effect9.gen(function* () {
728
724
  const { AsyncSerialModbusServer } = yield* Effect9.promise(() => import("modbus-rs"));
729
725
  const server = yield* Effect9.tryPromise({
730
726
  try: () => AsyncSerialModbusServer.bindAscii(options, handlers),
@@ -734,11 +730,11 @@ var serialAsciiServerLayer = (options, handlers) => Layer5.scopedDiscard(Effect9
734
730
  yield* Effect9.addFinalizer(() => Effect9.logDebug("Serial ASCII server shutting down").pipe(Effect9.andThen(Effect9.tryPromise({
735
731
  try: () => server.shutdown(),
736
732
  catch: (error) => toModbusError(error)
737
- })), Effect9.catchAll(() => Effect9.void)));
733
+ })), Effect9.catch(() => Effect9.void)));
738
734
  }));
739
735
  // src/TcpModbusServerService.ts
740
736
  import { Effect as Effect10, Layer as Layer6 } from "effect";
741
- var tcpServerLayer = (options, handlers) => Layer6.scopedDiscard(Effect10.gen(function* () {
737
+ var tcpServerLayer = (options, handlers) => Layer6.effectDiscard(Effect10.gen(function* () {
742
738
  const { AsyncTcpModbusServer } = yield* Effect10.promise(() => import("modbus-rs"));
743
739
  const server = yield* Effect10.tryPromise({
744
740
  try: () => AsyncTcpModbusServer.bind(options, handlers),
@@ -748,11 +744,11 @@ var tcpServerLayer = (options, handlers) => Layer6.scopedDiscard(Effect10.gen(fu
748
744
  yield* Effect10.addFinalizer(() => Effect10.logDebug("TCP server shutting down").pipe(Effect10.andThen(Effect10.tryPromise({
749
745
  try: () => server.shutdown(),
750
746
  catch: (error) => toModbusError(error)
751
- })), Effect10.catchAll(() => Effect10.void)));
747
+ })), Effect10.catch(() => Effect10.void)));
752
748
  }));
753
749
  // src/TcpGatewayService.ts
754
750
  import { Effect as Effect11, Layer as Layer7 } from "effect";
755
- var tcpGatewayLayer = (options, gatewayConfig) => Layer7.scopedDiscard(Effect11.gen(function* () {
751
+ var tcpGatewayLayer = (options, gatewayConfig) => Layer7.effectDiscard(Effect11.gen(function* () {
756
752
  const { AsyncTcpGateway } = yield* Effect11.promise(() => import("modbus-rs"));
757
753
  const gateway = yield* Effect11.tryPromise({
758
754
  try: () => AsyncTcpGateway.bind(options, gatewayConfig),
@@ -762,50 +758,50 @@ var tcpGatewayLayer = (options, gatewayConfig) => Layer7.scopedDiscard(Effect11.
762
758
  yield* Effect11.addFinalizer(() => Effect11.logDebug("TCP gateway shutting down").pipe(Effect11.andThen(Effect11.tryPromise({
763
759
  try: () => gateway.shutdown(),
764
760
  catch: (error) => toModbusError(error)
765
- })), Effect11.catchAll(() => Effect11.void)));
761
+ })), Effect11.catch(() => Effect11.void)));
766
762
  }));
767
763
  // src/WasmWsTransportService.ts
768
- import { Effect as Effect12, Layer as Layer8 } from "effect";
769
- class WasmWsTransportService extends Effect12.Service()("WasmWsTransportService", {
770
- scoped: makeTransportScoped("WasmWsTransport", (TC, options) => TC.connect(options), "WasmWsTransportService", { moduleSpecifier: "modbus-rs/web" })
771
- }) {
764
+ import { Context as Context5, Layer as Layer8 } from "effect";
765
+ class WasmWsTransportService extends Context5.Service()("WasmWsTransportService") {
766
+ static makeScoped = makeTransportScoped("WasmWsTransport", (TC, options) => TC.connect(options), "WasmWsTransportService", { moduleSpecifier: "modbus-rs/web" });
767
+ static make = (options) => Layer8.effect(WasmWsTransportService, WasmWsTransportService.makeScoped(options));
772
768
  static makeMockTransport = (devices) => {
773
769
  const factory = makeMockTransport(devices);
774
- return (options) => Layer8.scoped(WasmWsTransportService, factory(options));
770
+ return (options) => Layer8.effect(WasmWsTransportService, factory(options));
775
771
  };
776
772
  }
777
773
  // src/WasmRtuTransportService.ts
778
- import { Effect as Effect13, Layer as Layer9 } from "effect";
779
- class WasmRtuTransportService extends Effect13.Service()("WasmRtuTransportService", {
780
- scoped: makeTransportScoped("WasmRtuTransport", (TC, { port, ...rest }) => TC.open(port, rest), "WasmRtuTransportService", { moduleSpecifier: "modbus-rs/web" })
781
- }) {
774
+ import { Context as Context6, Layer as Layer9 } from "effect";
775
+ class WasmRtuTransportService extends Context6.Service()("WasmRtuTransportService") {
776
+ static makeScoped = makeTransportScoped("WasmRtuTransport", (TC, { port, ...rest }) => TC.open(port, rest), "WasmRtuTransportService", { moduleSpecifier: "modbus-rs/web" });
777
+ static make = (options) => Layer9.effect(WasmRtuTransportService, WasmRtuTransportService.makeScoped(options));
782
778
  static makeMockTransport = (devices) => {
783
779
  const factory = makeMockTransport(devices);
784
- return (options) => Layer9.scoped(WasmRtuTransportService, factory(options));
780
+ return (options) => Layer9.effect(WasmRtuTransportService, factory(options));
785
781
  };
786
782
  }
787
783
  // src/WasmAsciiTransportService.ts
788
- import { Effect as Effect14, Layer as Layer10 } from "effect";
789
- class WasmAsciiTransportService extends Effect14.Service()("WasmAsciiTransportService", {
790
- scoped: makeTransportScoped("WasmAsciiTransport", (TC, { port, ...rest }) => TC.open(port, rest), "WasmAsciiTransportService", { moduleSpecifier: "modbus-rs/web" })
791
- }) {
784
+ import { Context as Context7, Layer as Layer10 } from "effect";
785
+ class WasmAsciiTransportService extends Context7.Service()("WasmAsciiTransportService") {
786
+ static makeScoped = makeTransportScoped("WasmAsciiTransport", (TC, { port, ...rest }) => TC.open(port, rest), "WasmAsciiTransportService", { moduleSpecifier: "modbus-rs/web" });
787
+ static make = (options) => Layer10.effect(WasmAsciiTransportService, WasmAsciiTransportService.makeScoped(options));
792
788
  static makeMockTransport = (devices) => {
793
789
  const factory = makeMockTransport(devices);
794
- return (options) => Layer10.scoped(WasmAsciiTransportService, factory(options));
790
+ return (options) => Layer10.effect(WasmAsciiTransportService, factory(options));
795
791
  };
796
792
  }
797
793
  // src/WasmSerialTransportService.ts
798
- import { Context as Context2, Layer as Layer11 } from "effect";
799
- class WasmSerialTransportService extends Context2.Tag("WasmSerialTransportService")() {
794
+ import { Context as Context8, Layer as Layer11 } from "effect";
795
+ class WasmSerialTransportService extends Context8.Service()("WasmSerialTransportService") {
800
796
  static fromAscii(options) {
801
- return Layer11.project(WasmAsciiTransportService, WasmSerialTransportService, (ascii) => ascii)(WasmAsciiTransportService.Default(options));
797
+ return Layer11.flatMap(WasmAsciiTransportService.make(options), (context) => Layer11.succeed(WasmSerialTransportService, Context8.get(context, WasmAsciiTransportService)));
802
798
  }
803
799
  static fromRtu(options) {
804
- return Layer11.project(WasmRtuTransportService, WasmSerialTransportService, (rtu) => rtu)(WasmRtuTransportService.Default(options));
800
+ return Layer11.flatMap(WasmRtuTransportService.make(options), (context) => Layer11.succeed(WasmSerialTransportService, Context8.get(context, WasmRtuTransportService)));
805
801
  }
806
802
  static makeMockTransport = (devices) => {
807
803
  const factory = makeMockTransport(devices);
808
- return (options) => Layer11.scoped(WasmSerialTransportService, factory(options));
804
+ return (options) => Layer11.effect(WasmSerialTransportService, factory(options));
809
805
  };
810
806
  }
811
807
  // src/WasmSerialPort.ts
@@ -819,7 +815,7 @@ var requestSerialPort = () => Effect15.tryPromise({
819
815
  });
820
816
  // src/WasmTcpServerService.ts
821
817
  import { Effect as Effect16, Layer as Layer12 } from "effect";
822
- var wasmWsServerLayer = (options, handlers) => Layer12.scopedDiscard(Effect16.gen(function* () {
818
+ var wasmWsServerLayer = (options, handlers) => Layer12.effectDiscard(Effect16.gen(function* () {
823
819
  const { WasmWsModbusServer } = yield* Effect16.promise(() => import("modbus-rs/web"));
824
820
  const server = yield* Effect16.tryPromise({
825
821
  try: () => WasmWsModbusServer.bind(options, handlers),
@@ -829,15 +825,15 @@ var wasmWsServerLayer = (options, handlers) => Layer12.scopedDiscard(Effect16.ge
829
825
  yield* Effect16.forkScoped(Effect16.tryPromise({
830
826
  try: () => server.serve(),
831
827
  catch: (error) => toModbusError(error)
832
- }).pipe(Effect16.catchAll((error) => Effect16.logError("WASM WS server loop ended", error))));
828
+ }).pipe(Effect16.catch((error) => Effect16.logError("WASM WS server loop ended", error))));
833
829
  yield* Effect16.addFinalizer(() => Effect16.logDebug("WASM WS server shutting down").pipe(Effect16.andThen(Effect16.tryPromise({
834
830
  try: () => server.shutdown(),
835
831
  catch: (error) => toModbusError(error)
836
- })), Effect16.catchAll(() => Effect16.void)));
832
+ })), Effect16.catch(() => Effect16.void)));
837
833
  }));
838
834
  // src/WasmSerialModbusServerService.ts
839
835
  import { Effect as Effect17, Layer as Layer13 } from "effect";
840
- var wasmSerialRtuServerLayer = (options, handlers) => Layer13.scopedDiscard(Effect17.gen(function* () {
836
+ var wasmSerialRtuServerLayer = (options, handlers) => Layer13.effectDiscard(Effect17.gen(function* () {
841
837
  const { WasmSerialModbusServer } = yield* Effect17.promise(() => import("modbus-rs/web"));
842
838
  const server = yield* Effect17.tryPromise({
843
839
  try: () => WasmSerialModbusServer.bindRtu(options, handlers),
@@ -847,13 +843,13 @@ var wasmSerialRtuServerLayer = (options, handlers) => Layer13.scopedDiscard(Effe
847
843
  yield* Effect17.forkScoped(Effect17.tryPromise({
848
844
  try: () => server.serve(),
849
845
  catch: (error) => toModbusError(error)
850
- }).pipe(Effect17.catchAll((error) => Effect17.logError("WASM serial RTU server loop ended", error))));
846
+ }).pipe(Effect17.catch((error) => Effect17.logError("WASM serial RTU server loop ended", error))));
851
847
  yield* Effect17.addFinalizer(() => Effect17.logDebug("WASM serial RTU server shutting down").pipe(Effect17.andThen(Effect17.tryPromise({
852
848
  try: () => server.shutdown(),
853
849
  catch: (error) => toModbusError(error)
854
- })), Effect17.catchAll(() => Effect17.void)));
850
+ })), Effect17.catch(() => Effect17.void)));
855
851
  }));
856
- var wasmSerialAsciiServerLayer = (options, handlers) => Layer13.scopedDiscard(Effect17.gen(function* () {
852
+ var wasmSerialAsciiServerLayer = (options, handlers) => Layer13.effectDiscard(Effect17.gen(function* () {
857
853
  const { WasmSerialModbusServer } = yield* Effect17.promise(() => import("modbus-rs/web"));
858
854
  const server = yield* Effect17.tryPromise({
859
855
  try: () => WasmSerialModbusServer.bindAscii(options, handlers),
@@ -863,41 +859,41 @@ var wasmSerialAsciiServerLayer = (options, handlers) => Layer13.scopedDiscard(Ef
863
859
  yield* Effect17.forkScoped(Effect17.tryPromise({
864
860
  try: () => server.serve(),
865
861
  catch: (error) => toModbusError(error)
866
- }).pipe(Effect17.catchAll((error) => Effect17.logError("WASM serial ASCII server loop ended", error))));
862
+ }).pipe(Effect17.catch((error) => Effect17.logError("WASM serial ASCII server loop ended", error))));
867
863
  yield* Effect17.addFinalizer(() => Effect17.logDebug("WASM serial ASCII server shutting down").pipe(Effect17.andThen(Effect17.tryPromise({
868
864
  try: () => server.shutdown(),
869
865
  catch: (error) => toModbusError(error)
870
- })), Effect17.catchAll(() => Effect17.void)));
866
+ })), Effect17.catch(() => Effect17.void)));
871
867
  }));
872
868
  export {
873
- wasmWsServerLayer,
874
- wasmSerialRtuServerLayer,
875
- wasmSerialAsciiServerLayer,
876
- toModbusError,
877
- tcpServerLayer,
878
- tcpGatewayLayer,
879
- serialRtuServerLayer,
880
- serialAsciiServerLayer,
881
- retryableExceptionCodes,
882
- retryModbus,
883
- requestSerialPort,
884
- makeRetryPolicy,
885
- WasmWsTransportService,
886
- WasmSerialTransportService,
887
- WasmRtuTransportService,
888
- WasmAsciiTransportService,
889
- TcpTransportService,
890
- SerialTransportService,
891
- RtuTransportService,
892
- RetryPolicies,
893
- ModbusTransportError,
894
- ModbusTimeoutError,
895
- ModbusNotConnectedError,
896
- ModbusInvalidArgumentError,
897
- ModbusInternalError,
898
- ModbusExceptionError,
899
- ModbusConnectionClosedError,
900
- ModbusCircuitOpenError,
869
+ AsciiTransportService,
901
870
  ConnectionState,
902
- AsciiTransportService
871
+ ModbusCircuitOpenError,
872
+ ModbusConnectionClosedError,
873
+ ModbusExceptionError,
874
+ ModbusInternalError,
875
+ ModbusInvalidArgumentError,
876
+ ModbusNotConnectedError,
877
+ ModbusTimeoutError,
878
+ ModbusTransportError,
879
+ RetryPolicies,
880
+ RtuTransportService,
881
+ SerialTransportService,
882
+ TcpTransportService,
883
+ WasmAsciiTransportService,
884
+ WasmRtuTransportService,
885
+ WasmSerialTransportService,
886
+ WasmWsTransportService,
887
+ makeRetryPolicy,
888
+ requestSerialPort,
889
+ retryModbus,
890
+ retryableExceptionCodes,
891
+ serialAsciiServerLayer,
892
+ serialRtuServerLayer,
893
+ tcpGatewayLayer,
894
+ tcpServerLayer,
895
+ toModbusError,
896
+ wasmSerialAsciiServerLayer,
897
+ wasmSerialRtuServerLayer,
898
+ wasmWsServerLayer
903
899
  };