Skip to content

Instantly share code, notes, and snippets.

@miraklez
Last active October 26, 2020 11:53
Show Gist options
  • Select an option

  • Save miraklez/d8d2062c5f2219b36feedbfae5dcf015 to your computer and use it in GitHub Desktop.

Select an option

Save miraklez/d8d2062c5f2219b36feedbfae5dcf015 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 incrementRetries = assign({
retries: (ctx) => ctx.retries +1
})
const resetRetries = assign({ retries: 0 })
const isAutoConnect = (ctx) => ctx.autoConnect && isMoreRetries(ctx)
const isMoreRetries = ({ retries, maxRetries }) => maxRetries > retries
const PingPongStates = {
id: 'ping-pong',
initial: 'idle',
states: {
idle: {
after: {
PING_DELAY: 'waiting'
}
},
waiting: {
entry: 'sendPing',
on: {
PONG: 'idle',
},
after: {
PONG_TIMEOUT: {
target: '#websocket.failure',
message: 'PING-PONG Timeout'
}
}
}
}
}
const MessagesHandlerStates = {
id: 'messages',
initial: 'idle',
states: {
idle: {}
}
}
const ConnectedParallelStates = {
id: 'connected',
type: 'parallel',
states: {
messages: { ...MessagesHandlerStates },
pingpong: { ...PingPongStates }
}
}
const websocket = Machine({
id: 'websocket',
initial: 'idle',
context: {
url: undefined,
autoConnect: true,
retries: 0,
maxRetries: Infinity
},
states: {
idle: {
on: {
OPEN: {
target: 'connecting',
actions: 'setUrl'
}
}
},
connecting: {
on: {
SUCCESS: 'connected',
ERROR: 'failure'
}
},
connected: {
entry: resetRetries,
...ConnectedParallelStates,
on: {
NORMAL_CLOSE: 'idle',
ERROR: 'failure'
}
},
failure: {
exit: incrementRetries,
on: {
RETRY: {
target: 'connecting',
cond: isMoreRetries
}
},
after: {
AUTO_RETRY_DELAY: {
target: 'connecting',
cond: isAutoConnect
}
}
}
}
},{
delays: {
// linear function depend on number of retries
AUTO_RETRY_DELAY: (ctx, ev) => 1500,
PING_DELAY: () => 10000,
PONG_TIMEOUT: () => 5000
},
actions: {
setUrl: (ctx, ev) => ctx.url = ev.url,
sendPing: () => { console.log('send PING') }
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment