Last active
March 5, 2021 11:01
-
-
Save MichielDeMey/57edf2cf39e7aab404e4c21e4bca2a4d to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const dialTimeout = 7000; | |
const answerTimeout = 7000; | |
const externalActions = { | |
notify: () => { | |
window.alert('Notified care circle'); | |
} | |
} | |
const dialActor = (timeout = 5000) => { | |
return new Promise((resolve, reject) => { | |
setTimeout(resolve, timeout) | |
}) | |
} | |
const guards = { | |
shouldContactCaree: (ctx, event) => { | |
return ctx.shouldContactCaree | |
}, | |
maxAttemptsReached: (ctx, event, { cond }) => { | |
return ctx[cond.actor].attempts >= cond.numAttempts && !ctx[cond.actor].success | |
}, | |
maxAttempsCurrentCarerReached: (ctx, event, { cond }) => { | |
return ctx.carers[ctx.currentCarerIndex].attempts >= cond.numAttempts && !ctx.carers[ctx.currentCarerIndex].success | |
}, | |
couldNotContactCarers: (ctx, event, { cond }) => { | |
return ctx.carers.every((carer, i) => !carer.success && carer.attempts === ctx.numCarerAttempts); | |
} | |
} | |
const emergencyMachine = Machine({ | |
id: 'emergency', | |
context: { | |
shouldContactCaree: true, | |
currentCarerIndex: 0, | |
numCarerAttempts: 1, | |
caree: { | |
attempts: 0, | |
success: false, | |
firstName: 'John', | |
lastName: 'Doe', | |
phone: '+32411111111' | |
}, | |
carers: [{ | |
attempts: 0, | |
success: false, | |
firstName: 'Michiel', | |
lastName: 'De Mey', | |
phone: '+32411118b61111' | |
}, { | |
attempts: 0, | |
success: false, | |
firstName: 'Niels', | |
lastName: 'Peetermans', | |
phone: '+32411111111' | |
}, { | |
attempts: 0, | |
success: false, | |
firstName: 'Jane', | |
lastName: 'Doe', | |
phone: '+32411111111' | |
}] | |
}, | |
initial: 'idle', | |
states: { | |
idle: { | |
on: { | |
INCOMING_EMERGENCY: [{ | |
target: 'contactingCaree', | |
cond: { | |
type: 'shouldContactCaree' | |
} | |
}, { | |
target: 'contactingCarers', | |
}] | |
} | |
}, | |
contactingCaree: { | |
initial: 'check', | |
states: { | |
check: { | |
on: { | |
'': [{ | |
target: '#emergency.contactingCarers', | |
cond: { | |
type: 'maxAttemptsReached', | |
actor: 'caree', | |
numAttempts: 1 | |
} | |
}, { target: 'queue' }] | |
} | |
}, | |
queue: { | |
exit: ['increaseCareeAttempt'], | |
invoke: { | |
id: 'dialCaree', | |
src: () => dialActor(), | |
onDone: { | |
target: 'dialing', | |
}, | |
onError: { | |
target: '#emergency.contactingCaree' | |
} | |
} | |
}, | |
dialing: { | |
on: { | |
ANSWER: { | |
target: 'answer' | |
}, | |
NO_ANSWER: [{ | |
target: '#emergency.contactingCaree', | |
}] | |
}, | |
after: { | |
[dialTimeout]: '#emergency.contactingCaree' | |
} | |
}, | |
answer: { | |
on: { | |
REAL_EMERGENCY: { | |
target: '#emergency.contactingCarers', | |
actions: ['successfulCareeAttempt'] | |
}, | |
FALSE_ALARM: { | |
target: '#emergency.end', | |
actions: ['successfulCareeAttempt'] | |
}, | |
HANGUP: '#emergency.contactingCaree' | |
}, | |
after: { | |
[dialTimeout]: '#emergency.contactingCaree' | |
} | |
} | |
}, | |
}, | |
contactingCarers: { | |
initial: 'check', | |
states: { | |
check: { | |
entry: ['attemptCarer'], | |
on: { | |
'': [{ | |
target: '#emergency.notify', | |
cond: 'couldNotContactCarers' | |
}, { target: 'queue' }] | |
} | |
}, | |
queue: { | |
exit: ['increaseCarersAttempt'], | |
invoke: { | |
id: 'dialCarer', | |
src: () => dialActor(), | |
onDone: { | |
target: 'dialing', | |
}, | |
onError: { | |
target: '#emergency.contactingCarers', | |
} | |
} | |
}, | |
dialing: { | |
on: { | |
ANSWER: { | |
target: 'answer' | |
}, | |
NO_ANSWER: [{ | |
target: '#emergency.contactingCarers' | |
}] | |
}, | |
after: { | |
[dialTimeout]: '#emergency.contactingCarers' | |
} | |
}, | |
answer: { | |
on: { | |
CONFIRM: { | |
target: '#emergency.end', | |
actions: ['successfulCarerAttempt'] | |
}, | |
HANGUP: '#emergency.contactingCarers' | |
}, | |
after: { | |
[answerTimeout]: '#emergency.contactingCarers' | |
} | |
} | |
} | |
}, | |
notify: { | |
entry: ['notify'], | |
on: { | |
'': 'end' | |
} | |
}, | |
end: { | |
type: 'final' | |
} | |
} | |
}, { | |
actions: { | |
...externalActions, | |
increaseCareeAttempt: assign({ | |
caree: (ctx, event) => { | |
return { | |
...ctx.caree, | |
attempts: ctx.caree.attempts + 1 | |
} | |
} | |
}), | |
successfulCareeAttempt: assign({ | |
caree: (ctx, event) => { | |
return { | |
...ctx.caree, | |
success: true | |
} | |
} | |
}), | |
increaseCarersAttempt: assign({ | |
carers: (ctx, event) => { | |
const carerArr = [ ...ctx.carers ] | |
const currentAttempts = carerArr[ctx.currentCarerIndex].attempts; | |
carerArr[ctx.currentCarerIndex] = { | |
...ctx.carers[ctx.currentCarerIndex], | |
attempts: currentAttempts + 1 | |
} | |
return carerArr | |
} | |
}), | |
attemptCarer: assign({ | |
currentCarerIndex: (ctx, event) => { | |
if (ctx.carers[ctx.currentCarerIndex].attempts < ctx.numCarerAttempts) return ctx.currentCarerIndex; | |
return ctx.currentCarerIndex + 1 | |
} | |
}), | |
successfulCarerAttempt: assign({ | |
carers: (ctx, event) => { | |
const carerArr = [ ...ctx.carers ] | |
carerArr[ctx.currentCarerIndex] = { | |
...carerArr[ctx.currentCarerIndex], | |
success: true | |
} | |
return carerArr | |
} | |
}) | |
}, | |
guards | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment