Skip to content

Instantly share code, notes, and snippets.

@MarceloAlves
Created August 17, 2021 15:40
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 MarceloAlves/02a32825614e00b0ac656b9bcd9c2512 to your computer and use it in GitHub Desktop.
Save MarceloAlves/02a32825614e00b0ac656b9bcd9c2512 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
// - XState (all XState exports)
const createLinkMachine = Machine(
{
id: 'shortenLink',
context: {
linkHistory: [],
value: '',
errorMessage: null,
retries: 0,
},
initial: 'idle',
states: {
idle: {
tags: ['showingForm'],
on: {
CREATE_LINK: 'validateForm',
UPDATE_INPUT: {
actions: ['updateValue', 'clearErrorMessage'],
},
},
},
validateForm: {
tags: ['showingForm'],
invoke: {
id: 'validatingUrl',
src: 'validateUrl',
onDone: {
target: 'creatingLink',
actions: ['clearErrorMessage'],
},
onError: {
target: 'idle',
actions: ['setErrorMessage'],
},
},
},
creatingLink: {
tags: ['showingForm'],
always: [{ cond: 'retriesExceeded', target: 'cannotCreateLink' }],
invoke: {
id: 'creatingLink',
src: 'postLink',
onDone: {
target: 'linkCreated',
actions: ['prependLink'],
},
onError: {
target: 'creatingLink',
actions: ['incrementRetries', 'setErrorMessage'],
},
},
},
cannotCreateLink: {
tags: ['showingForm'],
exit: ['resetErrorCount'],
on: {
CREATE_LINK: 'validateForm',
},
},
linkCreated: {
tags: ['showingResult'],
exit: ['resetContext'],
on: {
RESTART: 'idle',
},
},
},
},
{
guards: {
retriesExceeded: (ctx) => {
return ctx.retries !== 0 && ctx.retries >= 2
},
},
services: {
validateUrl: async (ctx) => {
// const result = urlFormSchema.validate({ url: ctx.value })
// if (result.error) {
// return Promise.reject({ message: 'Must be a valid URL' })
// }
return {}
},
postLink: async (ctx) => {
// // const res = await fetch('/api/link', {
// // method: 'POST',
// // body: JSON.stringify({ url: ctx.value }),
// // headers: { 'Content-Type': 'application/json' },
// // })
// if (res.status === 201) {
// const data = res.json()
// return data
// }
// return Promise.reject({ status: res.status, message: 'Unable to create link. Please try again later.' })
return { id: 1234, url: 'https://example.com', slug: 'abc123'}
},
},
actions: {
updateValue: assign((_ctx, evt) => {
if (evt.type !== 'UPDATE_INPUT') return {}
return {
value: evt.value,
}
}),
resetContext: assign((_ctx, evt) => {
if (evt.type !== 'RESTART') return {}
return {
value: '',
errorMessage: null,
retries: 0,
}
}),
resetErrorCount: assign((_ctx, evt) => {
if (evt.type !== 'CREATE_LINK') return {}
return {
retries: 0,
}
}),
incrementRetries: assign((ctx) => {
return {
retries: ctx.retries + 1,
}
}),
prependLink: assign((ctx, evt) => {
if (evt.type !== 'done.invoke.creatingLink') return {}
return {
linkHistory: [evt.data, ...ctx.linkHistory],
}
}),
clearErrorMessage: assign((_ctx, evt) => {
if (evt.type !== 'done.invoke.validateUrl') return {}
return {
errorMessage: null,
}
}),
setErrorMessage: assign((_ctx, evt) => {
if (evt.type === 'error.platform.validatingUrl' || evt.type === 'error.platform.creatingLink') {
return {
errorMessage: evt.data.message,
}
}
return {}
}),
},
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment