Sukima27th March 2020 at 3:20pm
The following utility allow for easy integration into using XState services.
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();
};
}