base/src/API.js

45 lines
2.6 KiB
JavaScript
Raw Normal View History

/**
* API Component Module
*/
const APIComponent = globalThis.Component.register('API', container => {
container.request = globalThis.NewState({ url: '', method: 'GET', headers: {}, data: null, timeout: 10000, responseType: '' })
container.response = globalThis.NewState({ loading: false, ok: null, status: null, error: null, headers: {}, responseType: '', result: null })
container.result = globalThis.NewState()
container.do = (opt = {}) => {
return new Promise((resolve, reject) => {
const req = { ...container.request, ...opt }
if (!req.url) throw new Error('.url is required')
req.headers = { ...container.request.headers, ...opt.headers }
container.response.loading = true
globalThis.HTTP.request(req).then(resp => {
Object.keys(resp).forEach(k => { if (k !== 'result') container.response[k] = resp[k] })
if (resp.result && typeof resp.result === 'object' && container.result && typeof container.result === 'object') {
Object.assign(container.result, resp.result)
} else {
container.result = resp.result
}
container.response.loading = false
if (resp.ok === false) throw new Error(resp.error)
if (typeof resp.result === 'object' && resp.result.error) throw new Error(resp.result.error)
container.dispatchEvent(new CustomEvent('response', { detail: resp, bubbles: false }))
resolve(resp)
}).catch(err => {
if (!opt.noui && globalThis.UI?.toast) globalThis.UI.toast(err.message, { type: 'danger' })
container.dispatchEvent(new CustomEvent('error', { detail: err, bubbles: true }))
reject(err)
})
})
}
let _autoTimer = null
container.request.__watch(null, () => {
if (!container.hasAttribute('auto') || !container.request.url) return
if (_autoTimer) return
_autoTimer = Promise.resolve().then(() => {
container.do()
_autoTimer = null
})
})
})
export { APIComponent };