Skip to content

Instantly share code, notes, and snippets.

@reid
Created November 17, 2020 18:57
Show Gist options
  • Save reid/01e0ed59fa79e729c436eed690ccc594 to your computer and use it in GitHub Desktop.
Save reid/01e0ed59fa79e729c436eed690ccc594 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 fetchMachine = Machine({
id: 'webpush',
initial: 'unsubscribed',
context: {apiRequests: 0},
states: {
unsubscribed: {
entry: 'resetApiRequestCounter',
on: {
SUBSCRIBE: [
{
target: 'subscribe',
cond: 'subscriptionDoesNotExist'
},
{
target: 'startOver',
cond: 'registrationIsMissing'
},
{
target: 'updateRegistration',
cond: 'subscriptionEndpointIsStale'
},
{
target: 'updateAssociation',
cond: 'associationIsStale'
},
{target: 'addRegistration'}
]
}
},
startOver: {
invoke: {
src: 'unsubscribe',
onDone: {
target: 'subscribe',
actions: 'clearSubscription'
},
onError: 'failed'
}
},
unsubscribe: {
invoke: {
src: 'unsubscribe',
onDone: [
{target: 'failed', cond: 'requestCountOverLimit'},
{
target: 'deleteAssociation',
actions: 'clearSubscription'
}
],
onError: 'failed'
}
},
deleteAssociation: {
exit: 'clearRegistrationId',
invoke: {
src: 'deleteAssociation',
onDone: {
target: 'unsubscribed'
},
onError: {
// log also?
target: 'unsubscribed'
}
}
},
subscribe: {
invoke: {
src: 'subscribe',
onDone: {
target: 'addRegistration',
actions: assign({
subscription: (_, event) => event.data
})
},
onError: 'failed'
}
},
addRegistration: {
invoke: {
src: 'addRegistration',
onDone: {
target: 'addAssociation',
actions: assign({
registrationId: (_, event) => event.data.registrationId
})
},
onError: 'failed'
}
},
updateRegistration: {
invoke: {
src: 'updateRegistration',
onDone: 'updateAssociation',
onError: [
{
target: 'subscribe',
cond: 'failedBecauseRegistrationDoesNotExist'
},
{target: 'failed'}
]
}
},
addAssociation: {
invoke: {
src: 'addAssociation',
onDone: 'complete',
onError: [
{
target: 'failed',
cond: 'requestCountOverLimit'
},
{
target: 'updateAssociation',
cond: 'failedBecauseAssociationDoesNotExist'
},
{target: 'failed'}
]
}
},
updateAssociation: {
invoke: {
src: 'updateAssociation',
onDone: 'complete',
onError: [
{
target: 'failed',
cond: 'requestCountOverLimit'
},
{
target: 'addRegistration',
cond: 'failedBecauseRegistrationDoesNotExist'
},
{
target: 'addAssociation',
cond: 'failedBecauseAssociationDoesNotExist'
},
{target: 'failed'}
]
}
},
failed: {
type: 'final'
},
complete: {
entry: ['updateSubscriptionTimestamp'],
invoke: {
src: 'saveContextToStorage',
onDone: {
target: 'processPermissionGrant',
cond: 'previousPermissionStateWasNotGranted'
},
onError: 'failed'
}
},
processPermissionGrant: {
invoke: {
src: 'onGrantedPermissions',
onDone: 'subscribed',
onError: 'failed'
}
},
subscribed: {
type: 'final'
}
}
},
{
actions: {
clearRegistrationId: assign({registrationId: null}),
clearSubscription: assign({subscription: null}),
resetApiRequestCounter: assign({apiRequests: 0}),
updateSubscriptionTimestamp: assign({subscriptionTimestamp: Date.now()})
},
services: {
onGrantedPermissions: () => Promise.resolve(),
subscribe: () => {},
unsubscribe: () => {},
addRegistration: () => {},
updateRegistration: () => {},
addAssociation: () => {},
updateAssociation: () => {},
deleteAssociation: () => {},
saveContextToStorage: () => {}
},
guards: {
subscriptionDoesNotExist: () => {},
registrationIsMissing: () => {},
associationIsStale: () => {},
subscriptionEndpointIsStale: () => {},
failedBecauseRegistrationDoesNotExist: () => {},
failedBecauseAssociationDoesNotExist: () => {},
failedBecauseAssociationAlreadyExists: () => {},
previousPermissionStateWasNotGranted: () => {},
requestCountUnderLimit: () => {}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment