export const fetchMixin = function(superClass) { return class extends superClass { constructor() { super(); this.__abortControllers = new Map(); } get(url, overwrite = true) { return this.do('GET', url, null, overwrite); } head(url) { return fetch(url, { method: 'HEAD' }); } post(url, data, overwrite = true) { return this.do('POST', url, data, overwrite); } async do(method, url, data, overwrite = true) { this.__cancelRunningRequest(method, url); if (overwrite === true) { const ac = new AbortController(); this.__abortControllers.set(`${method}:${url}`, ac); } try { const reqOptions = { method, signal: overwrite ? this.__abortControllers.get(`${method}:${url}`).signal : null, mode: 'cors', cache: 'no-cache', headers: { 'Content-Type': 'application/json; charset=utf-8' }, referrer: 'no-referrer', body: data ? JSON.stringify(data) : undefined }; document.dispatchEvent(new CustomEvent('before-request', { detail: reqOptions, bubbles: true, composed: true })); const resp = await fetch(url, reqOptions); this.__abortControllers.delete(`${method}:${url}`); if (resp.status === 500) { console.error(resp); } if (resp.status !== 200) { document.dispatchEvent(new CustomEvent('request-error', { detail: resp, bubbles: true, composed: true })); } return await resp.json(); } catch (err) { if (err.name === 'AbortError') { return { statusCode: -1, error: err }; } else { this.__abortControllers.delete(`${method}:${url}`); return { statusCode: null, error: err }; } } } isInFlight(method, url) { if (url === undefined) { console.error('Missing url parameter'); return false; } return Boolean(this.__abortControllers.get(`${method}:${url}`)); } __cancelRunningRequest(method, url) { if (this.__abortControllers.has(`${method}:${url}`)) { try { this.__abortControllers.get(`${method}:${url}`).abort(); } catch (err) { } this.__abortControllers.delete(`${method}:${url}`); } } }; };