{"version":3,"file":"xhrFetch.mjs","sources":["../src/xhrFetch.js"],"sourcesContent":["const XHR_READY_STATE = {\n  // Client has been created. open() not called yet.\n  UNSENT: 0,\n  // open() has been called.\n  OPENED: 1,\n  // send() has been called, and headers and status are available.\n  HEADERS_RECEIVED: 2,\n  // Downloading; responseText holds partial data.\n  LOADING: 3,\n  // The operation is complete.\n  DONE: 4,\n};\n\nconst noop = () => {};\n\nconst isInRange = (num, begin, end) => num >= begin && num <= end;\n\n// https://github.com/github/fetch/blob/master/fetch.js#L368-L382\nconst parseHeaders = (rawHeaders = '') => {\n  const headers = new Headers();\n  // Replace instances of \\r\\n and \\n followed by at least one space or horizontal tab with a space\n  // https://tools.ietf.org/html/rfc7230#section-3.2\n  const preProcessedHeaders = rawHeaders.replace(/\\r?\\n[\\t ]+/g, ' ');\n  preProcessedHeaders.split(/\\r?\\n/).forEach((line) => {\n    const parts = line.split(':');\n    const key = parts.shift().trim();\n    if (key) {\n      const value = parts.join(':').trim();\n      headers.append(key, value);\n    }\n  });\n  return headers;\n};\n\nconst DEFAULT_CONFIG = {\n  method: 'GET',\n  headers: {},\n  body: null,\n  onDownloadProgress: noop,\n  onUploadProgress: noop,\n  signal: null,\n  credentials: null,\n};\n\nconst createFetchishResponse = (xhr) => {\n  const {\n    response,\n    responseText,\n    responseURL,\n    status,\n    statusText,\n  } = xhr;\n\n  const blob = () => Promise.resolve(new Blob([response]));\n  const json = () => Promise.resolve(JSON.parse(responseText));\n  const text = () => Promise.resolve(responseText);\n\n  const clone = () => createFetchishResponse(xhr);\n\n  const headers = parseHeaders(xhr.getAllResponseHeaders());\n  const url = responseURL || headers.get('X-Request-URL');\n\n  return {\n    blob,\n    clone,\n    headers,\n    json,\n    ok: isInRange(status, 200, 299),\n    status,\n    statusText,\n    text,\n    url,\n  };\n};\n\nconst xhrFetch = (endpoint, {\n  method = 'GET',\n  headers = {},\n  body = null,\n  onDownloadProgress = noop,\n  onUploadProgress = noop,\n  signal,\n  credentials = null,\n} = DEFAULT_CONFIG) => new Promise((resolve, reject) => {\n  const xmlHttpRequest = new XMLHttpRequest();\n\n  const abortXhr = () => {\n    xmlHttpRequest.abort();\n  };\n\n  if (signal) {\n    signal.addEventListener('abort', abortXhr);\n  }\n\n  xmlHttpRequest.open(method.toLowerCase(), endpoint, true);\n\n  // IE10 assumes `withCredentials` is set after `open()` is called.\n  if (credentials === 'include') {\n    xmlHttpRequest.withCredentials = true;\n  }\n\n  if (credentials === 'omit') {\n    xmlHttpRequest.withCredentials = false;\n  }\n\n  Object.keys(headers).forEach(key => xmlHttpRequest.setRequestHeader(key, headers[key]));\n\n  // TODO switch from DOM Level 2 events to using Level 0 events for browser compatibility\n  xmlHttpRequest.addEventListener('readystatechange', () => {\n    if (xmlHttpRequest.readyState === XHR_READY_STATE.DONE) {\n      // https://xhr.spec.whatwg.org/#the-abort()-method\n      if (signal) {\n        signal.removeEventListener('abort', abortXhr);\n      }\n    }\n  });\n\n  xmlHttpRequest.addEventListener('error', () => {\n    reject(new TypeError('Network request failed'));\n  });\n\n  xmlHttpRequest.addEventListener('timeout', () => {\n    reject(new TypeError('Network request failed'));\n  });\n\n  xmlHttpRequest.addEventListener('abort', () => {\n    reject(new DOMException('Aborted', 'AbortError'));\n  });\n\n  xmlHttpRequest.addEventListener('load', () => {\n    // Handle errors just like `fetch` does. So we resolve all upstream errors, and only throw\n    // network errors which are handled in the error event listener.\n    resolve(createFetchishResponse(xmlHttpRequest));\n  });\n\n  /* download */\n  xmlHttpRequest.addEventListener('progress', xhrEvent => onDownloadProgress(xhrEvent));\n\n  /* upload */\n  xmlHttpRequest.upload.addEventListener('progress', xhrEvent => onUploadProgress(xhrEvent));\n\n  xmlHttpRequest.send(body);\n});\n\nexport default xhrFetch;\n"],"names":["const","noop","DEFAULT_CONFIG","method","headers","body","onDownloadProgress","onUploadProgress","signal","credentials","createFetchishResponse","xhr","num","rawHeaders","Headers","replace","split","forEach","line","parts","key","shift","trim","value","join","append","parseHeaders","getAllResponseHeaders","url","responseURL","get","Promise","resolve","Blob","response","JSON","parse","responseText","ok","status","statusText","endpoint","ref","reject","xmlHttpRequest","XMLHttpRequest","abortXhr","abort","addEventListener","open","toLowerCase","withCredentials","Object","keys","setRequestHeader","readyState","removeEventListener","TypeError","DOMException","xhrEvent","upload","send"],"mappings":"AAAAA,IAaMC,eAqBAC,EAAiB,CACrBC,OAAQ,MACRC,QAAS,GACTC,KAAM,KACNC,mBAAoBL,EACpBM,iBAAkBN,EAClBO,OAAQ,KACRC,YAAa,MAGTC,WAA0BC,OA7BbC,0EA4CXR,WAzCcS,kBAAa,QAC3BT,EAAU,IAAIU,eAGQD,EAAWE,QAAQ,eAAgB,KAC3CC,MAAM,SAASC,iBAASC,OACpCC,EAAQD,EAAKF,MAAM,KACnBI,EAAMD,EAAME,QAAQC,UACtBF,EAAK,KACDG,EAAQJ,EAAMK,KAAK,KAAKF,OAC9BlB,EAAQqB,OAAOL,EAAKG,MAGjBnB,EA4BSsB,CAAaf,EAAIgB,yBAC3BC,EAAMC,GAAezB,EAAQ0B,IAAI,uBAEhC,wBATYC,QAAQC,QAAQ,IAAIC,KAAK,CAACC,8BAIzBxB,EAAuBC,YAQzCP,yBAXiB2B,QAAQC,QAAQG,KAAKC,MAAMC,KAa5CC,IApDe1B,EAoDD2B,EApDqB3B,GAoDb,KApD6BA,GAoDxB,YAC3B2B,aACAC,yBAdiBT,QAAQC,QAAQK,QAgBjCT,4BAIca,EAAUC,kBAQxBxC,iCAPO,sCACC,gCACH,gDACcD,2CACFA,wDAEL,MACO,IAAI8B,iBAASC,EAASW,OACrCC,EAAiB,IAAIC,eAErBC,aACJF,EAAeG,SAGbvC,GACFA,EAAOwC,iBAAiB,QAASF,GAGnCF,EAAeK,KAAK9C,EAAO+C,cAAeT,GAAU,GAGhC,YAAhBhC,IACFmC,EAAeO,iBAAkB,GAGf,SAAhB1C,IACFmC,EAAeO,iBAAkB,GAGnCC,OAAOC,KAAKjD,GAASa,iBAAQG,UAAOwB,EAAeU,iBAAiBlC,EAAKhB,EAAQgB,MAGjFwB,EAAeI,iBAAiB,8BAlG1B,IAmGAJ,EAAeW,YAEb/C,GACFA,EAAOgD,oBAAoB,QAASV,KAK1CF,EAAeI,iBAAiB,mBAC9BL,EAAO,IAAIc,UAAU,6BAGvBb,EAAeI,iBAAiB,qBAC9BL,EAAO,IAAIc,UAAU,6BAGvBb,EAAeI,iBAAiB,mBAC9BL,EAAO,IAAIe,aAAa,UAAW,iBAGrCd,EAAeI,iBAAiB,kBAG9BhB,EAAQtB,EAAuBkC,MAIjCA,EAAeI,iBAAiB,oBAAYW,UAAYrD,EAAmBqD,KAG3Ef,EAAegB,OAAOZ,iBAAiB,oBAAYW,UAAYpD,EAAiBoD,KAEhFf,EAAeiB,KAAKxD"}