@xstate/effect 1.0.0-beta.1 → 1.0.0-beta.2
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
|
@@ -264,12 +264,13 @@ See [atoms and React](docs/atoms-and-react.md) for complete examples with import
|
|
|
264
264
|
|
|
265
265
|
## Testing and errors
|
|
266
266
|
|
|
267
|
-
<!-- error types from src/errors.ts; timeout failure from src/actor.ts -->
|
|
267
|
+
<!-- error types and causeFromError from src/errors.ts; timeout failure from src/actor.ts -->
|
|
268
268
|
|
|
269
269
|
- Use `sendAndAwait` from `@xstate/effect` to acknowledge one event after its transition and immediate effects. It does not wait for child replies, invoked work, background actions or future timers.
|
|
270
270
|
- Use `TestClock` to drive deadlines without waiting for real time.
|
|
271
271
|
- `ActorStoppedError` reports a stop before an awaited result.
|
|
272
272
|
- `EffectFailure<E>` carries the original `Cause<E>` in task and stream error snapshots, including defects and self-interruption.
|
|
273
|
+
- Use `causeFromError(error)` to obtain the original Cause from `EffectFailure` or wrap an ordinary error. Use `Cause.findErrorOption` to inspect its typed failure.
|
|
273
274
|
- Timed waits fail with Effect's `Cause.TimeoutError`.
|
|
274
275
|
- `join` replays the original Cause and preserves a task's typed failure. Unexpected machine errors have type `unknown`.
|
|
275
276
|
|
|
@@ -53,6 +53,18 @@ declare const NotReadyError_base: new <A extends Record<string, any> = {}>(args:
|
|
|
53
53
|
export declare class NotReadyError extends NotReadyError_base {
|
|
54
54
|
get message(): string;
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Returns an EffectFailure's original Cause, or wraps an ordinary error with
|
|
58
|
+
* Cause.fail. Defects and interruption in an existing Cause are preserved.
|
|
59
|
+
*
|
|
60
|
+
* @experimental
|
|
61
|
+
*/
|
|
62
|
+
export declare function causeFromError<E>(error: E): Cause.Cause<UnwrapEffectFailure<E>>;
|
|
63
|
+
/**
|
|
64
|
+
* Extracts the typed failure from EffectFailure while retaining ordinary errors.
|
|
65
|
+
*
|
|
66
|
+
* @experimental
|
|
67
|
+
*/
|
|
56
68
|
export type UnwrapEffectFailure<E> = E extends EffectFailure<infer Failure> ? Failure : E;
|
|
57
69
|
declare const EventRejectedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
58
70
|
readonly _tag: "EventRejectedError";
|
|
@@ -4,7 +4,7 @@ export { EffectActor } from "./effectActor.js";
|
|
|
4
4
|
export { sendAndAwait } from "./sendAndAwait.js";
|
|
5
5
|
export { ActorScope, withActorScope } from "./actorScope.js";
|
|
6
6
|
export { deadLetters, emitted, inspect, join, send, snapshots, waitFor, type EmittedEventFrom, type SendableEventFrom, type WaitForOptions } from "./actor.js";
|
|
7
|
-
export { ActorStoppedError, EventRejectedError, EffectFailure, EffectInterruptedError } from "./errors.js";
|
|
7
|
+
export { ActorStoppedError, EventRejectedError, EffectFailure, EffectInterruptedError, causeFromError, type UnwrapEffectFailure } from "./errors.js";
|
|
8
8
|
export { setupEffect, type EffectAction, type EffectActionArgs, type EffectSetupReturn } from "./setupEffect.js";
|
|
9
9
|
export { type RequirementsFrom } from "./types.js";
|
|
10
10
|
export { taggedState, type StateTag, type TaggedState, type TaggedStateFrom } from "./state.js";
|
|
@@ -79,10 +79,22 @@ class NotReadyError extends Data.TaggedError('NotReadyError') {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* Returns an EffectFailure's original Cause, or wraps an ordinary error with
|
|
84
|
+
* Cause.fail. Defects and interruption in an existing Cause are preserved.
|
|
85
|
+
*
|
|
86
|
+
* @experimental
|
|
87
|
+
*/
|
|
83
88
|
function causeFromError(error) {
|
|
84
89
|
return error instanceof EffectFailure ? error.cause : Cause.fail(error);
|
|
85
90
|
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Extracts the typed failure from EffectFailure while retaining ordinary errors.
|
|
94
|
+
*
|
|
95
|
+
* @experimental
|
|
96
|
+
*/
|
|
97
|
+
|
|
86
98
|
/**
|
|
87
99
|
* An event rejected at the actor's delivery boundary.
|
|
88
100
|
*
|
|
@@ -576,15 +588,16 @@ function closeEffectHost(host) {
|
|
|
576
588
|
discard: true
|
|
577
589
|
}).pipe(Effect.andThen(Scope.close(host.scope, Exit.void))));
|
|
578
590
|
}
|
|
591
|
+
const EFFECT_FORWARD = 'xstate.effect.forward';
|
|
579
592
|
|
|
580
|
-
/**
|
|
581
|
-
* Delivers a stream item to the parent as an event. This runs outside a
|
|
582
|
-
* transition, so it uses the system relay like core's observable logic does.
|
|
583
|
-
*/
|
|
593
|
+
/** Queues a stream item for the source actor to forward in its transition. */
|
|
584
594
|
function relayToParent(actor, event) {
|
|
585
595
|
const actorWithParent = actor;
|
|
586
596
|
if (actorWithParent._parent) {
|
|
587
|
-
actor.system._relay(actorWithParent, actorWithParent
|
|
597
|
+
actor.system._relay(actorWithParent, actorWithParent, {
|
|
598
|
+
type: EFFECT_FORWARD,
|
|
599
|
+
event
|
|
600
|
+
});
|
|
588
601
|
}
|
|
589
602
|
}
|
|
590
603
|
|
|
@@ -987,4 +1000,4 @@ function taggedState(snapshot) {
|
|
|
987
1000
|
};
|
|
988
1001
|
}
|
|
989
1002
|
|
|
990
|
-
export { ActorStoppedError as A,
|
|
1003
|
+
export { ActorStoppedError as A, EFFECT_FORWARD as E, NotReadyError as N, causeFromError as a, EffectFailure as b, createEffectActor as c, runHostedEffect as d, EffectActor as e, ActorScope as f, EventRejectedError as g, EffectInterruptedError as h, relayToParent as r, startHostedEffect as s, taggedState as t, withActorScope as w };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Cause } from 'effect';
|
|
2
2
|
import { Atom, AsyncResult } from 'effect/reactivity';
|
|
3
3
|
import { StateMachine } from 'xstate';
|
|
4
|
-
import { c as createEffectActor, a as causeFromError, N as NotReadyError, t as taggedState } from './state-
|
|
5
|
-
export { N as NotReadyError } from './state-
|
|
4
|
+
import { c as createEffectActor, a as causeFromError, N as NotReadyError, t as taggedState } from './state-54c1cda0.js';
|
|
5
|
+
export { N as NotReadyError } from './state-54c1cda0.js';
|
|
6
6
|
import 'xstate/durable';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/xstate-effect.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Schema, Effect, Stream, Cause, Exit, Queue, Data } from 'effect';
|
|
2
2
|
import { createStepLogic, setup } from 'xstate';
|
|
3
|
-
import { s as startHostedEffect, r as relayToParent,
|
|
4
|
-
export {
|
|
3
|
+
import { s as startHostedEffect, E as EFFECT_FORWARD, r as relayToParent, b as EffectFailure, A as ActorStoppedError, a as causeFromError, d as runHostedEffect } from './state-54c1cda0.js';
|
|
4
|
+
export { f as ActorScope, A as ActorStoppedError, e as EffectActor, b as EffectFailure, h as EffectInterruptedError, g as EventRejectedError, a as causeFromError, c as createEffectActor, t as taggedState, w as withActorScope } from './state-54c1cda0.js';
|
|
5
5
|
export { s as sendAndAwait } from './sendAndAwait-bf1d4117.js';
|
|
6
6
|
import { dual } from 'effect/Function';
|
|
7
7
|
import 'xstate/durable';
|
|
@@ -390,7 +390,9 @@ function createEffectEventStreamLogic(sourceOrConfig) {
|
|
|
390
390
|
const stream = config.stream;
|
|
391
391
|
const logic = createStepLogic({
|
|
392
392
|
id: config.id,
|
|
393
|
-
validator: config.validator
|
|
393
|
+
validator: config.validator && {
|
|
394
|
+
check: request => request.kind === 'event' && request.event.type === EFFECT_FORWARD ? undefined : config.validator.check(request)
|
|
395
|
+
},
|
|
394
396
|
schemas: toLogicSchemas(config.schemas),
|
|
395
397
|
context: undefined,
|
|
396
398
|
run: ({
|
|
@@ -399,6 +401,10 @@ function createEffectEventStreamLogic(sourceOrConfig) {
|
|
|
399
401
|
self,
|
|
400
402
|
system
|
|
401
403
|
}, enq) => {
|
|
404
|
+
if (event.type === EFFECT_FORWARD) {
|
|
405
|
+
enq.sendBack(event.event);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
402
408
|
if (event.type === EFFECT_COMPLETE) {
|
|
403
409
|
return {
|
|
404
410
|
status: 'done',
|
|
@@ -434,6 +440,9 @@ function createEffectEventStreamLogic(sourceOrConfig) {
|
|
|
434
440
|
}));
|
|
435
441
|
}
|
|
436
442
|
});
|
|
443
|
+
Object.assign(logic, {
|
|
444
|
+
isInternalEventType: eventType => eventType === EFFECT_FORWARD
|
|
445
|
+
});
|
|
437
446
|
return brandLogic(logic, undefined, undefined);
|
|
438
447
|
}
|
|
439
448
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xstate/effect",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Effect integration for XState",
|
|
6
6
|
"keywords": [
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@oxlint/plugins": "^1.76.0",
|
|
35
35
|
"effect": "^4.0.0",
|
|
36
|
-
"xstate": "^6.0.0-beta.
|
|
36
|
+
"xstate": "^6.0.0-beta.3"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@oxlint/plugins": "^1.76.0",
|
|
40
40
|
"effect": "4.0.6",
|
|
41
41
|
"fast-check": "4.10.2",
|
|
42
42
|
"@xstate/test": "^2.0.0-beta.1",
|
|
43
|
-
"xstate": "^6.0.0-beta.
|
|
43
|
+
"xstate": "^6.0.0-beta.3"
|
|
44
44
|
},
|
|
45
45
|
"preconstruct": {
|
|
46
46
|
"entrypoints": [
|