import type { Config, ServiceConfig } from '$lib/config'; import type { AsyncServiceHandler, ServiceData, ServiceHandler } from '$lib/services/service'; import { getServiceHandler } from '$lib/services/services'; import { serverConfig } from './config'; export const serviceData: Array> = []; function isPromise(p: any): boolean { return typeof p === 'object' && typeof p.then === 'function'; } async function pollGeneric(upstream: ServiceData, url: string): Promise { upstream.status = undefined; return fetch(url) .then((resp: Response): ServiceData => { upstream.status = resp.ok ? 'online' : 'offline'; return upstream; }) .catch((error) => { console.warn("could not fetch status for '" + url + "': " + error); upstream.status = 'offline'; return upstream; }); } function wrapHandler(handler: ServiceHandler): AsyncServiceHandler { return async (config: ServiceConfig): Promise => { const value = handler(config); if (isPromise(value) === true) { return (value as Promise) .then((data: ServiceData) => { if (data.status != undefined) { return data; } return pollGeneric(data, config.url); }) .catch((error) => { console.warn("could not resolve service '" + config.url + "': " + error); return pollGeneric({}, config.url); }); } return pollGeneric(value as ServiceData, config.url); }; } function pollServices() { const config: Config = serverConfig(); for (const [i, group] of config.services.entries()) { for (const [j, service] of group.items.entries()) { const handler: ServiceHandler = getServiceHandler(service.type || '') || (() => { return {} as ServiceData; }); wrapHandler(handler)(service).then((data: ServiceData) => { serviceData[i][j] = data; }); } } } export function initializeServiceData() { const config = serverConfig(); serviceData.length = config.services.length; for (let i = 0; i < serviceData.length; i++) { serviceData[i] = []; for (let j = 0; j < config.services[i].items.length; j++) { serviceData[i][j] = {}; } } } export function initServicePolling() { initializeServiceData(); pollServices(); setInterval(pollServices, 30000); }