@xstate/effect 0.1.0-alpha.2 → 0.1.0-alpha.4

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
@@ -195,7 +195,7 @@ These are free functions that take any XState `ActorRef`, including the `EffectA
195
195
  | `waitFor(actor, predicate, { timeout })` | `Effect<Snapshot, ActorStoppedError \| Cause.TimeoutError>` |
196
196
  | `join(actor)` | `Effect<Output, ErrorFrom<Logic> \| ActorStoppedError>` |
197
197
  | `inspect(actor)` | `Stream<InspectionEvent>` |
198
- | `deadLetters(actor)` | `Stream<DeadLetterInspectionEvent>` |
198
+ | `deadLetters(actor)` | `Stream<EventRejection>` |
199
199
 
200
200
  `send` and `waitFor` are dual: each takes the actor first, or returns a function of the actor so it can be piped.
201
201
 
@@ -215,7 +215,9 @@ const snapshot = yield* waitFor(
215
215
 
216
216
  The `timeout` failure is Effect's `Cause.TimeoutError`, not the `TimeoutError` that `xstate` exports for its own delayed-transition errors.
217
217
 
218
- `snapshots` ends when the actor completes. If the actor errors, the stream emits the error snapshot and ends. `waitFor` and `join` fail with `ActorStoppedError` when the actor stops or errors before the awaited result; `join` fails with the actor's typed error when the actor's status is `error`.
218
+ `snapshots` ends when the actor completes. If the actor errors, the stream emits the error snapshot and ends. `waitFor` fails with `ActorStoppedError` when the actor stops or errors before the awaited result. `join` fails with `ActorStoppedError` when the actor stops without output, and with `snapshot.error` when the actor's status is `error`.
219
+
220
+ For `fromEffect` logic that typed error is the Effect's `E`. For a machine it is `unknown`, because an action can throw an arbitrary value or an unhandled child error can fail the machine, so `join(machineActor)` has `unknown` in its error channel. Model domain failures as final states and read them from the machine's output; treat a machine-level error as a defect with `Effect.orDie`, or handle it with `Effect.catch`, to keep the rest of the program typed.
219
221
 
220
222
  ```ts
221
223
  const program = Effect.gen(function* () {
@@ -554,7 +556,7 @@ Assert with `waitFor` for a state the actor should reach, and with `join` for th
554
556
 
555
557
  Observe with `inspect` for every inspection event and `deadLetters` for events the system could not deliver. A test that ends with no dead letters confirms that every event it sent was accepted.
556
558
 
557
- Path generation in `xstate/graph` (`getShortestPaths`, `getSimplePaths`, `createTestModel`) operates on the machine, not on a running actor, so it works on an Effect-backed machine unchanged. Execute the generated paths against an actor from `createEffectActor`.
559
+ Path generation in `xstate/graph` (`getShortestPaths`, `getSimplePaths`) operates on the machine, not on a running actor, so it works on an Effect-backed machine unchanged. Execute the generated paths against an actor from `createEffectActor`, or run them with `testPaths()` from `@xstate/test`.
558
560
 
559
561
  ## Retries and supervision
560
562
 
@@ -575,7 +577,7 @@ const supervised = Effect.retry(Effect.scoped(program), {
575
577
  });
576
578
  ```
577
579
 
578
- `join` fails with the machine's typed error, so the schedule sees the actual failure. Retrying `program` without `Effect.scoped` would reuse the outer scope and leak the actors from failed attempts until that scope closes.
580
+ `join` fails when the actor errors or stops before producing output, so the schedule sees the actual failure. For a machine that failure is `unknown` (see [Observing actors](#observing-actors)); narrow it before the retry if the schedule should only see some errors. Retrying `program` without `Effect.scoped` would reuse the outer scope and leak the actors from failed attempts until that scope closes.
579
581
 
580
582
  ## Errors
581
583
 
@@ -583,7 +585,7 @@ const supervised = Effect.retry(Effect.scoped(program), {
583
585
 
584
586
  | Error | Raised by | Fields |
585
587
  | ------------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------------------ |
586
- | `ActorStoppedError` | `waitFor`, `join` when the actor stops or errors before the awaited result | `actorId: string`, `snapshot: Snapshot<unknown>` |
588
+ | `ActorStoppedError` | `waitFor` when the actor stops or errors; `join` when it stops without output | `actorId: string`, `snapshot: Snapshot<unknown>` |
587
589
  | `EffectInterruptedError` | Effect logic interrupted from inside, such as `Effect.interrupt`, reported as `snapshot.error` | `cause: Cause.Cause<never>` |
588
590
  | `Cause.TimeoutError` | `waitFor` with `{ timeout }` when no snapshot matches in time | Effect's own error; `_tag: 'TimeoutError'` |
589
591
 
@@ -1,5 +1,5 @@
1
1
  import { Cause, Duration, Effect, Stream } from 'effect';
2
- import type { Actor, ActorRef, AnyActorRef, AnyEventObject, DeadLetterInspectionEvent, EmittedFrom, ErrorFrom, InspectionEvent, OutputFrom, SnapshotFrom } from 'xstate';
2
+ import type { Actor, ActorRef, AnyActorRef, AnyEventObject, EmittedFrom, EventRejection, ErrorFrom, InspectionEvent, OutputFrom, SnapshotFrom } from 'xstate';
3
3
  import type { EffectActor } from "./effectActor.js";
4
4
  import { ActorStoppedError } from "./errors.js";
5
5
  /** The event type accepted by an actor's `send` method. */
@@ -68,9 +68,10 @@ export declare function join<TActor extends AnyActorRef>(actor: TActor): Effect.
68
68
  */
69
69
  export declare function inspect(actor: AnyActorRef): Stream.Stream<InspectionEvent>;
70
70
  /**
71
- * Streams the events the actor's system could not deliver: sends to a
72
- * stopped actor, invalid external events and internal events sent from
73
- * outside their owner. A dead letter is not an actor error. The stream runs
74
- * until it is interrupted or its scope closes.
71
+ * Streams the events the actor's system could not deliver, as reported by
72
+ * `system.onRejectedEvent`: sends to a stopped actor, invalid external
73
+ * events and internal events sent from outside their owner. A dead letter is
74
+ * not an actor error. The stream runs until it is interrupted or its scope
75
+ * closes.
75
76
  */
76
- export declare function deadLetters(actor: AnyActorRef): Stream.Stream<DeadLetterInspectionEvent>;
77
+ export declare function deadLetters(actor: AnyActorRef): Stream.Stream<EventRejection>;
@@ -48,7 +48,7 @@ export declare class EffectActor<TLogic extends AnyActorLogic> implements ActorR
48
48
  })) => void): Subscription;
49
49
  /**
50
50
  * Observes the inspection events of this actor and its children: every
51
- * transition, event delivery and dead letter of the execution.
51
+ * actor creation and transition of the execution.
52
52
  */
53
53
  inspect(observer: Observer<InspectionEvent> | ((event: InspectionEvent) => void)): Subscription;
54
54
  [symbolObservable](): this;
@@ -130,7 +130,7 @@ class EffectActor {
130
130
 
131
131
  /**
132
132
  * Observes the inspection events of this actor and its children: every
133
- * transition, event delivery and dead letter of the execution.
133
+ * actor creation and transition of the execution.
134
134
  */
135
135
  inspect(observer) {
136
136
  const handler = typeof observer === 'function' ? observer : event => observer.next?.(event);
@@ -1,7 +1,7 @@
1
1
  import { Cause } from 'effect';
2
2
  import { Atom, AsyncResult } from 'effect/unstable/reactivity';
3
- import { c as createEffectActor, N as NotReadyError, t as taggedState } from './state-9a718be3.js';
4
- export { N as NotReadyError } from './state-9a718be3.js';
3
+ import { c as createEffectActor, N as NotReadyError, t as taggedState } from './state-798ea663.js';
4
+ export { N as NotReadyError } from './state-798ea663.js';
5
5
  import 'xstate';
6
6
  import 'xstate/durable';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { Schema, Effect, Stream, Exit, Cause, Queue } from 'effect';
2
2
  import { createLogic, setup } from 'xstate';
3
- import { s as startHostedEffect, r as relayToParent, E as EffectInterruptedError, A as ActorStoppedError, a as runHostedEffect } from './state-9a718be3.js';
4
- export { A as ActorStoppedError, b as EffectActor, E as EffectInterruptedError, c as createEffectActor, t as taggedState } from './state-9a718be3.js';
3
+ import { s as startHostedEffect, r as relayToParent, E as EffectInterruptedError, A as ActorStoppedError, a as runHostedEffect } from './state-798ea663.js';
4
+ export { A as ActorStoppedError, b as EffectActor, E as EffectInterruptedError, c as createEffectActor, t as taggedState } from './state-798ea663.js';
5
5
  import { dual } from 'effect/Function';
6
6
  import 'xstate/durable';
7
7
 
@@ -608,13 +608,18 @@ function inspect(actor) {
608
608
  }
609
609
 
610
610
  /**
611
- * Streams the events the actor's system could not deliver: sends to a
612
- * stopped actor, invalid external events and internal events sent from
613
- * outside their owner. A dead letter is not an actor error. The stream runs
614
- * until it is interrupted or its scope closes.
611
+ * Streams the events the actor's system could not deliver, as reported by
612
+ * `system.onRejectedEvent`: sends to a stopped actor, invalid external
613
+ * events and internal events sent from outside their owner. A dead letter is
614
+ * not an actor error. The stream runs until it is interrupted or its scope
615
+ * closes.
615
616
  */
616
617
  function deadLetters(actor) {
617
- return Stream.filter(inspect(actor), event => event.type === '@xstate.deadletter');
618
+ return Stream.callback(queue => Effect.acquireRelease(Effect.sync(() => actor.system.onRejectedEvent(rejection => {
619
+ Queue.offerUnsafe(queue, rejection);
620
+ })), subscription => Effect.sync(() => {
621
+ subscription.unsubscribe();
622
+ })));
618
623
  }
619
624
 
620
625
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xstate/effect",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
4
4
  "type": "module",
5
5
  "description": "Effect integration for XState",
6
6
  "keywords": [
@@ -30,11 +30,11 @@
30
30
  },
31
31
  "peerDependencies": {
32
32
  "effect": "^4.0.0-rc.115",
33
- "xstate": "^6.0.0-alpha.58"
33
+ "xstate": "^6.0.0-alpha.61"
34
34
  },
35
35
  "devDependencies": {
36
36
  "effect": "4.0.0-rc.115",
37
- "xstate": "^6.0.0-alpha.58"
37
+ "xstate": "^6.0.0-alpha.61"
38
38
  },
39
39
  "preconstruct": {
40
40
  "entrypoints": [