Skip to content

Instantly share code, notes, and snippets.

@timoxley
Last active July 20, 2022 19:39
Show Gist options
  • Save timoxley/2e1774ecfe95274a1cc20bab02140bce to your computer and use it in GitHub Desktop.
Save timoxley/2e1774ecfe95274a1cc20bab02140bce to your computer and use it in GitHub Desktop.
XState list processing machine
export function todoMachine ({ contextKey, task, ...opts }) {
return {
...opts,
initial: 'run',
states: {
run: {
invoke: {
src: (ctx, event) => (fn) => {
const itemDone = (key) => (data) => {
fn({ type: 'itemDone', data: { key, data } })
}
const todo = ctx[contextKey] || {}
Object.keys(todo)
.filter(key => !todo[key])
.forEach((key) => {
task(key).then(itemDone(key), itemDone(key))
})
}
},
on: {
itemDone: {
actions: actions.assign({
[contextKey]: (ctx, event) => {
const { key, data } = event.data
return Object.assign({}, ctx[contextKey], {
[key]: data
})
}
})
},
'': {
target: 'end',
cond: ctx => Object.values(ctx[contextKey]).every(Boolean)
}
}
},
end: {
type: 'final'
}
}
}
}
// Usage
function wait (delay) {
return new Promise(resolve => setTimeout(resolve, delay))
}
const machine = Machine({
context: {
todoItems: {
one: false,
two: false,
three: false
}
},
initial: 'start',
states: {
start: todoMachine({
contextKey: 'todoItems',
task: async (key) => {
await wait(500)
return true
},
onDone: 'end'
}),
end: {
type: 'final'
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment