{"id":38898858,"url":"https://github.com/andyngdz/query-machine","last_synced_at":"2026-01-17T15:01:01.956Z","repository":{"id":40269169,"uuid":"403988709","full_name":"andyngdz/query-machine","owner":"andyngdz","description":"A combination of XState and Axios","archived":false,"fork":false,"pushed_at":"2023-01-07T10:55:58.000Z","size":573,"stargazers_count":0,"open_issues_count":2,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-06T12:48:32.655Z","etag":null,"topics":["ajax","api","axios","machine","query","query-machine","react","rest-api","xstate"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/query-machine","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andyngdz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-07T13:28:09.000Z","updated_at":"2021-10-07T06:31:02.000Z","dependencies_parsed_at":"2023-02-06T23:46:21.451Z","dependency_job_id":null,"html_url":"https://github.com/andyngdz/query-machine","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/andyngdz/query-machine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyngdz%2Fquery-machine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyngdz%2Fquery-machine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyngdz%2Fquery-machine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyngdz%2Fquery-machine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andyngdz","download_url":"https://codeload.github.com/andyngdz/query-machine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyngdz%2Fquery-machine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28510928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T13:38:16.342Z","status":"ssl_error","status_checked_at":"2026-01-17T13:37:44.060Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ajax","api","axios","machine","query","query-machine","react","rest-api","xstate"],"created_at":"2026-01-17T15:00:31.995Z","updated_at":"2026-01-17T15:01:01.935Z","avatar_url":"https://github.com/andyngdz.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cbr /\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/andyngdz/query-machine/main/logo.png\" alt=\"XState\" width=\"96\"/\u003e\n  \u003cbr /\u003e\n    \u003csub\u003e\u003cstrong\u003eA combination of XState and Axios\u003c/strong\u003e\u003c/sub\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n\u003c/p\u003e\n\n[![npm version](https://badge.fury.io/js/query-machine.svg)](https://badge.fury.io/js/query-machine)\n\nquery-machine is a combination of [XState](https://xstate.js.org/) and [Axios](https://axios-http.com/)\n\n### Features\n\n- Provides both XState/Axios by core\n- Returns AxiosInstance and State Machines\n- Reactive, easy to manage states\n\n### Installation\n\nUsing npm:\n\n```\nnpm install query-machine\n```\n\nUsing bower:\n\n```\nbower install query-machine\n```\n\nUsing yarn:\n\n```\nyarn install query-machine\n```\n\n## Quick start\n\n\n### Create a new machine\n```javascript\n// hooks/useQueryMachine.ts\n\nimport { useCreateAxiosQueryMachine } from 'query-machine'\n\nexport const useQueryMachine = () =\u003e {\n  const axiosQueryMachine = useCreateAxiosQueryMachine({\n    baseURL: 'https://dog.ceo/api'\n  })\n\n  // axiosQueryMachine\n  // [IUseQueryMachine, AxiosInstance]\n\n  return axiosQueryMachine\n}\n```\n\n#### Use your own AxiosInstance?\n```javascript\n// hooks/useQueryMachine.ts\n\n// You need to install axios\nimport axios from \"axios\"\nimport { useCreateQueryMachine } from 'query-machine'\n\n// Create a new axios instance\n// Use this instance to config interceptors, etc...\nexport const apiBase = axios.create({ baseURL: 'https://dog.ceo/api' })\n\nexport const useQueryMachine = () =\u003e {\n  const queryMachine = useCreateQueryMachine(apiBase)\n\n  return queryMachine\n}\n```\n\n### Example\n\n```javascript\nimport { useQueryMachine } from 'hooks/useQueryMachine'\n\nexport const Home = () =\u003e {\n  const [queryMachine] = useQueryMachine()\n  const [dogState, { onGet }] = queryMachine\u003cIDogResponse\u003e()\n\n  onGet('/breeds/image/random')\n\n  // Check state, context\n  // isRequest?\n  dogState.matches('request')\n  // Context\n  dogState.context\n  // Data\n  dogState.context.data \u003c- Your data here\n  return ....\n}\n```\n\n#### Checking states\n\n```javascript\nimport { useQueryMachine } from 'hooks/useQueryMachine'\n\nconst [queryMachine] = useQueryMachine()\nconst [dogState, { onGet }] = queryMachine\u003cIDogResponse\u003e()\n\n// Request to get a random image\nonGet('/breeds/image/random')\n\n\n// isFailure?\ndogState.matches('failure')\n// isIdle?\ndogState.matches('idle')\n// isRequest?\ndogState.matches('request')\n// isSuccess?\ndogState.matches('success')\n```\n\n##### Or you can check directly\n\n```javascript\nimport { useQueryMachine } from 'hooks/useQueryMachine'\n\nconst [queryMachine] = useQueryMachine()\nconst [dogState, { isFailure, isIdle, isRequest, isSuccess }] =\n  queryMachine\u003cIDogResponse\u003e()\n```\n\n#### Where are errors?\n\n```javascript\nimport { useQueryMachine } from 'hooks/useQueryMachine'\n\nconst [queryMachine] = useQueryMachine()\nconst [dogState, { onGet, isFailure }] =  queryMachine\u003cIDogResponse\u003e()\n\n// Request to get a random image, but the dog runs away?\nonGet('/breeds/image/random')\n\n// Check status here\ndogState.matches('failure') \u003c- First way to check failure\nisFailure \u003c- Second way to check failure\n\n// Get errors here\ndogState.context.error \u003c- AxiosError\n```\n\n#### Interceptors\n\n```javascript\n// apiBase from hooks\n\n// Add a request interceptor\napiBase.interceptors.request.use(\n  config =\u003e {\n    // Do something before request is sent\n    return config\n  },\n  error =\u003e {\n    // Do something with request error\n    return Promise.reject(error)\n  }\n)\n\n// Add a response interceptor\napiBase.interceptors.response.use(\n  response =\u003e {\n    // Any status code that lie within the range of 2xx cause this function to trigger\n    // Do something with response data\n    return response\n  },\n  error =\u003e {\n    // Any status codes that falls outside the range of 2xx cause this function to trigger\n    // Do something with response error\n    return Promise.reject(error)\n  }\n)\n```\n\n#### Custom request?\n\n```javascript\nimport { useQueryMachine } from 'hooks/useQueryMachine'\n\nconst [queryMachine, apiBase] = useQueryMachine()\nconst [dogState, { send }] = queryMachine\u003cIDogResponse\u003e()\n\n// Send custom request\nsend('REQUEST', {\n  request: () =\u003e {\n    // Do something here?\n    const randomDogImage1 = apiBase.get('/breeds/image/random')\n    // May do something here again?\n\n    return randomDogImage1\n  }\n})\n\n// Your data will be here\ndogState.context.data\n```\n\n##### Multi requests\n\n```javascript\n// Your need to install axios\nimport axios from 'axios'\nimport { useQueryMachine } from 'hooks/useQueryMachine'\n\nconst [queryMachine, apiBase] = useQueryMachine()\nconst [dogState, { send }] = queryMachine\u003cIDogResponse\u003e()\n\n// Send custom request\nsend('REQUEST', {\n  request: () =\u003e {\n    // Do something here?\n    const randomDogImage1 = apiBase.get('/breeds/image/random')\n    const randomDogImage2 = apiBase.get('/breeds/image/random')\n    const randomDogImage3 = apiBase.get('/breeds/image/random')\n    // May do something here again?\n\n    return axios.all([randomDogImage1, randomDogImage2, randomDogImage3])\n  }\n})\n\n// Data will be an array here\ndogState.context.data\n```\n\n### Loader\n```javascript\nimport { MachineLoader } from 'query-machine'\nimport { useQueryMachine } from 'hooks/useQueryMachine'\nimport { useEffectOnce } from 'react-use'\n\nexport const Home = () =\u003e {\n  const [queryMachine] = useQueryMachine()\n  const [dogState, { onGet }] = queryMachine\u003cIDogResponse\u003e()\n\n  useEffectOnce(() =\u003e {\n    onGet('/breeds/image/random')\n  })\n\n  return (\n    \u003cMachineLoader\n      state={dogState}\n      onLoading={() =\u003e // Your custom loading component, or you don't need to use this}\n      onBuilder={data =\u003e {\n        const { message } = data\n        return \u003cdiv\u003e{message}\u003c/div\u003e\n      }}\n    /\u003e\n  )\n}\n```\n\n### Additional information\n\n```javascript\n// AxiosError\n\nexport interface AxiosError\u003cT = any\u003e extends Error {\n  config: AxiosRequestConfig;\n  code?: string;\n  request?: any;\n  response?: AxiosResponse\u003cT\u003e;\n  isAxiosError: boolean;\n  toJSON: () =\u003e object;\n}\n```\n\n```json\n// AxiosResponse\n\n{\n  \"url\": \"/breeds/image/random\",\n  \"method\": \"get\",\n  \"headers\": {\n    \"Accept\": \"application/json, text/plain, */*\"\n  },\n  \"baseURL\": \"https://dog.ceo/api\",\n  \"transformRequest\": [null],\n  \"transformResponse\": [null],\n  \"timeout\": 0,\n  \"xsrfCookieName\": \"XSRF-TOKEN\",\n  \"xsrfHeaderName\": \"X-XSRF-TOKEN\",\n  \"maxContentLength\": -1,\n  \"maxBodyLength\": -1,\n  \"transitional\": {\n    \"silentJSONParsing\": true,\n    \"forcedJSONParsing\": true,\n    \"clarifyTimeoutError\": false\n  }\n}\n```\n\n```json\n// AxiosResponse[]\n\n[\n  {\n    \"data\": {\n      \"message\": \"https://images.dog.ceo/breeds/pitbull/20190801_154956.jpg\",\n      \"status\": \"success\"\n    },\n    \"status\": 200,\n    \"statusText\": \"\",\n    \"headers\": {\n      \"cache-control\": \"no-cache, private\",\n      \"content-type\": \"application/json\"\n    },\n    \"config\": {\n      \"url\": \"/breeds/image/random\",\n      \"method\": \"get\",\n      \"headers\": {\n        \"Accept\": \"application/json, text/plain, */*\"\n      },\n      \"baseURL\": \"https://dog.ceo/api\",\n      \"transformRequest\": [null],\n      \"transformResponse\": [null],\n      \"timeout\": 0,\n      \"xsrfCookieName\": \"XSRF-TOKEN\",\n      \"xsrfHeaderName\": \"X-XSRF-TOKEN\",\n      \"maxContentLength\": -1,\n      \"maxBodyLength\": -1,\n      \"transitional\": {\n        \"silentJSONParsing\": true,\n        \"forcedJSONParsing\": true,\n        \"clarifyTimeoutError\": false\n      }\n    },\n    \"request\": {}\n  },\n  {\n    \"data\": {\n      \"message\": \"https://images.dog.ceo/breeds/retriever-golden/Z6A_4500_200808.jpg\",\n      \"status\": \"success\"\n    },\n    \"status\": 200,\n    \"statusText\": \"\",\n    \"headers\": {\n      \"cache-control\": \"no-cache, private\",\n      \"content-type\": \"application/json\"\n    },\n    \"config\": {\n      \"url\": \"/breeds/image/random\",\n      \"method\": \"get\",\n      \"headers\": {\n        \"Accept\": \"application/json, text/plain, */*\"\n      },\n      \"baseURL\": \"https://dog.ceo/api\",\n      \"transformRequest\": [null],\n      \"transformResponse\": [null],\n      \"timeout\": 0,\n      \"xsrfCookieName\": \"XSRF-TOKEN\",\n      \"xsrfHeaderName\": \"X-XSRF-TOKEN\",\n      \"maxContentLength\": -1,\n      \"maxBodyLength\": -1,\n      \"transitional\": {\n        \"silentJSONParsing\": true,\n        \"forcedJSONParsing\": true,\n        \"clarifyTimeoutError\": false\n      }\n    },\n    \"request\": {}\n  }\n]\n```\n\n### Credits\n\nA special thanks to [XState](https://xstate.js.org/) and [Axios](https://axios-http.com/)\n\n### License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyngdz%2Fquery-machine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandyngdz%2Fquery-machine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyngdz%2Fquery-machine/lists"}