Skip to content

Instantly share code, notes, and snippets.

@austinsamsel
Last active December 15, 2020 16:24
Show Gist options
  • Save austinsamsel/e63e3760c0e116168ae0ce548603be47 to your computer and use it in GitHub Desktop.
Save austinsamsel/e63e3760c0e116168ae0ce548603be47 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const createMachine = ({...props}) => {
return Machine({...props})
}
const ERROR_MESSAGES = {
GENERAL: 'There was an error.'
}
const showcases = [
{
id: '1',
name: 'foo',
momentIDs: ['abc', 'def'],
},
{
id: '2',
name: 'bar',
momentIDs: ['abc', '123'],
},
{
id: '3',
name: 'snake',
momentIDs: ['abc1', '1234', 'def', '456', 'ghi'],
},
];
const fetchShowcases = () =>
new Promise((resolve) => {
setTimeout(() => {
console.log('fetching showcases');
resolve(showcases);
}, 2000);
});
// trigger these
const addToShowcase = (context) => {
const { selectedShowcase, moment } = context;
return new Promise((resolve) => {
setTimeout(() => {
console.log(
`adding moment ${moment.id} to showcase ${selectedShowcase.id}`,
);
resolve({});
}, 2000);
});
};
const removeFromShowcase = (context) => {
const { selectedShowcase, moment } = context;
return new Promise((resolve) => {
setTimeout(() => {
console.log(
`removing moment ${moment.id} from showcase ${selectedShowcase.id}`,
);
resolve({});
}, 3000);
});
};
const testInvoke = (context) => {
console.log('test invoke start');
return new Promise((resolve) => {
setTimeout(() => {
console.log(`test invoke result`, context);
resolve({});
}, 2000);
});
};
const createShowcase = (context) => {
const { showcaseName, showcases } = context;
return new Promise((resolve) => {
setTimeout(() => {
console.log(`creating showcase ${showcaseName}`);
const newShowcase = {
id: `${showcases.length + 1}`,
name: showcaseName,
momentIDs: ['123'],
};
assign({
showcases: [...showcases, newShowcase],
});
resolve(newShowcase);
}, 2000);
});
};
const showcasesWithMoment = (momentId, showcases) => {
return showcases.filter((s) => {
return s.momentIDs.includes(momentId);
});
};
const createMomentShowcaseMachine = ({
id,
name,
momentIDs,
momentId,
}) =>
createMachine({
id: 'showcase',
initial: 'idle',
context: {
id,
name,
hasMoment: momentIDs.includes(momentId),
// @todo there may be a missed case here where the momentId is in momentIds
isFull: momentIDs.length === 5,
},
states: {
idle: {
on: {
TOGGLE_HAS_MOMENT: {
actions: [
assign({ hasMoment: (context) => !context.hasMoment }),
'commit',
],
target: 'syncing',
},
},
},
syncing: {
invoke: {
id: 'testinvoke',
src: testInvoke,
onDone: 'idle',
onError: 'error',
},
},
error: {
id: 'error',
on: {
RELOAD: {
target: 'refetch',
},
},
},
refetch: {
invoke: {
id: 'refetch',
src: testInvoke,
onDone: 'idle',
onError: 'error',
},
},
},
});
const momentShowcaseMachine = Machine({
id: 'momentShowcase',
type: 'parallel',
context: {
selectedShowcase: undefined,
showcases: [],
showcaseName: undefined,
filter: undefined,
moment: {
id: '123'
},
errorMessage: ''
},
states: {
visibility: {
initial: 'collapsed',
states: {
collapsed: {
on: {
EXPAND: 'expanded',
},
},
expanded: {
on: {
COLLAPSE: 'collapsed',
},
},
},
},
list: {
id: 'list',
initial: 'loading',
states: {
loading: {
invoke: {
id: 'fetchShowcases',
src: fetchShowcases,
onDone: {
target: '#list.edit_showcases',
actions: assign({
showcases: (context, event) => {
return event.data.map((showcase) => {
const newShowcase = {
...showcase,
momentId: context.moment.id,
};
return {
...newShowcase,
ref: spawn(createMomentShowcaseMachine(newShowcase)),
};
});
},
}),
},
onError: {
target: '#list.error',
}
}
},
edit_showcases: {
id: 'edit_showcases',
initial: 'idle',
states: {
idle: {
on: {
CHANGE_SHOWCASE_FILTER_INPUT: {
actions: assign({
filter: (context, event) => event.value.trim(),
}),
},
NEW_SHOWCASE: {
target: '#edit_showcases.add',
actions: assign({
filter: '',
}),
},
},
},
add: {
on: {
CHANGE_SHOWCASE_NAME_INPUT: {
actions: assign({
showcaseName: (context, event) => event.value.trim(),
}),
},
CREATE_SHOWCASE: '#edit_showcases.loading',
CANCEL: '#edit_showcases.idle',
},
},
loading: {
invoke: {
src: createShowcase,
onDone: {
target: '#edit_showcases.idle',
actions: assign({
showcases: (context, event) => {
const newShowcase = {
...event.data,
momentId: context.moment.id,
};
return [
...context.showcases,
{
...newShowcase,
ref: spawn(createMomentShowcaseMachine(newShowcase),
),
},
];
},
}),
},
onError: {
target: '#list.error',
actions: assign({
errorMessage: (context, event) => event.data?.i18nKey ?? ERROR_MESSAGES.GENERAL,
}),
},
}
}
}
},
error: {
on: {
RELOAD: {
target: '#list',
},
},
},
}
}
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment