menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

Statecharts

The Statecharts community on Spectrum is (along with spectrum) MOVING TO OTHER PLATFORMS: For statecharts discussions in general go to Statecharts Discussion on GitHub (link) or Gitter (link). For XState-specific questions, go to the XState discussion forum for Q&A or the Stately discord chat to chat.

Channels
Team

🚀 XState Wish List

November 14, 2019 at 9:14pm

🚀 XState Wish List

November 14, 2019 at 9:14pm
As we're working on releasing 4.7 and moving towards 5.0 this holiday season, I wanted to ask all of you: What is on your XState wish list?
Do you wish there was a different syntax for defining machines? Do you wish there were built-in patterns? Do you wish there were other visual tools?
(If you want small feature requests or fixed bugs, please post here instead: http://github.com/davidkpiano/xstate/issues/new)
Let us know! 👇📝

November 14, 2019 at 10:25pm
Per-state context might be nice and I have seen it mentioned in a few other threads. For my use case we are using submachines to split the context. It's working out great but I would think there are scenarios when per-state context would allow for a clean and minimal implementation of a state chart. Will add more requests if I think of them. I am really enjoying building front-ends with XState so far! Thanks for the work you have put into it.
like-fill
6

November 15, 2019 at 8:32am
I'd like to see some official ports to other languages and environments. For example, the team I'm working with uses C# and .Net in the back end, and a simple, convenient NuGet package would help in persuading them of the merits of adopting statecharts. (Some xstate-like solutions exist in this world but they don't seem as featureful or actively maintained.)
A vscode extension to visualize the current file
like-fill
44
I'd love a more functional approach to the syntax and a simplified API 🙏
When I started learning, it was difficult to differentiate which parts of the machine config are XState API and which are implementation specific and there also appears to be more than one way to skin a cat which can be quite intimidating when starting. I wasn't sure which to pick.
I like the look of https://thisrobot.life and while I feel it could be improved, I really like the simplicity of it and the way they stick to doing things one way (nested states always invoke a machine). It feels like a much less intimidating API and looks easier to pick up IMO.
Edited
like-fill
6
Great suggestion. The nice thing about XState being an object syntax is that it's really easy to add a simplified API on top of it. Would it be helpful to introduce an opinionated package for this?
Like, a hypothetical /builder?
like-fill
12
My biggest request would be a way to, in an action, send an event to "self" without having a reference to an instantiated Machine.
Would it be helpful to introduce an opinionated package for this?
I had actually thought about trying exactly that, if I ever get through my mountainous todo list haha. Perhaps worth starting an /fp repo or something and we can begin a discussion for the desired syntax :)
Edited
like-fill
2
There is a way, it's just not documented (yet)! It's called a "pure action" - which is an action that doesn't return a side-effect, but just (possibly dynamically) returns what action(s) should be executed:
actions: pure((ctx, e) => {
const myCustomEvent = {/* ... */};
return [
send(myCustomEvent), // sends to self
() => { console.log('hi') } // some fire-and-forget action
];
})
like-fill
4
pardon my (perhaps) stupidity, but what's the difference between that and this:
actions: [
send({ type: 'CUSTOM', ... }),
'fireAndForgetAction',
]

November 15, 2019 at 10:52pm
Hey! First of all, thanks for creating XState and sharing about state-charts on your talks/internet. It's been a great discovery. So far I have just used the library on a project (WIP) and it's been very valuable to surface complexity and make state explicit. I'm also starting to use state-charts on a side-project, for now I'm using it as a thinking tool but for sure I'll use it also when I start coding it.
TLDR: Improve the visualizer, better integrate it with Typescript and add extra tooling for it.
So, my main pain points are:
  • Lack of integration of the visualizer with Typescript (once you have types mixed with the machine definition, or any foreign keyword for the visualizer, it stops working)
  • Visualization export/sharing, just for documentation or for discussion with team mates. This can be done with the Gists saving feature, but it's a pain to clean Typescript, copy, save…
  • Visualization automatic layout could be improved, sometimes it's a mess. Also activities don't render. There are performance issues also.
  • Improved documentation with more examples, specially on Angular/RxJS. I need to spend more time researching, but right now I have my machine definitions on separate files, and then one huge file with the interpreter definition, and implementation of actions, services, etc. Having good examples of how to organize code, on a testable, dependency injected way would make me happy.
For the visualization/design, some ideas:
  • it would be cool if there was a way to visualize the communication between machines, spawned machines, service machines…
  • on browser based projects maybe the interpreter could inject the definition into window and we could have a browser extension to preview the machine… not sure if it's a good idea as it might run the real side-effects…
  • have some CLI tooling to export SVG files or interactive self-contained HTML files
  • maybe instead of having the browser extension, it would be nice to have some kind of CLI tool that starts a local server with the visualizer
Edited
like-fill
15

November 16, 2019 at 3:08pm
Hi! I am currently experimenting with XState and other state management solutions (mobx, mst, overmind, etc) trying to find the holy grail of DX in React :)
Would it be possible / make sense, to have derived state of context in the machine configuration? Something similar to views in mobx state tree (https://github.com/mobxjs/mobx-state-tree#views)
So a machine configuration would look like :
{
id: 'derivedState',
context: {
foo: 'foo',
bar: 'bar',
},
views: {
foobar: context => `${context.foo}${context.bar}`
},
states: {...}
}
Right now I am doing this inside the UI Components (React) with useMemo, but I am thinking that it would be cool (especially with the actor model) if we could have all the logic / computations live in the machine.
Would you consider behavior like this or do you think it's out of scope for XState?
In addition, another feature I would like to see is a package with helpful reusable machines that we could import and use for everyday use cases like fetching data.
Edited
like-fill
3
+10 to Typescript working in the visualizer!! :)
like-fill
7
I really like the idea of derived state. It definitely is in-scope.
In addition, another feature I would like to see is a package with helpful reusable machines that we could import and use for everyday use cases like fetching data.
That's coming soon in an /patterns package!
Typescript working in the visualizer!!
The VS Code plugin will naturally support this.
like-fill
14
No difference with this simple example, but its utility comes into play when you might need to vary which actions are executed based on context/event.
like-fill
2
The VS Code plugin will naturally support this (TypeScript)
Is this easier that it seems? I've been tinkering with using tsc and post-processing to see how it might work. I have something which can take the code below and produce a machine.js that can be pushed to a gist.
// From https://github.com/Spiralis/xstate-timer
import { Machine } from "xstate";
import { ITimerContext } from "./interface";
import { TimerMachineConfig } from "./machine";
import { TimerMethodConfig } from "./methods";
const TimerContext: ITimerContext = {
config: {
title: "Timer example",
duration_ms: 10000,
update_freq_ms: 100,
auto_start: false,
auto_finalize: false, // Moves the machine "done" final-state when set.
},
_: {},
};
TimerMachineConfig.context = TimerContext;
const machine = Machine(TimerMachineConfig, TimerMethodConfig);
Edited

November 18, 2019 at 11:17pm
Would the /patterns library include a debounce when receiving events? I've been having a hard time trying to figure out the best way to implement a debounce for a text input using state-charts.
Edited
like-fill
1

November 19, 2019 at 7:56pm
🎁Vim syntax highlighting plugin for machine definitions!
like-fill
1
This should not be too hard to implement as a preview, since its already a JS app
First of all thanks for starting this project to improve workflows in applications. I just started using the library but I've always written my own FSM in the past (C, C++, JS) which always helped to keep complex business logic comprehensible. It could also create documentation and worked as basis for generating UI inputs. I've recently played around with the idea that exposing a statechart via Web API is a good example of proper Hypemedia REST APIs. So I created a simple koa server that serves statecharts like POST /counter will create a new counter service. The response also contains the actions/events that can be performed on that service, like in this case: INC and which method the client is supposed to use. So when you PUT /counter/0/INC then the response will contain actions URLs for INC and DEC. I'll link a simple video how that looks like like. The project should help people understand statecharts and Hypermedia responses. Its working pretty good already. One big feature misssing is the restoration of delays and time based things. Like in the request example with the timeout. Restoring the state should re-initate the timeout easily. Maybe this could be considered as a new feature to make persisting and restoring such charts easier.
like-fill
3

November 20, 2019 at 7:22am
Great question! I was waiting for it.
So there are some of my childish wishes:
simplified syntax for example in my own implementation
{
enter : "./firstState",
firstState : {
meta : {
...
},
listen : {
ACTION : { goto : './errorState' }
},
enter : [
{ goto : './secondState', if: 'condition' },
],
exit : [
{ call : 'something', if: 'condition' },
],
invoke : 'something',
then : '../doneState',
catch : '../errorState',
},
errorState : { type : 'throw' },
doneState : { type : 'done' },
}
I know that Xstate is following SCXML specification, but sometimes I just have a feeling that following some specifications and patters can be a huge blocker for development and problem solving.
partials aside of services, activities etc, there should be also some kind library with meta states that can be later inherited from, some kind of partials. Just to achieve some kind of DRY. It may even be global library, like export const MSTMachine = Machine.makeCopy() MSTMachine.partials.add( partial )
const machine = Machine({
enter : "./firstState",
states : {
resourceStateTypeA : {
extends : _products,
meta : {
type: 'productA',
},
},
resourceStateTypeB : {
extends : _products,
meta : {
type: 'productB',
},
},
},
},
{
partials : {
_products : {
initial : 'fetch',
meta : {
perPage: 10,
},
states : {
fetch : { invoke ... },
onDone : 'doneState',
onError : 'errorState',
}
}
}
})
Partials should be deep merged with states.
promises actions should allow promises, sometimes I need to wait for something on entering state
extended interpreter while working with MST for example, I am many times using proxies for matching services, activities, guards, so I am not repeating myself with defining everything again and again.
Machine({}, {
services : new Proxy(self,handler)
})
I would rather see something like this:
export const MSTMachine = Machine.makeCopy()
MSTMachine.resolveService = (environment, serviceName) => tryResolve(environment.node, serviceName)
custom or at least 2 final types machine may finish also with an error, current syntax is overcomplicating it. I would like to use for example it that way.
machine.start().then().catch().finally()
Can be done with extended interpreter.
same type of variables state value, toStrings, etc should always return same type of object, let it be array of strings or object, but always same.
Edited
like-fill
1
Love using xstate but there is a big learning curve (even tougher with TS). The patterns idea is good. I would definitely want to see at least a more fleshed out example of a single page app that demos the following
  • Routing with nested routes - preferably with hash routing
  • CRUD operations with secured APIs (not just public APIs that can be called with no context)
  • Dealing with LARGE lists returned by APIs and having Actors represent each item (for performing CRUD operations)
  • All in TS or have a TS version
  • As mentioned earlier, how to keep it all tidy or best practices to keep code organized
  • Finally, document the app using the visualizer. Could you have one massive diagram for the whole machine and its actors, would you split it in multiple diagrams, a bit of both?
I think fleshing out the reddit app example with the above points would really help us understand how to use xstate.
Edited
like-fill
12
Great list! Thanks for making it. Here's some of my thoughts:
  • simplified syntax - Since an XState Machine config is just an object, you can create any simplified syntax you want on top of it.
  • partials - Same with partials. I don't want to introduce an API-specific extends keyword etc. when you can use JS naturally:
resourceStateTypeA: {
..._products,
meta: { type: 'productA' }
}
// or...
resourceStateTypeA: createProductState('productA')
  • promises - Can you give an example? invoke is the way you should do this.
  • extended interpreter - Would also like a better example of this with XState.
  • custom or at least 2 final types - This goes against the notion of a machine, which is either "done" or not. Extending the interpreter would just complicate this.
  • same type of variables - Do you mean e.g., "green" vs. { red: "walk" }? How would you rather represent atomic state values?
like-fill
1

November 21, 2019 at 7:21am
The viz as a stand-alone npm package :P
like-fill
4
Thanks for your answer! While reading your answer I realised I was seriously biased also as I said "childish wishes" ;) That's my second proof that xstate is in good hands. I actually removed my bias, and rewrite my code. Everything become super clean and all my ideas went to trash. So yeah, sometimes one must express himself to move around some mental blockade. Sorry for spamming this thread.
"Since an XState Machine config is just an object" - aha! moment
like-fill
1

November 21, 2019 at 4:49pm
You're not spamming, your comments are very insightful, so thanks!
This is a related thread - if you want a completely different syntax for XState, it's easy to build one on top of XState.

Functional approach to define machines

message-simple
40
Show more messages