Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions __test__/lib/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('Request', () => {
})

// ──────────────────────────────────────────────
// 基础功能
// Basic features
// ──────────────────────────────────────────────

test('should append GET params to query string', async () => {
Expand Down Expand Up @@ -188,7 +188,7 @@ describe('Request', () => {
})

// ──────────────────────────────────────────────
// 生命周期回调
// Lifecycle callbacks
// ──────────────────────────────────────────────

test('should call onSuccess with response data', async () => {
Expand Down Expand Up @@ -629,7 +629,7 @@ describe('Request', () => {
}, 10000)

// ──────────────────────────────────────────────
// thenable: await / Promise.all 支持
// thenable: await / Promise.all support
// ──────────────────────────────────────────────

test('should be directly awaitable without .promise', async () => {
Expand Down Expand Up @@ -666,7 +666,7 @@ describe('Request', () => {
})
})

// ─── 测试辅助函数 ──────────────────────────────
// ─── Test helpers ──────────────────────────────

function jsonResponse(data: unknown): Response {
return {
Expand Down
34 changes: 17 additions & 17 deletions lib/request.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { objectToQueryString } from './url'
import { MIME_TYPES } from './const/http'

// ─── Thenable handle (可 await 的返回结果) ───
// ─── Thenable handle ───

export interface RequestHandle<T> {
then: <R1 = T, R2 = never>(
Expand All @@ -15,7 +15,7 @@ export interface RequestHandle<T> {
abort: () => void
}

// ─── 拦截器类型 ───
// ─── Interceptor types ───

export type RequestInterceptor = (
config: RequestInit
Expand All @@ -27,14 +27,14 @@ export type ResponseInterceptor<T = unknown, U = unknown> = (

export type ErrorInterceptor = (error: unknown) => unknown | Promise<unknown>

// ─── 缓存配置 ───
// ─── Cache config ───

export interface CacheConfig {
/** Time-to-live in milliseconds. */
ttl: number
}

// ─── 请求配置 ───
// ─── Request config ───

export interface RequestConfig extends RequestInit {
params?: Record<PropertyKey, any>
Expand All @@ -53,7 +53,7 @@ export interface RequestConfig extends RequestInit {
/** Download progress callback. Receives (loadedBytes, totalBytes). */
onDownloadProgress?: (loaded: number, total: number) => void

// ─── 生命周期回调 ───
// ─── Lifecycle callbacks ───
onSuccess?: (data: unknown) => void
onError?: (error: unknown) => void
onAbort?: () => void
Expand Down Expand Up @@ -147,7 +147,7 @@ export class Request {
return () => this.removeInterceptor(this.errorInterceptors, interceptor)
}

// ─── 快捷方法 ───
// ─── Convenience methods ───

get<T = unknown>(
url: string,
Expand Down Expand Up @@ -182,7 +182,7 @@ export class Request {
this.cacheMap.clear()
}

// ─── 核心:request ───
// ─── Core: request ───

request<T = unknown>(
url: string,
Expand All @@ -191,7 +191,7 @@ export class Request {
const controller = new AbortController()
const promise = this.execute<T>(url, config, controller)

// onAbort abort() 时直接触发
// onAbort fires directly when abort() is called
const handle = {
then: (onfulfilled?: any, onrejected?: any) =>
(promise as Promise<T>).then(onfulfilled, onrejected),
Expand All @@ -207,7 +207,7 @@ export class Request {
return handle
}

// ─── 内部:execute ───
// ─── Internal: execute ───

private buildCacheKey(method: string, url: string): string {
return `${method}:${url}`
Expand All @@ -229,7 +229,7 @@ export class Request {
retryDelay = 0,
cache,
onDownloadProgress,
// 剥离回调,不下传到 RequestInit
// Strip lifecycle callbacks — don't pass them down to RequestInit
onSuccess,
onError,
onAbort: _onAbort,
Expand Down Expand Up @@ -259,7 +259,7 @@ export class Request {
onFinally?.()
return dedupData as T
} catch {
// 上游失败了,fall through 重新发起
// Upstream failed, fall through to retry
}
}

Expand Down Expand Up @@ -308,7 +308,7 @@ export class Request {
}
}

// ─── 内部:executeWithRetry ───
// ─── Internal: executeWithRetry ───

private async executeWithRetry<T>(
requestUrl: string,
Expand Down Expand Up @@ -404,7 +404,7 @@ export class Request {
continue
}

// 最后一次尝试:执行 errorInterceptors throw
// Last attempt: run errorInterceptors then throw
const processedError = await this.runErrorInterceptors(error, [
...this.errorInterceptors,
...errorInterceptors
Expand All @@ -420,7 +420,7 @@ export class Request {
throw new Error('Unreachable')
}

// ─── 进度读取 ───
// ─── Progress reader ───

private async readResponseWithProgress(
response: Response,
Expand Down Expand Up @@ -458,7 +458,7 @@ export class Request {
return new Blob([allChunks.buffer], { type: contentType || undefined })
}

// ─── 构建请求 ───
// ─── Build request ───

private buildRequestInit(
method: string,
Expand Down Expand Up @@ -542,7 +542,7 @@ export class Request {
return Object.fromEntries(entries)
}

// ─── 拦截器管道 ───
// ─── Interceptor pipeline ───

private async runRequestInterceptors(
config: RequestInit,
Expand Down Expand Up @@ -577,7 +577,7 @@ export class Request {
return currentError
}

// ─── 响应解析 ───
// ─── Response parsing ───

private async parseResponse(response: Response) {
const contentType = response.headers.get('content-type') ?? ''
Expand Down
Loading