Skip to content

Instantly share code, notes, and snippets.

@MichielDeMey
Last active September 24, 2019 14:07
Show Gist options
  • Save MichielDeMey/e45531064b27d6982b8089759aba73de to your computer and use it in GitHub Desktop.
Save MichielDeMey/e45531064b27d6982b8089759aba73de to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const guards = {
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
},
additionalAttemptsMainCarerReached: (ctx, event, { cond }) => {
return ctx.mainCarer.additionalAttempts >= cond.numAttempts
},
couldNotContactAdditionalCarers: (ctx, event, { cond }) => {
return ctx.carers.every((carer, i) => !carer.success && ctx.contactedCarers.includes(i))
}
}
const emergencyMachine = Machine({
id: 'emergency',
context: {
currentCarerIndex: 0,
contactedCarers: [],
caree: {
attempts: 0,
success: false,
firstName: 'John',
lastName: 'Doe',
phone: '+32411111111'
},
mainCarer: {
attempts: 0,
additionalAttempts: 0,
success: false,
firstName: 'Michiel',
lastName: 'De Mey',
phone: '+32411111111'
},
carers: [{
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'
}
}
},
contactingCaree: {
initial: 'queue',
states: {
queue: {
on: {
START_CALL: 'dialing'
}
},
dialing: {
entry: ['increaseCareeAttempt'],
on: {
ANSWER: {
target: 'answer',
actions: ['successfulCareeAttempt']
},
NO_ANSWER: [{
target: '#emergency.contactingMainCarer',
cond: {
type: 'maxAttemptsReached',
actor: 'caree',
numAttempts: 1
}
}, {
target: 'queue'
}]
}
},
answer: {
on: {
REAL_EMERGENCY: '#emergency.contactingEmergencyServices',
FALSE_ALARM: '#emergency.internalFeedback'
}
}
}
},
contactingEmergencyServices: {
on: {
ANSWER: 'contactingMainCarer',
NO_ANSWER: 'contactingEmergencyServices'
}
},
contactingMainCarer: {
initial: 'queue',
states: {
queue: {
on: {
START_CALL: 'dialing'
}
},
dialing: {
entry: ['increaseMainCarerAttempt'],
on: {
ANSWER: {
target: 'answer',
actions: ['successfulMainCarerAttempt']
},
NO_ANSWER: [{
target: '#emergency.contactingAdditionalCarers',
cond: {
type: 'maxAttemptsReached',
actor: 'mainCarer',
numAttempts: 3
}
}, {
target: 'queue'
}]
}
},
answer: {
on: {
NOTIFIED: {
target: '#emergency.inform',
}
}
}
}
},
contactingAdditionalCarers: {
initial: 'queue',
states: {
queue: {
on: {
START_CALL: 'dialing'
}
},
dialing: {
entry: ['increaseAdditionalCarersAttempt'],
on: {
ANSWER: {
target: 'answer',
actions: ['successfulAdditionalCarerAttempt']
},
NO_ANSWER: [{
target: '#emergency.contactingAdditionalCarers',
actions: ['attemptAdditionalCarer'],
cond: {
type: 'maxAttempsCurrentCarerReached',
numAttempts: 3
}
}, {
target: 'queue'
}]
}
},
answer: {
on: {
NOTIFIED: '#emergency.inform'
}
}
},
on: {
'': [{
target: '#emergency.inform',
cond: {
type: 'additionalAttemptsMainCarerReached',
numAttempts: 1
}
}, {
target: '#emergency.contactingMainCarer',
actions: ['increaseAdditionalMainCarerAttempt'],
cond: 'couldNotContactAdditionalCarers'
}]
}
},
inform: {
on: {
INFORMED: 'end'
}
},
internalFeedback: {
on: {
FEEDBACK_PROVIDED: 'end'
}
},
end: {
type: 'final'
}
}
}, {
actions: {
increaseCareeAttempt: assign({
caree: (ctx, event) => {
return {
...ctx.caree,
attempts: ctx.caree.attempts + 1
}
}
}),
successfulCareeAttempt: assign({
caree: (ctx, event) => {
return {
...ctx.caree,
success: true
}
}
}),
increaseMainCarerAttempt: assign({
mainCarer: (ctx, event) => {
return {
...ctx.mainCarer,
attempts: ctx.mainCarer.attempts + 1
}
}
}),
successfulMainCarerAttempt: assign({
mainCarer: (ctx, event) => {
return {
...ctx.mainCarer,
success: true
}
}
}),
increaseAdditionalCarersAttempt: 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
}
}),
increaseAdditionalMainCarerAttempt: assign({
mainCarer: (ctx, event) => {
return {
...ctx.mainCarer,
additionalAttempts: ctx.mainCarer.additionalAttempts + 1
}
}
}),
attemptAdditionalCarer: assign({
contactedCarers: (ctx, event) => {
const contactedCarersArr = [ ...ctx.contactedCarers]
contactedCarersArr.push(ctx.currentCarerIndex)
return contactedCarersArr
},
currentCarerIndex: (ctx, event) => ctx.currentCarerIndex + 1,
}),
successfulAdditionalCarerAttempt: 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