Skip to content

Instantly share code, notes, and snippets.

@jmakeig
Created December 27, 2019 07:56
Show Gist options
  • Save jmakeig/40d03832ec00ba58444e4d8adda6beb4 to your computer and use it in GitHub Desktop.
Save jmakeig/40d03832ec00ba58444e4d8adda6beb4 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const config = {
id: 'annotation',
initial: 'unselected',
context: {
id: null,
annotation: null,
errorMessage: null
},
states: {
unselected: {
on: {
select: {
target: 'selected',
actions: assign({
id: (context, event) => event.id
})
}
}
},
selected: {
id: 'selected',
initial: 'loading',
on: {
blur: { target: 'unselected' }
},
states: {
loading: {
invoke: {
id: 'fetchAnnotation',
src: 'fetchAnnotationService',
onDone: {
target: 'viewing',
actions: assign({ annotation: (context, event) => event.data })
},
onError: {
target: 'error',
actions: assign({
errorMessage: (context, event) => event.data
})
}
}
},
error: {},
viewing: {
on: {
edit: 'editing'
}
},
editing: {
id: 'editing',
initial: 'clean',
entry: 'cacheClean',
states: {
clean: {
on: {
change: {
target: 'dirty',
actions: 'updateAnnotation'
},
cancel: '#annotation.selected.viewing'
}
},
dirty: {
id: 'dirty',
initial: 'changing',
on: {
save: 'saving',
blur: undefined
},
states: {
changing: {
on: {
cancel:{ target: 'confirming'},
change: {
target: 'changing',
actions: 'updateAnnotation'
}
}
},
confirming: {
invoke: {
id: 'confirmCancel',
src: 'confirmCancelService',
onDone: {
target: '#annotation.selected.viewing',
actions: 'revertCached'
},
onError: { target: 'changing' }
}
}
}
},
saving: {
invoke: {
id: 'saveAnnotation',
src: 'saveAnnotationService',
onDone: {
target: '#annotation.selected.viewing',
actions: assign({
annotation: (context, event) => event.data
})
},
onError: {
actions: assign({
errorMessage: (context, event) => event.data
})
}
}
}
}
}
}
}
}
};
// For XState visualizer
function confirmCancel(message = 'You sure?') {
return new Promise(function(resolve, reject) {
if (window.confirm(message)) {
resolve();
} else {
reject();
}
});
}
const options = {
actions: {
updateAnnotation: assign({
annotation: (context, event) =>
// This is an awkward way to update the `comment` property
Object.assign({}, context.annotation, {
comment: event.comment,
now: new Date().valueOf()
})
}),
cacheClean: assign({
cache: (context, event) => Object.assign({}, context.annotation)
}),
revertCached: assign({ annotation: (c,e) => Object.assign({}, context.cache)})
},
services: {
fetchAnnotationService: (context, event) => Promise.resolve({id: 'ANN1234', comment: 'Hi!', timestamp: new Date().toISOString()}),
confirmCancelService: (context, event) => confirmCancel(),
saveAnnotationService: (context, event) => Promise.resolve({})
}
};
const machine = Machine(config, options);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment