Releases: statelyai/xstate
v4.3.1
v4.3.0
- 🚚 Improved import/export experience!
The interpreter
is now included in the main module:
- import { interpret } from 'xstate/lib/interpreter';
+ import { interpret } from 'xstate';
As well as common actions, send
, assign
, and sendParent
:
- import { actions } from 'xstate';
- const { send, assign, sendParent } = actions;
+ import { send, assign, sendParent } from 'xstate';
This change is reflected in the documentation as well as the tests.
- ⚛️ Redux DevTools is now supported by XState. This can be turned off/on with the
devTools
property (true
by default):
const service = interpret(someMachine, {
devTools: false // don't show in Redux DevTools
});
ℹ️ Note: JUMP and SKIP actions in the DevTools will have no effect on XState, because there is no reliable way to arbitrarily go from one state to another with state machines, especially if side-effects are executed.
- 👓 Better TypeScript inference for event types is now available thanks to @sangallimarco #303
- 🏷 Service IDs will now take the ID of the machine if one is not specified:
const machine = Machine({ id: 'foo', /* ... */ });
// ...
{
invoke: {
// Invoked child service will have .id === 'foo'
src: machine
}
}
- 📖 Lots of documentation updates, especially with Invoking Services.
- 🐛 Fixed bugs: #326, #329, #331
v4.2.4
- 🕵️ Anonymous functions (including arrow functions) as actions are no longer silently ignored, and are executed. #298
- 💥 New method on services:
.execute(state)
will execute the state's actions (defined onstate.actions
). #295 - 📖 Documentation updates:
- Forbidden transitions
- Transient state nodes
- Various formatting/fixes
- 🕐 State history is correctly disposed now, to prevent memory leaks.
- ☎️ Second argument to invoked callbacks,
onEvent
, now let you register event listeners for when the machine sends events directly to the invoked callbacks. (docs coming 🔜) - 🚦 Activities are now properly disposed when a service is stopped.
v4.2.3
v4.2.2
- 📚 New & updated docs:
- 🔬
state.changed()
logic fixed to better determine if a state actually changed. - 💥 Action order corrected to properly execute nested final state actions before parent final state actions. #273
v4.2.1
- 📚 Lots of documentation updates: https://xstate.js.org/docs
- 💥 Added the
.event
property toState
instances, so you can know which event caused the transition to the currentState
:
const lightMachine = Machine({ /* ... */ });
const currentState = lightMachine.transition('green', 'TIMER');
console.log(currentState.event);
// => { type: 'TIMER' }
- 👪 Fixed #269 by ensuring two things:
- Services invoked on the parent machine (which are alive for the lifetime of the machine, FYI) are successfully invoked when the machine is started
- Starting activities (such as
invoke
, which is an activity) should be executed before executingonEntry
actions.
v4.2.0
- ➕ Added CODE_OF_CONDUCT.md
- 💙 Added Webflow as a sponsor
- 📖 Added documentation directly to the
master
branch for easier maintenance (in the/docs
directory) - The
send(...)
action creator now accepts an "event expression", which is a function that providescontext
andevent
as arguments and returns anEvent
:
import { actions } from 'xstate';
const { send } = actions;
// contrived example
const sendName = send((ctx, event) => ({
type: 'NAME',
name: ctx.user.name
}));
Only use this when necessary - a static argument, e.g., send({ type: 'FOO' })
is still preferred (because it's more deterministic). This follows the <send>
SCXML spec for the eventexpr
attribute.
This also works with sendParent(eventExpr)
.
- 🆕 Added the
state.inert
getter property onState
instances, which represents a state as-is without actions. - #️⃣ Targets can now be represented as getters that return references to
StateNodes
rather than string IDs:
const lightMachine = Machine({
// ...
states: {
green: {
on: {
get TIMER() {
return lightMachine.states.yellow;
}
}
},
yellow: { /* ... */ }
}
});
This is completely optional, and useful when if you want to avoid strings or have stricter typings.
- 🔧 Strict machines (
strict: true
) will no longer throw errors for built-in events, such asdone.state.*
ordone.invoke.*
events. - 📞 Now you can
invoke
a service that can send multiple events back to the parent via a callback:
// ...
states: {
counting: {
invoke: {
src: (ctx, event) => (callback) => {
const interval = setInterval(() => {
// sends 'SOME_EVENT' to parent on interval
callback('SOME_EVENT');
}, ctx.interval);
return () => clearInterval(interval);
}
}
}
}
// ...
This makes it easy to communicate with streams of events (such as Observables) through invoke
. Note that since there can be an infinite number of events, it's not assumed that a callback interval will call onDone
. Instead, you have to manually send doneInvoke(id)
via the callback
(this will be in the docs 🔜).
- ⛔️ An interpreted machine (service) will now throw an error if the initial state given to it is invalid.
v4.1.1
.npmignore
was removed ❌- The
"files"
property was added instead to ensure only the desired files show up in the NPM package.
v4.1.0
- For browser builds, the global export was renamed to
XState
(previously:xstate
). - The
data
property of theStateNode
config is now an "Assigner" or "PropertyAssigner" instead ofany
. - The
new State()
constructor now takes an object with properties for each parameter, instead of positional arguments. - New static method:
State.create({ ... })
which does the same as above. - The
error(...)
action creator now takessrc
as a second argument. For errors from an invoked service, the service ID will populate thesrc
. onError: ...
transition property added to invoke config.- Numeric targets are now being coerced to strings, to resolve edge-case issues e.g.,
3 !== '3'
when selecting state transitions. actionTypes.null
is nowactionTypes.nullEvent
, which alleviates some autocomplete issues in VS Code, etc.- Instead of
params
andcontent
,data
will be used (polymorphic property - can take an "Assigner" or "PropertyAssigner") - Done data is now correctly passed to the
'done.state'
event. #224 - The
process.env.NODE_ENV
check will no longer produce errors in browser environments. #227 - The
Machine
interface was renamed toStateMachine
to prevent naming conflicts. #231 - History state edge-cases are now resolved, and usage of the
history
property to indicate a history state is deprecated (usetype: 'history'
instead).