or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

actors.mddocs/

0

# Actors

1

2

Actor system for creating, managing, and communicating with stateful actors that run state machines and other logic. Actors encapsulate state and behavior, communicating through message passing in a predictable and isolated manner.

3

4

## Capabilities

5

6

### Actor Creation

7

8

Creates and manages actor instances from various types of actor logic including state machines and specialized actor types.

9

10

```typescript { .api }

11

/**

12

* Creates an actor instance from actor logic

13

* @param logic - Actor logic (state machine or other actor logic)

14

* @param options - Optional configuration for the actor

15

* @returns Actor instance that can be started, stopped, and communicated with

16

*/

17

function createActor<TLogic extends AnyActorLogic>(

18

logic: TLogic,

19

options?: ActorOptions<TLogic>

20

): Actor<TLogic>;

21

22

/**

23

* Legacy alias for createActor

24

* @deprecated Use createActor instead

25

*/

26

function interpret<TLogic extends AnyActorLogic>(

27

logic: TLogic,

28

options?: ActorOptions<TLogic>

29

): Actor<TLogic>;

30

31

interface ActorOptions<TLogic extends AnyActorLogic> {

32

/** Unique identifier for the actor */

33

id?: string;

34

/** System identifier for the actor */

35

systemId?: string;

36

/** Input data for the actor */

37

input?: InputFrom<TLogic>;

38

/** Parent actor reference */

39

parent?: AnyActorRef;

40

/** Synchronize snapshot with parent */

41

syncSnapshot?: boolean;

42

/** Actor system reference */

43

system?: AnyActorSystem;

44

/** Logger for the actor */

45

logger?: (msg: string) => void;

46

/** Inspection observer */

47

inspect?: Observer<InspectionEvent>;

48

/** DevTools adapter */

49

devTools?: DevToolsAdapter;

50

}

51

```

52

53

**Usage Examples:**

54

55

```typescript

56

import { createMachine, createActor } from "xstate";

57

58

// Create actor from state machine

59

const machine = createMachine({

60

initial: "idle",

61

states: {

62

idle: {

63

on: { START: "running" }

64

},

65

running: {

66

on: { STOP: "idle" }

67

}

68

}

69

});

70

71

const actor = createActor(machine, {

72

id: "my-actor",

73

input: { count: 0 }

74

});

75

76

// Start the actor

77

actor.start();

78

79

// Send events

80

actor.send({ type: "START" });

81

```

82

83

### Actor Class

84

85

Main actor implementation providing state management, event handling, and lifecycle control.

86

87

```typescript { .api }

88

class Actor<TLogic extends AnyActorLogic> implements ActorRef<SnapshotFrom<TLogic>, EventFromLogic<TLogic>> {

89

/** Unique actor identifier */

90

readonly id: string;

91

/** Actor logic */

92

readonly logic: TLogic;

93

/** Actor options */

94

readonly options: ActorOptions<TLogic>;

95

/** Actor status */

96

readonly status: "not-started" | "running" | "stopped" | "error";

97

98

/**

99

* Starts the actor and begins processing

100

*/

101

start(): this;

102

103

/**

104

* Stops the actor and cleans up resources

105

*/

106

stop(): this;

107

108

/**

109

* Sends an event to the actor

110

* @param event - Event to send

111

*/

112

send(event: EventFromLogic<TLogic>): void;

113

114

/**

115

* Gets the current snapshot

116

* @returns Current actor snapshot

117

*/

118

getSnapshot(): SnapshotFrom<TLogic>;

119

120

/**

121

* Gets persisted snapshot data

122

* @returns Persisted snapshot

123

*/

124

getPersistedSnapshot(): Snapshot<unknown>;

125

126

/**

127

* Subscribes to actor state changes

128

* @param observer - Observer function or object

129

* @returns Subscription object

130

*/

131

subscribe(observer: Observer<SnapshotFrom<TLogic>>): Subscription;

132

133

/**

134

* Subscribes to actor state changes with next/error/complete callbacks

135

* @param nextListener - Called on state changes

136

* @param errorListener - Called on errors

137

* @param completeListener - Called on completion

138

* @returns Subscription object

139

*/

140

subscribe(

141

nextListener: (snapshot: SnapshotFrom<TLogic>) => void,

142

errorListener?: (error: any) => void,

143

completeListener?: () => void

144

): Subscription;

145

}

146

```

147

148

### Actor References

149

150

Interface for communicating with actors, providing a stable API for message passing and observation.

151

152

```typescript { .api }

153

interface ActorRef<

154

TSnapshot extends Snapshot<unknown>,

155

TEvent extends EventObject

156

> {

157

/** Unique actor identifier */

158

readonly id: string;

159

160

/**

161

* Sends an event to the actor

162

* @param event - Event to send

163

*/

164

send(event: TEvent): void;

165

166

/**

167

* Subscribes to actor state changes

168

* @param observer - Observer function or object

169

* @returns Subscription object

170

*/

171

subscribe(observer: Observer<TSnapshot>): Subscription;

172

173

/**

174

* Gets the current snapshot

175

* @returns Current actor snapshot

176

*/

177

getSnapshot(): TSnapshot;

178

179

/**

180

* Gets persisted snapshot data

181

* @returns Persisted snapshot

182

*/

183

getPersistedSnapshot(): Snapshot<unknown>;

184

185

/** Symbol.observable implementation */

186

[Symbol.observable](): InteropObservable<TSnapshot>;

187

}

188

189

interface BaseActorRef<TEvent extends EventObject> {

190

readonly id: string;

191

send(event: TEvent): void;

192

}

193

194

type AnyActorRef = ActorRef<any, any>;

195

type AnyActor = Actor<any>;

196

```

197

198

### Callback Actors

199

200

Creates actors from callback functions for subscription-based or free-form logic with bidirectional communication.

201

202

```typescript { .api }

203

/**

204

* Creates callback actor logic for subscription-based or free-form logic

205

* @param callback - Function defining the actor's behavior with access to input, system, self, sendBack, receive, emit

206

* @returns CallbackActorLogic that can be used to create actors

207

*/

208

function fromCallback<

209

TEvent extends EventObject,

210

TSentEvent extends EventObject = AnyEventObject,

211

TInput = any,

212

TEmitted = any

213

>(

214

callback: CallbackLogicFunction<TEvent, TSentEvent, TInput, TEmitted>

215

): CallbackActorLogic<TEvent, TInput, TEmitted>;

216

217

type CallbackLogicFunction<

218

TEvent extends EventObject,

219

TSentEvent extends EventObject,

220

TInput,

221

TEmitted

222

> = (params: {

223

/** Input data provided to the actor */

224

input: TInput;

225

/** Actor system reference */

226

system: AnyActorSystem;

227

/** Reference to this actor */

228

self: CallbackActorRef<TEvent, TInput>;

229

/** Function to send events back to parent */

230

sendBack: (event: TSentEvent) => void;

231

/** Function to register event handler */

232

receive: (listener: (event: TEvent) => void) => void;

233

/** Function to emit events to external handlers */

234

emit: (event: TEmitted) => void;

235

}) => (() => void) | void;

236

237

type CallbackActorLogic<TEvent extends EventObject, TInput, TEmitted> =

238

ActorLogic<CallbackSnapshot<TInput>, TEvent, TInput, AnyEventObject, TEmitted>;

239

240

interface CallbackSnapshot<TInput> extends Snapshot<undefined> {

241

input: TInput;

242

}

243

244

type CallbackActorRef<TEvent extends EventObject, TInput> =

245

ActorRef<CallbackSnapshot<TInput>, TEvent>;

246

```

247

248

**Usage Examples:**

249

250

```typescript

251

import { fromCallback, createActor } from "xstate/actors";

252

253

// WebSocket callback actor

254

const websocketLogic = fromCallback(({ input, sendBack, receive, emit }) => {

255

const ws = new WebSocket(input.url);

256

257

ws.onopen = () => emit({ type: "connected" });

258

ws.onmessage = (event) => sendBack({ type: "MESSAGE", data: event.data });

259

ws.onerror = (error) => sendBack({ type: "ERROR", error });

260

261

receive((event) => {

262

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

263

ws.send(event.data);

264

}

265

});

266

267

return () => ws.close();

268

});

269

270

const actor = createActor(websocketLogic, {

271

input: { url: "ws://localhost:8080" }

272

});

273

```

274

275

### Promise Actors

276

277

Creates actors from async functions that resolve to a single value.

278

279

```typescript { .api }

280

/**

281

* Creates promise actor logic from an async process

282

* @param promiseCreator - Async function that returns a promise

283

* @returns PromiseActorLogic that resolves/rejects and emits the result

284

*/

285

function fromPromise<TOutput, TInput = any, TEmitted = any>(

286

promiseCreator: (params: {

287

input: TInput;

288

system: AnyActorSystem;

289

self: PromiseActorRef<TOutput>;

290

signal: AbortSignal;

291

emit: (event: TEmitted) => void;

292

}) => PromiseLike<TOutput>

293

): PromiseActorLogic<TOutput, TInput, TEmitted>;

294

295

type PromiseActorLogic<TOutput, TInput, TEmitted> =

296

ActorLogic<PromiseSnapshot<TOutput, TInput>, AnyEventObject, TInput, AnyEventObject, TEmitted>;

297

298

interface PromiseSnapshot<TOutput, TInput> extends Snapshot<TOutput> {

299

input: TInput;

300

}

301

302

type PromiseActorRef<TOutput> = ActorRef<PromiseSnapshot<TOutput, any>, AnyEventObject>;

303

```

304

305

**Usage Examples:**

306

307

```typescript

308

import { fromPromise, createActor } from "xstate/actors";

309

310

// Fetch data promise actor

311

const fetchUserLogic = fromPromise(async ({ input, signal, emit }) => {

312

emit({ type: "FETCH_START" });

313

314

const response = await fetch(`/api/users/${input.userId}`, {

315

signal

316

});

317

318

if (!response.ok) {

319

throw new Error(`Failed to fetch user: ${response.status}`);

320

}

321

322

const user = await response.json();

323

emit({ type: "FETCH_SUCCESS", user });

324

325

return user;

326

});

327

328

const actor = createActor(fetchUserLogic, {

329

input: { userId: "123" }

330

});

331

```

332

333

### Observable Actors

334

335

Creates actors from observable streams for reactive programming patterns.

336

337

```typescript { .api }

338

/**

339

* Creates observable actor logic from an observable stream

340

* @param observableCreator - Function that creates a subscribable stream

341

* @returns ObservableActorLogic that emits values from the stream

342

*/

343

function fromObservable<TContext, TInput = any, TEmitted = any>(

344

observableCreator: (params: {

345

input: TInput;

346

system: AnyActorSystem;

347

self: ObservableActorRef<TContext>;

348

emit: (event: TEmitted) => void;

349

}) => Subscribable<TContext>

350

): ObservableActorLogic<TContext, TInput, TEmitted>;

351

352

/**

353

* Creates event observable actor logic that sends events to parent

354

* @param lazyObservable - Function that creates a subscribable event stream

355

* @returns ObservableActorLogic that forwards events to parent

356

*/

357

function fromEventObservable<TEvent extends EventObject, TInput = any, TEmitted = any>(

358

lazyObservable: (params: {

359

input: TInput;

360

system: AnyActorSystem;

361

self: ObservableActorRef<TEvent>;

362

emit: (event: TEmitted) => void;

363

}) => Subscribable<TEvent>

364

): ObservableActorLogic<TEvent, TInput, TEmitted>;

365

366

type ObservableActorLogic<TContext, TInput, TEmitted> =

367

ActorLogic<ObservableSnapshot<TContext, TInput>, AnyEventObject, TInput, AnyEventObject, TEmitted>;

368

369

interface ObservableSnapshot<TContext, TInput> extends Snapshot<undefined> {

370

context: TContext;

371

input: TInput;

372

}

373

374

type ObservableActorRef<TContext> = ActorRef<ObservableSnapshot<TContext, any>, AnyEventObject>;

375

```

376

377

### Transition Actors

378

379

Creates actors from transition functions for reducer-like state management.

380

381

```typescript { .api }

382

/**

383

* Creates transition actor logic from a transition function and initial state

384

* @param transition - Function that computes next state given current state and event

385

* @param initialContext - Initial state value or factory function

386

* @returns TransitionActorLogic for reducer-like state management

387

*/

388

function fromTransition<TContext, TEvent extends EventObject, TInput = any, TEmitted = any>(

389

transition: (

390

state: TContext,

391

event: TEvent,

392

actorScope: ActorScope<TContext, TEvent, TEmitted>

393

) => TContext,

394

initialContext: TContext | ((input: TInput) => TContext)

395

): TransitionActorLogic<TContext, TEvent, TInput, TEmitted>;

396

397

type TransitionActorLogic<TContext, TEvent extends EventObject, TInput, TEmitted> =

398

ActorLogic<TransitionSnapshot<TContext>, TEvent, TInput, AnyEventObject, TEmitted>;

399

400

interface TransitionSnapshot<TContext> extends Snapshot<undefined> {

401

context: TContext;

402

}

403

404

type TransitionActorRef<TContext, TEvent extends EventObject> =

405

ActorRef<TransitionSnapshot<TContext>, TEvent>;

406

```

407

408

### Actor Utilities

409

410

Utility functions and types for working with actors and actor systems.

411

412

```typescript { .api }

413

/**

414

* Creates an empty actor with undefined context

415

* @returns Empty actor reference

416

*/

417

function createEmptyActor(): ActorRef<Snapshot<undefined>, AnyEventObject, AnyEventObject>;

418

419

/**

420

* Converts actor to a promise that resolves when actor reaches final state

421

* @param actor - Actor to convert

422

* @returns Promise that resolves with actor output

423

*/

424

function toPromise<TActor extends AnyActorRef>(

425

actor: TActor

426

): Promise<OutputFrom<TActor>>;

427

428

/**

429

* Waits for actor to reach specific conditions

430

* @param actor - Actor to observe

431

* @param predicate - Condition to wait for

432

* @param options - Optional timeout and other options

433

* @returns Promise that resolves when condition is met

434

*/

435

function waitFor<TActor extends AnyActorRef, T>(

436

actor: TActor,

437

predicate: (snapshot: SnapshotFrom<TActor>) => T | undefined,

438

options?: { timeout?: number }

439

): Promise<T>;

440

```

441

442

## Actor System Types

443

444

```typescript { .api }

445

interface ActorSystem<T extends Record<string, AnyActorLogic>> {

446

/** Get actor by ID */

447

get<K extends keyof T>(id: K): ActorRefFrom<T[K]>;

448

/** Register actor logic */

449

register<TActorLogic extends AnyActorLogic>(

450

id: string,

451

actorLogic: TActorLogic

452

): ActorRefFrom<TActorLogic>;

453

}

454

455

interface ActorScope<TContext, TEvent extends EventObject, TEmitted> {

456

/** Reference to this actor */

457

self: ActorRef<any, TEvent>;

458

/** Function to emit events */

459

emit: (event: TEmitted) => void;

460

/** Actor system reference */

461

system: AnyActorSystem;

462

}

463

464

interface Observer<T> {

465

next?: (value: T) => void;

466

error?: (error: any) => void;

467

complete?: () => void;

468

}

469

470

interface Subscription {

471

unsubscribe(): void;

472

}

473

474

interface Subscribable<T> {

475

subscribe(observer: Observer<T>): Subscription;

476

subscribe(

477

next: (value: T) => void,

478

error?: (error: any) => void,

479

complete?: () => void

480

): Subscription;

481

}

482

```