const HOST = 'https://api.getkoala.com' function getBaseUrl(property = 'host') { if (typeof globalThis !== 'undefined' && globalThis.koalaSettings) { return globalThis.koalaSettings[property as 'host' | 'wssHost'] || globalThis.koalaSettings.host || HOST } return HOST } export const BASE_URL = getBaseUrl('host') export const BASE_WSS_URL = getBaseUrl('wssHost') export function post(path: string, body: string | object) { return fetch(`${BASE_URL}${path}`, { method: 'POST', body: typeof body === 'string' ? body : JSON.stringify(body), keepalive: true, headers: { 'Content-Type': 'application/json' } }) } export function fetchJson(path: string) { return fetch(`${BASE_URL}${path}`).then((res) => { if (!res.ok) { throw new Error(`${res.status} ${res.statusText}`) } return res.json() }) } // https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch const send = navigator.sendBeacon && navigator.sendBeacon.bind(navigator) function maybeBeacon(path: string, body: string) { if (send) { try { return send(`${BASE_URL}${path}`, body) } catch (_ignored) { // do nothing } } return false } export function sendBeacon(path: string, data: object) { const body = JSON.stringify(data) // if beacon isn't supported, or if it returns false, fallback to a regular fetch request return ( maybeBeacon(path, body) || post(path, body) .then(() => true) .catch(() => false) ) }