| 277 | } |
| 278 | |
| 279 | async request(path, options = {}) { |
| 280 | const url = `${this.baseUrl}${path}`; |
| 281 | const { |
| 282 | timeoutMs, |
| 283 | retry, |
| 284 | retryDelayMs, |
| 285 | requestKey, |
| 286 | cancelPrevious, |
| 287 | priority, |
| 288 | silentNetworkError, |
| 289 | silentTimeoutError, |
| 290 | signal: externalSignal, |
| 291 | ...rawFetchOptions |
| 292 | } = options; |
| 293 | |
| 294 | const defaultOptions = { |
| 295 | headers: { |
| 296 | 'Content-Type': 'application/json', |
| 297 | }, |
| 298 | }; |
| 299 | |
| 300 | const finalOptions = { ...defaultOptions, ...rawFetchOptions }; |
| 301 | const mergedHeaders = { |
| 302 | ...(defaultOptions.headers || {}), |
| 303 | ...(rawFetchOptions.headers || {}), |
| 304 | }; |
| 305 | if (Object.keys(mergedHeaders).length) { |
| 306 | finalOptions.headers = mergedHeaders; |
| 307 | } |
| 308 | |
| 309 | const effectiveTimeoutMs = Number(timeoutMs) > 0 ? Number(timeoutMs) : this.getAdaptiveTimeoutMs(); |
| 310 | const retryCount = Number.isInteger(retry) ? retry : this.defaultRetryCount; |
| 311 | const retryWaitMs = Number(retryDelayMs) > 0 ? Number(retryDelayMs) : this.defaultRetryDelayMs; |
| 312 | const requestPriority = String(priority || '').toLowerCase() || 'normal'; |
| 313 | const allowSilentNetworkError = Boolean(silentNetworkError); |
| 314 | const allowSilentTimeoutError = Boolean(silentTimeoutError); |
| 315 | |
| 316 | if (finalOptions.body && typeof finalOptions.body === 'object') { |
| 317 | finalOptions.body = JSON.stringify(finalOptions.body); |
| 318 | } |
| 319 | |
| 320 | const runner = async () => { |
| 321 | for (let attempt = 0; attempt <= retryCount; attempt += 1) { |
| 322 | let timedOut = false; |
| 323 | let timeoutId = null; |
| 324 | const controller = new AbortController(); |
| 325 | |
| 326 | if (requestKey && cancelPrevious) { |
| 327 | const previousController = this.inflightRequests.get(requestKey); |
| 328 | if (previousController) { |
| 329 | previousController.__cancelReason = 'request_replaced'; |
| 330 | previousController.abort(); |
| 331 | } |
| 332 | } |
| 333 | if (requestKey) { |
| 334 | this.inflightRequests.set(requestKey, controller); |
| 335 | } |
| 336 | |