// src/http.js (function(global) { const { Component, NewState } = global; const HTTP = { get: ({ url, ...opt }) => HTTP.request({ url, method: 'GET', ...opt }), post: ({ url, data, ...opt }) => HTTP.request({ url, method: 'POST', data, ...opt }), put: ({ url, data, ...opt }) => HTTP.request({ url, method: 'PUT', data, ...opt }), delete: ({ url, ...opt }) => HTTP.request({ url, method: 'DELETE', ...opt }), head: ({ url, ...opt }) => HTTP.request({ url, method: 'HEAD', ...opt }), request: async ({ url, method = 'POST', data = undefined, headers = {}, responseType, timeout = 10000 }) => { method = method.toUpperCase() const opt = { method, headers: { 'Content-Type': 'application/json', ...headers } } if (data !== undefined) opt.body = JSON.stringify(data) const controller = new AbortController() const timer = setTimeout(() => controller.abort(), timeout) opt.signal = controller.signal try { const response = await fetch(url, opt) clearTimeout(timer) const result = responseType === 'blob' ? await response.blob() : (responseType === 'text' ? await response.text() : await response.json()) return { ok: response.ok, status: response.status, result } } catch (err) { clearTimeout(timer) return { ok: false, status: 0, error: err.message } } } }; Component.register('API', container => { if (!container.state.request) container.state.request = { url: '', method: 'GET', data: {}, noui: false } if (!container.state.response) container.state.response = { ok: false, status: 0, result: null, loading: false } container.do = async (req) => { const opt = { ...container.state.request, ...req } container.state.response.loading = true const resp = await HTTP.request(opt) Object.assign(container.state.response, resp, { loading: false }) if (!resp.ok) { if (!opt.noui && global.UI?.toast) global.UI.toast(resp.error || 'Request failed', { type: 'danger' }) } container.dispatchEvent(new CustomEvent('success', { bubbles: false, detail: resp.result })) return resp } let _autoTimer = null container.state.request.__watch(null, () => { if (!container.hasAttribute('auto') || !container.state.request.url) return if (_autoTimer) return _autoTimer = Promise.resolve().then(() => { container.do() _autoTimer = null }) }) }); global.HTTP = HTTP; })(globalThis);