-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPIKE needed] Ergonomic Improvement Ideas #235
Comments
In addition, we should explore different ways of handling ember-concurrency tasks as machine-invokables. @sukima has a wonderful little utility here that enables tasks to be located anywhere outside the lifecycle of the machine: https://tritarget.org/#ember-concurrency%20with%20XState:[[ember-concurrency%20with%20XState]]%20[[Ember%20XState%20Utility]] It may be beneficial to support the scenario where a nested component contains a task that the machine is aware of and something cancels the task. Supporting both cancellation and error would allow for slightly different workflows, if needed. @sukima's Code copied here import { didCancel } from 'ember-concurrency';
/**
* Wraps an ember-concurrency task into an XState service.
*
* Machine({
* id: 'example',
* initial: 'fetch',
* states: {
* 'fetch': {
* invoke: { src: 'fetch' },
* on: {
* DONE: 'done',
* CANCEL: 'cancelled',
* ERROR: 'errored',
* },
* },
* 'cancelled': { type: 'final' },
* 'errored': { type: 'final' },
* 'done': { type: 'final' },
* },
* }).withConfig({
* services: {
* fetch: taskService(this.fetchTask),
* },
* });
*
* @function
* @param {TaskProp} taskProp the task property (not instance) to call perform() on
* @return {CallbackService} an XState compatable callback based service
*/
export function taskService(taskProp) {
return (...args) => (callback) => {
let taskInstance = taskProp.perform(...args);
taskInstance.then(
(data) => callback({ type: 'DONE', data }),
(error) => didCancel(error)
? callback({ type: 'CANCEL' })
: callback({ type: 'ERROR', error })
);
return () => taskInstance.cancel();
};
} |
Current state: It works and makes use of https://github.com/pzuraq/ember-usable under the hood |
cc @pzuraq |
hmm, I need to finish that, this branch is where I'm taking it but haven't had time to finish it up and land it. Seems like a perfect use case for |
I’m curious about the syntax like @matchesState(‘testing’)
IsTesting: Boolean Reading something like that throws me off; it reminds me of something like that the |
yeah, that's my feeling about it too. And then what happens if someone wants 2 or more state machines in a component? those decorators wouldn't be able to work. I think exporting some vanilla JS helpers will help a bunch, as well as some helpers to use in the template. I think there should be some explicitness about which machine is being used where. idk. |
That’s a second concern of mine as well that goes right along with my confusion. I’ll admit that I know nothing about @matchesState(‘statechart’, ‘testing’)
IsTesting Would be much easier to grok on a quick read without context (which will be a lot of people reading most code!) |
The idea was that you usually only have one so it's easier to just have a default property that it matches against which safes some typing. Right now the default is
Will match against the It might make sense to have configuration option for this though. So if you call you statechart properties different you might want to change the default in one place instead of always doing If you don't like this implicitness you can always do I totally understand the magical feel though and that it trips people up at first. It might makes sense to change the docs to the explicit version - because many people share this feeling when getting into |
That’s awesome!
That makes a lot of sense to me! Sorry to derail the conversation from the initial purpose, but I thought that addressing that feedback might be tied up with addressing the API of the addon as a whole. |
The idea of these decorators is to wrap the boilerplate up in a neat tidy package. Thus such I would argue one component running two or more machines is out of scope and to implement that yourself. The boilerplate to interface with XState is so minimal it is very easy to use it out-of-the-box. That said one could also just have two There are so many ways to skin the cat there does not need to be one twue way. |
As discussed with @NullVoxPopuli, @pangratz and @sukima in a recent call we want to try to improve the ergonomics of the addon for modern Ember.js usage.
Areas for improvement:
statechart
-decorator.We came up with some ideas about a new way to integrate xstate with
ember-statecharts
:Using a mechanism similiar to
@use and Resources
- RFCBenefits of this approach
@use
Questions
@use
-decorator?@use
-like functionality just for this addon that we can later on switch out for@use
?Next steps
@NullVoxPopuli, @pangratz, @sukima as far as I remember we were all pretty much in favor of this approach so I'm adding the other versions we discussed only for reference.
Other ideas:
class decorator
Property decorator
The text was updated successfully, but these errors were encountered: