Actor-based state management & orchestration for complex app logic.
MIT License
Bot releases are visible (Hide)
Published by github-actions[bot] 11 months ago
c9908b7fb
Thanks @davidkpiano! - Fixed the TActor
type passed down by setup
in absence of provided actors.Published by Andarist 11 months ago
#4480 3e610a1f3
Thanks @Andarist! - Children IDs in combination with setup
can now be typed using types.children
:
const machine = setup({
types: {} as {
children: {
myId: 'actorKey';
};
},
actors: {
actorKey: child
}
}).createMachine({});
const actorRef = createActor(machine).start();
actorRef.getSnapshot().children.myId; // ActorRefFrom<typeof child> | undefined
Published by github-actions[bot] 11 months ago
#4488 9ca3c3dcf
Thanks @davidkpiano! - The spawn(...)
action creator has been renamed to spawnChild(...)
to avoid confusion.
import { spawnChild, assign } from 'xstate';
const childMachine = createMachine({
on: {
someEvent: {
actions: [
// spawnChild(...) instead of spawn(...)
spawnChild('someSrc'),
// spawn() is used inside of assign()
assign({
anotherRef: ({ spawn }) => spawn('anotherSrc')
})
]
}
}
});
#4488 9ca3c3dcf
Thanks @davidkpiano! - The stop(...)
action creator is renamed to stopChild(...)
, to make it clear that only child actors may be stopped from the parent actor.
Published by github-actions[bot] 11 months ago
#4467 3c71e537d
Thanks @Andarist! - The state.configuration
property has been renamed to state._nodes
.
- state.configuration
+ state._nodes
#4467 3c71e537d
Thanks @Andarist! - The state.meta
getter has been replaced with state.getMeta()
methods:
- state.meta
+ state.getMeta()
#4353 a3a11c84e
Thanks @davidkpiano! - You can now use the setup({ ... }).createMachine({ ... })
function to setup implementations for actors
, actions
, guards
, and delays
that will be used in the created machine:
import { setup, createMachine } from 'xstate';
const fetchUser = fromPromise(async ({ input }) => {
const response = await fetch(`/user/${input.id}`);
const user = await response.json();
return user;
});
const machine = setup({
actors: {
fetchUser
},
actions: {
clearUser: assign({ user: undefined })
},
guards: {
isUserAdmin: (_, params) => params.user.role === 'admin'
}
}).createMachine({
// ...
invoke: {
// Strongly typed!
src: 'fetchUser',
input: ({ context }) => ({ id: context.userId }),
onDone: {
guard: {
type: 'isUserAdmin',
params: ({ context }) => ({ user: context.user })
},
target: 'success',
actions: assign({ user: ({ event }) => event.output })
},
onError: {
target: 'failure',
actions: 'clearUser'
}
}
});
Published by github-actions[bot] 11 months ago
Published by github-actions[bot] 11 months ago
#4451 21f18b54b
Thanks @Andarist! - Removed the ability to configure input
within the implementations object. You no longer can do this:
createMachine(
{
invoke: {
src: 'child'
}
},
{
actors: {
child: {
src: childMachine,
input: 'foo'
}
}
}
);
The input
can only be provided within the config of the machine.
Published by github-actions[bot] 11 months ago
#4288 cfdf754f8
Thanks @davidkpiano! - The useMachine(machine)
hook now returns { snapshot, send, service }
instead of { state, send, actorRef }
:
const {
- state,
+ snapshot,
send,
- actorRef
+ service
} = useMachine(machine);
cfdf754f8
Thanks @davidkpiano! - The useInterpret(machine)
and useSpawn(machine)
hooks have been removed; use the useActorRef(machine)
hook instead.Published by github-actions[bot] 11 months ago
#4438 7bbf41d7d
Thanks @Andarist! - Removed State#toStrings
method.
#4443 18862e53c
Thanks @Andarist! - State
class has been removed and replaced by MachineSnapshot
object. They largely have the same properties and methods. On of the main noticeable results of this change is that you can no longer check state instanceof State
.
#4444 d6e41a923
Thanks @Andarist! - Removed mapState
utility function.
Published by github-actions[bot] 12 months ago
Published by github-actions[bot] 12 months ago
Published by github-actions[bot] 12 months ago
#4414 26fbc6c85
Thanks @davidkpiano! - All inspector events (snapshot, event, actor) now have a common actorRef
property. This makes it easier to discern which inspection event is for which actor:
const actor = createActor(someMachine, {
inspect: (event) => {
// Was previously a type error
if (event.actorRef === actor) {
// This event is for the root actor
}
if (event.type === '@xstate.event') {
// previously event.targetRef
event.actorRef;
}
}
});
In the 'xstate.event'
event, the actorRef
property is now the target actor (recipient of the event). Previously, this was the event.targetRef
property (which is now removed).
Published by github-actions[bot] 12 months ago
c46a80015
Thanks @davidkpiano! - Internal: changed the actor context type from ActorContext
to ActorScope
to mitigate confusion.Published by github-actions[bot] 12 months ago
#4329 41f5a7dc5
Thanks @davidkpiano! - You can now spawn(...)
actors directly outside of assign(...)
action creators:
import { createMachine, spawn } from 'xstate';
const listenerMachine = createMachine({
// ...
});
const parentMachine = createMachine({
// ...
on: {
'listener.create': {
entry: spawn(listenerMachine, { id: 'listener' })
}
}
// ...
});
const actor = createActor(parentMachine).start();
actor.send({ type: 'listener.create' });
actor.getSnapshot().children.listener; // ActorRefFrom<typeof listenerMachine>
#4257 531a63482
Thanks @Andarist! - Action parameters can now be directly accessed from the 2nd argument of the action implementation:
const machine = createMachine(
{
// ...
entry: {
type: 'greet',
params: { message: 'hello' }
}
},
{
actions: {
greet: (_, params) => {
params.message; // 'hello'
}
}
}
);
#4257 531a63482
Thanks @Andarist! - Guard parameters can now be directly accessed from the 2nd argument of the guard implementation:
const machine = createMachine(
{
// ...
on: {
EVENT: {
guard: {
type: 'isGreaterThan',
params: { value: 10 }
}
}
}
},
{
guards: {
isGreaterThan: (_, params) => {
params.value; // 10
}
}
}
);
#4405 a01169eb2
Thanks @Andarist! - Fixed crash on a systemId
synchronous re-registration attempt that could happen, for example, when dealing with reentering transitions.
#4401 eea74c594
Thanks @Andarist! - Fixed the issue with stopped state machines not updating their snapshots with that information.
#4403 3f84bba72
Thanks @Andarist! - Fixed an issue with rehydrated actors not registering themselves in the system.
Published by github-actions[bot] 12 months ago
57814f46d
Thanks @Andarist! - Atomic and parallel states should no longer be reentered when the transition target doesn't escape them. You can get the reentering behavior by configuring reenter: true
for the transition.#4387 0be0ef015
Thanks @Andarist! - Added support to stateIn
guard for checking a combination of an ID and a path, eg. stateIn('#b.B1')
.
#4384 e0bbe3397
Thanks @Andarist! - Fixed an issue that caused parallel states with direct final children to be completed without all regions being in their final states.
Published by github-actions[bot] 12 months ago
Published by github-actions[bot] 12 months ago
#4372 c19e6fb1e
Thanks @Andarist! - Removed State['_internalQueue']
.
#4371 8b3f6647c
Thanks @Andarist! - Changed behavior of always
transitions. Previously they were always selected after selecting any transition (including the always
transitions). Because of that it was relatively easy to create an infinite loop using them.
Now they are no longer selected if the preceeding transition doesn't change the state of a machine.
#4377 14cb2ed0c
Thanks @Andarist! - exit
actions of all states are no longer called when the machine gets stopped externally. Note that they are still called when the machine reaches its final state.
Published by github-actions[bot] almost 1 year ago
#4363 3513280db
Thanks @Andarist! - Removed the ability to target deep descendants with the initial
property.
#4363 3513280db
Thanks @Andarist! - Removed the ability to target multiple descendants with the initial
property.
#4216 04cad53e0
Thanks @Andarist! - Removed the ability to define delayed transitions using an array. Only object variant is supported now:
createMachine({
initial: 'a',
states: {
a: {
after: {
10000: 'b',
noon: 'c'
}
}
// ...
}
});
#3921 0ca1b860c
Thanks @davidkpiano! - Spawned actors that have a referenced source (not inline) can be deeply persisted and restored:
const machine = createMachine({
context: ({ spawn }) => ({
// This will be persisted
ref: spawn('reducer', { id: 'child' })
// This cannot be persisted:
// ref: spawn(fromTransition((s) => s, { count: 42 }), { id: 'child' })
})
}).provide({
actors: {
reducer: fromTransition((s) => s, { count: 42 })
}
});
03ac5c013
Thanks @Andarist! - xstate.done.state.*
events will now be generated recursively for all parallel states on the ancestors path.#4361 1a00b5a54
Thanks @Andarist! - Fixed a runtime crash related to machines with their root state's type being final (createMachine({ type: 'final' })
).
#4357 84c46c1ae
Thanks @Andarist! - Fixed an issue with not all actions of initial transitions resolving to the initial state of the machine itself being executed.
#4356 81b6edafd
Thanks @Andarist! - Fixed an issue with actions of initial transitions being called too many times.
Published by github-actions[bot] about 1 year ago
#4351 6f1818365
Thanks @Andarist! - Fixed an issue that prevented invoke.input
from seeing the context updated by the same-level entry
actions.
#4344 f9b17f1e9
Thanks @davidkpiano! - Inspection events are now exported:
import type {
InspectedActorEvent,
InspectedEventEvent,
InspectedSnapshotEvent,
InspectionEvent
} from 'xstate';
Published by github-actions[bot] about 1 year ago
#4082 13480c3a9
Thanks @davidkpiano! - You can now inspect actor system updates using the inspect
option in createActor(logic, { inspect })
. The types of inspection events you can observe include:
@xstate.actor
- An actor ref has been created in the system@xstate.event
- An event was sent from a source actor ref to a target actor ref in the system@xstate.snapshot
- An actor ref emitted a snapshot due to a received eventimport { createMachine } from 'xstate';
const machine = createMachine({
// ...
});
const actor = createActor(machine, {
inspect: (inspectionEvent) => {
if (inspectionEvent.type === '@xstate.actor') {
console.log(inspectionEvent.actorRef);
}
if (inspectionEvent.type === '@xstate.event') {
console.log(inspectionEvent.sourceRef);
console.log(inspectionEvent.targetRef);
console.log(inspectionEvent.event);
}
if (inspectionEvent.type === '@xstate.snapshot') {
console.log(inspectionEvent.actorRef);
console.log(inspectionEvent.event);
console.log(inspectionEvent.snapshot);
}
}
});
Published by github-actions[bot] about 1 year ago
#4335 ba111c32c
Thanks @davidkpiano! - Composable (e.g. higher-order) logic should now work as expected for state machine logic, as well as all other types of logic.
#4330 9f69d46a6
Thanks @Andarist! - Fixed an issue with rehydrated actors not having their internal reference to the parent set correctly.