nim-sync 1.0.0

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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Exponential backoff retry utility for API calls.
3
+ */
4
+ export interface RetryOptions {
5
+ /** Maximum number of retry attempts (default: 3) */
6
+ maxRetries?: number;
7
+ /** Initial delay in milliseconds (default: 1000) */
8
+ initialDelay?: number;
9
+ /** Maximum delay in milliseconds (default: 10000) */
10
+ maxDelay?: number;
11
+ /** Whether to retry on network errors (default: true) */
12
+ retryOnNetworkError?: boolean;
13
+ /** Status codes to retry (default: [429, 500, 502, 503, 504]) */
14
+ retryStatusCodes?: number[];
15
+ }
16
+ /**
17
+ * Executes a function with exponential backoff retry logic.
18
+ *
19
+ * @param fn - Function to execute with retry logic
20
+ * @param options - Retry configuration options
21
+ * @returns Result of the function if successful
22
+ * @throws Last error if all retries are exhausted
23
+ */
24
+ export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
25
+ /**
26
+ * Creates a retryable fetch wrapper with exponential backoff.
27
+ *
28
+ * @param apiKey - API key for authentication
29
+ * @param baseURL - Base URL for the API
30
+ * @param endpoint - API endpoint to call
31
+ * @param options - Retry configuration options
32
+ * @returns Fetch response with retry logic
33
+ */
34
+ export declare function retryableFetch(apiKey: string, baseURL: string, endpoint: string, options?: RetryOptions): Promise<Response>;
35
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/lib/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC5B;AAUD;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CA8BZ;AAwED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAenB"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Exponential backoff retry utility for API calls.
3
+ */
4
+ const DEFAULT_OPTIONS = {
5
+ maxRetries: 3,
6
+ initialDelay: 1000,
7
+ maxDelay: 10000,
8
+ retryOnNetworkError: true,
9
+ retryStatusCodes: [429, 500, 502, 503, 504]
10
+ };
11
+ /**
12
+ * Executes a function with exponential backoff retry logic.
13
+ *
14
+ * @param fn - Function to execute with retry logic
15
+ * @param options - Retry configuration options
16
+ * @returns Result of the function if successful
17
+ * @throws Last error if all retries are exhausted
18
+ */
19
+ export async function withRetry(fn, options = {}) {
20
+ const opts = { ...DEFAULT_OPTIONS, ...options };
21
+ let lastError = null;
22
+ for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
23
+ try {
24
+ return await fn();
25
+ }
26
+ catch (error) {
27
+ lastError = error instanceof Error ? error : new Error(String(error));
28
+ // Determine if we should retry
29
+ const shouldRetry = shouldRetryError(error, opts);
30
+ if (!shouldRetry || attempt === opts.maxRetries) {
31
+ throw lastError;
32
+ }
33
+ // Calculate delay with exponential backoff
34
+ const delay = Math.min(opts.initialDelay * Math.pow(2, attempt), opts.maxDelay);
35
+ // Wait before retrying
36
+ await new Promise(resolve => setTimeout(resolve, delay));
37
+ }
38
+ }
39
+ // This should never be reached due to throw in loop, but TypeScript needs it
40
+ throw lastError || new Error('Retry logic failed unexpectedly');
41
+ }
42
+ /**
43
+ * Determines if an error should trigger a retry.
44
+ *
45
+ * @param error - The caught error
46
+ * @param options - Retry configuration
47
+ * @returns True if the error should trigger a retry
48
+ */
49
+ function shouldRetryError(error, options) {
50
+ // Network errors (timeouts, connection refused, etc.)
51
+ if (options.retryOnNetworkError && isNetworkError(error)) {
52
+ return true;
53
+ }
54
+ // Check if it's an HTTP error with retryable status code
55
+ if (isHttpError(error)) {
56
+ const statusCode = getStatusCode(error);
57
+ return options.retryStatusCodes.includes(statusCode);
58
+ }
59
+ return false;
60
+ }
61
+ /**
62
+ * Checks if an error is a network error (timeout, connection refused, etc.).
63
+ */
64
+ function isNetworkError(error) {
65
+ if (!(error instanceof Error)) {
66
+ return false;
67
+ }
68
+ const networkErrorPatterns = [
69
+ 'network',
70
+ 'timeout',
71
+ 'connection',
72
+ 'fetch',
73
+ 'abort',
74
+ 'ECONNREFUSED',
75
+ 'ETIMEDOUT'
76
+ ];
77
+ const message = error.message.toLowerCase();
78
+ const name = error.name.toLowerCase();
79
+ return networkErrorPatterns.some(pattern => message.includes(pattern) || name.includes(pattern));
80
+ }
81
+ /**
82
+ * Checks if an error is an HTTP error with a status code.
83
+ */
84
+ function isHttpError(error) {
85
+ return (typeof error === 'object' &&
86
+ error !== null &&
87
+ 'statusCode' in error &&
88
+ typeof error.statusCode === 'number');
89
+ }
90
+ /**
91
+ * Extracts the status code from an HTTP error.
92
+ */
93
+ function getStatusCode(error) {
94
+ if (isHttpError(error)) {
95
+ return error.statusCode;
96
+ }
97
+ return 0;
98
+ }
99
+ /**
100
+ * Creates a retryable fetch wrapper with exponential backoff.
101
+ *
102
+ * @param apiKey - API key for authentication
103
+ * @param baseURL - Base URL for the API
104
+ * @param endpoint - API endpoint to call
105
+ * @param options - Retry configuration options
106
+ * @returns Fetch response with retry logic
107
+ */
108
+ export async function retryableFetch(apiKey, baseURL, endpoint, options = {}) {
109
+ return withRetry(async () => {
110
+ const response = await fetch(`${baseURL}${endpoint}`, {
111
+ headers: {
112
+ 'Authorization': `Bearer ${apiKey}`,
113
+ 'Content-Type': 'application/json'
114
+ }
115
+ });
116
+ if (!response.ok) {
117
+ throw { statusCode: response.status, statusText: response.statusText };
118
+ }
119
+ return response;
120
+ }, options);
121
+ }
122
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/lib/retry.ts"],"names":[],"mappings":"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"}