Skip to content

Instantly share code, notes, and snippets.

@Colubi
Created December 18, 2019 11:07
Show Gist options
  • Save Colubi/2f901b7a155b38624936f0e7850dddf9 to your computer and use it in GitHub Desktop.
Save Colubi/2f901b7a155b38624936f0e7850dddf9 to your computer and use it in GitHub Desktop.

Revisions

  1. Colubi created this gist Dec 18, 2019.
    78 changes: 78 additions & 0 deletions machine.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    const allowRetry = (retries, maxRetries) => retries < maxRetries;
    const FetchMachine = Machine({
    id: "fetch",
    initial: "idle",
    context: {
    request: null,
    data: null,
    error: null,
    retries: 0,
    maxRetries: 0,
    },
    states: {
    idle: {
    on: {
    FETCH: "pending",
    },
    },
    pending: {
    invoke: {
    src: "fetch",
    onDone: {
    target: "success",
    actions: ["setData", "notifySuccess"],
    },
    onError: {
    target: "failure",
    actions: ["setError", "notifyError"],
    },
    },
    },
    failure: {
    on: {
    "": {
    target: "finalFailure",
    cond: "canNotRetry",
    },
    RETRY: {
    target: "pending",
    actions: "incrementRetries",
    },
    },
    },
    finalFailure: {
    on: {},
    type: "final",
    },
    success: {
    on: {
    REFRESH: {
    target: "pending",
    actions: "resetRetries",
    },
    },
    },
    },
    }, {
    guards: {
    canNotRetry: ({ retries, maxRetries }) => !allowRetry(retries, maxRetries),
    },
    actions: {
    setData: assign({ data: (_, event) => event.data }),
    setError: assign({ error: (_, event) => event.data.message }),
    incrementRetries: assign({ retries: context => context.retries + 1 }),
    resetRetries: assign({ retries: context => 0 }),
    notifySuccess: context => { },
    notifyError: context => { },
    },
    services: {
    fetch: async ({ request }) => {
    if (!request) {
    throw new Error("Machine must receive a valid request object in context");
    }
    const response = await request();
    return response.data;
    },
    },
    });