@superutils/fetch 1.5.14 → 1.5.16
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.
- package/README.md +217 -212
- package/dist/browser/index.min.js.map +1 -1
- package/dist/index.d.cts +80 -27
- package/dist/index.d.ts +80 -27
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -155,40 +155,33 @@ type FetchInterceptorResponse = Interceptor<Response, FetchArgsInterceptor>;
|
|
|
155
155
|
* ```javascript
|
|
156
156
|
* import fetch from '@superutils/fetch'
|
|
157
157
|
*
|
|
158
|
-
* // first transform result (user object) and ensure user result alwasy contain a hexadecimal crypto balance
|
|
159
|
-
* const ensureBalanceHex = (user = {}) => {
|
|
160
|
-
* user.crypto ??= {}
|
|
161
|
-
* user.crypto.balance ??= '0x0'
|
|
162
|
-
* return user
|
|
163
|
-
* }
|
|
164
|
-
* // then check convert hexadecimal number to BigInt
|
|
165
|
-
* const hexToBigInt = user => {
|
|
166
|
-
* user.crypto.balance = BigInt(user.crypto.balance)
|
|
167
|
-
* return user
|
|
168
|
-
* }
|
|
169
|
-
* // then log balance (no transformation)
|
|
170
|
-
* const logBalance = (result, url) => {
|
|
171
|
-
* // only log balance for single user requests
|
|
172
|
-
* const shouldLog = result?.hasOwnProperty('crypto') && /^[0-9]+$/.test(
|
|
173
|
-
* url?.split('/users/')[1].replace('/', '')
|
|
174
|
-
* )
|
|
175
|
-
* shouldLog && console.log(
|
|
176
|
-
* new Date().toISOString(),
|
|
177
|
-
* '[UserBalance] UserID:', result.id,
|
|
178
|
-
* result.crypto.balance
|
|
179
|
-
* )
|
|
180
|
-
* }
|
|
181
|
-
* // now we make the actaul fetch request
|
|
182
158
|
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/users/1', {
|
|
183
159
|
* interceptors: {
|
|
184
160
|
* result: [
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
161
|
+
* // 1. check & convert user crypto balance to BigInt
|
|
162
|
+
* userCryptoBalanceToBigInt,
|
|
163
|
+
*
|
|
164
|
+
* // 2. log balance (no transformation)
|
|
165
|
+
* logUserBalance
|
|
188
166
|
* ]
|
|
189
167
|
* }
|
|
190
168
|
* })
|
|
191
169
|
* console.log({result})
|
|
170
|
+
*
|
|
171
|
+
* function userCryptoBalanceToBigInt(user = {}) {
|
|
172
|
+
* user.crypto ??= {}
|
|
173
|
+
* user.crypto.balance ??= '0x0'
|
|
174
|
+
* user.crypto.balance = BigInt(user.crypto.balance || '0x0')
|
|
175
|
+
* return user
|
|
176
|
+
* }
|
|
177
|
+
*
|
|
178
|
+
* function logUserBalance(user, url) {
|
|
179
|
+
* console.log(
|
|
180
|
+
* new Date().toISOString(),
|
|
181
|
+
* '[UserBalance] UserID:', user.id,
|
|
182
|
+
* user.crypto.balance
|
|
183
|
+
* )
|
|
184
|
+
* }
|
|
192
185
|
* ```
|
|
193
186
|
*/
|
|
194
187
|
type FetchInterceptorResult<Args extends unknown[] = FetchArgsInterceptor> = Interceptor<unknown, Args>;
|
|
@@ -377,6 +370,61 @@ type FetchRetryOptions = Omit<Partial<RetryOptions>, 'retry' | 'retryIf'> & {
|
|
|
377
370
|
* Default: `0`
|
|
378
371
|
*/
|
|
379
372
|
retry?: number;
|
|
373
|
+
/**
|
|
374
|
+
* An optional predicate function to determine retry eligibility.
|
|
375
|
+
* Also useful for side effects like logging or analytics.
|
|
376
|
+
*
|
|
377
|
+
* Returning `true` explicitly triggers a retry, while `false` prevents it.
|
|
378
|
+
* If the function returns `undefined` or `void`, the default library logic is used
|
|
379
|
+
* (retry if an exception was thrown or if `response.ok` is `false`).
|
|
380
|
+
*
|
|
381
|
+
* @param response The Response object from the last attempt, if available.
|
|
382
|
+
* @param retryCount The current retry attempt number (starting from 1).
|
|
383
|
+
* @param error The error encountered during the request, if any.
|
|
384
|
+
*
|
|
385
|
+
* @returns A boolean indicating whether to retry, or a promise resolving to boolean.
|
|
386
|
+
*
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* #### Example: Retry on specific status codes
|
|
390
|
+
* ```javascript
|
|
391
|
+
* import fetch from '@superutils/fetch'
|
|
392
|
+
*
|
|
393
|
+
* fetch
|
|
394
|
+
* .get('[DUMMYJSON-DOT-COM]/products/1', {
|
|
395
|
+
* retry: 3, // If request fails, retry up to three more times
|
|
396
|
+
* // Retry on rate limits (429) or transient server errors (5xx).
|
|
397
|
+
* retryIf: r => r.status === 429 || r.status >= 500,
|
|
398
|
+
* })
|
|
399
|
+
* .then(console.log)
|
|
400
|
+
* ```
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* #### Example: Polling (Retry until a condition is met)
|
|
404
|
+
* Keep retrying every minute until a product is back in stock.
|
|
405
|
+
* ```javascript
|
|
406
|
+
* import fetch from '@superutils/fetch'
|
|
407
|
+
*
|
|
408
|
+
* fetch
|
|
409
|
+
* .get('[DUMMYJSON-DOT-COM]/products/1', {
|
|
410
|
+
* delay: 60_000, // Wait 1 minute between attempts
|
|
411
|
+
* retry: 10, // Attempt up to 10 more times
|
|
412
|
+
* retryIf: async (response) => {
|
|
413
|
+
* if (!response?.ok) return true // Retry on network or server errors
|
|
414
|
+
*
|
|
415
|
+
* // Use response.clone() to avoid consuming the body stream used by the final result.
|
|
416
|
+
* const result = await response.clone().json()
|
|
417
|
+
*
|
|
418
|
+
* // Retry if the product is still NOT in stock
|
|
419
|
+
* return result?.availabilityStatus !== 'In Stock'
|
|
420
|
+
* },
|
|
421
|
+
*
|
|
422
|
+
* // Ensure the overall timeout accounts for the polling duration
|
|
423
|
+
* timeout: 60_000 * 15
|
|
424
|
+
* })
|
|
425
|
+
* .then(product => console.log('Product is back in stock:', product))
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
380
428
|
retryIf?: RetryIfFunc<Response>;
|
|
381
429
|
};
|
|
382
430
|
/**
|
|
@@ -487,6 +535,11 @@ type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ?
|
|
|
487
535
|
* which minimizes code repetition across your application. If a method is not specified during creation, the client
|
|
488
536
|
* will default to `GET`.
|
|
489
537
|
*
|
|
538
|
+
* **Option Priority:**
|
|
539
|
+
* 1. `fixedOptions`: Highest priority. Cannot be overridden by the caller.
|
|
540
|
+
* 2. `options`: Options passed during the specific call.
|
|
541
|
+
* 3. `commonOptions`: Default options set at creation time.
|
|
542
|
+
*
|
|
490
543
|
* The returned client also includes a `.deferred()` method, providing the same debounce, throttle, and sequential
|
|
491
544
|
* execution capabilities found in functions like `fetch.get.deferred()`.
|
|
492
545
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -155,40 +155,33 @@ type FetchInterceptorResponse = Interceptor<Response, FetchArgsInterceptor>;
|
|
|
155
155
|
* ```javascript
|
|
156
156
|
* import fetch from '@superutils/fetch'
|
|
157
157
|
*
|
|
158
|
-
* // first transform result (user object) and ensure user result alwasy contain a hexadecimal crypto balance
|
|
159
|
-
* const ensureBalanceHex = (user = {}) => {
|
|
160
|
-
* user.crypto ??= {}
|
|
161
|
-
* user.crypto.balance ??= '0x0'
|
|
162
|
-
* return user
|
|
163
|
-
* }
|
|
164
|
-
* // then check convert hexadecimal number to BigInt
|
|
165
|
-
* const hexToBigInt = user => {
|
|
166
|
-
* user.crypto.balance = BigInt(user.crypto.balance)
|
|
167
|
-
* return user
|
|
168
|
-
* }
|
|
169
|
-
* // then log balance (no transformation)
|
|
170
|
-
* const logBalance = (result, url) => {
|
|
171
|
-
* // only log balance for single user requests
|
|
172
|
-
* const shouldLog = result?.hasOwnProperty('crypto') && /^[0-9]+$/.test(
|
|
173
|
-
* url?.split('/users/')[1].replace('/', '')
|
|
174
|
-
* )
|
|
175
|
-
* shouldLog && console.log(
|
|
176
|
-
* new Date().toISOString(),
|
|
177
|
-
* '[UserBalance] UserID:', result.id,
|
|
178
|
-
* result.crypto.balance
|
|
179
|
-
* )
|
|
180
|
-
* }
|
|
181
|
-
* // now we make the actaul fetch request
|
|
182
158
|
* const result = await fetch.get('[DUMMYJSON-DOT-COM]/users/1', {
|
|
183
159
|
* interceptors: {
|
|
184
160
|
* result: [
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
161
|
+
* // 1. check & convert user crypto balance to BigInt
|
|
162
|
+
* userCryptoBalanceToBigInt,
|
|
163
|
+
*
|
|
164
|
+
* // 2. log balance (no transformation)
|
|
165
|
+
* logUserBalance
|
|
188
166
|
* ]
|
|
189
167
|
* }
|
|
190
168
|
* })
|
|
191
169
|
* console.log({result})
|
|
170
|
+
*
|
|
171
|
+
* function userCryptoBalanceToBigInt(user = {}) {
|
|
172
|
+
* user.crypto ??= {}
|
|
173
|
+
* user.crypto.balance ??= '0x0'
|
|
174
|
+
* user.crypto.balance = BigInt(user.crypto.balance || '0x0')
|
|
175
|
+
* return user
|
|
176
|
+
* }
|
|
177
|
+
*
|
|
178
|
+
* function logUserBalance(user, url) {
|
|
179
|
+
* console.log(
|
|
180
|
+
* new Date().toISOString(),
|
|
181
|
+
* '[UserBalance] UserID:', user.id,
|
|
182
|
+
* user.crypto.balance
|
|
183
|
+
* )
|
|
184
|
+
* }
|
|
192
185
|
* ```
|
|
193
186
|
*/
|
|
194
187
|
type FetchInterceptorResult<Args extends unknown[] = FetchArgsInterceptor> = Interceptor<unknown, Args>;
|
|
@@ -377,6 +370,61 @@ type FetchRetryOptions = Omit<Partial<RetryOptions>, 'retry' | 'retryIf'> & {
|
|
|
377
370
|
* Default: `0`
|
|
378
371
|
*/
|
|
379
372
|
retry?: number;
|
|
373
|
+
/**
|
|
374
|
+
* An optional predicate function to determine retry eligibility.
|
|
375
|
+
* Also useful for side effects like logging or analytics.
|
|
376
|
+
*
|
|
377
|
+
* Returning `true` explicitly triggers a retry, while `false` prevents it.
|
|
378
|
+
* If the function returns `undefined` or `void`, the default library logic is used
|
|
379
|
+
* (retry if an exception was thrown or if `response.ok` is `false`).
|
|
380
|
+
*
|
|
381
|
+
* @param response The Response object from the last attempt, if available.
|
|
382
|
+
* @param retryCount The current retry attempt number (starting from 1).
|
|
383
|
+
* @param error The error encountered during the request, if any.
|
|
384
|
+
*
|
|
385
|
+
* @returns A boolean indicating whether to retry, or a promise resolving to boolean.
|
|
386
|
+
*
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* #### Example: Retry on specific status codes
|
|
390
|
+
* ```javascript
|
|
391
|
+
* import fetch from '@superutils/fetch'
|
|
392
|
+
*
|
|
393
|
+
* fetch
|
|
394
|
+
* .get('[DUMMYJSON-DOT-COM]/products/1', {
|
|
395
|
+
* retry: 3, // If request fails, retry up to three more times
|
|
396
|
+
* // Retry on rate limits (429) or transient server errors (5xx).
|
|
397
|
+
* retryIf: r => r.status === 429 || r.status >= 500,
|
|
398
|
+
* })
|
|
399
|
+
* .then(console.log)
|
|
400
|
+
* ```
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* #### Example: Polling (Retry until a condition is met)
|
|
404
|
+
* Keep retrying every minute until a product is back in stock.
|
|
405
|
+
* ```javascript
|
|
406
|
+
* import fetch from '@superutils/fetch'
|
|
407
|
+
*
|
|
408
|
+
* fetch
|
|
409
|
+
* .get('[DUMMYJSON-DOT-COM]/products/1', {
|
|
410
|
+
* delay: 60_000, // Wait 1 minute between attempts
|
|
411
|
+
* retry: 10, // Attempt up to 10 more times
|
|
412
|
+
* retryIf: async (response) => {
|
|
413
|
+
* if (!response?.ok) return true // Retry on network or server errors
|
|
414
|
+
*
|
|
415
|
+
* // Use response.clone() to avoid consuming the body stream used by the final result.
|
|
416
|
+
* const result = await response.clone().json()
|
|
417
|
+
*
|
|
418
|
+
* // Retry if the product is still NOT in stock
|
|
419
|
+
* return result?.availabilityStatus !== 'In Stock'
|
|
420
|
+
* },
|
|
421
|
+
*
|
|
422
|
+
* // Ensure the overall timeout accounts for the polling duration
|
|
423
|
+
* timeout: 60_000 * 15
|
|
424
|
+
* })
|
|
425
|
+
* .then(product => console.log('Product is back in stock:', product))
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
380
428
|
retryIf?: RetryIfFunc<Response>;
|
|
381
429
|
};
|
|
382
430
|
/**
|
|
@@ -487,6 +535,11 @@ type ClientData<FixedOptions> = ExtractAs<[FixedOptions]> extends FetchAs.json ?
|
|
|
487
535
|
* which minimizes code repetition across your application. If a method is not specified during creation, the client
|
|
488
536
|
* will default to `GET`.
|
|
489
537
|
*
|
|
538
|
+
* **Option Priority:**
|
|
539
|
+
* 1. `fixedOptions`: Highest priority. Cannot be overridden by the caller.
|
|
540
|
+
* 2. `options`: Options passed during the specific call.
|
|
541
|
+
* 3. `commonOptions`: Default options set at creation time.
|
|
542
|
+
*
|
|
490
543
|
* The returned client also includes a `.deferred()` method, providing the same debounce, throttle, and sequential
|
|
491
544
|
* execution capabilities found in functions like `fetch.get.deferred()`.
|
|
492
545
|
*
|
package/package.json
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
},
|
|
6
6
|
"description": "A lightweight `fetch` wrapper for browsers and Node.js, designed to simplify data fetching and reduce boilerplate.",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@superutils/core": "^1.2.
|
|
9
|
-
"@superutils/promise": "^1.3.
|
|
8
|
+
"@superutils/core": "^1.2.15",
|
|
9
|
+
"@superutils/promise": "^1.3.14"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
"module": "./dist/index.js",
|
|
54
54
|
"type": "module",
|
|
55
55
|
"types": "./dist/index.d.ts",
|
|
56
|
-
"version": "1.5.
|
|
57
|
-
"gitHead": "
|
|
56
|
+
"version": "1.5.16",
|
|
57
|
+
"gitHead": "7be3be6fb4a8cb1955ee5f704fc49bbb792bd961"
|
|
58
58
|
}
|