Inspection
The Inspect API is a way to inspect the state transitions of your state machines and every aspect of actors in an actor system. Including:
- Actor lifecycle
- Actor event communication
- Actor snapshot updates
- State transition microsteps
The Inspect API lets you attach an “inspector,” an observer that observes inspection events, to the root of an actor system:
const actor = createActor(machine, {
inspect: (inspectionEvent) => {
// type: '@xstate.actor' or
// type: '@xstate.snapshot' or
// type: '@xstate.event' or
// type: '@xstate.microstep'
console.log(inspectionEvent);
},
});
The inspector will receive inspection events for every actor in the system, giving you granular visibility into everything happening, from how an individual actor is changing to how actors communicate with each other.
Inspection events​
Inspection events are event objects that have a type
property that indicates the type of inspection event. There are four types of inspection events:
@xstate.actor
for Actor inspection events@xstate.event
for Event inspection events@xstate.snapshot
for Snapshot inspection events@xstate.microstep
for Microstep inspection events
Actor inspection events​
The actor inspection event (@xstate.actor
) is emitted when an actor in the system is created. It contains the following properties:
type
- the type of inspection event, always'@xstate.actor'
actorRef
- the reference to the actorrootId
- the session ID of the root actor of the system
Example of an actor inspection event:
{
type: '@xstate.actor',
actorRef: {/* Actor reference */},
rootId: 'x:0',
}
Event inspection events​
The event inspection event (@xstate.event
) is emitted when an event is sent to an actor. It contains the following properties:
type
- the type of inspection event, always'@xstate.event'
actorRef
- the reference to the target actor of the eventrootId
- the session ID of the root actor of the systemevent
- the event object that was sentsourceRef
- the reference to the source actor that sent the event, orundefined
if the source is not known or an event was sent directly to the actor
Example of an event inspection event:
{
type: '@xstate.event',
actorRef: {/* Actor reference */},
rootId: 'x:0',
event: {
type: 'someEvent',
message: 'hello'
},
sourceRef: {/* Actor reference */},
}
Snapshot inspection events​
The snapshot inspection event (@xstate.snapshot
) is emitted when an actor's snapshot is updated. It contains the following properties:
type
- the type of inspection event, always'@xstate.snapshot'
actorRef
- the reference to the actorrootId
- the session ID of the root actor of the systemsnapshot
- the most recent snapshot of the actorevent
- the event that caused the snapshot to be updated
Example of a snapshot inspection event:
{
type: '@xstate.snapshot',
actorRef: {/* Actor reference */},
rootId: 'x:0',
snapshot: {
status: 'active',
context: { count: 31 },
// ...
},
event: {
type: 'increment'
}
}
Microstep inspection events​
The microstep inspection event (@xstate.microstep
) is emitted for each individual state transition, including intermediate "microsteps", that occurs during the processing of an event. This is particularly useful for observing eventless transitions (like always
transitions) and understanding the step-by-step progression through multiple states.
It contains the following properties:
type: '@xstate.microstep'
value
- the current state value after this microstepevent
- the event that triggered this microsteptransitions
- an array of transition objects that occurred in this microstep
Each transition object in the transitions
array contains:
eventType
- the event type that triggered the transition (empty string for eventless transitions)target
- an array of target state paths
Example of a microstep inspection event:
{
type: '@xstate.microstep',
value: 'c',
event: {
type: 'EV',
},
transitions: [
{
eventType: 'EV',
target: ['(machine).b'],
},
{
eventType: '',
target: ['(machine).c'],
},
],
}
Example of microstep events
Here's an example of microstep events:
const machine = createMachine({
initial: 'a',
states: {
a: {
on: {
EV: 'b',
},
},
b: {
always: 'c', // This will trigger automatically after entering state 'b'
},
c: {},
},
});
const events = [];
const actorRef = createActor(machine, {
inspect: (ev) => events.push(ev),
}).start();
actorRef.send({ type: 'EV' });
The microstep events will look like this:
// First microstep: EV transition to state 'b'
{
type: '@xstate.microstep',
value: 'b',
event: {
type: 'EV'
},
transitions: [
{
eventType: 'EV',
target: ['(machine).b']
}
]
},
// Second microstep: always transition to state 'c'
{
type: '@xstate.microstep',
value: 'c',
event: {
type: 'EV'
},
transitions: [
{
eventType: '', // Empty string indicates eventless transition
target: ['(machine).c']
}
]
}