Skip to content

Instantly share code, notes, and snippets.

@markbjerke
Last active June 10, 2020 16:43
Show Gist options
  • Save markbjerke/d3f26dc377768a2b85c64c99c72db755 to your computer and use it in GitHub Desktop.
Save markbjerke/d3f26dc377768a2b85c64c99c72db755 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 url = "localhost:8080/status";
const options = {};
const timeoutMs = 10 * 1000;
const requestId = 'request_id_0';
const lightMachine = Machine({
id: 'txrequest',
context: {
request: {
url,
options,
timeoutMs
},
response: undefined
},
initial: 'pending',
states: {
pending: {
on: {
FETCH: 'loading'
}
},
loading: {
invoke: {
id: `${requestId}`,
src: (context, event) => new Promise( async(resolve, reject) => {
const timeout = setTimeout(() => {didTimeout = true; reject(new TXTimeout(requestId))}, timeoutMs);
fetch(url, options).then((response) => {
clearTimeout(timeout);
if(!didTimeOut) {
resolve(response);
}
})
.catch((error) => { // only rejects if request wasn't sent; e.g. security/cors
if(!didTimeOut)
reject(error);
});
}),
onDone: {
target: 'response',
actions: assign((context, event) => {
context.response = event.response
})
},
onError: [
{ target: 'rejected.timeout', cond: 'isTimeout' },
{ target: 'rejected.notsent' }
]
},
on: {
CANCEL: 'pending'
}
},
response: { // transient state; evaluates the response and moves to resolved...
on: {
'': [
{ target: 'resolved.http_404', cond: 'isHttp404' },
{ target: 'resolved.http_401', cond: 'isHttp401' },
{ target: 'resolved.invalidStatusCode', cond: 'isInvalidStatusCode' },
{ target: 'resolved.success' }
]
}
},
resolved: {
states: {
success: {
type: 'final',
meta: {
message: 'The request succeeded!'
}
},
http_404: {
type: 'final',
meta: {
message: `The resource ${url} was not found.`
}
},
http_401: {
type: 'final',
meta: {
message: `The request failed authentication.`
}
},
invalidStatusCode: {
type: 'final',
meta: {
message: `The request failed, http status is not in range 200-299 inclusive.`
}
}
}
},
rejected: {
states: {
timeout: {
final: true,
meta: {
message: 'The request timed out.'
}
},
notsent: {
type: 'final',
meta: {
message: 'The request failed to send.'
}
}
}
}
}
},
{
guards: {
isTimeout: (context, event) => {
return event instanceof TXTimeout;
},
isHttp404: (context, event) => {
return 404 === context.response.status;
},
isHttp401: (context, event) => {
return 401 === context.response.status;
},
isInvalidStatusCode: (context, event) => {
return !context.response.status.ok;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment