Skip to content

Instantly share code, notes, and snippets.

@mrsln
Created July 21, 2020 11:24
Show Gist options
  • Save mrsln/8b0b240410cdf453d9eb933cd8f474a1 to your computer and use it in GitHub Desktop.
Save mrsln/8b0b240410cdf453d9eb933cd8f474a1 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const fetchMachine = Machine(
{
initial: "loading",
id: "fetch",
context: {
url: "",
},
states: {
loading: {
invoke: {
src: (context, _) => {
return fetch(context.url, { cache: "no-cache" })
.then((response) =>
Promise.all([Promise.resolve(response), response.json()])
)
.then(([response, body]) => ({ response, body }));
},
onDone: [
{
target: "successFinal",
cond: (_, event) => event.data.response.ok,
actions: assign((_, event) => {
return { body: event.data.body };
}),
},
{
target: "failureFinal",
actions: assign({
error: (_) => "Status code was not between 200-299",
}),
},
],
onError: {
target: "failureFinal",
actions: assign({ error: (_) => "Network error has occurred" }),
},
},
after: {
TIMEOUT_DELAY: {
target: "failureFinal",
actions: assign({
error: (context) =>
`Timeout has occur after waiting for 7000 milliseconds`,
}),
},
},
},
successFinal: {
type: "final",
data: (context, _) => ({ body: context.body }),
},
failureFinal: {
type: "final",
data: (context, _) => ({ error: context.error }),
},
},
},
{
delays: {
TIMEOUT_DELAY: 7000,
},
}
);
const playerMachine = Machine({
initial: "init",
context: {
pin: "",
lastError: "",
},
states: {
init: {
invoke: {
id: "getPin",
src: () => get("pin"),
onDone: [
{ target: "fetchPin", cond: (_context, event) => !event.data },
{ target: "playback", cond: (_context, event) => event.data },
],
onError: {
target: "fail.getPin",
actions: assign({
lastError: (_context, event) => event.data,
}),
},
},
},
fetchPin: {
id: "fetchPin",
invoke: {
src: fetchMachine,
data: {
url:
"https://www.random.org/integers/?num=1&min=1000&max=10000&col=5&base=10&format=plain&rnd=new",
},
onDone: [
{
target: "playback",
cond: (_context, event) => event.data && event.data.body,
actions: assign({ pin: (_context, event) => event.data && event.data.body }),
},
{
target: "fail.fetchPin",
},
],
onError: "fail.fetchPin",
},
},
playback: {
initial: "idle",
states: {
idle: {},
},
on: { TOGGLE_SETTINGS: "settings" },
},
settings: {
initial: "idle",
states: {
idle: {},
},
on: { TOGGLE_SETTINGS: "playback" },
},
fail: {
initial: "general",
meta: { isError: true },
states: {
general: { meta: "An error has happened" },
getPin: { meta: "Reading PIN from idb has failed" },
fetchPin: {
after: {
3000: "#fetchPin",
},
meta: "Getting PIN from the server has failed. Retrying in a moment.",
},
},
},
},
});
async function get() { return null }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment