Skip to content

Instantly share code, notes, and snippets.

@jaetask
Last active March 26, 2020 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaetask/00a101fb394e791f57245dda7c63d8b1 to your computer and use it in GitHub Desktop.
Save jaetask/00a101fb394e791f57245dda7c63d8b1 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// import { assign, Machine } from 'xstate';
const MIN_NUM_SURVEYS = 1;
const MAX_NUM_SURVEYS = 4;
const surveyInitialState = { name: 'Default Name' };
const canAdd = context => context.surveys.length < MAX_NUM_SURVEYS;
const canClone = context => context.surveys.length < MAX_NUM_SURVEYS;
const canUndoDelete = context => context.surveys.length < MAX_NUM_SURVEYS;
const canRename = (context, event) =>
context.surveys.length > 0 &&
Number.isInteger(event.position) &&
context.surveys[event.position] !== undefined &&
event.name.length > 0;
const canDelete = (context, event) =>
context.surveys.length > 0 &&
Number.isInteger(event.position) &&
context.surveys[event.position] !== undefined &&
context.surveys.length > MIN_NUM_SURVEYS;
const surveysMachine = Machine(
{
id: 'surveys',
initial: 'idle',
context: {
surveys: [surveyInitialState],
bin: undefined,
deletedPosition: undefined,
errorMessage: undefined,
},
states: {
idle: {
on: {
ERROR: {
target: 'idle',
actions: assign((context, { errorMessage }) => ({ hasDoneSomething: true, errorMessage })),
onEntry: (context, event) => {
console.log('Error state');
console.log('context', context);
console.log('event', event);
console.log('context.errorMessage', context.errorMessage);
},
},
RENAME_SURVEY: [
{
target: 'idle',
actions: assign({
surveys: (context, event) => {
// todo: guard name length etc
const { position, name } = event;
// todo: deep clone to ensure purity
const surveys = context.surveys;
surveys[position] = { ...context.surveys[position], name };
return surveys;
},
}),
cond: 'canRename',
},
{
target: 'idle',
cond: (context, event) => event.name === undefined || event.name.length === 0,
actions: send({ type: 'ERROR', errorMessage: 'You must set a name' }),
},
],
ADD_SURVEY: {
target: 'idle',
actions: assign({
surveys: (context, event) => {
const { name = surveyInitialState.name } = event;
return context.surveys.concat({ ...surveyInitialState, name });
},
}),
cond: 'canAdd',
},
CLONE_SURVEY: {
target: 'idle',
actions: assign({
surveys: (context, event) => {
const { position } = event;
return context.surveys.concat(context.surveys[position]);
},
}),
cond: 'canClone',
},
DELETE_SURVEY: {
target: 'idle',
actions: assign((context, event) => {
const { position } = event;
// todo: deep clone to ensure purity
const surveys = context.surveys;
const deleted = surveys.splice(position, 1);
return {
surveys,
bin: deleted[0],
};
}),
cond: 'canDelete',
},
UNDO_DELETE_SURVEY: {
target: 'idle',
actions: assign(context => {
// todo: deep clone to ensure purity
const survey = context.bin;
const position = context.deletedPosition;
const surveys = context.surveys;
surveys.splice(position, 0, survey);
return {
surveys,
bin: undefined,
deletedPosition: undefined,
};
}),
cond: 'canUndoDelete',
},
},
},
},
},
{
guards: {
canAdd,
canClone,
canDelete,
canRename,
canUndoDelete,
},
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment