graphql-hooks-with-get-support
Version:
2 lines (1 loc) • 6.45 kB
JavaScript
import e from"react";const r=e.createContext();r.displayName="ClientContext";var t=function(e){var r=e.name,t=e.type;this.uri=e.uri,this.name=r,this.type=t};class o{constructor(e={}){if(!e.url)throw Error("GraphQLClient: config.url is required");if(e.fetch&&"function"!=typeof e.fetch)throw Error("GraphQLClient: config.fetch must be a function");if(!e.fetch&&!fetch)throw Error("GraphQLClient: fetch must be polyfilled or passed in new GraphQLClient({ fetch })");if(e.ssrMode&&!e.cache)throw Error("GraphQLClient: config.cache is required when in ssrMode");this.cache=e.cache,this.headers=e.headers||{},this.ssrMode=e.ssrMode,this.ssrPromises=[],this.url=e.url,this.fetch=e.fetch||fetch.bind(),this.fetchOptions=e.fetchOptions||{},this.logErrors=void 0===e.logErrors||e.logErrors,this.onError=e.onError}setHeader(e,r){return this.headers[e]=r,this}setHeaders(e){return this.headers=e,this}removeHeader(e){return delete this.headers[e],this}logErrorResult({result:e,operation:r}){if(this.onError)return this.onError({result:e,operation:r});console.error("GraphQL Hooks Error"),console.groupCollapsed("---\x3e Full Error Details"),console.groupCollapsed("Operation:"),console.log(r),console.groupEnd(),e.fetchError&&(console.groupCollapsed("FETCH ERROR:"),console.log(e.fetchError),console.groupEnd()),e.httpError&&(console.groupCollapsed("HTTP ERROR:"),console.log(e.httpError),console.groupEnd()),e.graphQLErrors&&e.graphQLErrors.length>0&&(console.groupCollapsed("GRAPHQL ERROR:"),e.graphQLErrors.forEach(e=>console.log(e)),console.groupEnd()),console.groupEnd()}generateResult({fetchError:e,httpError:r,graphQLErrors:t,data:o}){return{error:!!(t&&t.length>0||e||r),fetchError:e,httpError:r,graphQLErrors:t,data:o}}getCacheKey(e,r={}){return{operation:e,fetchOptions:{...this.fetchOptions,...r.fetchOptionsOverrides}}}getCache(e){const r=this.cache?this.cache.get(e):null;if(r)return r}saveCache(e,r){this.cache&&this.cache.set(e,r)}getFetchOptions(e,r={}){const o={method:"POST",headers:{...this.headers},...this.fetchOptions,...r},{clone:s,files:n}=function e(r,o){var s;void 0===o&&(o="");var n=new Map;function a(e,r){var t=n.get(r);t?t.push.apply(t,e):n.set(r,e)}if("undefined"!=typeof File&&r instanceof File||"undefined"!=typeof Blob&&r instanceof Blob||r instanceof t)s=null,a([o],r);else{var i=o?o+".":"";if("undefined"!=typeof FileList&&r instanceof FileList)s=Array.prototype.map.call(r,(function(e,r){return a([""+i+r],e),null}));else if(Array.isArray(r))s=r.map((function(r,t){var o=e(r,""+i+t);return o.files.forEach(a),o.clone}));else if(r&&r.constructor===Object)for(var c in s={},r){var u=e(r[c],""+i+c);u.files.forEach(a),s[c]=u.clone}else s=r}return{clone:s,files:n}}(e),a=JSON.stringify(s);if(n.size){const e=new FormData;e.append("operations",a);const r={};let t=0;n.forEach(e=>{r[++t]=e}),e.append("map",JSON.stringify(r)),t=0,n.forEach((r,o)=>{e.append(`${++t}`,o,o.name)}),o.body=e}else o.headers["Content-Type"]="application/json","POST"==o.method&&(o.body=a);return o}request(e,r={}){var t=this.url;if(void 0!==r.fetchOptionsOverrides&&"GET"==r.fetchOptionsOverrides.method){var o={query:e.query,variables:JSON.stringify(e.variables)};t=t+"?"+Object.entries(o).map(([e,r])=>`${e}=${encodeURIComponent(r)}`).join("&")}return this.fetch(t,this.getFetchOptions(e,r.fetchOptionsOverrides)).then(e=>e.ok?e.json().then(({errors:e,data:r})=>this.generateResult({graphQLErrors:e,data:r})):e.text().then(r=>{const{status:t,statusText:o}=e;return this.generateResult({httpError:{status:t,statusText:o,body:r}})})).catch(e=>this.generateResult({fetchError:e})).then(r=>(r.error&&this.logErrors&&this.logErrorResult({result:r,operation:e}),r))}}const s={RESET_STATE:"RESET_STATE",LOADING:"LOADING",CACHE_HIT:"CACHE_HIT",REQUEST_RESULT:"REQUEST_RESULT"};function n(e,r){switch(r.type){case s.RESET_STATE:return r.initialState;case s.LOADING:return e.loading?e:{...e,loading:!0};case s.CACHE_HIT:return e.cacheHit?e:{...r.result,cacheHit:!0,loading:!1};case s.REQUEST_RESULT:return{...r.result,data:e.data&&r.result.data&&r.updateData?r.updateData(e.data,r.result.data):r.result.data,cacheHit:!1,loading:!1};default:return e}}function a(r,t){const o=e.useRef();return function e(r,t){var o,s;if(r===t)return!0;if(r&&t&&(o=r.constructor)===t.constructor){if(o===Date)return r.getTime()===t.getTime();if(o===RegExp)return""+r==""+t;if(o===Array&&(s=r.length)===t.length){for(;s--&&e(r[s],t[s]););return-1===s}if(o===Object){if(Object.keys(r).length!==Object.keys(t).length)return!1;for(s in r)if(!(s in t&&e(r[s],t[s])))return!1;return!0}}return r!=r&&t!=t}(t,o.current)||(o.current=t),e.useCallback(r,o.current)}function i(t,o={}){if("string"!=typeof t)throw Error("Your query must be a string. If you are using the `gql` template literal from graphql-tag, remove it from your query.");const i=e.useContext(r),c=e.useRef(!0),u=e.useRef(null),h={query:t,variables:o.variables,operationName:o.operationName},l=i.getCacheKey(h,o),f=o.isMutation||o.isManual,p=o.skipCache||!i.cache?null:i.cache.get(l),d={...p,cacheHit:!!p,loading:!f&&!p},[E,g]=e.useReducer(n,d),y=JSON.stringify(l);e.useEffect(()=>{o.updateData||g({type:s.RESET_STATE,initialState:d})},[y]),e.useEffect(()=>(c.current=!0,()=>{c.current=!1}),[]);const C=a(e=>{if(!c.current)return Promise.resolve();const r={...o,...e},t={...h,variables:r.variables,operationName:r.operationName},n=i.getCacheKey(t,r);u.current=n;const a=r.skipCache?null:i.getCache(n);return a?(g({type:s.CACHE_HIT,result:a}),Promise.resolve(a)):(g({type:s.LOADING}),i.request(t,r).then(e=>{if(r.updateData&&"function"!=typeof r.updateData)throw Error("options.updateData must be a function");const t={...e};return r.useCache&&(t.useCache=!0,t.cacheKey=n),c.current&&n===u.current&&g({type:s.REQUEST_RESULT,updateData:r.updateData,result:t}),e}))},[i,o,h]);return e.useEffect(()=>{E.useCache&&i.saveCache(E.cacheKey,E)},[i,E]),[C,E]}const c={useCache:!0};function u(t,o={}){const s={...c,...o},n=e.useContext(r),[a,u]=e.useState(!1),[h,l]=i(t,s);if(n.ssrMode&&!1!==o.ssr&&!a){if(!l.loading&&!l.data&&!l.error){const e=h();n.ssrPromises.push(e)}u(!0)}const f=JSON.stringify(s);return e.useEffect(()=>{h()},[t,f]),{...l,refetch:e.useCallback((e={})=>h({skipCache:!0,updateData:(e,r)=>r,...e}),[h])}}const h=(e,r)=>i(e,{useCache:!0,isManual:!0,...r}),l=(e,r)=>i(e,{isMutation:!0,...r});export{r as ClientContext,o as GraphQLClient,i as useClientRequest,h as useManualQuery,l as useMutation,u as useQuery};