UNPKG

aiwrapper

Version:

A Universal AI Wrapper for JavaScript & TypeScript

197 lines (196 loc) 6.32 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); let _httpRequest = (_url, _options) => { throw new Error("Not implemented"); }; const setHttpRequestImpl = (impl) => { _httpRequest = impl; }; const httpRequest = (url, options) => { return _httpRequest(url, options); }; async function parseResponseBody(response) { const contentType = response.headers.get("content-type") || ""; const isJson = contentType.includes("application/json"); try { const text = await response.text(); if (isJson && text) { try { return { json: JSON.parse(text), text }; } catch (e) { return { text }; } } return { text }; } catch (e) { return {}; } } class HttpRequestError extends Error { constructor(message, response, action, bodyData) { super(message); this.response = response; this.action = action; /** * Parsed JSON body if the response was JSON, otherwise undefined. * Only available if response was present and parseable. */ __publicField(this, "body"); /** * Raw text body if available. * Only available if response was present and body could be read. */ __publicField(this, "bodyText"); if (bodyData) { this.body = bodyData.json; this.bodyText = bodyData.text; } } } function parseRetryAfter(retryAfter) { const seconds = parseInt(retryAfter, 10); if (!isNaN(seconds) && seconds > 0) { return seconds * 1e3; } const date = new Date(retryAfter); if (!isNaN(date.getTime())) { const now = Date.now(); const delayMs = date.getTime() - now; return Math.max(0, delayMs); } return 0; } function createAbortError() { const abortError = new Error("The operation was aborted"); abortError.name = "AbortError"; return abortError; } const httpRequestWithRetry = async (url, options) => { var _a, _b; if ((_a = options.signal) == null ? void 0 : _a.aborted) { throw createAbortError(); } if (options.retries === void 0) { options.retries = 6; } if (options.backoffMs === void 0) { options.backoffMs = 100; } if (options.maxBackoffMs === void 0) { options.maxBackoffMs = 3e3; } if (options._maxTotalAttempts === void 0) { options._maxTotalAttempts = (options.retries || 6) + 1; options._attemptCount = 0; } options._attemptCount = (options._attemptCount || 0) + 1; try { const response = await httpRequest(url, options); if (!response.ok) { const status = response.status; const error = new Error(`HTTP error! status: ${status}`); let responseForCallback = response; try { responseForCallback = response.clone(); } catch (e) { } const bodyData = await parseResponseBody(response).catch(() => ({})); if (status === 400 && options.on400Error) { try { const action = await options.on400Error(responseForCallback, error, options); throw new HttpRequestError(`HTTP error! status: ${status}`, response, action, bodyData); } catch (customError) { if (customError instanceof HttpRequestError) { throw customError; } throw new HttpRequestError(`HTTP error! status: ${status}`, response, { retry: false }, bodyData); } } let retry = true; if (status >= 400 && status < 500 && status !== 429) { retry = false; } throw new HttpRequestError(`HTTP error! status: ${status}`, response, { retry }, bodyData); } return response; } catch (error) { if ((error == null ? void 0 : error.name) === "AbortError") { throw error; } if (!(error instanceof HttpRequestError)) { throw new HttpRequestError( error instanceof Error ? error.message : String(error), null, { retry: true } ); } if (error instanceof HttpRequestError) { if (error.action.retry) { if (options._attemptCount >= options._maxTotalAttempts) { throw error; } if (options.retries <= 0 && error.action.consumeRetry !== false) { throw error; } if (error.action.consumeRetry !== false) { options.retries -= 1; } let delayMs; const targetBackoffMs = Math.min(options.backoffMs * 2, options.maxBackoffMs); if (error.response) { const retryAfter = error.response.headers.get("retry-after"); if (retryAfter) { const retryAfterMs = parseRetryAfter(retryAfter); delayMs = retryAfterMs > 0 ? retryAfterMs : targetBackoffMs; } else { delayMs = targetBackoffMs; } } else { delayMs = targetBackoffMs; } if (delayMs === targetBackoffMs) { options.backoffMs = targetBackoffMs; } await new Promise((resolve) => { let timeout; let onAbort; if (options.signal) { onAbort = () => { var _a2; if (timeout !== void 0) { clearTimeout(timeout); } (_a2 = options.signal) == null ? void 0 : _a2.removeEventListener("abort", onAbort); resolve(null); }; if (options.signal.aborted) { options.signal.removeEventListener("abort", onAbort); resolve(null); return; } options.signal.addEventListener("abort", onAbort, { once: true }); } timeout = setTimeout(() => { if (options.signal && onAbort) { options.signal.removeEventListener("abort", onAbort); } resolve(null); }, delayMs); }); if ((_b = options.signal) == null ? void 0 : _b.aborted) { throw createAbortError(); } return httpRequestWithRetry(url, options); } } throw error; } }; export { HttpRequestError, httpRequest, httpRequestWithRetry, setHttpRequestImpl }; //# sourceMappingURL=http-request.js.map