2026-06-10 12:49:43 +08:00
|
|
|
// src/http.js
|
|
|
|
|
(function(global) {
|
|
|
|
|
const { Component, NewState } = global;
|
2026-05-14 20:04:31 +08:00
|
|
|
|
2026-06-10 12:49:43 +08:00
|
|
|
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)
|
2026-05-14 20:04:31 +08:00
|
|
|
|
2026-06-10 12:49:43 +08:00
|
|
|
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);
|