Skip to content

Instantly share code, notes, and snippets.

@hosmelq
Last active March 11, 2020 18:30
Show Gist options
  • Save hosmelq/dd2aeeb5d477e2049334cd66f9201e40 to your computer and use it in GitHub Desktop.
Save hosmelq/dd2aeeb5d477e2049334cd66f9201e40 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
function buildVibrationPattern(seconds) {
return new Array(seconds / 1500)
.fill(null)
.reduce(prev => [...prev, 0, 1000, 500], [])
}
const DEFAULT_WAIT_TIME = 30000
const CURRENT_ORDER_STATE = `WAITING_COURIER`
const ORDER_STATE = {
IN_PROGRESS: `IN_PROGRESS`,
WAITING_COURIER: `WAITING_COURIER`
}
const CURRENT_ORDER_TYPE = `DELIVERY`
const ORDER_TYPE = {
DELIVERY: `DELIVERY`,
HIRED: `HIRED`
}
Machine(
{
id: `courier-state-and-jobs`,
initial: `initializing`,
context: {
fetchKey: 1,
online: false,
offer: {
id: null,
receivedAt: null
}
},
states: {
initializing: {
on: {
'': [
{
cond: `isOffline`,
target: `offline`
},
{
cond: `isOnline`,
target: `online`
}
]
}
},
offline: {
entry: `setOffline`,
on: {
GO_ONLINE: `goOnline`
}
},
goOnline: {
invoke: {
id: `goOnline`,
src: `goOnline`,
onDone: `online`,
onError: `offline`
}
},
goOffline: {
invoke: {
id: `goOffline`,
src: `goOffline`,
onDone: `offline`,
onError: `offline`
}
},
online: {
entry: `setOnline`,
initial: `waiting`,
on: {
GO_OFFLINE: `goOffline`
},
states: {
waiting: {
on: {
ORDER_RECEIVED: {
actions: `setOffer`,
target: `fetchingOrder`
}
}
},
fetchingOrder: {
invoke: {
id: `fetchOrder`,
src: `fetchOrder`,
onDone: [
{
cond: `isAssigned`,
actions: `incrementFetchKey`,
target: `waiting`
},
{
cond: `doesNotHaveEnoughTimeToAcceptOrder`,
target: `waiting`
},
{
cond: `isDeliveryOrder`,
target: `offer`
},
{
cond: `isHiredOrder`,
actions: `incrementFetchKey`,
target: `waiting`
}
],
onError: `waiting`
}
},
offer: {
onDone: `waiting`,
initial: `waiting`,
states: {
waiting: {
entry: `vibrate`,
exit: `cancelVibration`,
on: {
ACCEPT_JOB: `accepting`,
REJECT_JOB: `rejecting`
},
after: {
ORDER_DELAY: `rejecting`
}
},
accepting: {
invoke: {
id: `acceptOrder`,
src: `acceptOrder`,
onDone: `done`,
onError: [
{
target: `done`
}
]
}
},
rejecting: {
invoke: {
id: `rejectOrder`,
src: `rejectOrder`,
onDone: `done`,
onError: [
{
target: `done`,
actions: (ctx, event) => {
console.log(`ctx: `, ctx)
console.log(`event: `, event)
}
}
]
}
},
done: {
entry: `resetOffer`,
type: `final`
}
}
}
}
}
}
},
{
actions: {
setOffline: assign({
online: () => false,
}),
setOnline: assign({
online: () => true,
}),
setOfferId: assign({
offer: () => ({
acceptedAt: new Date(),
id: 1,
receivedAt: new Date(),
}),
}),
resetOffer: assign({
offer: () => ({
acceptedAt: null,
id: null,
receivedAt: null,
}),
}),
incrementFetchKey: assign({
fetchKey: (ctx) => ctx.fetchKey + 1,
}),
vibrate: () => {
console.log(`vibrate`)
},
cancelVibration: () => {
console.log(`cancelVibration`)
},
},
delays: {
ORDER_DELAY: ctx => {
if (!ctx.time) {
return DEFAULT_WAIT_TIME
}
return Math.floor(ctx.time + DEFAULT_WAIT_TIME - Date.now())
},
},
guards: {
isOffline: ctx => !ctx.online,
isOnline: ctx => ctx.online,
isAssigned: (ctx, event) => ORDER_STATE.IN_PROGRESS === CURRENT_ORDER_STATE,
isDeliveryOrder: (ctx, event) => ORDER_TYPE.DELIVERY === CURRENT_ORDER_TYPE,
isHiredOrder: (ctx, event) => ORDER_TYPE.HIRED === CURRENT_ORDER_TYPE,
doesNotHaveEnoughTimeToAcceptOrder: ({offer: {receivedAt}}) => {
return false
}
}
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment