or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdactors.mdgraph-utilities.mdguards.mdindex.mdstate-machines.md

actions.mddocs/

0

# Actions

1

2

Comprehensive set of built-in actions for context assignment, event handling, actor communication, and lifecycle management. Actions are declarative and provide the building blocks for state machine behaviors.

3

4

## Capabilities

5

6

### Context Assignment

7

8

Updates the current context of the machine with new values, supporting both object assignment and functional updates.

9

10

```typescript { .api }

11

/**

12

* Updates the current context of the machine

13

* @param assignment - Object with new context values or function returning context update

14

* @returns ActionFunction that updates machine context

15

*/

16

function assign<TContext, TExpressionEvent extends EventObject>(

17

assignment:

18

| Assigner<TContext, TExpressionEvent>

19

| PartialAssigner<TContext, TExpressionEvent>

20

| PropertyAssigner<TContext, TExpressionEvent>

21

): ActionFunction<TContext, TExpressionEvent>;

22

23

type Assigner<TContext, TExpressionEvent extends EventObject> = (args: {

24

context: TContext;

25

event: TExpressionEvent;

26

spawn: Spawner;

27

}) => TContext;

28

29

type PartialAssigner<TContext, TExpressionEvent extends EventObject> = (args: {

30

context: TContext;

31

event: TExpressionEvent;

32

spawn: Spawner;

33

}) => Partial<TContext>;

34

35

type PropertyAssigner<TContext, TExpressionEvent extends EventObject> = {

36

[K in keyof TContext]?:

37

| TContext[K]

38

| ((args: { context: TContext; event: TExpressionEvent; spawn: Spawner }) => TContext[K]);

39

};

40

41

interface AssignAction extends ActionFunction<any, any> {

42

type: "xstate.assign";

43

}

44

```

45

46

**Usage Examples:**

47

48

```typescript

49

import { assign } from "xstate/actions";

50

51

// Object-based assignment

52

assign({ count: 42, name: "Updated" })

53

54

// Function-based assignment

55

assign(({ context, event }) => ({

56

count: context.count + 1,

57

lastEvent: event.type

58

}))

59

60

// Property-based assignment

61

assign({

62

count: ({ context }) => context.count + 1,

63

timestamp: () => Date.now()

64

})

65

66

// Partial assignment

67

assign(({ context, event }) => {

68

if (event.type === "INCREMENT") {

69

return { count: context.count + 1 };

70

}

71

return {};

72

})

73

```

74

75

### Event Handling

76

77

Actions for raising internal events and emitting external events.

78

79

```typescript { .api }

80

/**

81

* Raises an event to the internal event queue for immediate processing

82

* @param eventOrExpr - Event object or function returning event

83

* @param options - Optional configuration with id and delay

84

* @returns ActionFunction that raises internal events

85

*/

86

function raise<TEvent extends EventObject>(

87

eventOrExpr: TEvent | ((args: ActionArgs<any, any>) => TEvent),

88

options?: { id?: string; delay?: number }

89

): ActionFunction<any, any>;

90

91

/**

92

* Emits an event to external event handlers registered on the actor

93

* @param eventOrExpr - Event object or function returning event to emit

94

* @returns ActionFunction that emits events to external listeners

95

*/

96

function emit<TEvent extends EventObject>(

97

eventOrExpr: TEvent | ((args: ActionArgs<any, any>) => TEvent)

98

): ActionFunction<any, any>;

99

100

interface RaiseAction extends ActionFunction<any, any> {

101

type: "xstate.raise";

102

}

103

104

interface EmitAction extends ActionFunction<any, any> {

105

type: "xstate.emit";

106

}

107

```

108

109

**Usage Examples:**

110

111

```typescript

112

import { raise, emit } from "xstate/actions";

113

114

// Raise internal event

115

raise({ type: "INTERNAL_UPDATE", data: "processed" })

116

117

// Raise with delay

118

raise({ type: "TIMEOUT" }, { delay: 1000 })

119

120

// Emit external event

121

emit({ type: "STATUS_CHANGED", status: "ready" })

122

123

// Dynamic event creation

124

raise(({ context, event }) => ({

125

type: "COMPUTED",

126

result: context.value * 2

127

}))

128

```

129

130

### Actor Communication

131

132

Actions for sending events between actors and managing parent-child communication.

133

134

```typescript { .api }

135

/**

136

* Sends an event to a specific actor

137

* @param actor - Target actor reference, string ID, or function resolving to actor

138

* @param eventOrExpr - Event object or function returning event to send

139

* @param options - Optional configuration with id and delay

140

* @returns ActionFunction that sends events to other actors

141

*/

142

function sendTo<TTargetActor extends AnyActorRef, TEvent extends EventObject>(

143

actor: TTargetActor | string | ((args: ActionArgs<any, any>) => TTargetActor | string),

144

eventOrExpr: TEvent | ((args: ActionArgs<any, any>) => TEvent),

145

options?: { id?: string; delay?: number }

146

): ActionFunction<any, any>;

147

148

/**

149

* Sends an event to the parent machine

150

* @param eventOrExpr - Event object or function returning event to send

151

* @param options - Optional configuration with id and delay

152

* @returns ActionFunction for parent communication

153

*/

154

function sendParent<TEvent extends EventObject>(

155

eventOrExpr: TEvent | ((args: ActionArgs<any, any>) => TEvent),

156

options?: { id?: string; delay?: number }

157

): ActionFunction<any, any>;

158

159

/**

160

* Forwards the current event to a target actor

161

* @param actor - Target actor reference, string ID, or function resolving to actor

162

* @param options - Optional configuration with id and delay

163

* @returns ActionFunction that forwards events without modification

164

*/

165

function forwardTo<TTargetActor extends AnyActorRef>(

166

actor: TTargetActor | string | ((args: ActionArgs<any, any>) => TTargetActor | string),

167

options?: { id?: string; delay?: number }

168

): ActionFunction<any, any>;

169

170

interface SendToAction extends ActionFunction<any, any> {

171

type: "xstate.sendTo";

172

}

173

```

174

175

**Usage Examples:**

176

177

```typescript

178

import { sendTo, sendParent, forwardTo } from "xstate/actions";

179

180

// Send to specific actor

181

sendTo("childActor", { type: "UPDATE", data: "new value" })

182

183

// Send with delay

184

sendTo("childActor", { type: "DELAYED_UPDATE" }, { delay: 2000 })

185

186

// Send to parent

187

sendParent({ type: "CHILD_COMPLETED", result: "success" })

188

189

// Dynamic actor resolution

190

sendTo(

191

({ context }) => context.targetActor,

192

({ event }) => ({ type: "FORWARDED", original: event })

193

)

194

195

// Forward current event

196

forwardTo("childActor")

197

```

198

199

### Actor Lifecycle

200

201

Actions for spawning and stopping child actors.

202

203

```typescript { .api }

204

/**

205

* Spawns a child actor

206

* @param src - Actor logic or string reference to actor logic

207

* @param options - Optional configuration with id, systemId, input, and syncSnapshot

208

* @returns ActionFunction that creates and starts child actors

209

*/

210

function spawnChild<TActorLogic extends AnyActorLogic>(

211

src: TActorLogic | string,

212

options?: {

213

id?: string | ((args: ActionArgs<any, any>) => string);

214

systemId?: string;

215

input?: InputFrom<TActorLogic> | ((args: ActionArgs<any, any>) => InputFrom<TActorLogic>);

216

syncSnapshot?: boolean;

217

}

218

): ActionFunction<any, any>;

219

220

/**

221

* Stops a child actor

222

* @param actorRef - Actor reference, string ID, or function resolving to actor

223

* @returns ActionFunction that stops and removes child actors

224

*/

225

function stopChild(

226

actorRef: AnyActorRef | string | ((args: ActionArgs<any, any>) => AnyActorRef | string)

227

): ActionFunction<any, any>;

228

229

/**

230

* Deprecated alias for stopChild

231

* @deprecated Use stopChild instead

232

*/

233

function stop(

234

actorRef: AnyActorRef | string | ((args: ActionArgs<any, any>) => AnyActorRef | string)

235

): ActionFunction<any, any>;

236

237

interface SpawnAction extends ActionFunction<any, any> {

238

type: "xstate.spawnChild";

239

}

240

241

interface StopAction extends ActionFunction<any, any> {

242

type: "xstate.stopChild";

243

}

244

```

245

246

**Usage Examples:**

247

248

```typescript

249

import { spawnChild, stopChild } from "xstate/actions";

250

251

// Spawn child actor

252

spawnChild("childLogic", {

253

id: "child-1",

254

input: { initialValue: 100 }

255

})

256

257

// Dynamic spawning

258

spawnChild(

259

({ context }) => context.childLogic,

260

{

261

id: ({ event }) => `child-${event.childId}`,

262

input: ({ context, event }) => ({

263

parentContext: context,

264

eventData: event.data

265

})

266

}

267

)

268

269

// Stop child actor

270

stopChild("child-1")

271

272

// Dynamic stopping

273

stopChild(({ context }) => context.activeChild)

274

```

275

276

### Execution Control

277

278

Actions for controlling action execution flow and canceling delayed actions.

279

280

```typescript { .api }

281

/**

282

* Creates an action that executes dynamically queued actions

283

* @param collect - Function that receives enqueue function and action context

284

* @returns ActionFunction that allows conditional action execution

285

*/

286

function enqueueActions<TContext, TExpressionEvent extends EventObject>(

287

collect: (

288

enqueue: {

289

assign: typeof assign;

290

raise: typeof raise;

291

sendTo: typeof sendTo;

292

sendParent: typeof sendParent;

293

spawnChild: typeof spawnChild;

294

stopChild: typeof stopChild;

295

cancel: typeof cancel;

296

log: typeof log;

297

emit: typeof emit;

298

},

299

params: {

300

context: TContext;

301

event: TExpressionEvent;

302

check: (guard: any) => boolean;

303

self: AnyActorRef;

304

}

305

) => void

306

): ActionFunction<TContext, TExpressionEvent>;

307

308

/**

309

* Cancels a delayed sendTo action that is waiting to be executed

310

* @param sendId - ID of the sendTo action to cancel (string or function returning string)

311

* @returns ActionFunction that cancels scheduled delayed actions

312

*/

313

function cancel(

314

sendId: string | ((args: ActionArgs<any, any>) => string)

315

): ActionFunction<any, any>;

316

317

interface EnqueueActionsAction extends ActionFunction<any, any> {

318

type: "xstate.enqueueActions";

319

}

320

321

interface CancelAction extends ActionFunction<any, any> {

322

type: "xstate.cancel";

323

}

324

```

325

326

**Usage Examples:**

327

328

```typescript

329

import { enqueueActions, cancel } from "xstate/actions";

330

331

// Dynamic action execution

332

enqueueActions(({ enqueue, check, context, event }) => {

333

if (check("isValidUser")) {

334

enqueue.assign({ lastLogin: Date.now() });

335

enqueue.sendParent({ type: "USER_VALIDATED" });

336

} else {

337

enqueue.raise({ type: "VALIDATION_FAILED" });

338

}

339

340

if (context.shouldNotify) {

341

enqueue.emit({ type: "LOGIN_ATTEMPT", user: context.user });

342

}

343

})

344

345

// Cancel delayed action

346

cancel("delayed-notification")

347

348

// Dynamic cancellation

349

cancel(({ context }) => context.pendingActionId)

350

```

351

352

### Debugging

353

354

Actions for logging and debugging state machine execution.

355

356

```typescript { .api }

357

/**

358

* Logs values during action execution

359

* @param value - Value to log (string or function returning value)

360

* @param label - Optional label for the log entry

361

* @returns ActionFunction that logs to the actor's logger

362

*/

363

function log<TContext, TExpressionEvent extends EventObject>(

364

value?: string | ((args: ActionArgs<TContext, TExpressionEvent>) => any),

365

label?: string

366

): ActionFunction<TContext, TExpressionEvent>;

367

368

interface LogAction extends ActionFunction<any, any> {

369

type: "xstate.log";

370

}

371

```

372

373

**Usage Examples:**

374

375

```typescript

376

import { log } from "xstate/actions";

377

378

// Simple logging

379

log("State machine started")

380

381

// Dynamic logging

382

log(({ context, event }) => `User ${context.userId} performed ${event.type}`)

383

384

// Labeled logging

385

log(({ context }) => context.debugInfo, "Debug Info")

386

387

// Log context and event (default behavior)

388

log()

389

```

390

391

## Action Types and Utilities

392

393

```typescript { .api }

394

interface ActionArgs<TContext, TExpressionEvent extends EventObject> {

395

/** Current machine context */

396

context: TContext;

397

/** Current event being processed */

398

event: TExpressionEvent;

399

/** Reference to the current actor */

400

self: AnyActorRef;

401

/** Function for spawning child actors */

402

spawn: Spawner;

403

}

404

405

interface ActionFunction<TContext, TExpressionEvent extends EventObject> {

406

(args: ActionArgs<TContext, TExpressionEvent>): void;

407

/** Action type identifier */

408

type?: string;

409

/** Resolve dynamic parameters */

410

resolve?: (args: ActionArgs<TContext, TExpressionEvent>) => any;

411

}

412

413

type Actions<TContext, TEvent extends EventObject, TAction> =

414

| Action<TContext, TEvent, TAction>

415

| Action<TContext, TEvent, TAction>[];

416

417

type Action<TContext, TEvent extends EventObject, TAction> =

418

| TAction

419

| ActionFunction<TContext, TEvent>

420

| { type: string; [key: string]: any };

421

422

interface Spawner {

423

<TActorLogic extends AnyActorLogic>(

424

src: TActorLogic,

425

options?: {

426

id?: string;

427

input?: InputFrom<TActorLogic>;

428

syncSnapshot?: boolean;

429

}

430

): ActorRefFrom<TActorLogic>;

431

}

432

433

type UnknownAction = Action<any, any, any>;

434

```

435

436

## Best Practices

437

438

**Action Composition:**

439

```typescript

440

// Combine multiple actions

441

entry: [

442

assign({ status: "loading" }),

443

log("Starting data fetch"),

444

spawnChild("fetchLogic", { id: "fetcher" })

445

]

446

447

// Use enqueueActions for conditional logic

448

entry: enqueueActions(({ enqueue, check, context }) => {

449

enqueue.assign({ startTime: Date.now() });

450

451

if (check("shouldLog")) {

452

enqueue.log("Process started");

453

}

454

455

if (context.enableNotifications) {

456

enqueue.emit({ type: "PROCESS_STARTED" });

457

}

458

})

459

```

460

461

**Dynamic Parameters:**

462

```typescript

463

// Actions with dynamic parameters

464

sendTo(

465

({ context }) => context.targetActor,

466

({ event, context }) => ({

467

type: "PROCESS_DATA",

468

data: event.data,

469

timestamp: context.currentTime

470

}),

471

{ delay: ({ context }) => context.processingDelay }

472

)

473

```