@xstate/effect 0.1.0-alpha.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/LICENSE +22 -0
- package/README.md +611 -0
- package/dist/declarations/src/actor.d.ts +76 -0
- package/dist/declarations/src/atom.d.ts +56 -0
- package/dist/declarations/src/brands.d.ts +1 -0
- package/dist/declarations/src/createEffectActor.d.ts +30 -0
- package/dist/declarations/src/effectActor.d.ts +60 -0
- package/dist/declarations/src/errors.d.ts +40 -0
- package/dist/declarations/src/fromEffect.d.ts +176 -0
- package/dist/declarations/src/index.d.ts +10 -0
- package/dist/declarations/src/schema.d.ts +80 -0
- package/dist/declarations/src/setupEffect.d.ts +94 -0
- package/dist/declarations/src/state.d.ts +44 -0
- package/dist/declarations/src/types.d.ts +52 -0
- package/dist/state-9a718be3.js +733 -0
- package/dist/xstate-effect-atom.d.ts +2 -0
- package/dist/xstate-effect-atom.js +88 -0
- package/dist/xstate-effect.d.ts +2 -0
- package/dist/xstate-effect.js +702 -0
- package/package.json +46 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { type ActorLogicValidator, type AnyActorRef, type EventObject, type MachineContext, type SetupConfig, type SetupReturn, type SetupSchemas, type SetupStateSchema, type Sources, type SystemRegistry, type SystemRuntime } from 'xstate';
|
|
3
|
+
import { effectActionBrand } from "./brands.js";
|
|
4
|
+
import type { EffectRequirements } from "./types.js";
|
|
5
|
+
import { type EffectSetupSchemas, type EffectSetupStateSchema, type ToStandardSetupSchemas, type ToStandardSetupStates, type ValidateEffectSetupSchemas, type ValidateEffectSetupStates } from "./schema.js";
|
|
6
|
+
/**
|
|
7
|
+
* Argument an Effect action receives. It mirrors the v6 action argument
|
|
8
|
+
* object: the machine's `context` and the `event` that caused the transition,
|
|
9
|
+
* the actor itself and its family (`self`, `parent`, `children`), the
|
|
10
|
+
* registered `actions`, `actors`, `guards` and `delays`, the actor `system`,
|
|
11
|
+
* and the `params` and `output` the transition passed along.
|
|
12
|
+
*/
|
|
13
|
+
export type EffectActionArgs<TContext extends MachineContext = MachineContext, TEvent extends EventObject = EventObject> = {
|
|
14
|
+
readonly context: TContext;
|
|
15
|
+
readonly event: TEvent;
|
|
16
|
+
readonly self: AnyActorRef;
|
|
17
|
+
readonly parent: AnyActorRef | undefined;
|
|
18
|
+
readonly children: Record<string, AnyActorRef | undefined>;
|
|
19
|
+
readonly actions: Record<string, unknown>;
|
|
20
|
+
readonly actors: Record<string, unknown>;
|
|
21
|
+
readonly guards: Record<string, unknown>;
|
|
22
|
+
readonly delays: Record<string, unknown>;
|
|
23
|
+
readonly system: SystemRuntime<SystemRegistry>;
|
|
24
|
+
readonly params?: unknown;
|
|
25
|
+
readonly output?: unknown;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* An action registered with `setupEffect({ actions })`. It is called
|
|
29
|
+
* synchronously during the transition with the arguments the transition
|
|
30
|
+
* enqueued, and returns an Effect that runs afterwards in the actor's Effect
|
|
31
|
+
* context. The Effect is interrupted when the actor stops; its failures and
|
|
32
|
+
* defects route to the state's `onError`.
|
|
33
|
+
*/
|
|
34
|
+
export type EffectAction<TContext extends MachineContext = MachineContext, TEvent extends EventObject = EventObject, TError = unknown, TRequirements = never> = (args: EffectActionArgs<TContext, TEvent>) => Effect.Effect<void, TError, TRequirements>;
|
|
35
|
+
type AnyEffectAction = EffectAction<any, any, any, any>;
|
|
36
|
+
type EffectActionRequirements<TAction> = TAction extends (...args: any[]) => infer TResult ? EffectRequirements<TResult> : never;
|
|
37
|
+
type CoreEffectAction<TAction> = TAction extends (...args: infer TArgs) => any ? ((...args: TArgs) => void) & {
|
|
38
|
+
readonly [effectActionBrand]?: EffectActionRequirements<TAction>;
|
|
39
|
+
} : never;
|
|
40
|
+
type CoreEffectActionMap<TActionMap> = {
|
|
41
|
+
[K in keyof TActionMap]: CoreEffectAction<TActionMap[K]>;
|
|
42
|
+
};
|
|
43
|
+
type EffectSetupConfig<TSchemas extends EffectSetupSchemas, TStates extends Record<string, EffectSetupStateSchema>, TActionMap extends Record<string, AnyEffectAction>, TActorMap extends Sources['actors'], TGuardMap extends Sources['guards'], TDelayMap extends Sources['delays'], TValidator extends ActorLogicValidator | undefined, TSourceSchemas extends SetupSchemas = ToStandardSetupSchemas<TSchemas>> = {
|
|
44
|
+
validator?: TValidator;
|
|
45
|
+
actions?: TActionMap & Record<string, AnyEffectAction>;
|
|
46
|
+
actors?: TActorMap;
|
|
47
|
+
guards?: NonNullable<SetupConfig<TSourceSchemas, ToStandardSetupStates<TStates>, CoreEffectActionMap<TActionMap>, TActorMap, TGuardMap, TDelayMap, TValidator>['guards']>;
|
|
48
|
+
delays?: NonNullable<SetupConfig<TSourceSchemas, ToStandardSetupStates<TStates>, CoreEffectActionMap<TActionMap>, TActorMap, TGuardMap, TDelayMap, TValidator>['delays']>;
|
|
49
|
+
schemas?: TSchemas & ([TValidator] extends [ActorLogicValidator] ? ValidateEffectSetupSchemas<TSchemas> : unknown);
|
|
50
|
+
states?: TStates & ([TValidator] extends [ActorLogicValidator] ? ValidateEffectSetupStates<TStates> : unknown);
|
|
51
|
+
};
|
|
52
|
+
type MergeRecord<TBase, TExtension> = Omit<TBase, keyof TExtension> & TExtension;
|
|
53
|
+
type MergeSetupSchemas<TBaseSchemas extends SetupSchemas, TExtensionSchemas extends SetupSchemas> = {
|
|
54
|
+
[K in keyof TBaseSchemas | keyof TExtensionSchemas]: K extends 'events' | 'internalEvents' | 'emitted' | 'children' | 'actions' | 'guards' ? MergeRecord<K extends keyof TBaseSchemas ? NonNullable<TBaseSchemas[K]> : {}, K extends keyof TExtensionSchemas ? NonNullable<TExtensionSchemas[K]> : {}> : K extends keyof TExtensionSchemas ? TExtensionSchemas[K] : K extends keyof TBaseSchemas ? TBaseSchemas[K] : never;
|
|
55
|
+
} extends infer TMergedSchemas extends SetupSchemas ? TMergedSchemas : never;
|
|
56
|
+
interface RuntimeValidationDoesNotSupportTransformingSchemas {
|
|
57
|
+
readonly __xstate_effect_error: 'Runtime validation does not support schemas with different encoded and decoded types';
|
|
58
|
+
}
|
|
59
|
+
type RuntimeValidationCompatibility<TSchemas, TStates, TValidator> = [
|
|
60
|
+
TValidator
|
|
61
|
+
] extends [ActorLogicValidator] ? [TSchemas] extends [ValidateEffectSetupSchemas<TSchemas>] ? [TStates] extends [ValidateEffectSetupStates<TStates>] ? unknown : RuntimeValidationDoesNotSupportTransformingSchemas : RuntimeValidationDoesNotSupportTransformingSchemas : unknown;
|
|
62
|
+
declare const inheritedEffectValidator: unique symbol;
|
|
63
|
+
type InheritedEffectValidator = typeof inheritedEffectValidator;
|
|
64
|
+
type ResolveExtendedValidator<TBase, TExtension> = [TExtension] extends [
|
|
65
|
+
InheritedEffectValidator
|
|
66
|
+
] ? TBase : Exclude<TExtension, InheritedEffectValidator>;
|
|
67
|
+
type ExtendValidatorConfig<TExtension> = [TExtension] extends [
|
|
68
|
+
InheritedEffectValidator
|
|
69
|
+
] ? {
|
|
70
|
+
validator?: never;
|
|
71
|
+
} : {
|
|
72
|
+
validator: TExtension;
|
|
73
|
+
};
|
|
74
|
+
type EffectSetupExtensionConfig<TBaseSchemas extends SetupSchemas, TBaseStates extends Record<string, SetupStateSchema>, TBaseValidator extends ActorLogicValidator | undefined, TExtensionSchemas extends EffectSetupSchemas, TExtensionStates extends Record<string, EffectSetupStateSchema>, TExtensionActionMap extends Record<string, AnyEffectAction>, TExtensionActorMap extends Sources['actors'], TExtensionGuardMap extends Sources['guards'], TExtensionDelayMap extends Sources['delays'], TExtensionValidator extends ActorLogicValidator | undefined | InheritedEffectValidator> = EffectSetupConfig<TExtensionSchemas, TExtensionStates, TExtensionActionMap, TExtensionActorMap, TExtensionGuardMap, TExtensionDelayMap, ResolveExtendedValidator<TBaseValidator, TExtensionValidator>, MergeSetupSchemas<TBaseSchemas, ToStandardSetupSchemas<TExtensionSchemas>>> & ExtendValidatorConfig<TExtensionValidator> & RuntimeValidationCompatibility<NoInfer<TBaseSchemas>, NoInfer<TBaseStates>, ResolveExtendedValidator<TBaseValidator, TExtensionValidator>>;
|
|
75
|
+
/**
|
|
76
|
+
* What `setupEffect` returns: the XState `SetupReturn` with an `extend` method
|
|
77
|
+
* that also accepts Effect schemas and Effect-returning actions. Call
|
|
78
|
+
* `createMachine` on it to build a machine whose registered actions and actors
|
|
79
|
+
* contribute to `RequirementsFrom`.
|
|
80
|
+
*/
|
|
81
|
+
export type EffectSetupReturn<TStates extends Record<string, SetupStateSchema> = Record<string, SetupStateSchema>, TSchemas extends SetupSchemas = {}, TSetupActionMap extends Sources['actions'] = {}, TSetupActorMap extends Sources['actors'] = {}, TSetupGuardMap extends Sources['guards'] = {}, TSetupDelayMap extends Sources['delays'] = {}, TSetupDelays extends string = Extract<keyof TSetupDelayMap, string>, TValidator extends ActorLogicValidator | undefined = undefined> = Omit<SetupReturn<TStates, TSchemas, TSetupActionMap, TSetupActorMap, TSetupGuardMap, TSetupDelayMap, TSetupDelays, SystemRegistry, TValidator>, 'extend'> & {
|
|
82
|
+
extend<const TExtensionSchemas extends EffectSetupSchemas = {}, const TExtensionStates extends Record<string, EffectSetupStateSchema> = {}, TExtensionActionMap extends Record<string, AnyEffectAction> = {}, TExtensionActorMap extends Sources['actors'] = {}, TExtensionGuardMap extends Sources['guards'] = {}, TExtensionDelayMap extends Sources['delays'] = {}, const TExtensionValidator extends ActorLogicValidator | undefined | InheritedEffectValidator = InheritedEffectValidator>(config: EffectSetupExtensionConfig<TSchemas, TStates, TValidator, TExtensionSchemas, TExtensionStates, TExtensionActionMap, TExtensionActorMap, TExtensionGuardMap, TExtensionDelayMap, TExtensionValidator>): EffectSetupReturn<MergeRecord<TStates, ToStandardSetupStates<TExtensionStates>>, MergeSetupSchemas<TSchemas, ToStandardSetupSchemas<TExtensionSchemas>>, MergeRecord<TSetupActionMap, CoreEffectActionMap<TExtensionActionMap>>, MergeRecord<TSetupActorMap, TExtensionActorMap>, MergeRecord<TSetupGuardMap, TExtensionGuardMap>, MergeRecord<TSetupDelayMap, TExtensionDelayMap>, TSetupDelays | Extract<keyof TExtensionDelayMap, string>, ResolveExtendedValidator<TValidator, TExtensionValidator>>;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* The Effect-aware form of XState's `setup`. It accepts Effect `Schema` values
|
|
86
|
+
* wherever `setup` accepts Standard Schemas, and actions that return an
|
|
87
|
+
* Effect, which it wraps so the transition stays synchronous while the Effect
|
|
88
|
+
* runs in the actor's Effect context. Everything else, including `actors`,
|
|
89
|
+
* `guards`, `delays` and `extend`, behaves as in `setup`. Machines built from
|
|
90
|
+
* it must be started with `createEffectActor`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function setupEffect(): EffectSetupReturn;
|
|
93
|
+
export declare function setupEffect<const TSchemas extends EffectSetupSchemas = {}, const TStates extends Record<string, EffectSetupStateSchema> = Record<string, EffectSetupStateSchema>, TActionMap extends Record<string, AnyEffectAction> = {}, TActorMap extends Sources['actors'] = {}, TGuardMap extends Sources['guards'] = {}, TDelayMap extends Sources['delays'] = {}, const TValidator extends ActorLogicValidator | undefined = undefined>(config: EffectSetupConfig<TSchemas, TStates, TActionMap, TActorMap, TGuardMap, TDelayMap, TValidator>): EffectSetupReturn<ToStandardSetupStates<TStates>, ToStandardSetupSchemas<TSchemas>, CoreEffectActionMap<TActionMap>, TActorMap, TGuardMap, TDelayMap, Extract<keyof TDelayMap, string>, TValidator>;
|
|
94
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AnyMachineSnapshot, AnyStateMachine, MachineContext, MachineSnapshot, SnapshotFrom, StateContextFromStateValue, StateSchema, StateValueFromStateSchema } from 'xstate';
|
|
2
|
+
type IsUnion<T, U = T> = T extends unknown ? [U] extends [T] ? false : true : never;
|
|
3
|
+
type Join<TPrefix extends string, TKey extends string> = TPrefix extends '' ? TKey : `${TPrefix}.${TKey}`;
|
|
4
|
+
/** The tag of the machine itself, used when the root state is parallel. */
|
|
5
|
+
declare const MACHINE_TAG = "(machine)";
|
|
6
|
+
/**
|
|
7
|
+
* The dotted path of a state value: `'idle'`, `'form.editing'`. A parallel
|
|
8
|
+
* state has no single path, so its tag stops at the parallel state, or is
|
|
9
|
+
* `'(machine)'` when the machine itself is parallel.
|
|
10
|
+
*/
|
|
11
|
+
export type StateTag<TValue, TPrefix extends string = ''> = string extends TValue ? string : TValue extends string ? Join<TPrefix, TValue> : TValue extends object ? string extends keyof TValue ? string : IsUnion<keyof TValue & string> extends true ? TPrefix extends '' ? typeof MACHINE_TAG : TPrefix : {
|
|
12
|
+
[K in keyof TValue & string]: StateTag<TValue[K], Join<TPrefix, K>>;
|
|
13
|
+
}[keyof TValue & string] : never;
|
|
14
|
+
type TaggedStateOf<TSnapshot, TValue, TContext extends MachineContext, TSchema extends StateSchema> = TValue extends unknown ? {
|
|
15
|
+
readonly _tag: StateTag<TValue>;
|
|
16
|
+
readonly value: TValue;
|
|
17
|
+
readonly context: StateContextFromStateValue<TSchema, TContext, TValue>;
|
|
18
|
+
readonly snapshot: TSnapshot;
|
|
19
|
+
} : never;
|
|
20
|
+
/**
|
|
21
|
+
* A machine snapshot as a tagged union over its states. `_tag` is the state's
|
|
22
|
+
* dotted path and `context` is the context of that state, including any
|
|
23
|
+
* per-state context schema, so `Match.tag` narrows both.
|
|
24
|
+
*/
|
|
25
|
+
export type TaggedStateFrom<TSnapshot> = TSnapshot extends MachineSnapshot<infer TContext, infer _TEvent, infer _TChildren, infer _TStateValue, infer _TTag, infer _TOutput, infer _TMeta, infer TSchema> ? TaggedStateOf<TSnapshot, StateValueFromStateSchema<TSchema>, TContext, TSchema> : never;
|
|
26
|
+
/** The tagged state union of a machine. */
|
|
27
|
+
export type TaggedState<TMachine extends AnyStateMachine> = TaggedStateFrom<SnapshotFrom<TMachine>>;
|
|
28
|
+
/**
|
|
29
|
+
* Views a machine snapshot as a tagged union member for `Match.tag`,
|
|
30
|
+
* `Match.tags` or a `switch` on `_tag`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* const view = Match.type<TaggedStateFrom<typeof snapshot>>().pipe(
|
|
36
|
+
* Match.tag('loading', ({ context }) => `Loading ${context.id}`),
|
|
37
|
+
* Match.tag('done', () => 'Done'),
|
|
38
|
+
* Match.exhaustive
|
|
39
|
+
* );
|
|
40
|
+
* view(taggedState(snapshot));
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function taggedState<TSnapshot extends AnyMachineSnapshot>(snapshot: TSnapshot): TaggedStateFrom<TSnapshot>;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Effect } from 'effect';
|
|
2
|
+
import type { EffectLogicBrand } from "./fromEffect.js";
|
|
3
|
+
import { effectActionBrand } from "./brands.js";
|
|
4
|
+
/** The `R` channel of an Effect type, or `never` for anything else. */
|
|
5
|
+
export type EffectRequirements<T> = T extends Effect.Effect<any, any, infer R> ? R : never;
|
|
6
|
+
type RequirementsFromActions<T> = T extends Record<string, (...args: any[]) => any> ? T[keyof T] extends infer TAction ? TAction extends {
|
|
7
|
+
readonly [effectActionBrand]?: infer R;
|
|
8
|
+
} ? unknown extends R ? EffectRequirements<TAction extends (...args: any[]) => infer TResult ? TResult : never> : Exclude<R, undefined> : EffectRequirements<TAction extends (...args: any[]) => infer TResult ? TResult : never> : never : never;
|
|
9
|
+
/**
|
|
10
|
+
* Recursion budget for walking registered child machines. A machine cannot
|
|
11
|
+
* contain itself as a registered actor type, but deeply nested machine trees
|
|
12
|
+
* are capped at this depth to keep the conditional type finite.
|
|
13
|
+
*/
|
|
14
|
+
type MaxDepth = 10;
|
|
15
|
+
type PrevDepth = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
16
|
+
type Depth = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
17
|
+
type RequirementsFromActors<T, TDepth extends Depth> = T extends Record<string, any> ? RequirementsFrom<T[keyof T], TDepth> : never;
|
|
18
|
+
/** `invoke` accepts a single config or an array of them. */
|
|
19
|
+
type InvokeEntry<TInvoke> = TInvoke extends readonly (infer U)[] ? U : TInvoke;
|
|
20
|
+
/**
|
|
21
|
+
* Requirements of the logic passed inline as `invoke.src`. A string `src`
|
|
22
|
+
* names an actor registered in `setup({ actors })`, whose requirements are
|
|
23
|
+
* already collected from the actor map, so it contributes nothing here.
|
|
24
|
+
*/
|
|
25
|
+
type RequirementsFromInvoke<TInvoke, TDepth extends Depth> = InvokeEntry<TInvoke> extends infer TEntry ? TEntry extends {
|
|
26
|
+
src: infer TSrc;
|
|
27
|
+
} ? TSrc extends string ? never : RequirementsFrom<TSrc, TDepth> : never : never;
|
|
28
|
+
/**
|
|
29
|
+
* Walks the machine's literal config tree (the state schema) collecting
|
|
30
|
+
* requirements from inline `invoke.src` logic at the root and in every
|
|
31
|
+
* descendant state node.
|
|
32
|
+
*/
|
|
33
|
+
type RequirementsFromStateSchema<TSchema, TDepth extends Depth> = (TSchema extends {
|
|
34
|
+
invoke: infer TInvoke;
|
|
35
|
+
} ? RequirementsFromInvoke<TInvoke, TDepth> : never) | (TSchema extends {
|
|
36
|
+
states: infer TStates;
|
|
37
|
+
} ? TStates extends Record<string, any> ? RequirementsFromStateSchema<TStates[keyof TStates], TDepth> : never : never);
|
|
38
|
+
/**
|
|
39
|
+
* Collects the Effect service requirements of an actor logic.
|
|
40
|
+
*
|
|
41
|
+
* For Effect logic this is the logic's own `R`. For a state machine it is the
|
|
42
|
+
* union of the requirements of its registered Effect actions, its registered
|
|
43
|
+
* Effect actors, the Effect logic passed inline as `invoke.src` anywhere in
|
|
44
|
+
* its state tree, and — recursively — the requirements of any child machine
|
|
45
|
+
* reached either way (capped at {@link MaxDepth} levels of machine nesting).
|
|
46
|
+
*/
|
|
47
|
+
export type RequirementsFrom<T, TDepth extends Depth = MaxDepth> = T extends EffectLogicBrand<any, infer R> ? R : T extends {
|
|
48
|
+
readonly _actionMap: infer TActionMap;
|
|
49
|
+
readonly _actorMap: infer TActorMap;
|
|
50
|
+
readonly _stateSchema: infer TStateSchema;
|
|
51
|
+
} ? RequirementsFromActions<TActionMap> | ([TDepth] extends [0] ? never : RequirementsFromActors<TActorMap, PrevDepth[TDepth]> | RequirementsFromStateSchema<TStateSchema, PrevDepth[TDepth]>) : never;
|
|
52
|
+
export {};
|