UNPKG

@embrace-io/web-sdk

Version:
129 lines (128 loc) 4.44 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); let _opentelemetry_api = require("@opentelemetry/api"); //#region src/transport/FetchTransport/FetchTransport.ts const KEEPALIVE_BYTE_BUDGET = 49152; const MAX_KEEPALIVE_REQUESTS = 9; let inflightKeepaliveBytes = 0; let inflightKeepaliveCount = 0; /** @internal for testing only */ function _resetKeepaliveTracking() { inflightKeepaliveBytes = 0; inflightKeepaliveCount = 0; } var FetchTransport = class FetchTransport { _config; constructor(_config) { this._config = _config; } static async _compressRequest(data) { const stream = new CompressionStream("gzip"); const writer = stream.writable.getWriter(); writer.write(data); writer.close(); const compressedChunks = []; const reader = stream.readable.getReader(); let done = false; while (!done) { const result = await reader.read(); if (result.value) compressedChunks.push(result.value); done = result.done; } const compressedData = new Uint8Array(compressedChunks.reduce((acc, chunk) => acc + chunk.length, 0)); let offset = 0; for (const chunk of compressedChunks) { compressedData.set(chunk, offset); offset += chunk.length; } return compressedData; } send(data, timeoutMillis) { return this._asyncSend(data, timeoutMillis); } shutdown() {} async _asyncSend(data, timeoutMillis) { let request = data; const headers = { "Content-Type": "application/json", ...this._config.headers }; let signal; let timeoutId; if ("timeout" in AbortSignal) signal = AbortSignal.timeout(timeoutMillis); else { const controller = new AbortController(); signal = controller.signal; timeoutId = setTimeout(() => { controller.abort(new DOMException("TimeoutError", "TimeoutError")); }, timeoutMillis); } let keepalive = false; try { if (this._config.compression === "gzip") { try { request = await FetchTransport._compressRequest(data); } catch (error) { const compressError = error instanceof Error ? error : new Error(String(error)); _opentelemetry_api.diag.warn(`Fetch transport gzip compression failed: ${compressError.message}`); return { status: "failure", error: compressError }; } headers["Content-Encoding"] = "gzip"; headers["Content-Length"] = request.length.toString(); } const wouldExceedBytes = inflightKeepaliveBytes + request.byteLength > KEEPALIVE_BYTE_BUDGET; keepalive = !wouldExceedBytes && !(inflightKeepaliveCount >= MAX_KEEPALIVE_REQUESTS); if (keepalive) { inflightKeepaliveBytes += request.byteLength; inflightKeepaliveCount++; } else { const reason = wouldExceedBytes ? `inflight bytes (${inflightKeepaliveBytes} + ${request.byteLength}) would exceed ${KEEPALIVE_BYTE_BUDGET}B budget` : `concurrent count (${inflightKeepaliveCount}) at limit of ${MAX_KEEPALIVE_REQUESTS}`; _opentelemetry_api.diag.debug(`Sending without keepalive: ${reason}`); } const response = await fetch(this._config.url, { method: "POST", keepalive, headers, body: request, signal }); if (response.ok) return { status: "success" }; const error = /* @__PURE__ */ new Error(`${response.status} Fetch request failed`); const message = `Fetch transport received HTTP ${response.status} (keepalive=${keepalive})`; if (response.status >= 500) { _opentelemetry_api.diag.debug(message); return { status: "retryable", error }; } _opentelemetry_api.diag.warn(message); return { status: "failure", error }; } catch (error) { const fetchError = error instanceof Error ? error : new Error(String(error)); const isRetryable = fetchError instanceof TypeError || fetchError instanceof DOMException && fetchError.name === "TimeoutError"; const message = `Fetch transport failed (keepalive=${keepalive}): ${fetchError.message}`; if (isRetryable) _opentelemetry_api.diag.debug(message); else _opentelemetry_api.diag.warn(message); return { status: isRetryable ? "retryable" : "failure", error: fetchError }; } finally { if (timeoutId !== void 0) clearTimeout(timeoutId); if (keepalive) { inflightKeepaliveBytes -= request.byteLength; inflightKeepaliveCount--; } } } }; //#endregion exports.FetchTransport = FetchTransport; exports._resetKeepaliveTracking = _resetKeepaliveTracking; //# sourceMappingURL=FetchTransport.cjs.map