UNPKG

@wevu/web-apis

Version:

Web API polyfills and global installers for mini-program runtimes

164 lines (163 loc) 5.55 kB
import { t as RequestGlobalsEventTarget, u as resolveRequestGlobalsHost } from "./shared-pgiOoBm7.mjs"; import { AbortControllerPolyfill } from "./abort.mjs"; import { HeadersPolyfill, headersToObject } from "./http.mjs"; import { fetch } from "./fetch.mjs"; //#region src/xhr.ts function createProgressEvent(type) { return { type, lengthComputable: false, loaded: 0, total: 0 }; } function createError(type) { const error = new Error(type); error.name = type === "abort" ? "AbortError" : type === "timeout" ? "TimeoutError" : "NetworkError"; return error; } function resolveFetch() { const host = resolveRequestGlobalsHost(); return typeof host.fetch === "function" ? host.fetch.bind(host) : fetch; } var XMLHttpRequestUploadPolyfill = class extends RequestGlobalsEventTarget {}; var XMLHttpRequestPolyfill = class XMLHttpRequestPolyfill extends RequestGlobalsEventTarget { static UNSENT = 0; static OPENED = 1; static HEADERS_RECEIVED = 2; static LOADING = 3; static DONE = 4; UNSENT = XMLHttpRequestPolyfill.UNSENT; OPENED = XMLHttpRequestPolyfill.OPENED; HEADERS_RECEIVED = XMLHttpRequestPolyfill.HEADERS_RECEIVED; LOADING = XMLHttpRequestPolyfill.LOADING; DONE = XMLHttpRequestPolyfill.DONE; upload = new XMLHttpRequestUploadPolyfill(); readyState = XMLHttpRequestPolyfill.UNSENT; response = null; responseText = ""; responseType = ""; responseURL = ""; status = 0; statusText = ""; timeout = 0; withCredentials = false; miniProgram = null; onreadystatechange = null; onabort = null; onerror = null; onload = null; onloadend = null; onloadstart = null; onprogress = null; ontimeout = null; method = "GET"; url = ""; requestHeaders = new HeadersPolyfill(); responseHeaders = new HeadersPolyfill(); requestController = null; timeoutId = null; sent = false; open(method, url) { this.method = String(method || "GET").toUpperCase(); this.url = url; this.status = 0; this.statusText = ""; this.response = null; this.responseText = ""; this.responseURL = ""; this.responseHeaders = new HeadersPolyfill(); this.sent = false; this.transitionTo(XMLHttpRequestPolyfill.OPENED); } setRequestHeader(key, value) { if (this.readyState !== XMLHttpRequestPolyfill.OPENED || this.sent) throw new Error("Failed to execute setRequestHeader: invalid readyState"); this.requestHeaders.append(key, value); } getAllResponseHeaders() { if (this.readyState < XMLHttpRequestPolyfill.HEADERS_RECEIVED) return ""; let content = ""; this.responseHeaders.forEach((value, key) => { content += `${key}: ${value}\r\n`; }); return content; } getResponseHeader(key) { if (this.readyState < XMLHttpRequestPolyfill.HEADERS_RECEIVED) return null; return this.responseHeaders.get(key); } abort() { if (!this.requestController) return; this.requestController.abort(); } async send(body) { if (this.readyState !== XMLHttpRequestPolyfill.OPENED) throw new Error("Failed to execute send: invalid readyState"); this.sent = true; this.dispatchEvent({ type: "loadstart" }); this.upload.dispatchEvent(createProgressEvent("loadstart")); const controller = new (typeof AbortController === "function" ? AbortController : AbortControllerPolyfill)(); this.requestController = controller; if (this.timeout > 0) this.timeoutId = setTimeout(() => { controller.abort(createError("timeout")); }, this.timeout); try { const response = await resolveFetch()(this.url, { method: this.method, headers: headersToObject(this.requestHeaders), body, miniProgram: this.miniProgram ?? void 0, signal: controller.signal }); this.responseHeaders = typeof Headers === "function" && response.headers instanceof Headers ? response.headers : new HeadersPolyfill(response.headers); this.status = response.status; this.statusText = response.statusText ?? ""; this.responseURL = response.url ?? this.url; this.transitionTo(XMLHttpRequestPolyfill.HEADERS_RECEIVED); this.transitionTo(XMLHttpRequestPolyfill.LOADING); if (this.responseType === "arraybuffer") this.response = await response.arrayBuffer(); else { const text = await response.text(); this.responseText = text; this.response = this.responseType === "json" ? text ? JSON.parse(text) : null : text; } this.finish("load"); } catch (error) { const reason = controller.signal && "reason" in controller.signal ? controller.signal.reason : void 0; if (controller.signal?.aborted) { const type = reason instanceof Error && reason.name === "TimeoutError" ? "timeout" : "abort"; this.finish(type); return; } this.response = null; this.responseText = ""; this.status = 0; this.statusText = ""; this.transitionTo(XMLHttpRequestPolyfill.DONE); this.dispatchEvent({ type: "error" }); this.dispatchEvent({ type: "loadend" }); throw error; } finally { if (this.timeoutId) { clearTimeout(this.timeoutId); this.timeoutId = null; } this.requestController = null; } } finish(type) { this.transitionTo(XMLHttpRequestPolyfill.DONE); if (type === "abort") this.dispatchEvent({ type: "abort" }); else if (type === "timeout") this.dispatchEvent({ type: "timeout" }); else { this.dispatchEvent(createProgressEvent("progress")); this.dispatchEvent({ type: "load" }); } this.dispatchEvent({ type: "loadend" }); } transitionTo(nextState) { this.readyState = nextState; this.dispatchEvent({ type: "readystatechange" }); } }; //#endregion export { XMLHttpRequestPolyfill, XMLHttpRequestUploadPolyfill };