effect-machine 0.11.0 → 0.13.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 +128 -324
- package/dist/actor.d.ts +52 -31
- package/dist/actor.js +218 -283
- package/dist/cluster/adapters/in-memory.d.ts +28 -0
- package/dist/cluster/adapters/in-memory.js +79 -0
- package/dist/cluster/entity-actor-ref.d.ts +56 -0
- package/dist/cluster/entity-actor-ref.js +33 -0
- package/dist/cluster/entity-machine.d.ts +31 -49
- package/dist/cluster/entity-machine.js +178 -52
- package/dist/cluster/index.d.ts +5 -2
- package/dist/cluster/index.js +4 -1
- package/dist/cluster/persistence.d.ts +49 -0
- package/dist/cluster/persistence.js +18 -0
- package/dist/cluster/to-entity.d.ts +9 -3
- package/dist/cluster/to-entity.js +16 -4
- package/dist/errors.d.ts +25 -17
- package/dist/errors.js +10 -5
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -3
- package/dist/internal/brands.d.ts +14 -1
- package/dist/internal/runtime.d.ts +142 -0
- package/dist/internal/runtime.js +357 -0
- package/dist/internal/transition.d.ts +10 -4
- package/dist/internal/transition.js +24 -12
- package/dist/internal/utils.d.ts +42 -6
- package/dist/internal/utils.js +27 -1
- package/dist/machine.d.ts +89 -55
- package/dist/machine.js +80 -68
- package/dist/schema.d.ts +35 -34
- package/dist/schema.js +33 -4
- package/dist/supervision.d.ts +97 -0
- package/dist/supervision.js +42 -0
- package/dist/testing.d.ts +17 -8
- package/dist/testing.js +22 -23
- package/package.json +7 -7
- package/v3/dist/actor.d.ts +54 -37
- package/v3/dist/actor.js +209 -277
- package/v3/dist/cluster/adapters/in-memory.d.ts +15 -0
- package/v3/dist/cluster/adapters/in-memory.js +62 -0
- package/v3/dist/cluster/entity-actor-ref.d.ts +49 -0
- package/v3/dist/cluster/entity-actor-ref.js +19 -0
- package/v3/dist/cluster/entity-machine.d.ts +34 -49
- package/v3/dist/cluster/entity-machine.js +134 -50
- package/v3/dist/cluster/index.d.ts +5 -2
- package/v3/dist/cluster/index.js +4 -1
- package/v3/dist/cluster/persistence.d.ts +48 -0
- package/v3/dist/cluster/persistence.js +14 -0
- package/v3/dist/cluster/to-entity.d.ts +5 -2
- package/v3/dist/cluster/to-entity.js +12 -4
- package/v3/dist/errors.d.ts +18 -8
- package/v3/dist/errors.js +9 -4
- package/v3/dist/index.d.ts +6 -4
- package/v3/dist/index.js +3 -2
- package/v3/dist/internal/brands.d.ts +15 -1
- package/v3/dist/internal/runtime.d.ts +142 -0
- package/v3/dist/internal/runtime.js +335 -0
- package/v3/dist/internal/transition.d.ts +10 -4
- package/v3/dist/internal/transition.js +23 -11
- package/v3/dist/internal/utils.d.ts +42 -6
- package/v3/dist/internal/utils.js +27 -1
- package/v3/dist/machine.d.ts +35 -47
- package/v3/dist/machine.js +62 -64
- package/v3/dist/schema.d.ts +35 -34
- package/v3/dist/schema.js +29 -3
- package/v3/dist/supervision.d.ts +97 -0
- package/v3/dist/supervision.js +42 -0
- package/v3/dist/testing.d.ts +18 -9
- package/v3/dist/testing.js +21 -22
package/dist/machine.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { BrandedEvent, BrandedState, TaggedOrConstructor } from "./internal/brands.js";
|
|
1
|
+
import { DeferReplyResult, ReplyResult, TransitionResult } from "./internal/utils.js";
|
|
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 { EffectHandlers, EffectSlots, EffectsDef, EffectsSchema, GuardHandlers, GuardSlots, GuardsDef, GuardsSchema, MachineContext } 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
9
|
import { Cause, Duration, Effect, Schema, Scope, ServiceMap } 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, ProvideHandlers, ReplyResult, SlotContext, 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,7 +23,13 @@ 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, 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
|
|
@@ -45,9 +52,11 @@ interface StateHandlerContext<State, Event, ED extends EffectsDef> {
|
|
|
45
52
|
readonly system: ActorSystem;
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
48
|
-
* Transition handler function
|
|
55
|
+
* Transition handler function.
|
|
56
|
+
* When Reply is concrete (event has a reply schema), handler must return Machine.reply().
|
|
57
|
+
* When Reply is never, handler returns plain state.
|
|
49
58
|
*/
|
|
50
|
-
type TransitionHandler<S, E, NewState, GD extends GuardsDef, ED extends EffectsDef, R> = (ctx: HandlerContext<S, E, GD, ED>) => TransitionResult<NewState, R>;
|
|
59
|
+
type TransitionHandler<S, E, NewState, GD extends GuardsDef, ED extends EffectsDef, R, Reply = never> = (ctx: HandlerContext<S, E, GD, ED>) => TransitionResult<NewState, R, Reply>;
|
|
51
60
|
/**
|
|
52
61
|
* State effect handler function
|
|
53
62
|
*/
|
|
@@ -91,9 +100,6 @@ interface TimeoutConfig<State, Event> {
|
|
|
91
100
|
/** Event to send when the timer fires. Static or derived from current state. */
|
|
92
101
|
readonly event: Event | ((state: State) => Event);
|
|
93
102
|
}
|
|
94
|
-
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
95
|
-
type IsUnknown<T> = unknown extends T ? ([T] extends [unknown] ? true : false) : false;
|
|
96
|
-
type NormalizeR<T> = IsAny<T> extends true ? T : IsUnknown<T> extends true ? never : T;
|
|
97
103
|
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> {
|
|
98
104
|
readonly state: MachineStateSchema<SD> & {
|
|
99
105
|
Type: S;
|
|
@@ -113,22 +119,14 @@ type HasEffectKeys<EFD extends EffectsDef> = [keyof EFD] extends [never] ? false
|
|
|
113
119
|
type SlotContext<State, Event> = MachineContext<State, Event, MachineRef<Event>>;
|
|
114
120
|
/** Combined handlers for build() - guards and effects only */
|
|
115
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);
|
|
116
|
-
/** Whether the machine has any guard or effect slots */
|
|
117
|
-
type HasSlots<GD extends GuardsDef, EFD extends EffectsDef> = HasGuardKeys<GD> extends true ? true : HasEffectKeys<EFD>;
|
|
118
122
|
/**
|
|
119
|
-
*
|
|
123
|
+
* Bind slot handlers to a machine, returning a fresh copy with handlers installed.
|
|
124
|
+
* If no handlers provided and machine has no slots, returns the machine as-is.
|
|
125
|
+
* Validates that all required slots are provided and no extra slots are given.
|
|
120
126
|
*
|
|
121
|
-
*
|
|
122
|
-
* accepted by `Machine.spawn` and `ActorSystem.spawn` (regular overload).
|
|
123
|
-
* Testing utilities (`simulate`, `createTestHarness`, etc.) still accept `Machine`.
|
|
127
|
+
* @internal — used by spawn, replay, simulate, test harness, entity-machine
|
|
124
128
|
*/
|
|
125
|
-
declare
|
|
126
|
-
/** @internal */
|
|
127
|
-
readonly _inner: Machine<State, Event, R, any, any, any, any>;
|
|
128
|
-
/** @internal */
|
|
129
|
-
constructor(machine: Machine<State, Event, R, any, any, any, any>);
|
|
130
|
-
get initial(): State;
|
|
131
|
-
}
|
|
129
|
+
declare const materializeMachine: <S, E, R, GD extends GuardsDef, EFD extends EffectsDef>(machine: Machine<S, E, R, any, any, GD, EFD>, handlers?: Record<string, any>) => Machine<S, E, never, any, any, GD, EFD>;
|
|
132
130
|
/**
|
|
133
131
|
* Machine definition with fluent builder API.
|
|
134
132
|
*
|
|
@@ -171,6 +169,8 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
171
169
|
};
|
|
172
170
|
readonly stateSchema?: Schema.Schema<State>;
|
|
173
171
|
readonly eventSchema?: Schema.Schema<Event>;
|
|
172
|
+
/** @internal */
|
|
173
|
+
readonly _replySchemas: ReadonlyMap<string, Schema.Decoder<unknown>>;
|
|
174
174
|
/**
|
|
175
175
|
* Context tag for accessing machine state/event/self in slot handlers.
|
|
176
176
|
* Uses shared module-level tag for all machines.
|
|
@@ -186,24 +186,25 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
186
186
|
}>;
|
|
187
187
|
get guardsSchema(): GuardsSchema<GD> | undefined;
|
|
188
188
|
get effectsSchema(): EffectsSchema<EFD> | undefined;
|
|
189
|
+
get replySchemas(): ReadonlyMap<string, Schema.Decoder<unknown>>;
|
|
189
190
|
/** @internal */
|
|
190
191
|
constructor(initial: State, stateSchema?: Schema.Schema<State>, eventSchema?: Schema.Schema<Event>, guardsSchema?: GuardsSchema<GD>, effectsSchema?: EffectsSchema<EFD>);
|
|
191
192
|
from<NS extends VariantsUnion<_SD> & BrandedState, R1>(state: TaggedOrConstructor<NS>, build: (scope: TransitionScope<State, Event, R, _SD, _ED, GD, EFD, NS>) => R1): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
192
193
|
from<NS extends ReadonlyArray<TaggedOrConstructor<VariantsUnion<_SD> & BrandedState>>, R1>(states: NS, build: (scope: TransitionScope<State, Event, R, _SD, _ED, GD, EFD, NS[number] extends TaggedOrConstructor<infer S extends VariantsUnion<_SD> & BrandedState> ? S : never>) => R1): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
193
194
|
/** @internal */
|
|
194
|
-
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, GD, EFD, never
|
|
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, GD, EFD, never, ExtractReply<NE>>, reenter: boolean): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
195
196
|
/** Register transition for a single state */
|
|
196
|
-
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, GD, EFD, never
|
|
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, GD, EFD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
197
198
|
/** Register transition for multiple states (handler receives union of state types) */
|
|
198
|
-
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, GD, EFD, never
|
|
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, GD, EFD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
199
200
|
/**
|
|
200
201
|
* Like `on()`, but forces onEnter/spawn to run even when transitioning to the same state tag.
|
|
201
202
|
* Use this to restart timers, re-run spawned effects, or reset state-scoped effects.
|
|
202
203
|
*/
|
|
203
204
|
/** Single state */
|
|
204
|
-
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, GD, EFD, never
|
|
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, GD, EFD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
205
206
|
/** Multiple states */
|
|
206
|
-
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, GD, EFD, never
|
|
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, GD, EFD, never, ExtractReply<NE>>): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
207
208
|
/**
|
|
208
209
|
* Register a wildcard transition that fires from any state when no specific transition matches.
|
|
209
210
|
* Specific `.on()` transitions always take priority over `.onAny()`.
|
|
@@ -301,50 +302,83 @@ declare class Machine<State, Event, R = never, _SD extends Record<string, Schema
|
|
|
301
302
|
*/
|
|
302
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, GD, EFD>;
|
|
303
304
|
final<NS extends VariantsUnion<_SD> & BrandedState>(state: TaggedOrConstructor<NS>): Machine<State, Event, R, _SD, _ED, GD, EFD>;
|
|
304
|
-
/**
|
|
305
|
-
* Finalize the machine. Returns a `BuiltMachine` — the only type accepted by `Machine.spawn`.
|
|
306
|
-
*
|
|
307
|
-
* - Machines with slots: pass implementations as the first argument.
|
|
308
|
-
* - Machines without slots: call with no arguments.
|
|
309
|
-
*/
|
|
310
|
-
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>>;
|
|
311
305
|
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>;
|
|
312
306
|
}
|
|
313
307
|
declare class TransitionScope<State, Event, R, _SD extends Record<string, Schema.Struct.Fields>, _ED extends Record<string, Schema.Struct.Fields>, GD extends GuardsDef, EFD extends EffectsDef, SelectedState extends VariantsUnion<_SD> & BrandedState> {
|
|
314
308
|
private readonly machine;
|
|
315
309
|
private readonly states;
|
|
316
310
|
constructor(machine: Machine<State, Event, R, _SD, _ED, GD, EFD>, states: ReadonlyArray<TaggedOrConstructor<SelectedState>>);
|
|
317
|
-
on<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS, GD, EFD, never
|
|
318
|
-
reenter<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS, GD, EFD, never
|
|
311
|
+
on<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS, GD, EFD, never, ExtractReply<NE>>): TransitionScope<State, Event, R, _SD, _ED, GD, EFD, SelectedState>;
|
|
312
|
+
reenter<NE extends VariantsUnion<_ED> & BrandedEvent, RS extends VariantsUnion<_SD> & BrandedState>(event: TaggedOrConstructor<NE>, handler: TransitionHandler<SelectedState, NE, RS, GD, EFD, never, ExtractReply<NE>>): TransitionScope<State, Event, R, _SD, _ED, GD, EFD, SelectedState>;
|
|
319
313
|
}
|
|
320
314
|
declare const make: typeof Machine.make;
|
|
321
315
|
/**
|
|
322
|
-
* Spawn an actor
|
|
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
|
+
/**
|
|
343
|
+
* Spawn an actor from a machine.
|
|
344
|
+
*
|
|
345
|
+
* For machines with slots, pass implementations via `{ slots: { ... } }`.
|
|
323
346
|
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
* for that state (timers, scoped resources, etc.). Transition history
|
|
329
|
-
* is not replayed — only the current state's entry effects run.
|
|
347
|
+
* @example
|
|
348
|
+
* ```ts
|
|
349
|
+
* // No slots
|
|
350
|
+
* const actor = yield* Machine.spawn(machine);
|
|
330
351
|
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
352
|
+
* // With slots
|
|
353
|
+
* const actor = yield* Machine.spawn(machine, {
|
|
354
|
+
* slots: { canRetry: ({ max }, { state }) => state.attempts < max },
|
|
355
|
+
* });
|
|
356
|
+
*
|
|
357
|
+
* // With hydration
|
|
358
|
+
* const actor = yield* Machine.spawn(machine, { hydrate: savedState });
|
|
359
|
+
* ```
|
|
333
360
|
*/
|
|
334
361
|
declare const spawn: <S extends {
|
|
335
362
|
readonly _tag: string;
|
|
336
363
|
}, E extends {
|
|
337
364
|
readonly _tag: string;
|
|
338
|
-
}, R>(machine:
|
|
365
|
+
}, R>(machine: AnyMachine<S, E, R>, options?: string | {
|
|
339
366
|
id?: string;
|
|
340
367
|
hydrate?: S;
|
|
368
|
+
slots?: Record<string, any>;
|
|
369
|
+
supervision?: Supervision.Policy;
|
|
341
370
|
}) => Effect.Effect<ActorRef<S, E>, never, R>;
|
|
342
|
-
declare const replay:
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
371
|
+
declare const replay: {
|
|
372
|
+
<S extends {
|
|
373
|
+
readonly _tag: string;
|
|
374
|
+
}, E extends {
|
|
375
|
+
readonly _tag: string;
|
|
376
|
+
}, R>(machine: AnyMachine<S, E, R>, events: ReadonlyArray<E>, options?: {
|
|
377
|
+
from?: S;
|
|
378
|
+
slots?: Record<string, any>;
|
|
379
|
+
}): Effect.Effect<S, never, R>;
|
|
380
|
+
};
|
|
381
|
+
declare const reply: <State, Reply>(state: State, reply: Reply) => ReplyResult<State, Reply>;
|
|
382
|
+
declare const deferReply: <State>(state: State) => DeferReplyResult<State>;
|
|
349
383
|
//#endregion
|
|
350
|
-
export { BackgroundEffect,
|
|
384
|
+
export { BackgroundEffect, type DeferReplyResult, HandlerContext, Machine, MachineRef, MakeConfig, ProvideHandlers, type ReplyResult, SlotContext, SpawnEffect, StateEffectHandler, StateHandlerContext, TaskOptions, TimeoutConfig, Transition, TransitionHandler, deferReply, findTransitions, machine_d_exports, make, materializeMachine, replay, reply, spawn };
|
package/dist/machine.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { Inspector } from "./inspection.js";
|
|
3
|
-
import { getTag, stubSystem } from "./internal/utils.js";
|
|
4
|
-
import { ProvisionValidationError, SlotProvisionError } from "./errors.js";
|
|
5
|
-
import { emitWithTimestamp } from "./internal/inspection.js";
|
|
6
|
-
import { MachineContextTag } from "./slot.js";
|
|
3
|
+
import { getTag, makeDeferReply, makeReply, stubSystem } from "./internal/utils.js";
|
|
7
4
|
import { findTransitions, invalidateIndex, resolveTransition, runTransitionHandler, shouldPostpone } from "./internal/transition.js";
|
|
5
|
+
import { emitWithTimestamp } from "./internal/inspection.js";
|
|
6
|
+
import { ProvisionValidationError, SlotProvisionError } from "./errors.js";
|
|
8
7
|
import { createActor } from "./actor.js";
|
|
9
|
-
import {
|
|
8
|
+
import { MachineContextTag } from "./slot.js";
|
|
9
|
+
import { Cause, Effect, Exit, Option, Random, Scope } from "effect";
|
|
10
10
|
//#region src/machine.ts
|
|
11
11
|
var machine_exports = /* @__PURE__ */ __exportAll({
|
|
12
|
-
BuiltMachine: () => BuiltMachine,
|
|
13
12
|
Machine: () => Machine,
|
|
13
|
+
deferReply: () => deferReply,
|
|
14
14
|
findTransitions: () => findTransitions,
|
|
15
15
|
make: () => make,
|
|
16
|
+
materializeMachine: () => materializeMachine,
|
|
16
17
|
replay: () => replay,
|
|
18
|
+
reply: () => reply,
|
|
17
19
|
spawn: () => spawn
|
|
18
20
|
});
|
|
19
21
|
const emitTaskInspection = (input) => Effect.flatMap(Effect.serviceOption(Inspector), (inspector) => Option.isNone(inspector) ? Effect.void : emitWithTimestamp(inspector.value, (timestamp) => ({
|
|
@@ -26,22 +28,49 @@ const emitTaskInspection = (input) => Effect.flatMap(Effect.serviceOption(Inspec
|
|
|
26
28
|
timestamp
|
|
27
29
|
})));
|
|
28
30
|
/**
|
|
29
|
-
*
|
|
31
|
+
* Bind slot handlers to a machine, returning a fresh copy with handlers installed.
|
|
32
|
+
* If no handlers provided and machine has no slots, returns the machine as-is.
|
|
33
|
+
* Validates that all required slots are provided and no extra slots are given.
|
|
30
34
|
*
|
|
31
|
-
*
|
|
32
|
-
* accepted by `Machine.spawn` and `ActorSystem.spawn` (regular overload).
|
|
33
|
-
* Testing utilities (`simulate`, `createTestHarness`, etc.) still accept `Machine`.
|
|
35
|
+
* @internal — used by spawn, replay, simulate, test harness, entity-machine
|
|
34
36
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
const materializeMachine = (machine, handlers) => {
|
|
38
|
+
if (handlers === void 0) {
|
|
39
|
+
const hasGuards = machine._guardsSchema !== void 0 && Object.keys(machine._guardsSchema.definitions).length > 0;
|
|
40
|
+
const hasEffects = machine._effectsSchema !== void 0 && Object.keys(machine._effectsSchema.definitions).length > 0;
|
|
41
|
+
if (hasGuards || hasEffects) {
|
|
42
|
+
const missing = [];
|
|
43
|
+
if (machine._guardsSchema !== void 0) missing.push(...Object.keys(machine._guardsSchema.definitions));
|
|
44
|
+
if (machine._effectsSchema !== void 0) missing.push(...Object.keys(machine._effectsSchema.definitions));
|
|
45
|
+
throw new ProvisionValidationError({
|
|
46
|
+
missing,
|
|
47
|
+
extra: []
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return machine;
|
|
44
51
|
}
|
|
52
|
+
const requiredSlots = /* @__PURE__ */ new Set();
|
|
53
|
+
if (machine._guardsSchema !== void 0) for (const name of Object.keys(machine._guardsSchema.definitions)) requiredSlots.add(name);
|
|
54
|
+
if (machine._effectsSchema !== void 0) for (const name of Object.keys(machine._effectsSchema.definitions)) requiredSlots.add(name);
|
|
55
|
+
const providedSlots = new Set(Object.keys(handlers));
|
|
56
|
+
const missing = [];
|
|
57
|
+
const extra = [];
|
|
58
|
+
for (const name of requiredSlots) if (!providedSlots.has(name)) missing.push(name);
|
|
59
|
+
for (const name of providedSlots) if (!requiredSlots.has(name)) extra.push(name);
|
|
60
|
+
if (missing.length > 0 || extra.length > 0) throw new ProvisionValidationError({
|
|
61
|
+
missing,
|
|
62
|
+
extra
|
|
63
|
+
});
|
|
64
|
+
const result = new Machine(machine.initial, machine.stateSchema, machine.eventSchema, machine._guardsSchema, machine._effectsSchema);
|
|
65
|
+
result._transitions = [...machine._transitions];
|
|
66
|
+
result._finalStates = new Set(machine._finalStates);
|
|
67
|
+
result._spawnEffects = [...machine._spawnEffects];
|
|
68
|
+
result._backgroundEffects = [...machine._backgroundEffects];
|
|
69
|
+
result._postponeRules = [...machine._postponeRules];
|
|
70
|
+
result._replySchemas = machine._replySchemas;
|
|
71
|
+
if (machine._guardsSchema !== void 0) for (const name of Object.keys(machine._guardsSchema.definitions)) result._guardHandlers.set(name, handlers[name]);
|
|
72
|
+
if (machine._effectsSchema !== void 0) for (const name of Object.keys(machine._effectsSchema.definitions)) result._effectHandlers.set(name, handlers[name]);
|
|
73
|
+
return result;
|
|
45
74
|
};
|
|
46
75
|
/**
|
|
47
76
|
* Machine definition with fluent builder API.
|
|
@@ -69,6 +98,7 @@ var Machine = class Machine {
|
|
|
69
98
|
/** @internal */ _slots;
|
|
70
99
|
stateSchema;
|
|
71
100
|
eventSchema;
|
|
101
|
+
/** @internal */ _replySchemas;
|
|
72
102
|
/**
|
|
73
103
|
* Context tag for accessing machine state/event/self in slot handlers.
|
|
74
104
|
* Uses shared module-level tag for all machines.
|
|
@@ -95,6 +125,9 @@ var Machine = class Machine {
|
|
|
95
125
|
get effectsSchema() {
|
|
96
126
|
return this._effectsSchema;
|
|
97
127
|
}
|
|
128
|
+
get replySchemas() {
|
|
129
|
+
return this._replySchemas;
|
|
130
|
+
}
|
|
98
131
|
/** @internal */
|
|
99
132
|
constructor(initial, stateSchema, eventSchema, guardsSchema, effectsSchema) {
|
|
100
133
|
this.initial = initial;
|
|
@@ -105,6 +138,7 @@ var Machine = class Machine {
|
|
|
105
138
|
this._postponeRules = [];
|
|
106
139
|
this._guardsSchema = guardsSchema;
|
|
107
140
|
this._effectsSchema = effectsSchema;
|
|
141
|
+
this._replySchemas = eventSchema?._replySchemas ?? /* @__PURE__ */ new Map();
|
|
108
142
|
this._guardHandlers = /* @__PURE__ */ new Map();
|
|
109
143
|
this._effectHandlers = /* @__PURE__ */ new Map();
|
|
110
144
|
this.stateSchema = stateSchema;
|
|
@@ -348,40 +382,6 @@ var Machine = class Machine {
|
|
|
348
382
|
this._finalStates.add(stateTag);
|
|
349
383
|
return this;
|
|
350
384
|
}
|
|
351
|
-
/**
|
|
352
|
-
* Finalize the machine. Returns a `BuiltMachine` — the only type accepted by `Machine.spawn`.
|
|
353
|
-
*
|
|
354
|
-
* - Machines with slots: pass implementations as the first argument.
|
|
355
|
-
* - Machines without slots: call with no arguments.
|
|
356
|
-
*/
|
|
357
|
-
build(...args) {
|
|
358
|
-
const handlers = args[0];
|
|
359
|
-
if (handlers !== void 0) {
|
|
360
|
-
const requiredSlots = /* @__PURE__ */ new Set();
|
|
361
|
-
if (this._guardsSchema !== void 0) for (const name of Object.keys(this._guardsSchema.definitions)) requiredSlots.add(name);
|
|
362
|
-
if (this._effectsSchema !== void 0) for (const name of Object.keys(this._effectsSchema.definitions)) requiredSlots.add(name);
|
|
363
|
-
const providedSlots = new Set(Object.keys(handlers));
|
|
364
|
-
const missing = [];
|
|
365
|
-
const extra = [];
|
|
366
|
-
for (const name of requiredSlots) if (!providedSlots.has(name)) missing.push(name);
|
|
367
|
-
for (const name of providedSlots) if (!requiredSlots.has(name)) extra.push(name);
|
|
368
|
-
if (missing.length > 0 || extra.length > 0) throw new ProvisionValidationError({
|
|
369
|
-
missing,
|
|
370
|
-
extra
|
|
371
|
-
});
|
|
372
|
-
const result = new Machine(this.initial, this.stateSchema, this.eventSchema, this._guardsSchema, this._effectsSchema);
|
|
373
|
-
result._transitions = [...this._transitions];
|
|
374
|
-
result._finalStates = new Set(this._finalStates);
|
|
375
|
-
result._spawnEffects = [...this._spawnEffects];
|
|
376
|
-
result._backgroundEffects = [...this._backgroundEffects];
|
|
377
|
-
result._postponeRules = [...this._postponeRules];
|
|
378
|
-
const anyHandlers = handlers;
|
|
379
|
-
if (this._guardsSchema !== void 0) for (const name of Object.keys(this._guardsSchema.definitions)) result._guardHandlers.set(name, anyHandlers[name]);
|
|
380
|
-
if (this._effectsSchema !== void 0) for (const name of Object.keys(this._effectsSchema.definitions)) result._effectHandlers.set(name, anyHandlers[name]);
|
|
381
|
-
return new BuiltMachine(result);
|
|
382
|
-
}
|
|
383
|
-
return new BuiltMachine(this);
|
|
384
|
-
}
|
|
385
385
|
static make(config) {
|
|
386
386
|
return new Machine(config.initial, config.state, config.event, config.guards, config.effects);
|
|
387
387
|
}
|
|
@@ -402,27 +402,36 @@ var TransitionScope = class {
|
|
|
402
402
|
};
|
|
403
403
|
const make = Machine.make;
|
|
404
404
|
/**
|
|
405
|
-
* Spawn an actor from a
|
|
405
|
+
* Spawn an actor from a machine.
|
|
406
|
+
*
|
|
407
|
+
* For machines with slots, pass implementations via `{ slots: { ... } }`.
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```ts
|
|
411
|
+
* // No slots
|
|
412
|
+
* const actor = yield* Machine.spawn(machine);
|
|
406
413
|
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
* for that state (timers, scoped resources, etc.). Transition history
|
|
412
|
-
* is not replayed — only the current state's entry effects run.
|
|
414
|
+
* // With slots
|
|
415
|
+
* const actor = yield* Machine.spawn(machine, {
|
|
416
|
+
* slots: { canRetry: ({ max }, { state }) => state.attempts < max },
|
|
417
|
+
* });
|
|
413
418
|
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
419
|
+
* // With hydration
|
|
420
|
+
* const actor = yield* Machine.spawn(machine, { hydrate: savedState });
|
|
421
|
+
* ```
|
|
416
422
|
*/
|
|
417
|
-
const spawn = Effect.fn("effect-machine.spawn")(function* (
|
|
423
|
+
const spawn = Effect.fn("effect-machine.spawn")(function* (machine, idOrOptions) {
|
|
418
424
|
const opts = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
|
|
419
|
-
const actor = yield* createActor(opts?.id ?? `actor-${
|
|
425
|
+
const actor = yield* createActor(opts?.id ?? `actor-${(yield* Random.next).toString(36).slice(2)}`, materializeMachine(machine, opts?.slots), {
|
|
426
|
+
initialState: opts?.hydrate,
|
|
427
|
+
supervision: opts?.supervision
|
|
428
|
+
});
|
|
420
429
|
const maybeScope = yield* Effect.serviceOption(Scope.Scope);
|
|
421
430
|
if (Option.isSome(maybeScope)) yield* Scope.addFinalizer(maybeScope.value, actor.stop);
|
|
422
431
|
return actor;
|
|
423
432
|
});
|
|
424
|
-
const replay = Effect.fn("effect-machine.replay")(function* (
|
|
425
|
-
const machine =
|
|
433
|
+
const replay = Effect.fn("effect-machine.replay")(function* (input, events, options) {
|
|
434
|
+
const machine = materializeMachine(input, options?.slots);
|
|
426
435
|
let state = options?.from ?? machine.initial;
|
|
427
436
|
const hasPostponeRules = machine.postponeRules.length > 0;
|
|
428
437
|
const postponed = [];
|
|
@@ -430,7 +439,8 @@ const replay = Effect.fn("effect-machine.replay")(function* (built, events, opti
|
|
|
430
439
|
const self = {
|
|
431
440
|
send: dummySend,
|
|
432
441
|
cast: dummySend,
|
|
433
|
-
spawn: () => Effect.die("spawn not supported in replay")
|
|
442
|
+
spawn: () => Effect.die("spawn not supported in replay"),
|
|
443
|
+
reply: () => Effect.succeed(false)
|
|
434
444
|
};
|
|
435
445
|
for (const event of events) {
|
|
436
446
|
if (machine.finalStates.has(state._tag)) break;
|
|
@@ -464,5 +474,7 @@ const replay = Effect.fn("effect-machine.replay")(function* (built, events, opti
|
|
|
464
474
|
}
|
|
465
475
|
return state;
|
|
466
476
|
});
|
|
477
|
+
const reply = makeReply;
|
|
478
|
+
const deferReply = makeDeferReply;
|
|
467
479
|
//#endregion
|
|
468
|
-
export {
|
|
480
|
+
export { Machine, deferReply, findTransitions, machine_exports, make, materializeMachine, replay, reply, spawn };
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import { FullEventBrand, FullStateBrand } from "./internal/brands.js";
|
|
1
|
+
import { FullEventBrand, FullStateBrand, ReplyTypeBrand } from "./internal/brands.js";
|
|
2
2
|
import { Schema } from "effect";
|
|
3
3
|
|
|
4
4
|
//#region src/schema.d.ts
|
|
5
|
+
declare const ReplySchemaSymbol: unique symbol;
|
|
6
|
+
type ReplySchemaSymbol = typeof ReplySchemaSymbol;
|
|
7
|
+
/**
|
|
8
|
+
* Fields annotated with a reply schema.
|
|
9
|
+
* Structurally identical to Schema.Struct.Fields at runtime,
|
|
10
|
+
* but carries the reply schema type at compile time.
|
|
11
|
+
*/
|
|
12
|
+
type ReplyFields<F extends Schema.Struct.Fields, RS extends Schema.Schema<unknown>> = F & {
|
|
13
|
+
readonly [ReplySchemaSymbol]: RS;
|
|
14
|
+
};
|
|
5
15
|
/**
|
|
6
16
|
* Extract the TypeScript type from a TaggedStruct schema
|
|
7
17
|
*/
|
|
@@ -12,20 +22,23 @@ type TaggedStructType<Tag extends string, Fields extends Schema.Struct.Fields> =
|
|
|
12
22
|
type VariantSchemas<D extends Record<string, Schema.Struct.Fields>> = { readonly [K in keyof D & string]: Schema.TaggedStruct<K, D[K]> };
|
|
13
23
|
/**
|
|
14
24
|
* Build union type from variant schemas.
|
|
15
|
-
*
|
|
25
|
+
* Reply-bearing variants carry ReplyTypeBrand<R> for ask() inference.
|
|
16
26
|
*/
|
|
17
|
-
type VariantsUnion<D extends Record<string, Schema.Struct.Fields>> = { [K in keyof D & string]: TaggedStructType<K, D[K]>
|
|
27
|
+
type VariantsUnion<D extends Record<string, Schema.Struct.Fields>> = { [K in keyof D & string]: TaggedStructType<K, D[K]> & (D[K] extends {
|
|
28
|
+
readonly [ReplySchemaSymbol]: Schema.Schema<infer R>;
|
|
29
|
+
} ? ReplyTypeBrand<R> : unknown) }[keyof D & string];
|
|
18
30
|
/**
|
|
19
|
-
* Check if fields are empty (no required properties)
|
|
31
|
+
* Check if fields are empty (no required string properties).
|
|
32
|
+
* Symbol keys (like ReplySchemaSymbol) are metadata, not payload fields.
|
|
20
33
|
*/
|
|
21
|
-
type IsEmptyFields<Fields extends Schema.Struct.Fields> = keyof Fields extends never ? true : false;
|
|
34
|
+
type IsEmptyFields<Fields extends Schema.Struct.Fields> = string & keyof Fields extends never ? true : false;
|
|
22
35
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* Non-empty structs require args: `State.Loading({ url })`
|
|
26
|
-
*
|
|
27
|
-
* Each variant also has a `derive` method for constructing from a source object.
|
|
36
|
+
* Resolve the reply brand for a variant's fields.
|
|
37
|
+
* If fields carry ReplySchemaSymbol, adds ReplyTypeBrand<R>.
|
|
28
38
|
*/
|
|
39
|
+
type VariantReplyBrand<Fields extends Schema.Struct.Fields> = Fields extends {
|
|
40
|
+
readonly [ReplySchemaSymbol]: Schema.Schema<infer R>;
|
|
41
|
+
} ? ReplyTypeBrand<R> : unknown;
|
|
29
42
|
/**
|
|
30
43
|
* Constructor functions for each variant.
|
|
31
44
|
* Empty structs: plain values with `_tag`: `State.Idle`
|
|
@@ -33,10 +46,11 @@ type IsEmptyFields<Fields extends Schema.Struct.Fields> = keyof Fields extends n
|
|
|
33
46
|
*
|
|
34
47
|
* Each variant also has a `derive` method for constructing from a source object.
|
|
35
48
|
* The source type uses `object` to accept branded state types without index signature issues.
|
|
49
|
+
* Reply-bearing variants carry ReplyTypeBrand<R> for ask() type inference.
|
|
36
50
|
*/
|
|
37
|
-
type VariantConstructors<D extends Record<string, Schema.Struct.Fields>, Brand> = { readonly [K in keyof D & string]: IsEmptyFields<D[K]> extends true ? TaggedStructType<K, D[K]> & Brand & {
|
|
51
|
+
type VariantConstructors<D extends Record<string, Schema.Struct.Fields>, Brand> = { readonly [K in keyof D & string]: IsEmptyFields<D[K]> extends true ? TaggedStructType<K, D[K]> & Brand & VariantReplyBrand<D[K]> & {
|
|
38
52
|
readonly derive: (source: object) => TaggedStructType<K, D[K]> & Brand;
|
|
39
|
-
} : ((args: Schema.Struct.Type<D[K]>) => TaggedStructType<K, D[K]> & Brand) & {
|
|
53
|
+
} : ((args: Schema.Struct.Type<D[K]>) => TaggedStructType<K, D[K]> & Brand & VariantReplyBrand<D[K]>) & {
|
|
40
54
|
readonly derive: (source: object, partial?: Partial<Schema.Struct.Type<D[K]>>) => TaggedStructType<K, D[K]> & Brand;
|
|
41
55
|
readonly _tag: K;
|
|
42
56
|
} };
|
|
@@ -67,6 +81,11 @@ interface MachineSchemaBase<D extends Record<string, Schema.Struct.Fields>, Bran
|
|
|
67
81
|
<R>(cases: MatchCases<D, R>): (value: VariantsUnion<D> & Brand) => R;
|
|
68
82
|
<R>(value: VariantsUnion<D> & Brand, cases: MatchCases<D, R>): R;
|
|
69
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* Reply schemas per variant tag. Only populated for event schemas
|
|
86
|
+
* with variants defined via `Event.reply()`.
|
|
87
|
+
*/
|
|
88
|
+
readonly _replySchemas: ReadonlyMap<string, Schema.Decoder<unknown>>;
|
|
70
89
|
}
|
|
71
90
|
/**
|
|
72
91
|
* Schema-first state definition that provides:
|
|
@@ -116,26 +135,8 @@ type MachineEventSchema<D extends Record<string, Schema.Struct.Fields>> = Schema
|
|
|
116
135
|
* ```
|
|
117
136
|
*/
|
|
118
137
|
declare const State: <const D extends Record<string, Schema.Struct.Fields>>(definition: D) => MachineStateSchema<D>;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
* The schema's definition type D creates a unique brand, preventing
|
|
123
|
-
* accidental use of constructors from different event schemas
|
|
124
|
-
* (unless they have identical definitions).
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* ```ts
|
|
128
|
-
* const OrderEvent = MachineSchema.Event({
|
|
129
|
-
* Ship: { trackingId: Schema.String },
|
|
130
|
-
* Cancel: {},
|
|
131
|
-
* })
|
|
132
|
-
*
|
|
133
|
-
* type OrderEvent = typeof OrderEvent.Type
|
|
134
|
-
*
|
|
135
|
-
* // Construct
|
|
136
|
-
* const e = OrderEvent.Ship({ trackingId: "abc" })
|
|
137
|
-
* ```
|
|
138
|
-
*/
|
|
139
|
-
declare const Event: <const D extends Record<string, Schema.Struct.Fields>>(definition: D) => MachineEventSchema<D>;
|
|
138
|
+
declare const Event: (<const D extends Record<string, Schema.Struct.Fields>>(definition: D) => MachineEventSchema<D>) & {
|
|
139
|
+
reply: <F extends Schema.Struct.Fields, RS extends Schema.Schema<unknown>>(fields: F, replySchema: RS) => ReplyFields<F, RS>;
|
|
140
|
+
};
|
|
140
141
|
//#endregion
|
|
141
|
-
export { Event, MachineEventSchema, MachineStateSchema, State, VariantsUnion };
|
|
142
|
+
export { Event, MachineEventSchema, MachineStateSchema, ReplyFields, ReplySchemaSymbol, State, VariantsUnion };
|