effect-machine 0.12.0 → 0.14.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 +133 -324
- package/dist/actor.d.ts +46 -28
- package/dist/actor.js +276 -315
- package/dist/cluster/entity-machine.d.ts +1 -1
- package/dist/cluster/entity-machine.js +20 -9
- package/dist/cluster/to-entity.d.ts +3 -3
- package/dist/errors.d.ts +24 -20
- package/dist/errors.js +10 -6
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -2
- package/dist/internal/runtime.d.ts +82 -7
- package/dist/internal/runtime.js +162 -58
- package/dist/internal/transition.d.ts +12 -11
- package/dist/internal/transition.js +12 -14
- package/dist/machine.d.ts +148 -140
- package/dist/machine.js +141 -155
- package/dist/schema.d.ts +14 -0
- package/dist/schema.js +10 -1
- package/dist/slot.d.ts +112 -86
- package/dist/slot.js +92 -59
- package/dist/supervision.d.ts +97 -0
- package/dist/supervision.js +42 -0
- package/dist/testing.d.ts +21 -12
- package/dist/testing.js +23 -26
- package/package.json +7 -7
- package/v3/dist/actor.d.ts +53 -30
- package/v3/dist/actor.js +286 -311
- package/v3/dist/cluster/entity-machine.d.ts +1 -1
- package/v3/dist/cluster/entity-machine.js +5 -5
- package/v3/dist/cluster/to-entity.d.ts +1 -1
- package/v3/dist/errors.d.ts +14 -10
- package/v3/dist/errors.js +11 -7
- package/v3/dist/index.d.ts +6 -5
- package/v3/dist/index.js +3 -2
- package/v3/dist/inspection.d.ts +3 -22
- package/v3/dist/inspection.js +1 -15
- package/v3/dist/internal/brands.d.ts +4 -8
- package/v3/dist/internal/inspection.js +1 -1
- package/v3/dist/internal/runtime.d.ts +87 -10
- package/v3/dist/internal/runtime.js +177 -61
- package/v3/dist/internal/transition.d.ts +13 -12
- package/v3/dist/internal/transition.js +14 -16
- package/v3/dist/internal/utils.js +5 -1
- package/v3/dist/machine.d.ts +158 -143
- package/v3/dist/machine.js +148 -155
- package/v3/dist/schema.d.ts +25 -11
- package/v3/dist/schema.js +18 -5
- package/v3/dist/slot.d.ts +112 -86
- package/v3/dist/slot.js +92 -59
- package/v3/dist/supervision.d.ts +97 -0
- package/v3/dist/supervision.js +42 -0
- package/v3/dist/testing.d.ts +21 -12
- package/v3/dist/testing.js +23 -24
package/v3/dist/machine.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ReplyResult, TransitionResult } from "./internal/utils.js";
|
|
1
|
+
import { DeferReplyResult, ReplyResult, TransitionResult } from "./internal/utils.js";
|
|
3
2
|
import { BrandedEvent, BrandedState, ExtractReply, TaggedOrConstructor } from "./internal/brands.js";
|
|
4
3
|
import { MachineEventSchema, MachineStateSchema, VariantsUnion } from "./schema.js";
|
|
5
4
|
import { DuplicateActorError } from "./errors.js";
|
|
5
|
+
import { MachineContext, ProvideSlots, SlotCalls, SlotsDef, SlotsSchema } from "./slot.js";
|
|
6
|
+
import { Supervision } from "./supervision.js";
|
|
6
7
|
import { findTransitions } from "./internal/transition.js";
|
|
7
8
|
import { ActorRef, ActorSystem } from "./actor.js";
|
|
8
|
-
import { Cause, Context, Duration, Effect, Schema, Scope } from "effect";
|
|
9
|
+
import { Cause, Context, Duration, Effect, Option, Schema, Scope } from "effect";
|
|
9
10
|
|
|
10
11
|
//#region src/machine.d.ts
|
|
11
12
|
declare namespace machine_d_exports {
|
|
12
|
-
export { BackgroundEffect,
|
|
13
|
+
export { BackgroundEffect, DeferReplyResult, HandlerContext, Machine, MachineRef, MakeConfig, PersistConfig, ReplyResult, SpawnEffect, StateEffectHandler, StateHandlerContext, TaskOptions, TimeoutConfig, Transition, TransitionHandler, deferReply, findTransitions, make, materializeMachine, replay, reply, spawn };
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* Self reference for sending events back to the machine
|
|
@@ -22,26 +23,31 @@ interface MachineRef<Event> {
|
|
|
22
23
|
readonly _tag: string;
|
|
23
24
|
}, E2 extends {
|
|
24
25
|
readonly _tag: string;
|
|
25
|
-
}, R2>(id: string, machine:
|
|
26
|
+
}, R2>(id: string, machine: Machine<S2, E2, R2, any, any, any>) => Effect.Effect<ActorRef<S2, E2>, DuplicateActorError, R2>;
|
|
27
|
+
/**
|
|
28
|
+
* Settle a deferred reply from a spawn handler.
|
|
29
|
+
* Only usable when the transition handler returned `Machine.deferReply(state)`.
|
|
30
|
+
* Returns true if a pending reply was settled, false if none was pending.
|
|
31
|
+
*/
|
|
32
|
+
readonly reply: (value: unknown) => Effect.Effect<boolean>;
|
|
26
33
|
}
|
|
27
34
|
/**
|
|
28
35
|
* Handler context passed to transition handlers
|
|
29
36
|
*/
|
|
30
|
-
interface HandlerContext<State, Event,
|
|
37
|
+
interface HandlerContext<State, Event, SD extends SlotsDef = Record<string, never>> {
|
|
31
38
|
readonly state: State;
|
|
32
39
|
readonly event: Event;
|
|
33
|
-
readonly
|
|
34
|
-
readonly effects: EffectSlots<ED>;
|
|
40
|
+
readonly slots: SlotCalls<SD>;
|
|
35
41
|
}
|
|
36
42
|
/**
|
|
37
43
|
* Handler context passed to state effect handlers (onEnter, spawn, background)
|
|
38
44
|
*/
|
|
39
|
-
interface StateHandlerContext<State, Event,
|
|
45
|
+
interface StateHandlerContext<State, Event, SD extends SlotsDef = Record<string, never>> {
|
|
40
46
|
readonly actorId: string;
|
|
41
47
|
readonly state: State;
|
|
42
48
|
readonly event: Event;
|
|
43
49
|
readonly self: MachineRef<Event>;
|
|
44
|
-
readonly
|
|
50
|
+
readonly slots: SlotCalls<SD>;
|
|
45
51
|
readonly system: ActorSystem;
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
@@ -49,38 +55,66 @@ interface StateHandlerContext<State, Event, ED extends EffectsDef> {
|
|
|
49
55
|
* When Reply is concrete (event has a reply schema), handler must return Machine.reply().
|
|
50
56
|
* When Reply is never, handler returns plain state.
|
|
51
57
|
*/
|
|
52
|
-
type TransitionHandler<S, E, NewState,
|
|
58
|
+
type TransitionHandler<S, E, NewState, SD extends SlotsDef, R, Reply = never> = (ctx: HandlerContext<S, E, SD>) => TransitionResult<NewState, R, Reply>;
|
|
53
59
|
/**
|
|
54
60
|
* State effect handler function
|
|
55
61
|
*/
|
|
56
|
-
type StateEffectHandler<S, E,
|
|
62
|
+
type StateEffectHandler<S, E, SD extends SlotsDef, R> = (ctx: StateHandlerContext<S, E, SD>) => Effect.Effect<void, never, R>;
|
|
57
63
|
/**
|
|
58
64
|
* Transition definition
|
|
59
65
|
*/
|
|
60
|
-
interface Transition<State, Event,
|
|
66
|
+
interface Transition<State, Event, SD extends SlotsDef, R> {
|
|
61
67
|
readonly stateTag: string;
|
|
62
68
|
readonly eventTag: string;
|
|
63
|
-
readonly handler: TransitionHandler<State, Event, State,
|
|
69
|
+
readonly handler: TransitionHandler<State, Event, State, SD, R>;
|
|
64
70
|
readonly reenter?: boolean;
|
|
65
71
|
}
|
|
66
72
|
/**
|
|
67
73
|
* Spawn effect - state-scoped forked effect
|
|
68
74
|
*/
|
|
69
|
-
interface SpawnEffect<State, Event,
|
|
75
|
+
interface SpawnEffect<State, Event, SD extends SlotsDef, R> {
|
|
70
76
|
readonly stateTag: string;
|
|
71
|
-
readonly handler: StateEffectHandler<State, Event,
|
|
77
|
+
readonly handler: StateEffectHandler<State, Event, SD, R>;
|
|
72
78
|
}
|
|
73
79
|
/**
|
|
74
80
|
* Background effect - runs for entire machine lifetime
|
|
75
81
|
*/
|
|
76
|
-
interface BackgroundEffect<State, Event,
|
|
77
|
-
readonly handler: StateEffectHandler<State, Event,
|
|
82
|
+
interface BackgroundEffect<State, Event, SD extends SlotsDef, R> {
|
|
83
|
+
readonly handler: StateEffectHandler<State, Event, SD, R>;
|
|
78
84
|
}
|
|
79
|
-
interface TaskOptions<State, Event,
|
|
80
|
-
readonly onSuccess
|
|
81
|
-
readonly onFailure?: (cause: Cause.Cause<E1>, ctx: StateHandlerContext<State, Event,
|
|
85
|
+
interface TaskOptions<State, Event, SD extends SlotsDef, A, E1, ES, EF> {
|
|
86
|
+
readonly onSuccess?: (value: A, ctx: StateHandlerContext<State, Event, SD>) => ES;
|
|
87
|
+
readonly onFailure?: (cause: Cause.Cause<E1>, ctx: StateHandlerContext<State, Event, SD>) => EF;
|
|
82
88
|
readonly name?: string;
|
|
83
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Local persistence configuration for Machine.spawn.
|
|
92
|
+
*
|
|
93
|
+
* Fully-resolved callbacks — no service dependency.
|
|
94
|
+
* Separate from cluster EntityPersistence which uses a service-based adapter.
|
|
95
|
+
*/
|
|
96
|
+
interface PersistConfig<S> {
|
|
97
|
+
/** Load saved state on actor start (and restart). Returns None for cold start. */
|
|
98
|
+
readonly load: () => Effect.Effect<Option.Option<S>>;
|
|
99
|
+
/** Save state after each transition. Runs inline (blocks next event). */
|
|
100
|
+
readonly save: (state: S) => Effect.Effect<void>;
|
|
101
|
+
/** Optional filter — return false to skip saving for this transition. */
|
|
102
|
+
readonly shouldSave?: (state: S, previousState: S) => boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Called after load() returns Some(state). Inspect the restored state
|
|
105
|
+
* and decide how to proceed before the machine starts.
|
|
106
|
+
*
|
|
107
|
+
* Return Some(state) to use that state, or None to discard and start fresh.
|
|
108
|
+
* Called on both initial spawn and supervision restart.
|
|
109
|
+
* Receives `initial` (machine.initial) for comparison.
|
|
110
|
+
*
|
|
111
|
+
* Use cases: validate persisted state against external systems,
|
|
112
|
+
* migrate schema changes, downgrade to a safe state on partial corruption.
|
|
113
|
+
*/
|
|
114
|
+
readonly onRestore?: (state: S, context: {
|
|
115
|
+
readonly initial: S;
|
|
116
|
+
}) => Effect.Effect<Option.Option<S>>;
|
|
117
|
+
}
|
|
84
118
|
/**
|
|
85
119
|
* Configuration for `.timeout()` — gen_statem-style state timeouts.
|
|
86
120
|
*
|
|
@@ -93,44 +127,26 @@ interface TimeoutConfig<State, Event> {
|
|
|
93
127
|
/** Event to send when the timer fires. Static or derived from current state. */
|
|
94
128
|
readonly event: Event | ((state: State) => Event);
|
|
95
129
|
}
|
|
96
|
-
|
|
97
|
-
type IsUnknown<T> = unknown extends T ? ([T] extends [unknown] ? true : false) : false;
|
|
98
|
-
type NormalizeR<T> = IsAny<T> extends true ? T : IsUnknown<T> extends true ? never : T;
|
|
99
|
-
interface MakeConfig<SD extends Record<string, Schema.Struct.Fields>, ED extends Record<string, Schema.Struct.Fields>, S extends BrandedState, E extends BrandedEvent, GD extends GuardsDef, EFD extends EffectsDef> {
|
|
130
|
+
interface MakeConfig<SD extends Record<string, Schema.Struct.Fields>, ED extends Record<string, Schema.Struct.Fields>, S extends BrandedState, E extends BrandedEvent, SLD extends SlotsDef = Record<string, never>> {
|
|
100
131
|
readonly state: MachineStateSchema<SD> & {
|
|
101
132
|
Type: S;
|
|
102
133
|
};
|
|
103
134
|
readonly event: MachineEventSchema<ED> & {
|
|
104
135
|
Type: E;
|
|
105
136
|
};
|
|
106
|
-
readonly
|
|
107
|
-
readonly effects?: EffectsSchema<EFD>;
|
|
137
|
+
readonly slots?: SlotsSchema<SLD>;
|
|
108
138
|
readonly initial: S;
|
|
139
|
+
/** Validate slot inputs/outputs at runtime. Default: true. Set to false for hot paths. */
|
|
140
|
+
readonly slotValidation?: boolean;
|
|
109
141
|
}
|
|
110
|
-
/** Check if a GuardsDef has any actual keys */
|
|
111
|
-
type HasGuardKeys<GD extends GuardsDef> = [keyof GD] extends [never] ? false : GD extends Record<string, never> ? false : true;
|
|
112
|
-
/** Check if an EffectsDef has any actual keys */
|
|
113
|
-
type HasEffectKeys<EFD extends EffectsDef> = [keyof EFD] extends [never] ? false : EFD extends Record<string, never> ? false : true;
|
|
114
|
-
/** Context type passed to guard/effect handlers */
|
|
115
|
-
type SlotContext<State, Event> = MachineContext<State, Event, MachineRef<Event>>;
|
|
116
|
-
/** Combined handlers for build() - guards and effects only */
|
|
117
|
-
type ProvideHandlers<State, Event, GD extends GuardsDef, EFD extends EffectsDef, R> = (HasGuardKeys<GD> extends true ? GuardHandlers<GD, SlotContext<State, Event>, R> : object) & (HasEffectKeys<EFD> extends true ? EffectHandlers<EFD, SlotContext<State, Event>, R> : object);
|
|
118
|
-
/** Whether the machine has any guard or effect slots */
|
|
119
|
-
type HasSlots<GD extends GuardsDef, EFD extends EffectsDef> = HasGuardKeys<GD> extends true ? true : HasEffectKeys<EFD>;
|
|
120
142
|
/**
|
|
121
|
-
*
|
|
143
|
+
* Bind slot handlers to a machine, returning a fresh copy with handlers installed.
|
|
144
|
+
* If no handlers provided and machine has no slots, returns the machine as-is.
|
|
145
|
+
* Validates that all required slots are provided and no extra slots are given.
|
|
122
146
|
*
|
|
123
|
-
*
|
|
124
|
-
* accepted by `Machine.spawn` and `ActorSystem.spawn` (regular overload).
|
|
125
|
-
* Testing utilities (`simulate`, `createTestHarness`, etc.) still accept `Machine`.
|
|
147
|
+
* @internal — used by spawn, replay, simulate, test harness, entity-machine
|
|
126
148
|
*/
|
|
127
|
-
declare
|
|
128
|
-
/** @internal */
|
|
129
|
-
readonly _inner: Machine<State, Event, R, any, any, any, any>;
|
|
130
|
-
/** @internal */
|
|
131
|
-
constructor(machine: Machine<State, Event, R, any, any, any, any>);
|
|
132
|
-
get initial(): State;
|
|
133
|
-
}
|
|
149
|
+
declare const materializeMachine: <S, E, R, SD extends SlotsDef>(machine: Machine<S, E, R, any, any, SD>, handlers?: Record<string, any>) => Machine<S, E, never, any, any, SD>;
|
|
134
150
|
/**
|
|
135
151
|
* Machine definition with fluent builder API.
|
|
136
152
|
*
|
|
@@ -140,17 +156,16 @@ declare class BuiltMachine<State, Event, R = never> {
|
|
|
140
156
|
* - `R`: Effect requirements
|
|
141
157
|
* - `_SD`: State schema definition (for compile-time validation)
|
|
142
158
|
* - `_ED`: Event schema definition (for compile-time validation)
|
|
143
|
-
* - `
|
|
144
|
-
* - `EFD`: Effect definitions
|
|
159
|
+
* - `SD`: Slot definitions
|
|
145
160
|
*/
|
|
146
|
-
declare class Machine<State, Event, R = never, _SD extends Record<string, Schema.Struct.Fields> = Record<string, Schema.Struct.Fields>, _ED extends Record<string, Schema.Struct.Fields> = Record<string, Schema.Struct.Fields>,
|
|
161
|
+
declare class Machine<State, Event, R = never, _SD extends Record<string, Schema.Struct.Fields> = Record<string, Schema.Struct.Fields>, _ED extends Record<string, Schema.Struct.Fields> = Record<string, Schema.Struct.Fields>, SD extends SlotsDef = Record<string, never>> {
|
|
147
162
|
readonly initial: State;
|
|
148
163
|
/** @internal */
|
|
149
|
-
readonly _transitions: Array<Transition<State, Event,
|
|
164
|
+
readonly _transitions: Array<Transition<State, Event, SD, R>>;
|
|
150
165
|
/** @internal */
|
|
151
|
-
readonly _spawnEffects: Array<SpawnEffect<State, Event,
|
|
166
|
+
readonly _spawnEffects: Array<SpawnEffect<State, Event, SD, R>>;
|
|
152
167
|
/** @internal */
|
|
153
|
-
readonly _backgroundEffects: Array<BackgroundEffect<State, Event,
|
|
168
|
+
readonly _backgroundEffects: Array<BackgroundEffect<State, Event, SD, R>>;
|
|
154
169
|
/** @internal */
|
|
155
170
|
readonly _finalStates: Set<string>;
|
|
156
171
|
/** @internal */
|
|
@@ -159,20 +174,15 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
159
174
|
readonly eventTag: string;
|
|
160
175
|
}>;
|
|
161
176
|
/** @internal */
|
|
162
|
-
readonly
|
|
163
|
-
/** @internal */
|
|
164
|
-
readonly _effectsSchema?: EffectsSchema<EFD>;
|
|
177
|
+
readonly _slotsSchema?: SlotsSchema<SD>;
|
|
165
178
|
/** @internal */
|
|
166
|
-
readonly
|
|
179
|
+
readonly _slotHandlers: Map<string, (params: unknown) => unknown | Effect.Effect<unknown, never, R>>;
|
|
167
180
|
/** @internal */
|
|
168
|
-
readonly
|
|
181
|
+
readonly _slots: SlotCalls<SD>;
|
|
169
182
|
/** @internal */
|
|
170
|
-
readonly
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
};
|
|
174
|
-
readonly stateSchema?: Schema.Schema<State, unknown, never>;
|
|
175
|
-
readonly eventSchema?: Schema.Schema<Event, unknown, never>;
|
|
183
|
+
readonly _slotValidation: boolean;
|
|
184
|
+
readonly stateSchema?: Schema.Schema<State>;
|
|
185
|
+
readonly eventSchema?: Schema.Schema<Event>;
|
|
176
186
|
/** @internal */
|
|
177
187
|
readonly _replySchemas: ReadonlyMap<string, Schema.Schema.Any>;
|
|
178
188
|
/**
|
|
@@ -180,70 +190,72 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
180
190
|
* Uses shared module-level tag for all machines.
|
|
181
191
|
*/
|
|
182
192
|
readonly Context: Context.Tag<MachineContext<State, Event, MachineRef<Event>>, MachineContext<State, Event, MachineRef<Event>>>;
|
|
183
|
-
get transitions(): ReadonlyArray<Transition<State, Event,
|
|
184
|
-
get spawnEffects(): ReadonlyArray<SpawnEffect<State, Event,
|
|
185
|
-
get backgroundEffects(): ReadonlyArray<BackgroundEffect<State, Event,
|
|
193
|
+
get transitions(): ReadonlyArray<Transition<State, Event, SD, R>>;
|
|
194
|
+
get spawnEffects(): ReadonlyArray<SpawnEffect<State, Event, SD, R>>;
|
|
195
|
+
get backgroundEffects(): ReadonlyArray<BackgroundEffect<State, Event, SD, R>>;
|
|
186
196
|
get finalStates(): ReadonlySet<string>;
|
|
187
197
|
get postponeRules(): ReadonlyArray<{
|
|
188
198
|
readonly stateTag: string;
|
|
189
199
|
readonly eventTag: string;
|
|
190
200
|
}>;
|
|
191
|
-
get
|
|
192
|
-
get effectsSchema(): EffectsSchema<EFD> | undefined;
|
|
201
|
+
get slotsSchema(): SlotsSchema<SD> | undefined;
|
|
193
202
|
get replySchemas(): ReadonlyMap<string, Schema.Schema.Any>;
|
|
194
203
|
/** @internal */
|
|
195
|
-
constructor(initial: State, stateSchema?: Schema.Schema<State
|
|
196
|
-
from<NS extends VariantsUnion<_SD> & BrandedState, R1>(state: TaggedOrConstructor<NS>, build: (scope: TransitionScope<State, Event, R, _SD, _ED,
|
|
197
|
-
from<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, R1>(states: NS, build: (scope: TransitionScope<State, Event, R, _SD, _ED,
|
|
204
|
+
constructor(initial: State, stateSchema?: Schema.Schema<State>, eventSchema?: Schema.Schema<Event>, slotsSchema?: SlotsSchema<SD>, slotValidation?: boolean);
|
|
205
|
+
from<NS extends VariantsUnion<_SD> & BrandedState, R1>(state: TaggedOrConstructor<NS>, build: (scope: TransitionScope<State, Event, R, _SD, _ED, SD, NS>) => R1): Machine<State, Event, R, _SD, _ED, SD>;
|
|
206
|
+
from<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, R1>(states: NS, build: (scope: TransitionScope<State, Event, R, _SD, _ED, SD, NS[number] extends TaggedOrConstructor<infer S extends VariantsUnion<_SD> & BrandedState> ? S : never>) => R1): Machine<State, Event, R, _SD, _ED, SD>;
|
|
198
207
|
/** @internal */
|
|
199
|
-
scopeTransition<NS extends VariantsUnion<_SD> & BrandedState, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(states: ReadonlyArray<TaggedOrConstructor<NS>>, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS, NE, RS,
|
|
208
|
+
scopeTransition<NS extends VariantsUnion<_SD> & BrandedState, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(states: ReadonlyArray<TaggedOrConstructor<NS>>, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS, NE, RS, SD, never, ExtractReply<NE>>, reenter: boolean): Machine<State, Event, R, _SD, _ED, SD>;
|
|
200
209
|
/** Register transition for a single state */
|
|
201
|
-
on<NS extends VariantsUnion<_SD> & BrandedState, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS, NE, RS,
|
|
210
|
+
on<NS extends VariantsUnion<_SD> & BrandedState, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS, NE, RS, SD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
202
211
|
/** Register transition for multiple states (handler receives union of state types) */
|
|
203
|
-
on<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(states: NS, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS[number] extends TaggedOrConstructor<infer S> ? S : never, NE, RS,
|
|
212
|
+
on<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(states: NS, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS[number] extends TaggedOrConstructor<infer S> ? S : never, NE, RS, SD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
204
213
|
/**
|
|
205
214
|
* Like `on()`, but forces onEnter/spawn to run even when transitioning to the same state tag.
|
|
206
215
|
* Use this to restart timers, re-run spawned effects, or reset state-scoped effects.
|
|
207
216
|
*/
|
|
208
217
|
/** Single state */
|
|
209
|
-
reenter<NS extends VariantsUnion<_SD> & BrandedState, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS, NE, RS,
|
|
218
|
+
reenter<NS extends VariantsUnion<_SD> & BrandedState, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS, NE, RS, SD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
210
219
|
/** Multiple states */
|
|
211
|
-
reenter<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(states: NS, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS[number] extends TaggedOrConstructor<infer S> ? S : never, NE, RS,
|
|
220
|
+
reenter<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(states: NS, event: TaggedOrConstructor<NE>, handler: TransitionHandler<NS[number] extends TaggedOrConstructor<infer S> ? S : never, NE, RS, SD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
212
221
|
/**
|
|
213
222
|
* Register a wildcard transition that fires from any state when no specific transition matches.
|
|
214
223
|
* Specific `.on()` transitions always take priority over `.onAny()`.
|
|
215
224
|
*/
|
|
216
|
-
onAny<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<VariantsUnion<_SD> & BrandedState, NE, RS,
|
|
225
|
+
onAny<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<VariantsUnion<_SD> & BrandedState, NE, RS, SD, never>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
217
226
|
/** @internal */
|
|
218
227
|
private addTransition;
|
|
219
228
|
/**
|
|
220
229
|
* State-scoped effect that is forked on state entry and automatically cancelled on state exit.
|
|
221
|
-
* Use effect slots defined via `Slot.Effects` for the actual work.
|
|
222
230
|
*
|
|
223
231
|
* @example
|
|
224
232
|
* ```ts
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* fetchData: ({ url }, { self }) =>
|
|
233
|
-
* Effect.gen(function* () {
|
|
234
|
-
* yield* Effect.addFinalizer(() => Effect.log("Leaving Loading"));
|
|
235
|
-
* const data = yield* Http.get(url);
|
|
236
|
-
* yield* self.send(Event.Loaded({ data }));
|
|
237
|
-
* }),
|
|
238
|
-
* });
|
|
233
|
+
* machine.spawn(State.Loading, ({ self, state }) =>
|
|
234
|
+
* Effect.gen(function* () {
|
|
235
|
+
* yield* Effect.addFinalizer(() => Effect.log("Leaving Loading"));
|
|
236
|
+
* const data = yield* Http.get(state.url);
|
|
237
|
+
* yield* self.send(Event.Loaded({ data }));
|
|
238
|
+
* }),
|
|
239
|
+
* );
|
|
239
240
|
* ```
|
|
240
241
|
*/
|
|
241
|
-
|
|
242
|
+
/** Single state */
|
|
243
|
+
spawn<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, handler: StateEffectHandler<NS, VariantsUnion<_ED> & BrandedEvent, SD, Scope.Scope>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
244
|
+
/** Multiple states */
|
|
245
|
+
spawn<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>>(states: NS, handler: StateEffectHandler<NS[number] extends TaggedOrConstructor<infer S> ? S : never, VariantsUnion<_ED> & BrandedEvent, SD, Scope.Scope>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
242
246
|
/**
|
|
243
247
|
* State-scoped task that runs on entry and sends success/failure events.
|
|
244
248
|
* Interrupts do not emit failure events.
|
|
249
|
+
*
|
|
250
|
+
* Supports multi-state and shorthand overloads:
|
|
251
|
+
* - `.task(State.X, run, { onSuccess, onFailure })` — explicit mapping
|
|
252
|
+
* - `.task(State.X, run, { onFailure })` — shorthand when run returns Event directly
|
|
253
|
+
* - `.task([State.X, State.Y], run, opts)` — multi-state
|
|
245
254
|
*/
|
|
246
|
-
|
|
255
|
+
/** Single state — onSuccess optional (defaults to identity when task returns Event) */
|
|
256
|
+
task<NS extends VariantsUnion<_SD> & BrandedState, A, E1, ES extends VariantsUnion<_ED> & BrandedEvent, EF extends VariantsUnion<_ED> & BrandedEvent>(state: TaggedOrConstructor<NS>, run: (ctx: StateHandlerContext<NS, VariantsUnion<_ED> & BrandedEvent, SD>) => Effect.Effect<A, E1, Scope.Scope>, options: TaskOptions<NS, VariantsUnion<_ED> & BrandedEvent, SD, A, E1, ES, EF>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
257
|
+
/** Multiple states — onSuccess optional */
|
|
258
|
+
task<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, A, E1, ES extends VariantsUnion<_ED> & BrandedEvent, EF extends VariantsUnion<_ED> & BrandedEvent>(states: NS, run: (ctx: StateHandlerContext<NS[number] extends TaggedOrConstructor<infer S> ? S : never, VariantsUnion<_ED> & BrandedEvent, SD>) => Effect.Effect<A, E1, Scope.Scope>, options: TaskOptions<NS[number] extends TaggedOrConstructor<infer S> ? S : never, VariantsUnion<_ED> & BrandedEvent, SD, A, E1, ES, EF>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
247
259
|
/**
|
|
248
260
|
* State timeout — gen_statem's `state_timeout`.
|
|
249
261
|
*
|
|
@@ -265,28 +277,20 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
265
277
|
* })
|
|
266
278
|
* ```
|
|
267
279
|
*/
|
|
268
|
-
timeout<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, config: TimeoutConfig<NS, VariantsUnion<_ED> & BrandedEvent>): Machine<State, Event, R, _SD, _ED,
|
|
280
|
+
timeout<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, config: TimeoutConfig<NS, VariantsUnion<_ED> & BrandedEvent>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
269
281
|
/**
|
|
270
282
|
* Machine-lifetime effect that is forked on actor spawn and runs until the actor stops.
|
|
271
|
-
* Use effect slots defined via `Slot.Effects` for the actual work.
|
|
272
283
|
*
|
|
273
284
|
* @example
|
|
274
285
|
* ```ts
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
* .background(({ effects }) => effects.heartbeat())
|
|
281
|
-
* .build({
|
|
282
|
-
* heartbeat: (_, { self }) =>
|
|
283
|
-
* Effect.forever(
|
|
284
|
-
* Effect.sleep("30 seconds").pipe(Effect.andThen(self.send(Event.Ping)))
|
|
285
|
-
* ),
|
|
286
|
-
* });
|
|
286
|
+
* machine.background(({ self }) =>
|
|
287
|
+
* Effect.forever(
|
|
288
|
+
* Effect.sleep("30 seconds").pipe(Effect.andThen(self.send(Event.Ping))),
|
|
289
|
+
* ),
|
|
290
|
+
* );
|
|
287
291
|
* ```
|
|
288
292
|
*/
|
|
289
|
-
background(handler: StateEffectHandler<State, Event,
|
|
293
|
+
background(handler: StateEffectHandler<State, Event, SD, Scope.Scope>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
290
294
|
/**
|
|
291
295
|
* Postpone events — gen_statem's event postpone.
|
|
292
296
|
*
|
|
@@ -304,53 +308,64 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
304
308
|
* .postpone(State.Connecting, [Event.Data, Event.Cmd]) // multiple events
|
|
305
309
|
* ```
|
|
306
310
|
*/
|
|
307
|
-
postpone<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, events: TaggedOrConstructor<VariantsUnion<_ED> & BrandedEvent> | ReadonlyArray<TaggedOrConstructor<VariantsUnion<_ED> & BrandedEvent>>): Machine<State, Event, R, _SD, _ED,
|
|
308
|
-
final<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>): Machine<State, Event, R, _SD, _ED,
|
|
309
|
-
|
|
310
|
-
* Finalize the machine. Returns a `BuiltMachine` — the only type accepted by `Machine.spawn`.
|
|
311
|
-
*
|
|
312
|
-
* - Machines with slots: pass implementations as the first argument.
|
|
313
|
-
* - Machines without slots: call with no arguments.
|
|
314
|
-
*/
|
|
315
|
-
build<R2 = never>(...args: HasSlots<GD, EFD> extends true ? [handlers: ProvideHandlers<State, Event, GD, EFD, R2>] : [handlers?: ProvideHandlers<State, Event, GD, EFD, R2>]): BuiltMachine<State, Event, R | NormalizeR<R2>>;
|
|
316
|
-
static make<SD extends Record<string, Schema.Struct.Fields>, ED extends Record<string, Schema.Struct.Fields>, S extends BrandedState, E extends BrandedEvent, GD extends GuardsDef = Record<string, never>, EFD extends EffectsDef = Record<string, never>>(config: MakeConfig<SD, ED, S, E, GD, EFD>): Machine<S, E, never, SD, ED, GD, EFD>;
|
|
311
|
+
postpone<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>, events: TaggedOrConstructor<VariantsUnion<_ED> & BrandedEvent> | ReadonlyArray<TaggedOrConstructor<VariantsUnion<_ED> & BrandedEvent>>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
312
|
+
final<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
313
|
+
static make<SD extends Record<string, Schema.Struct.Fields>, ED extends Record<string, Schema.Struct.Fields>, S extends BrandedState, E extends BrandedEvent, SLD extends SlotsDef = Record<string, never>>(config: MakeConfig<SD, ED, S, E, SLD>): Machine<S, E, never, SD, ED, SLD>;
|
|
317
314
|
}
|
|
318
|
-
declare class TransitionScope<State, Event, R, _SD extends Record<string, Schema.Struct.Fields>, _ED extends Record<string, Schema.Struct.Fields>,
|
|
315
|
+
declare class TransitionScope<State, Event, R, _SD extends Record<string, Schema.Struct.Fields>, _ED extends Record<string, Schema.Struct.Fields>, SD extends SlotsDef, SelectedState extends VariantsUnion<_SD> & BrandedState> {
|
|
319
316
|
private readonly machine;
|
|
320
317
|
private readonly states;
|
|
321
|
-
constructor(machine: Machine<State, Event, R, _SD, _ED,
|
|
322
|
-
on<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS,
|
|
323
|
-
reenter<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS,
|
|
318
|
+
constructor(machine: Machine<State, Event, R, _SD, _ED, SD>, states: ReadonlyArray<TaggedOrConstructor<SelectedState>>);
|
|
319
|
+
on<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS, SD, never, ExtractReply<NE>>): TransitionScope<State, Event, R, _SD, _ED, SD, SelectedState>;
|
|
320
|
+
reenter<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS, SD, never, ExtractReply<NE>>): TransitionScope<State, Event, R, _SD, _ED, SD, SelectedState>;
|
|
324
321
|
}
|
|
325
322
|
declare const make: typeof Machine.make;
|
|
326
323
|
/**
|
|
327
|
-
* Spawn an actor from a
|
|
324
|
+
* Spawn an actor from a machine.
|
|
325
|
+
*
|
|
326
|
+
* For machines with slots, pass implementations via `{ slots: { ... } }`.
|
|
328
327
|
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
* for that state (timers, scoped resources, etc.). Transition history
|
|
334
|
-
* is not replayed — only the current state's entry effects run.
|
|
328
|
+
* @example
|
|
329
|
+
* ```ts
|
|
330
|
+
* // No slots
|
|
331
|
+
* const actor = yield* Machine.spawn(machine);
|
|
335
332
|
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
333
|
+
* // With slots
|
|
334
|
+
* const actor = yield* Machine.spawn(machine, {
|
|
335
|
+
* slots: { canRetry: ({ max }) => attempts < max },
|
|
336
|
+
* });
|
|
337
|
+
*
|
|
338
|
+
* // With persistence
|
|
339
|
+
* const actor = yield* Machine.spawn(machine, {
|
|
340
|
+
* persist: {
|
|
341
|
+
* load: () => storage.get("actor-state"),
|
|
342
|
+
* save: (state) => storage.set("actor-state", state),
|
|
343
|
+
* },
|
|
344
|
+
* });
|
|
345
|
+
* ```
|
|
338
346
|
*/
|
|
339
347
|
declare const spawn: <S extends {
|
|
340
348
|
readonly _tag: string;
|
|
341
349
|
}, E extends {
|
|
342
350
|
readonly _tag: string;
|
|
343
|
-
}, R
|
|
351
|
+
}, R, SD extends SlotsDef = Record<string, never>>(machine: Machine<S, E, R, any, any, SD>, options?: string | {
|
|
344
352
|
id?: string;
|
|
345
353
|
hydrate?: S;
|
|
354
|
+
slots?: ProvideSlots<SD, any>;
|
|
355
|
+
supervision?: Supervision.Policy;
|
|
356
|
+
persist?: PersistConfig<S>;
|
|
346
357
|
}) => Effect.Effect<ActorRef<S, E>, never, R>;
|
|
347
|
-
declare const replay:
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
358
|
+
declare const replay: {
|
|
359
|
+
<S extends {
|
|
360
|
+
readonly _tag: string;
|
|
361
|
+
}, E extends {
|
|
362
|
+
readonly _tag: string;
|
|
363
|
+
}, R, SD extends SlotsDef = Record<string, never>>(machine: Machine<S, E, R, any, any, SD>, events: ReadonlyArray<E>, options?: {
|
|
364
|
+
from?: S;
|
|
365
|
+
slots?: ProvideSlots<SD, any>;
|
|
366
|
+
}): Effect.Effect<S, never, R>;
|
|
367
|
+
};
|
|
354
368
|
declare const reply: <State, Reply>(state: State, reply: Reply) => ReplyResult<State, Reply>;
|
|
369
|
+
declare const deferReply: <State>(state: State) => DeferReplyResult<State>;
|
|
355
370
|
//#endregion
|
|
356
|
-
export { BackgroundEffect,
|
|
371
|
+
export { BackgroundEffect, type DeferReplyResult, HandlerContext, Machine, MachineRef, MakeConfig, PersistConfig, type ReplyResult, SpawnEffect, StateEffectHandler, StateHandlerContext, TaskOptions, TimeoutConfig, Transition, TransitionHandler, deferReply, findTransitions, machine_d_exports, make, materializeMachine, replay, reply, spawn };
|