effect-machine 0.13.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 +14 -9
- package/dist/actor.d.ts +9 -6
- package/dist/actor.js +97 -43
- package/dist/cluster/entity-machine.d.ts +1 -1
- package/dist/cluster/entity-machine.js +1 -1
- package/dist/cluster/to-entity.d.ts +1 -1
- package/dist/errors.d.ts +9 -2
- package/dist/errors.js +8 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/internal/runtime.d.ts +2 -2
- package/dist/internal/runtime.js +5 -10
- package/dist/internal/transition.d.ts +9 -9
- package/dist/internal/transition.js +3 -5
- package/dist/machine.d.ts +122 -135
- package/dist/machine.js +97 -112
- package/dist/schema.d.ts +14 -0
- package/dist/schema.js +9 -0
- package/dist/slot.d.ts +112 -86
- package/dist/slot.js +92 -59
- package/dist/testing.d.ts +16 -16
- package/dist/testing.js +3 -3
- package/package.json +3 -3
- package/v3/dist/actor.d.ts +19 -12
- package/v3/dist/actor.js +130 -75
- package/v3/dist/cluster/entity-machine.d.ts +1 -1
- package/v3/dist/cluster/to-entity.d.ts +1 -1
- package/v3/dist/errors.d.ts +12 -3
- package/v3/dist/errors.js +10 -4
- package/v3/dist/index.d.ts +6 -6
- package/v3/dist/index.js +2 -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 +8 -8
- package/v3/dist/internal/runtime.js +45 -28
- package/v3/dist/internal/transition.d.ts +10 -10
- package/v3/dist/internal/transition.js +8 -10
- package/v3/dist/internal/utils.js +5 -1
- package/v3/dist/machine.d.ts +153 -120
- package/v3/dist/machine.js +118 -115
- 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/testing.d.ts +16 -16
- package/v3/dist/testing.js +7 -7
package/dist/machine.d.ts
CHANGED
|
@@ -2,15 +2,15 @@ import { DeferReplyResult, ReplyResult, TransitionResult } from "./internal/util
|
|
|
2
2
|
import { BrandedEvent, BrandedState, ExtractReply, TaggedOrConstructor } from "./internal/brands.js";
|
|
3
3
|
import { MachineEventSchema, MachineStateSchema, VariantsUnion } from "./schema.js";
|
|
4
4
|
import { DuplicateActorError } from "./errors.js";
|
|
5
|
-
import {
|
|
5
|
+
import { MachineContext, ProvideSlots, SlotCalls, SlotsDef, SlotsSchema } from "./slot.js";
|
|
6
6
|
import { Supervision } from "./supervision.js";
|
|
7
7
|
import { findTransitions } from "./internal/transition.js";
|
|
8
8
|
import { ActorRef, ActorSystem } from "./actor.js";
|
|
9
|
-
import { Cause, Duration, Effect, Schema, Scope, ServiceMap } from "effect";
|
|
9
|
+
import { Cause, Duration, Effect, Option, Schema, Scope, ServiceMap } from "effect";
|
|
10
10
|
|
|
11
11
|
//#region src/machine.d.ts
|
|
12
12
|
declare namespace machine_d_exports {
|
|
13
|
-
export { BackgroundEffect, DeferReplyResult, HandlerContext, Machine, MachineRef, MakeConfig,
|
|
13
|
+
export { BackgroundEffect, DeferReplyResult, HandlerContext, Machine, MachineRef, MakeConfig, PersistConfig, ReplyResult, SpawnEffect, StateEffectHandler, StateHandlerContext, TaskOptions, TimeoutConfig, Transition, TransitionHandler, deferReply, findTransitions, make, materializeMachine, replay, reply, spawn };
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Self reference for sending events back to the machine
|
|
@@ -23,7 +23,7 @@ interface MachineRef<Event> {
|
|
|
23
23
|
readonly _tag: string;
|
|
24
24
|
}, E2 extends {
|
|
25
25
|
readonly _tag: string;
|
|
26
|
-
}, R2>(id: string, machine: Machine<S2, E2, R2, any, any, any
|
|
26
|
+
}, R2>(id: string, machine: Machine<S2, E2, R2, any, any, any>) => Effect.Effect<ActorRef<S2, E2>, DuplicateActorError, R2>;
|
|
27
27
|
/**
|
|
28
28
|
* Settle a deferred reply from a spawn handler.
|
|
29
29
|
* Only usable when the transition handler returned `Machine.deferReply(state)`.
|
|
@@ -34,21 +34,20 @@ interface MachineRef<Event> {
|
|
|
34
34
|
/**
|
|
35
35
|
* Handler context passed to transition handlers
|
|
36
36
|
*/
|
|
37
|
-
interface HandlerContext<State, Event,
|
|
37
|
+
interface HandlerContext<State, Event, SD extends SlotsDef = Record<string, never>> {
|
|
38
38
|
readonly state: State;
|
|
39
39
|
readonly event: Event;
|
|
40
|
-
readonly
|
|
41
|
-
readonly effects: EffectSlots<ED>;
|
|
40
|
+
readonly slots: SlotCalls<SD>;
|
|
42
41
|
}
|
|
43
42
|
/**
|
|
44
43
|
* Handler context passed to state effect handlers (onEnter, spawn, background)
|
|
45
44
|
*/
|
|
46
|
-
interface StateHandlerContext<State, Event,
|
|
45
|
+
interface StateHandlerContext<State, Event, SD extends SlotsDef = Record<string, never>> {
|
|
47
46
|
readonly actorId: string;
|
|
48
47
|
readonly state: State;
|
|
49
48
|
readonly event: Event;
|
|
50
49
|
readonly self: MachineRef<Event>;
|
|
51
|
-
readonly
|
|
50
|
+
readonly slots: SlotCalls<SD>;
|
|
52
51
|
readonly system: ActorSystem;
|
|
53
52
|
}
|
|
54
53
|
/**
|
|
@@ -56,38 +55,66 @@ interface StateHandlerContext<State, Event, ED extends EffectsDef> {
|
|
|
56
55
|
* When Reply is concrete (event has a reply schema), handler must return Machine.reply().
|
|
57
56
|
* When Reply is never, handler returns plain state.
|
|
58
57
|
*/
|
|
59
|
-
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>;
|
|
60
59
|
/**
|
|
61
60
|
* State effect handler function
|
|
62
61
|
*/
|
|
63
|
-
type StateEffectHandler<S, E,
|
|
62
|
+
type StateEffectHandler<S, E, SD extends SlotsDef, R> = (ctx: StateHandlerContext<S, E, SD>) => Effect.Effect<void, never, R>;
|
|
64
63
|
/**
|
|
65
64
|
* Transition definition
|
|
66
65
|
*/
|
|
67
|
-
interface Transition<State, Event,
|
|
66
|
+
interface Transition<State, Event, SD extends SlotsDef, R> {
|
|
68
67
|
readonly stateTag: string;
|
|
69
68
|
readonly eventTag: string;
|
|
70
|
-
readonly handler: TransitionHandler<State, Event, State,
|
|
69
|
+
readonly handler: TransitionHandler<State, Event, State, SD, R>;
|
|
71
70
|
readonly reenter?: boolean;
|
|
72
71
|
}
|
|
73
72
|
/**
|
|
74
73
|
* Spawn effect - state-scoped forked effect
|
|
75
74
|
*/
|
|
76
|
-
interface SpawnEffect<State, Event,
|
|
75
|
+
interface SpawnEffect<State, Event, SD extends SlotsDef, R> {
|
|
77
76
|
readonly stateTag: string;
|
|
78
|
-
readonly handler: StateEffectHandler<State, Event,
|
|
77
|
+
readonly handler: StateEffectHandler<State, Event, SD, R>;
|
|
79
78
|
}
|
|
80
79
|
/**
|
|
81
80
|
* Background effect - runs for entire machine lifetime
|
|
82
81
|
*/
|
|
83
|
-
interface BackgroundEffect<State, Event,
|
|
84
|
-
readonly handler: StateEffectHandler<State, Event,
|
|
82
|
+
interface BackgroundEffect<State, Event, SD extends SlotsDef, R> {
|
|
83
|
+
readonly handler: StateEffectHandler<State, Event, SD, R>;
|
|
85
84
|
}
|
|
86
|
-
interface TaskOptions<State, Event,
|
|
87
|
-
readonly onSuccess
|
|
88
|
-
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;
|
|
89
88
|
readonly name?: string;
|
|
90
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
|
+
}
|
|
91
118
|
/**
|
|
92
119
|
* Configuration for `.timeout()` — gen_statem-style state timeouts.
|
|
93
120
|
*
|
|
@@ -100,25 +127,18 @@ interface TimeoutConfig<State, Event> {
|
|
|
100
127
|
/** Event to send when the timer fires. Static or derived from current state. */
|
|
101
128
|
readonly event: Event | ((state: State) => Event);
|
|
102
129
|
}
|
|
103
|
-
interface MakeConfig<SD extends Record<string, Schema.Struct.Fields>, ED extends Record<string, Schema.Struct.Fields>, S extends BrandedState, E extends BrandedEvent,
|
|
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>> {
|
|
104
131
|
readonly state: MachineStateSchema<SD> & {
|
|
105
132
|
Type: S;
|
|
106
133
|
};
|
|
107
134
|
readonly event: MachineEventSchema<ED> & {
|
|
108
135
|
Type: E;
|
|
109
136
|
};
|
|
110
|
-
readonly
|
|
111
|
-
readonly effects?: EffectsSchema<EFD>;
|
|
137
|
+
readonly slots?: SlotsSchema<SLD>;
|
|
112
138
|
readonly initial: S;
|
|
139
|
+
/** Validate slot inputs/outputs at runtime. Default: true. Set to false for hot paths. */
|
|
140
|
+
readonly slotValidation?: boolean;
|
|
113
141
|
}
|
|
114
|
-
/** Check if a GuardsDef has any actual keys */
|
|
115
|
-
type HasGuardKeys<GD extends GuardsDef> = [keyof GD] extends [never] ? false : GD extends Record<string, never> ? false : true;
|
|
116
|
-
/** Check if an EffectsDef has any actual keys */
|
|
117
|
-
type HasEffectKeys<EFD extends EffectsDef> = [keyof EFD] extends [never] ? false : EFD extends Record<string, never> ? false : true;
|
|
118
|
-
/** Context type passed to guard/effect handlers */
|
|
119
|
-
type SlotContext<State, Event> = MachineContext<State, Event, MachineRef<Event>>;
|
|
120
|
-
/** Combined handlers for build() - guards and effects only */
|
|
121
|
-
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);
|
|
122
142
|
/**
|
|
123
143
|
* Bind slot handlers to a machine, returning a fresh copy with handlers installed.
|
|
124
144
|
* If no handlers provided and machine has no slots, returns the machine as-is.
|
|
@@ -126,7 +146,7 @@ type ProvideHandlers<State, Event, GD extends GuardsDef, EFD extends EffectsDef,
|
|
|
126
146
|
*
|
|
127
147
|
* @internal — used by spawn, replay, simulate, test harness, entity-machine
|
|
128
148
|
*/
|
|
129
|
-
declare const materializeMachine: <S, E, R,
|
|
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>;
|
|
130
150
|
/**
|
|
131
151
|
* Machine definition with fluent builder API.
|
|
132
152
|
*
|
|
@@ -136,17 +156,16 @@ declare const materializeMachine: <S, E, R, GD extends GuardsDef, EFD extends Ef
|
|
|
136
156
|
* - `R`: Effect requirements
|
|
137
157
|
* - `_SD`: State schema definition (for compile-time validation)
|
|
138
158
|
* - `_ED`: Event schema definition (for compile-time validation)
|
|
139
|
-
* - `
|
|
140
|
-
* - `EFD`: Effect definitions
|
|
159
|
+
* - `SD`: Slot definitions
|
|
141
160
|
*/
|
|
142
|
-
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>> {
|
|
143
162
|
readonly initial: State;
|
|
144
163
|
/** @internal */
|
|
145
|
-
readonly _transitions: Array<Transition<State, Event,
|
|
164
|
+
readonly _transitions: Array<Transition<State, Event, SD, R>>;
|
|
146
165
|
/** @internal */
|
|
147
|
-
readonly _spawnEffects: Array<SpawnEffect<State, Event,
|
|
166
|
+
readonly _spawnEffects: Array<SpawnEffect<State, Event, SD, R>>;
|
|
148
167
|
/** @internal */
|
|
149
|
-
readonly _backgroundEffects: Array<BackgroundEffect<State, Event,
|
|
168
|
+
readonly _backgroundEffects: Array<BackgroundEffect<State, Event, SD, R>>;
|
|
150
169
|
/** @internal */
|
|
151
170
|
readonly _finalStates: Set<string>;
|
|
152
171
|
/** @internal */
|
|
@@ -155,18 +174,13 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
155
174
|
readonly eventTag: string;
|
|
156
175
|
}>;
|
|
157
176
|
/** @internal */
|
|
158
|
-
readonly
|
|
159
|
-
/** @internal */
|
|
160
|
-
readonly _effectsSchema?: EffectsSchema<EFD>;
|
|
177
|
+
readonly _slotsSchema?: SlotsSchema<SD>;
|
|
161
178
|
/** @internal */
|
|
162
|
-
readonly
|
|
179
|
+
readonly _slotHandlers: Map<string, (params: unknown) => unknown | Effect.Effect<unknown, never, R>>;
|
|
163
180
|
/** @internal */
|
|
164
|
-
readonly
|
|
181
|
+
readonly _slots: SlotCalls<SD>;
|
|
165
182
|
/** @internal */
|
|
166
|
-
readonly
|
|
167
|
-
guards: GuardSlots<GD>;
|
|
168
|
-
effects: EffectSlots<EFD>;
|
|
169
|
-
};
|
|
183
|
+
readonly _slotValidation: boolean;
|
|
170
184
|
readonly stateSchema?: Schema.Schema<State>;
|
|
171
185
|
readonly eventSchema?: Schema.Schema<Event>;
|
|
172
186
|
/** @internal */
|
|
@@ -176,70 +190,72 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
176
190
|
* Uses shared module-level tag for all machines.
|
|
177
191
|
*/
|
|
178
192
|
readonly Context: ServiceMap.Service<MachineContext<State, Event, MachineRef<Event>>, MachineContext<State, Event, MachineRef<Event>>>;
|
|
179
|
-
get transitions(): ReadonlyArray<Transition<State, Event,
|
|
180
|
-
get spawnEffects(): ReadonlyArray<SpawnEffect<State, Event,
|
|
181
|
-
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>>;
|
|
182
196
|
get finalStates(): ReadonlySet<string>;
|
|
183
197
|
get postponeRules(): ReadonlyArray<{
|
|
184
198
|
readonly stateTag: string;
|
|
185
199
|
readonly eventTag: string;
|
|
186
200
|
}>;
|
|
187
|
-
get
|
|
188
|
-
get effectsSchema(): EffectsSchema<EFD> | undefined;
|
|
201
|
+
get slotsSchema(): SlotsSchema<SD> | undefined;
|
|
189
202
|
get replySchemas(): ReadonlyMap<string, Schema.Decoder<unknown>>;
|
|
190
203
|
/** @internal */
|
|
191
|
-
constructor(initial: State, stateSchema?: Schema.Schema<State>, eventSchema?: Schema.Schema<Event>,
|
|
192
|
-
from<NS extends VariantsUnion<_SD> & BrandedState, R1>(state: TaggedOrConstructor<NS>, build: (scope: TransitionScope<State, Event, R, _SD, _ED,
|
|
193
|
-
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>;
|
|
194
207
|
/** @internal */
|
|
195
|
-
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>;
|
|
196
209
|
/** Register transition for a single state */
|
|
197
|
-
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>;
|
|
198
211
|
/** Register transition for multiple states (handler receives union of state types) */
|
|
199
|
-
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>;
|
|
200
213
|
/**
|
|
201
214
|
* Like `on()`, but forces onEnter/spawn to run even when transitioning to the same state tag.
|
|
202
215
|
* Use this to restart timers, re-run spawned effects, or reset state-scoped effects.
|
|
203
216
|
*/
|
|
204
217
|
/** Single state */
|
|
205
|
-
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>;
|
|
206
219
|
/** Multiple states */
|
|
207
|
-
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>;
|
|
208
221
|
/**
|
|
209
222
|
* Register a wildcard transition that fires from any state when no specific transition matches.
|
|
210
223
|
* Specific `.on()` transitions always take priority over `.onAny()`.
|
|
211
224
|
*/
|
|
212
|
-
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>;
|
|
213
226
|
/** @internal */
|
|
214
227
|
private addTransition;
|
|
215
228
|
/**
|
|
216
229
|
* State-scoped effect that is forked on state entry and automatically cancelled on state exit.
|
|
217
|
-
* Use effect slots defined via `Slot.Effects` for the actual work.
|
|
218
230
|
*
|
|
219
231
|
* @example
|
|
220
232
|
* ```ts
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
* fetchData: ({ url }, { self }) =>
|
|
229
|
-
* Effect.gen(function* () {
|
|
230
|
-
* yield* Effect.addFinalizer(() => Effect.log("Leaving Loading"));
|
|
231
|
-
* const data = yield* Http.get(url);
|
|
232
|
-
* yield* self.send(Event.Loaded({ data }));
|
|
233
|
-
* }),
|
|
234
|
-
* });
|
|
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
|
+
* );
|
|
235
240
|
* ```
|
|
236
241
|
*/
|
|
237
|
-
|
|
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>;
|
|
238
246
|
/**
|
|
239
247
|
* State-scoped task that runs on entry and sends success/failure events.
|
|
240
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
|
|
241
254
|
*/
|
|
242
|
-
|
|
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, explicit onSuccess */
|
|
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>;
|
|
243
259
|
/**
|
|
244
260
|
* State timeout — gen_statem's `state_timeout`.
|
|
245
261
|
*
|
|
@@ -261,28 +277,20 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
261
277
|
* })
|
|
262
278
|
* ```
|
|
263
279
|
*/
|
|
264
|
-
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>;
|
|
265
281
|
/**
|
|
266
282
|
* Machine-lifetime effect that is forked on actor spawn and runs until the actor stops.
|
|
267
|
-
* Use effect slots defined via `Slot.Effects` for the actual work.
|
|
268
283
|
*
|
|
269
284
|
* @example
|
|
270
285
|
* ```ts
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
* .background(({ effects }) => effects.heartbeat())
|
|
277
|
-
* .build({
|
|
278
|
-
* heartbeat: (_, { self }) =>
|
|
279
|
-
* Effect.forever(
|
|
280
|
-
* Effect.sleep("30 seconds").pipe(Effect.andThen(self.send(Event.Ping)))
|
|
281
|
-
* ),
|
|
282
|
-
* });
|
|
286
|
+
* machine.background(({ self }) =>
|
|
287
|
+
* Effect.forever(
|
|
288
|
+
* Effect.sleep("30 seconds").pipe(Effect.andThen(self.send(Event.Ping))),
|
|
289
|
+
* ),
|
|
290
|
+
* );
|
|
283
291
|
* ```
|
|
284
292
|
*/
|
|
285
|
-
background(handler: StateEffectHandler<State, Event,
|
|
293
|
+
background(handler: StateEffectHandler<State, Event, SD, Scope.Scope>): Machine<State, Event, R, _SD, _ED, SD>;
|
|
286
294
|
/**
|
|
287
295
|
* Postpone events — gen_statem's event postpone.
|
|
288
296
|
*
|
|
@@ -300,45 +308,18 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
300
308
|
* .postpone(State.Connecting, [Event.Data, Event.Cmd]) // multiple events
|
|
301
309
|
* ```
|
|
302
310
|
*/
|
|
303
|
-
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,
|
|
304
|
-
final<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>): Machine<State, Event, R, _SD, _ED,
|
|
305
|
-
static make<SD extends Record<string, Schema.Struct.Fields>, ED extends Record<string, Schema.Struct.Fields>, S extends BrandedState, E extends BrandedEvent,
|
|
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>;
|
|
306
314
|
}
|
|
307
|
-
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> {
|
|
308
316
|
private readonly machine;
|
|
309
317
|
private readonly states;
|
|
310
|
-
constructor(machine: Machine<State, Event, R, _SD, _ED,
|
|
311
|
-
on<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS,
|
|
312
|
-
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>;
|
|
313
321
|
}
|
|
314
322
|
declare const make: typeof Machine.make;
|
|
315
|
-
/**
|
|
316
|
-
* Spawn an actor directly without ActorSystem ceremony.
|
|
317
|
-
* Accepts a `Machine` directly. For slotful machines, pass `{ slots }` in options.
|
|
318
|
-
*
|
|
319
|
-
* **Single actor, no registry.** Caller manages lifetime via `actor.stop`.
|
|
320
|
-
* If a `Scope` exists in context, cleanup attaches automatically on scope close.
|
|
321
|
-
*
|
|
322
|
-
* For registry, lookup by ID, persistence, or multi-actor coordination,
|
|
323
|
-
* use `ActorSystemService` / `system.spawn` instead.
|
|
324
|
-
*
|
|
325
|
-
* @example
|
|
326
|
-
* ```ts
|
|
327
|
-
* // Fire-and-forget — caller manages lifetime
|
|
328
|
-
* const actor = yield* Machine.spawn(machine.build());
|
|
329
|
-
* yield* actor.send(Event.Start);
|
|
330
|
-
* yield* actor.awaitFinal;
|
|
331
|
-
* yield* actor.stop;
|
|
332
|
-
*
|
|
333
|
-
* // Scope-aware — auto-cleans up on scope close
|
|
334
|
-
* yield* Effect.scoped(Effect.gen(function* () {
|
|
335
|
-
* const actor = yield* Machine.spawn(machine.build());
|
|
336
|
-
* yield* actor.send(Event.Start);
|
|
337
|
-
* // actor.stop called automatically when scope closes
|
|
338
|
-
* }));
|
|
339
|
-
* ```
|
|
340
|
-
*/
|
|
341
|
-
type AnyMachine<S, E, R> = Machine<S, E, R, any, any, any, any>;
|
|
342
323
|
/**
|
|
343
324
|
* Spawn an actor from a machine.
|
|
344
325
|
*
|
|
@@ -351,34 +332,40 @@ type AnyMachine<S, E, R> = Machine<S, E, R, any, any, any, any>;
|
|
|
351
332
|
*
|
|
352
333
|
* // With slots
|
|
353
334
|
* const actor = yield* Machine.spawn(machine, {
|
|
354
|
-
* slots: { canRetry: ({ max }
|
|
335
|
+
* slots: { canRetry: ({ max }) => attempts < max },
|
|
355
336
|
* });
|
|
356
337
|
*
|
|
357
|
-
* // With
|
|
358
|
-
* const actor = yield* Machine.spawn(machine, {
|
|
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
|
+
* });
|
|
359
345
|
* ```
|
|
360
346
|
*/
|
|
361
347
|
declare const spawn: <S extends {
|
|
362
348
|
readonly _tag: string;
|
|
363
349
|
}, E extends {
|
|
364
350
|
readonly _tag: string;
|
|
365
|
-
}, R
|
|
351
|
+
}, R, SD extends SlotsDef = Record<string, never>>(machine: Machine<S, E, R, any, any, SD>, options?: string | {
|
|
366
352
|
id?: string;
|
|
367
353
|
hydrate?: S;
|
|
368
|
-
slots?:
|
|
354
|
+
slots?: ProvideSlots<SD, any>;
|
|
369
355
|
supervision?: Supervision.Policy;
|
|
356
|
+
persist?: PersistConfig<S>;
|
|
370
357
|
}) => Effect.Effect<ActorRef<S, E>, never, R>;
|
|
371
358
|
declare const replay: {
|
|
372
359
|
<S extends {
|
|
373
360
|
readonly _tag: string;
|
|
374
361
|
}, E extends {
|
|
375
362
|
readonly _tag: string;
|
|
376
|
-
}, R
|
|
363
|
+
}, R, SD extends SlotsDef = Record<string, never>>(machine: Machine<S, E, R, any, any, SD>, events: ReadonlyArray<E>, options?: {
|
|
377
364
|
from?: S;
|
|
378
|
-
slots?:
|
|
365
|
+
slots?: ProvideSlots<SD, any>;
|
|
379
366
|
}): Effect.Effect<S, never, R>;
|
|
380
367
|
};
|
|
381
368
|
declare const reply: <State, Reply>(state: State, reply: Reply) => ReplyResult<State, Reply>;
|
|
382
369
|
declare const deferReply: <State>(state: State) => DeferReplyResult<State>;
|
|
383
370
|
//#endregion
|
|
384
|
-
export { BackgroundEffect, type DeferReplyResult, HandlerContext, Machine, MachineRef, MakeConfig,
|
|
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 };
|