@aigne/afs-http 1.11.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE.md +26 -0
  2. package/README.md +318 -0
  3. package/dist/adapters/express.cjs +74 -0
  4. package/dist/adapters/express.d.cts +56 -0
  5. package/dist/adapters/express.d.cts.map +1 -0
  6. package/dist/adapters/express.d.mts +56 -0
  7. package/dist/adapters/express.d.mts.map +1 -0
  8. package/dist/adapters/express.mjs +74 -0
  9. package/dist/adapters/express.mjs.map +1 -0
  10. package/dist/adapters/koa.cjs +73 -0
  11. package/dist/adapters/koa.d.cts +56 -0
  12. package/dist/adapters/koa.d.cts.map +1 -0
  13. package/dist/adapters/koa.d.mts +56 -0
  14. package/dist/adapters/koa.d.mts.map +1 -0
  15. package/dist/adapters/koa.mjs +73 -0
  16. package/dist/adapters/koa.mjs.map +1 -0
  17. package/dist/client.cjs +143 -0
  18. package/dist/client.d.cts +70 -0
  19. package/dist/client.d.cts.map +1 -0
  20. package/dist/client.d.mts +70 -0
  21. package/dist/client.d.mts.map +1 -0
  22. package/dist/client.mjs +144 -0
  23. package/dist/client.mjs.map +1 -0
  24. package/dist/errors.cjs +105 -0
  25. package/dist/errors.d.cts +63 -0
  26. package/dist/errors.d.cts.map +1 -0
  27. package/dist/errors.d.mts +63 -0
  28. package/dist/errors.d.mts.map +1 -0
  29. package/dist/errors.mjs +98 -0
  30. package/dist/errors.mjs.map +1 -0
  31. package/dist/handler.cjs +126 -0
  32. package/dist/handler.d.cts +43 -0
  33. package/dist/handler.d.cts.map +1 -0
  34. package/dist/handler.d.mts +43 -0
  35. package/dist/handler.d.mts.map +1 -0
  36. package/dist/handler.mjs +127 -0
  37. package/dist/handler.mjs.map +1 -0
  38. package/dist/index.cjs +33 -0
  39. package/dist/index.d.cts +8 -0
  40. package/dist/index.d.mts +8 -0
  41. package/dist/index.mjs +9 -0
  42. package/dist/protocol.cjs +68 -0
  43. package/dist/protocol.d.cts +119 -0
  44. package/dist/protocol.d.cts.map +1 -0
  45. package/dist/protocol.d.mts +119 -0
  46. package/dist/protocol.d.mts.map +1 -0
  47. package/dist/protocol.mjs +64 -0
  48. package/dist/protocol.mjs.map +1 -0
  49. package/dist/retry.cjs +111 -0
  50. package/dist/retry.d.cts +57 -0
  51. package/dist/retry.d.cts.map +1 -0
  52. package/dist/retry.d.mts +57 -0
  53. package/dist/retry.d.mts.map +1 -0
  54. package/dist/retry.mjs +105 -0
  55. package/dist/retry.mjs.map +1 -0
  56. package/package.json +55 -0
package/dist/retry.cjs ADDED
@@ -0,0 +1,111 @@
1
+
2
+ //#region src/retry.ts
3
+ /**
4
+ * Default retry options
5
+ */
6
+ const DEFAULT_RETRY_OPTIONS = {
7
+ maxRetries: 3,
8
+ initialDelay: 1e3,
9
+ maxDelay: 3e4,
10
+ multiplier: 2
11
+ };
12
+ /**
13
+ * Calculate delay for a given retry attempt using exponential backoff
14
+ * @param attempt - The retry attempt number (0-indexed)
15
+ * @param options - Retry options
16
+ * @returns Delay in milliseconds
17
+ */
18
+ function calculateDelay(attempt, options = {}) {
19
+ const initialDelay = options.initialDelay ?? DEFAULT_RETRY_OPTIONS.initialDelay;
20
+ const maxDelay = options.maxDelay ?? DEFAULT_RETRY_OPTIONS.maxDelay;
21
+ const delay = initialDelay * (options.multiplier ?? DEFAULT_RETRY_OPTIONS.multiplier) ** attempt;
22
+ return Math.min(delay, maxDelay);
23
+ }
24
+ /**
25
+ * Sleep for a given number of milliseconds
26
+ */
27
+ function sleep(ms) {
28
+ return new Promise((resolve) => setTimeout(resolve, ms));
29
+ }
30
+ /**
31
+ * Default function to check if a fetch error is retryable
32
+ */
33
+ function isRetryableError(error) {
34
+ const message = error.message.toLowerCase();
35
+ return [
36
+ "econnreset",
37
+ "etimedout",
38
+ "enotfound",
39
+ "econnrefused",
40
+ "epipe",
41
+ "network",
42
+ "fetch failed",
43
+ "socket hang up",
44
+ "connection reset",
45
+ "timeout"
46
+ ].some((pattern) => message.includes(pattern));
47
+ }
48
+ /**
49
+ * Check if an HTTP response status is retryable
50
+ */
51
+ function isRetryableStatus(status) {
52
+ if (status >= 500 && status < 600) return true;
53
+ if (status === 429) return true;
54
+ return false;
55
+ }
56
+ /**
57
+ * Execute a function with retry logic
58
+ * @param fn - The async function to execute
59
+ * @param options - Retry options
60
+ * @returns The result of the function
61
+ */
62
+ async function withRetry(fn, options = {}) {
63
+ const maxRetries = options.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries;
64
+ const isRetryable = options.isRetryable ?? ((error) => isRetryableError(error));
65
+ let lastError;
66
+ for (let attempt = 0; attempt <= maxRetries; attempt++) try {
67
+ return await fn();
68
+ } catch (error) {
69
+ lastError = error instanceof Error ? error : new Error(String(error));
70
+ if (!(attempt < maxRetries && isRetryable(lastError))) throw lastError;
71
+ await sleep(calculateDelay(attempt, options));
72
+ }
73
+ throw lastError ?? /* @__PURE__ */ new Error("Retry failed");
74
+ }
75
+ /**
76
+ * Execute a fetch request with retry logic
77
+ * @param url - The URL to fetch
78
+ * @param init - Fetch init options
79
+ * @param retryOptions - Retry options
80
+ * @returns The fetch response
81
+ */
82
+ async function fetchWithRetry(url, init, retryOptions = {}) {
83
+ const maxRetries = retryOptions.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries;
84
+ let lastError;
85
+ let lastResponse;
86
+ for (let attempt = 0; attempt <= maxRetries; attempt++) try {
87
+ const response = await fetch(url, init);
88
+ lastResponse = response;
89
+ if (isRetryableStatus(response.status) && attempt < maxRetries) {
90
+ await sleep(calculateDelay(attempt, retryOptions));
91
+ continue;
92
+ }
93
+ return response;
94
+ } catch (error) {
95
+ lastError = error instanceof Error ? error : new Error(String(error));
96
+ const isRetryable = retryOptions.isRetryable ?? isRetryableError;
97
+ if (!(attempt < maxRetries && isRetryable(lastError))) throw lastError;
98
+ await sleep(calculateDelay(attempt, retryOptions));
99
+ }
100
+ if (lastResponse) return lastResponse;
101
+ throw lastError ?? /* @__PURE__ */ new Error("Fetch failed after retries");
102
+ }
103
+
104
+ //#endregion
105
+ exports.DEFAULT_RETRY_OPTIONS = DEFAULT_RETRY_OPTIONS;
106
+ exports.calculateDelay = calculateDelay;
107
+ exports.fetchWithRetry = fetchWithRetry;
108
+ exports.isRetryableError = isRetryableError;
109
+ exports.isRetryableStatus = isRetryableStatus;
110
+ exports.sleep = sleep;
111
+ exports.withRetry = withRetry;
@@ -0,0 +1,57 @@
1
+ //#region src/retry.d.ts
2
+ /**
3
+ * Retry configuration options
4
+ */
5
+ interface RetryOptions {
6
+ /** Maximum number of retries (default: 3) */
7
+ maxRetries?: number;
8
+ /** Initial delay in milliseconds (default: 1000) */
9
+ initialDelay?: number;
10
+ /** Maximum delay in milliseconds (default: 30000) */
11
+ maxDelay?: number;
12
+ /** Delay multiplier for exponential backoff (default: 2) */
13
+ multiplier?: number;
14
+ /** Function to determine if an error is retryable */
15
+ isRetryable?: (error: Error, response?: Response) => boolean;
16
+ }
17
+ /**
18
+ * Default retry options
19
+ */
20
+ declare const DEFAULT_RETRY_OPTIONS: Required<Omit<RetryOptions, "isRetryable">>;
21
+ /**
22
+ * Calculate delay for a given retry attempt using exponential backoff
23
+ * @param attempt - The retry attempt number (0-indexed)
24
+ * @param options - Retry options
25
+ * @returns Delay in milliseconds
26
+ */
27
+ declare function calculateDelay(attempt: number, options?: Pick<RetryOptions, "initialDelay" | "maxDelay" | "multiplier">): number;
28
+ /**
29
+ * Sleep for a given number of milliseconds
30
+ */
31
+ declare function sleep(ms: number): Promise<void>;
32
+ /**
33
+ * Default function to check if a fetch error is retryable
34
+ */
35
+ declare function isRetryableError(error: Error): boolean;
36
+ /**
37
+ * Check if an HTTP response status is retryable
38
+ */
39
+ declare function isRetryableStatus(status: number): boolean;
40
+ /**
41
+ * Execute a function with retry logic
42
+ * @param fn - The async function to execute
43
+ * @param options - Retry options
44
+ * @returns The result of the function
45
+ */
46
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
47
+ /**
48
+ * Execute a fetch request with retry logic
49
+ * @param url - The URL to fetch
50
+ * @param init - Fetch init options
51
+ * @param retryOptions - Retry options
52
+ * @returns The fetch response
53
+ */
54
+ declare function fetchWithRetry(url: string, init?: RequestInit, retryOptions?: RetryOptions): Promise<Response>;
55
+ //#endregion
56
+ export { DEFAULT_RETRY_OPTIONS, RetryOptions, calculateDelay, fetchWithRetry, isRetryableError, isRetryableStatus, sleep, withRetry };
57
+ //# sourceMappingURL=retry.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.cts","names":[],"sources":["../src/retry.ts"],"mappings":";;AAGA;AAgBA;UAhBiB,YAAA;EAAA;EAAA,UAAA;EAAA;EAAA,YAAA;EAAA;EAAA,QAAA;EAAA;EAAA,UAAA;EAAA;EAAA,WAAA,IAAA,KAAA,EAUO,KAAA,EAAA,QAAA,GAAkB,QAAA;AAAA;AAAA;AAM1C;;AAN0C,cAM7B,qBAAA,EAAuB,QAAA,CAAS,IAAA,CAAK,YAAA;AAAA;;;;AAalD;AAeA;AA5BkD,iBAalC,cAAA,CAAA,OAAA,UAAA,OAAA,GAEL,IAAA,CAAK,YAAA;AAAA;AAahB;AAOA;AApBgB,iBAaA,KAAA,CAAA,EAAA,WAAmB,OAAA;AAAA;AAOnC;AAuBA;AA9BmC,iBAOnB,gBAAA,CAAA,KAAA,EAAwB,KAAA;AAAA;AAuBxC;AAkBA;AAzCwC,iBAuBxB,iBAAA,CAAA,MAAA;AAAA;AAkBhB;;;;;AAlBgB,iBAkBM,SAAA,GAAA,CAAA,EAAA,QAAuB,OAAA,CAAQ,CAAA,GAAA,OAAA,GAAa,YAAA,GAAoB,OAAA,CAAQ,CAAA;AAAA;;;AAoC9F;;;;AApC8F,iBAoCxE,cAAA,CAAA,GAAA,UAAA,IAAA,GAEb,WAAA,EAAA,YAAA,GACO,YAAA,GACb,OAAA,CAAQ,QAAA"}
@@ -0,0 +1,57 @@
1
+ //#region src/retry.d.ts
2
+ /**
3
+ * Retry configuration options
4
+ */
5
+ interface RetryOptions {
6
+ /** Maximum number of retries (default: 3) */
7
+ maxRetries?: number;
8
+ /** Initial delay in milliseconds (default: 1000) */
9
+ initialDelay?: number;
10
+ /** Maximum delay in milliseconds (default: 30000) */
11
+ maxDelay?: number;
12
+ /** Delay multiplier for exponential backoff (default: 2) */
13
+ multiplier?: number;
14
+ /** Function to determine if an error is retryable */
15
+ isRetryable?: (error: Error, response?: Response) => boolean;
16
+ }
17
+ /**
18
+ * Default retry options
19
+ */
20
+ declare const DEFAULT_RETRY_OPTIONS: Required<Omit<RetryOptions, "isRetryable">>;
21
+ /**
22
+ * Calculate delay for a given retry attempt using exponential backoff
23
+ * @param attempt - The retry attempt number (0-indexed)
24
+ * @param options - Retry options
25
+ * @returns Delay in milliseconds
26
+ */
27
+ declare function calculateDelay(attempt: number, options?: Pick<RetryOptions, "initialDelay" | "maxDelay" | "multiplier">): number;
28
+ /**
29
+ * Sleep for a given number of milliseconds
30
+ */
31
+ declare function sleep(ms: number): Promise<void>;
32
+ /**
33
+ * Default function to check if a fetch error is retryable
34
+ */
35
+ declare function isRetryableError(error: Error): boolean;
36
+ /**
37
+ * Check if an HTTP response status is retryable
38
+ */
39
+ declare function isRetryableStatus(status: number): boolean;
40
+ /**
41
+ * Execute a function with retry logic
42
+ * @param fn - The async function to execute
43
+ * @param options - Retry options
44
+ * @returns The result of the function
45
+ */
46
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
47
+ /**
48
+ * Execute a fetch request with retry logic
49
+ * @param url - The URL to fetch
50
+ * @param init - Fetch init options
51
+ * @param retryOptions - Retry options
52
+ * @returns The fetch response
53
+ */
54
+ declare function fetchWithRetry(url: string, init?: RequestInit, retryOptions?: RetryOptions): Promise<Response>;
55
+ //#endregion
56
+ export { DEFAULT_RETRY_OPTIONS, RetryOptions, calculateDelay, fetchWithRetry, isRetryableError, isRetryableStatus, sleep, withRetry };
57
+ //# sourceMappingURL=retry.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.mts","names":[],"sources":["../src/retry.ts"],"mappings":";;AAGA;AAgBA;UAhBiB,YAAA;EAAA;EAAA,UAAA;EAAA;EAAA,YAAA;EAAA;EAAA,QAAA;EAAA;EAAA,UAAA;EAAA;EAAA,WAAA,IAAA,KAAA,EAUO,KAAA,EAAA,QAAA,GAAkB,QAAA;AAAA;AAAA;AAM1C;;AAN0C,cAM7B,qBAAA,EAAuB,QAAA,CAAS,IAAA,CAAK,YAAA;AAAA;;;;AAalD;AAeA;AA5BkD,iBAalC,cAAA,CAAA,OAAA,UAAA,OAAA,GAEL,IAAA,CAAK,YAAA;AAAA;AAahB;AAOA;AApBgB,iBAaA,KAAA,CAAA,EAAA,WAAmB,OAAA;AAAA;AAOnC;AAuBA;AA9BmC,iBAOnB,gBAAA,CAAA,KAAA,EAAwB,KAAA;AAAA;AAuBxC;AAkBA;AAzCwC,iBAuBxB,iBAAA,CAAA,MAAA;AAAA;AAkBhB;;;;;AAlBgB,iBAkBM,SAAA,GAAA,CAAA,EAAA,QAAuB,OAAA,CAAQ,CAAA,GAAA,OAAA,GAAa,YAAA,GAAoB,OAAA,CAAQ,CAAA;AAAA;;;AAoC9F;;;;AApC8F,iBAoCxE,cAAA,CAAA,GAAA,UAAA,IAAA,GAEb,WAAA,EAAA,YAAA,GACO,YAAA,GACb,OAAA,CAAQ,QAAA"}
package/dist/retry.mjs ADDED
@@ -0,0 +1,105 @@
1
+ //#region src/retry.ts
2
+ /**
3
+ * Default retry options
4
+ */
5
+ const DEFAULT_RETRY_OPTIONS = {
6
+ maxRetries: 3,
7
+ initialDelay: 1e3,
8
+ maxDelay: 3e4,
9
+ multiplier: 2
10
+ };
11
+ /**
12
+ * Calculate delay for a given retry attempt using exponential backoff
13
+ * @param attempt - The retry attempt number (0-indexed)
14
+ * @param options - Retry options
15
+ * @returns Delay in milliseconds
16
+ */
17
+ function calculateDelay(attempt, options = {}) {
18
+ const initialDelay = options.initialDelay ?? DEFAULT_RETRY_OPTIONS.initialDelay;
19
+ const maxDelay = options.maxDelay ?? DEFAULT_RETRY_OPTIONS.maxDelay;
20
+ const delay = initialDelay * (options.multiplier ?? DEFAULT_RETRY_OPTIONS.multiplier) ** attempt;
21
+ return Math.min(delay, maxDelay);
22
+ }
23
+ /**
24
+ * Sleep for a given number of milliseconds
25
+ */
26
+ function sleep(ms) {
27
+ return new Promise((resolve) => setTimeout(resolve, ms));
28
+ }
29
+ /**
30
+ * Default function to check if a fetch error is retryable
31
+ */
32
+ function isRetryableError(error) {
33
+ const message = error.message.toLowerCase();
34
+ return [
35
+ "econnreset",
36
+ "etimedout",
37
+ "enotfound",
38
+ "econnrefused",
39
+ "epipe",
40
+ "network",
41
+ "fetch failed",
42
+ "socket hang up",
43
+ "connection reset",
44
+ "timeout"
45
+ ].some((pattern) => message.includes(pattern));
46
+ }
47
+ /**
48
+ * Check if an HTTP response status is retryable
49
+ */
50
+ function isRetryableStatus(status) {
51
+ if (status >= 500 && status < 600) return true;
52
+ if (status === 429) return true;
53
+ return false;
54
+ }
55
+ /**
56
+ * Execute a function with retry logic
57
+ * @param fn - The async function to execute
58
+ * @param options - Retry options
59
+ * @returns The result of the function
60
+ */
61
+ async function withRetry(fn, options = {}) {
62
+ const maxRetries = options.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries;
63
+ const isRetryable = options.isRetryable ?? ((error) => isRetryableError(error));
64
+ let lastError;
65
+ for (let attempt = 0; attempt <= maxRetries; attempt++) try {
66
+ return await fn();
67
+ } catch (error) {
68
+ lastError = error instanceof Error ? error : new Error(String(error));
69
+ if (!(attempt < maxRetries && isRetryable(lastError))) throw lastError;
70
+ await sleep(calculateDelay(attempt, options));
71
+ }
72
+ throw lastError ?? /* @__PURE__ */ new Error("Retry failed");
73
+ }
74
+ /**
75
+ * Execute a fetch request with retry logic
76
+ * @param url - The URL to fetch
77
+ * @param init - Fetch init options
78
+ * @param retryOptions - Retry options
79
+ * @returns The fetch response
80
+ */
81
+ async function fetchWithRetry(url, init, retryOptions = {}) {
82
+ const maxRetries = retryOptions.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries;
83
+ let lastError;
84
+ let lastResponse;
85
+ for (let attempt = 0; attempt <= maxRetries; attempt++) try {
86
+ const response = await fetch(url, init);
87
+ lastResponse = response;
88
+ if (isRetryableStatus(response.status) && attempt < maxRetries) {
89
+ await sleep(calculateDelay(attempt, retryOptions));
90
+ continue;
91
+ }
92
+ return response;
93
+ } catch (error) {
94
+ lastError = error instanceof Error ? error : new Error(String(error));
95
+ const isRetryable = retryOptions.isRetryable ?? isRetryableError;
96
+ if (!(attempt < maxRetries && isRetryable(lastError))) throw lastError;
97
+ await sleep(calculateDelay(attempt, retryOptions));
98
+ }
99
+ if (lastResponse) return lastResponse;
100
+ throw lastError ?? /* @__PURE__ */ new Error("Fetch failed after retries");
101
+ }
102
+
103
+ //#endregion
104
+ export { DEFAULT_RETRY_OPTIONS, calculateDelay, fetchWithRetry, isRetryableError, isRetryableStatus, sleep, withRetry };
105
+ //# sourceMappingURL=retry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.mjs","names":[],"sources":["../src/retry.ts"],"sourcesContent":["/**\n * Retry configuration options\n */\nexport interface RetryOptions {\n /** Maximum number of retries (default: 3) */\n maxRetries?: number;\n /** Initial delay in milliseconds (default: 1000) */\n initialDelay?: number;\n /** Maximum delay in milliseconds (default: 30000) */\n maxDelay?: number;\n /** Delay multiplier for exponential backoff (default: 2) */\n multiplier?: number;\n /** Function to determine if an error is retryable */\n isRetryable?: (error: Error, response?: Response) => boolean;\n}\n\n/**\n * Default retry options\n */\nexport const DEFAULT_RETRY_OPTIONS: Required<Omit<RetryOptions, \"isRetryable\">> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n multiplier: 2,\n};\n\n/**\n * Calculate delay for a given retry attempt using exponential backoff\n * @param attempt - The retry attempt number (0-indexed)\n * @param options - Retry options\n * @returns Delay in milliseconds\n */\nexport function calculateDelay(\n attempt: number,\n options: Pick<RetryOptions, \"initialDelay\" | \"maxDelay\" | \"multiplier\"> = {},\n): number {\n const initialDelay = options.initialDelay ?? DEFAULT_RETRY_OPTIONS.initialDelay;\n const maxDelay = options.maxDelay ?? DEFAULT_RETRY_OPTIONS.maxDelay;\n const multiplier = options.multiplier ?? DEFAULT_RETRY_OPTIONS.multiplier;\n\n const delay = initialDelay * multiplier ** attempt;\n return Math.min(delay, maxDelay);\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Default function to check if a fetch error is retryable\n */\nexport function isRetryableError(error: Error): boolean {\n const message = error.message.toLowerCase();\n\n // Network errors that are typically transient\n const retryablePatterns = [\n \"econnreset\",\n \"etimedout\",\n \"enotfound\",\n \"econnrefused\",\n \"epipe\",\n \"network\",\n \"fetch failed\",\n \"socket hang up\",\n \"connection reset\",\n \"timeout\",\n ];\n\n return retryablePatterns.some((pattern) => message.includes(pattern));\n}\n\n/**\n * Check if an HTTP response status is retryable\n */\nexport function isRetryableStatus(status: number): boolean {\n // 5xx server errors are retryable\n if (status >= 500 && status < 600) {\n return true;\n }\n // 429 Too Many Requests is retryable\n if (status === 429) {\n return true;\n }\n return false;\n}\n\n/**\n * Execute a function with retry logic\n * @param fn - The async function to execute\n * @param options - Retry options\n * @returns The result of the function\n */\nexport async function withRetry<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n const maxRetries = options.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries;\n const isRetryable = options.isRetryable ?? ((error: Error) => isRetryableError(error));\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Check if we should retry\n const shouldRetry = attempt < maxRetries && isRetryable(lastError);\n\n if (!shouldRetry) {\n throw lastError;\n }\n\n // Calculate and wait for the delay\n const delay = calculateDelay(attempt, options);\n await sleep(delay);\n }\n }\n\n // This should never be reached, but TypeScript needs it\n throw lastError ?? new Error(\"Retry failed\");\n}\n\n/**\n * Execute a fetch request with retry logic\n * @param url - The URL to fetch\n * @param init - Fetch init options\n * @param retryOptions - Retry options\n * @returns The fetch response\n */\nexport async function fetchWithRetry(\n url: string,\n init?: RequestInit,\n retryOptions: RetryOptions = {},\n): Promise<Response> {\n const maxRetries = retryOptions.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries;\n\n let lastError: Error | undefined;\n let lastResponse: Response | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, init);\n lastResponse = response;\n\n // Check if the response status is retryable\n if (isRetryableStatus(response.status) && attempt < maxRetries) {\n const delay = calculateDelay(attempt, retryOptions);\n await sleep(delay);\n continue;\n }\n\n return response;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Check if we should retry\n const isRetryable = retryOptions.isRetryable ?? isRetryableError;\n const shouldRetry = attempt < maxRetries && isRetryable(lastError);\n\n if (!shouldRetry) {\n throw lastError;\n }\n\n // Calculate and wait for the delay\n const delay = calculateDelay(attempt, retryOptions);\n await sleep(delay);\n }\n }\n\n // If we have a response (from retryable status), return it\n if (lastResponse) {\n return lastResponse;\n }\n\n // Otherwise throw the last error\n throw lastError ?? new Error(\"Fetch failed after retries\");\n}\n"],"mappings":";;;;AAmBA,MAAa,wBAAqE;CAChF,YAAY;CACZ,cAAc;CACd,UAAU;CACV,YAAY;CACb;;;;;;;AAQD,SAAgB,eACd,SACA,UAA0E,EAAE,EACpE;CACR,MAAM,eAAe,QAAQ,gBAAgB,sBAAsB;CACnE,MAAM,WAAW,QAAQ,YAAY,sBAAsB;CAG3D,MAAM,QAAQ,gBAFK,QAAQ,cAAc,sBAAsB,eAEpB;AAC3C,QAAO,KAAK,IAAI,OAAO,SAAS;;;;;AAMlC,SAAgB,MAAM,IAA2B;AAC/C,QAAO,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;;;;;AAM1D,SAAgB,iBAAiB,OAAuB;CACtD,MAAM,UAAU,MAAM,QAAQ,aAAa;AAgB3C,QAb0B;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAEwB,MAAM,YAAY,QAAQ,SAAS,QAAQ,CAAC;;;;;AAMvE,SAAgB,kBAAkB,QAAyB;AAEzD,KAAI,UAAU,OAAO,SAAS,IAC5B,QAAO;AAGT,KAAI,WAAW,IACb,QAAO;AAET,QAAO;;;;;;;;AAST,eAAsB,UAAa,IAAsB,UAAwB,EAAE,EAAc;CAC/F,MAAM,aAAa,QAAQ,cAAc,sBAAsB;CAC/D,MAAM,cAAc,QAAQ,iBAAiB,UAAiB,iBAAiB,MAAM;CAErF,IAAI;AAEJ,MAAK,IAAI,UAAU,GAAG,WAAW,YAAY,UAC3C,KAAI;AACF,SAAO,MAAM,IAAI;UACV,OAAO;AACd,cAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AAKrE,MAAI,EAFgB,UAAU,cAAc,YAAY,UAAU,EAGhE,OAAM;AAKR,QAAM,MADQ,eAAe,SAAS,QAAQ,CAC5B;;AAKtB,OAAM,6BAAa,IAAI,MAAM,eAAe;;;;;;;;;AAU9C,eAAsB,eACpB,KACA,MACA,eAA6B,EAAE,EACZ;CACnB,MAAM,aAAa,aAAa,cAAc,sBAAsB;CAEpE,IAAI;CACJ,IAAI;AAEJ,MAAK,IAAI,UAAU,GAAG,WAAW,YAAY,UAC3C,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,KAAK,KAAK;AACvC,iBAAe;AAGf,MAAI,kBAAkB,SAAS,OAAO,IAAI,UAAU,YAAY;AAE9D,SAAM,MADQ,eAAe,SAAS,aAAa,CACjC;AAClB;;AAGF,SAAO;UACA,OAAO;AACd,cAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;EAGrE,MAAM,cAAc,aAAa,eAAe;AAGhD,MAAI,EAFgB,UAAU,cAAc,YAAY,UAAU,EAGhE,OAAM;AAKR,QAAM,MADQ,eAAe,SAAS,aAAa,CACjC;;AAKtB,KAAI,aACF,QAAO;AAIT,OAAM,6BAAa,IAAI,MAAM,6BAA6B"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@aigne/afs-http",
3
+ "version": "1.11.0-beta.3",
4
+ "description": "AIGNE AFS HTTP transport provider for remote AFS access",
5
+ "license": "UNLICENSED",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "author": "Arcblock <blocklet@arcblock.io> https://github.com/arcblock",
10
+ "homepage": "https://github.com/arcblock/afs",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/arcblock/afs"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/arcblock/afs/issues"
17
+ },
18
+ "type": "module",
19
+ "main": "./dist/index.cjs",
20
+ "module": "./dist/index.mjs",
21
+ "types": "./dist/index.d.cts",
22
+ "exports": {
23
+ ".": {
24
+ "require": "./dist/index.cjs",
25
+ "import": "./dist/index.mjs"
26
+ },
27
+ "./*": "./*"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "LICENSE",
32
+ "README.md",
33
+ "CHANGELOG.md"
34
+ ],
35
+ "dependencies": {
36
+ "zod": "^3.25.67",
37
+ "@aigne/afs": "^1.11.0-beta.3"
38
+ },
39
+ "devDependencies": {
40
+ "@types/bun": "^1.3.6",
41
+ "npm-run-all": "^4.1.5",
42
+ "rimraf": "^6.1.2",
43
+ "tsdown": "0.20.0-beta.3",
44
+ "typescript": "5.9.2",
45
+ "@aigne/scripts": "0.0.0",
46
+ "@aigne/typescript-config": "0.0.0"
47
+ },
48
+ "scripts": {
49
+ "build": "tsdown",
50
+ "check-types": "tsc --noEmit",
51
+ "clean": "rimraf dist coverage",
52
+ "test": "bun test",
53
+ "test:coverage": "bun test --coverage --coverage-reporter=lcov --coverage-reporter=text"
54
+ }
55
+ }