You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Deduplication is **off** by default. Enable it via the `dedupe` option.
174
174
- The default hash function is `dedupeRequestHash`, which handles common body types and skips deduplication for streams and FormData.
175
+
- Optional stale-entry cleanup: `dedupeTTL` enables map-entry eviction, and `dedupeSweepInterval` controls how often eviction runs. TTL eviction only removes dedupe keys; it does not reject already in-flight promises.
175
176
-**Stream bodies** (`ReadableStream`, `FormData`): Deduplication is skipped for requests with these body types, as they cannot be reliably hashed or replayed.
176
177
-**Non-idempotent requests**: Use deduplication with caution for non-idempotent methods (e.g., POST), as it may suppress multiple intended requests.
177
178
-**Custom hash function**: Ensure your hash function uniquely identifies requests to avoid accidental deduplication.
|`dedupe`|`boolean`|`false`| If true, enables automatic deduplication of in-flight identical requests. |
32
-
|`dedupeHashFn`| `(params: DedupeHashParams) => string | undefined` |`dedupeRequestHash`| Custom function to generate deduplication keys. Use exported `DedupeHashParams` type for params. |
33
-
|`throwOnHttpError`|`boolean`|`false`| If true, throws an `HttpError` for all HTTP error responses (all 4xx and 5xx) after all retries are exhausted. Otherwise, returns the final `Response`. |
34
-
|`circuit`|`{ threshold: number, reset: number }`|`undefined`| Circuit-breaker configuration |
|`dedupe`|`boolean`|`false`| If true, enables automatic deduplication of in-flight identical requests. |
32
+
|`dedupeHashFn`|`(params: DedupeHashParams) => string \| undefined`|`dedupeRequestHash`| Custom function to generate deduplication keys. Return `undefined` to skip deduplication for a request. |
33
+
|`dedupeTTL`|`number` (ms) |`undefined`| Optional TTL for dedupe-map entries. Expired entries are evicted by the sweeper. |
34
+
|`dedupeSweepInterval`|`number` (ms) |`5000`| Interval used by the dedupe sweeper when `dedupeTTL` is set. |
35
+
|`throwOnHttpError`|`boolean`|`false`| If true, throws an `HttpError` for all HTTP error responses (all 4xx and 5xx) after all retries are exhausted. Otherwise, returns the final `Response`. |
36
+
|`circuit`|`{ threshold: number, reset: number }`|`undefined`| Circuit-breaker configuration |
|`fetchHandler`|`(input: RequestInfo \| URL, init?: RequestInit) => Promise<Response>`|`global fetch`| Custom fetch-compatible implementation to wrap (e.g., SvelteKit, Next.js, Nuxt, node-fetch, undici, or any polyfill). Defaults to global fetch. |
37
39
38
40
### Deduplication
39
41
@@ -59,6 +61,23 @@ const client = createClient({
59
61
**Default:**
60
62
Uses the built-in `dedupeRequestHash` function, which considers method, URL, and body, and skips deduplication for FormData and ReadableStream bodies.
61
63
64
+
#### `dedupeTTL` (number, milliseconds)
65
+
66
+
Optional TTL for dedupe-map entries. If set, expired entries are removed by a sweeper timer. This helps prevent stale in-flight dedupe keys from lingering indefinitely in failure or hanging-request scenarios.
67
+
68
+
Important behavior:
69
+
70
+
- Deduplication still works when `dedupeTTL` is `undefined`.
71
+
- TTL eviction only removes dedupe keys from the map.
72
+
- TTL eviction does **not** reject already in-flight promises.
73
+
74
+
#### `dedupeSweepInterval` (number, milliseconds)
75
+
76
+
Controls how often the dedupe sweeper checks for expired entries when `dedupeTTL` is enabled.
77
+
78
+
- Default: `5000` ms.
79
+
- Only relevant when `dedupeTTL` is set to a positive number.
You can optionally enable stale-entry eviction for the internal dedupe map:
23
+
24
+
```js
25
+
constclient=createClient({
26
+
dedupe:true,
27
+
dedupeTTL:30_000, // Evict dedupe entries older than 30s
28
+
dedupeSweepInterval:5_000, // Check every 5s
29
+
})
30
+
```
31
+
32
+
Behavior notes:
33
+
34
+
- Deduplication works with or without TTL.
35
+
-`dedupeTTL` only controls eviction of dedupe-map keys.
36
+
- TTL eviction does **not** reject an already in-flight request promise.
37
+
-`dedupeSweepInterval` only matters when `dedupeTTL` is a positive number.
38
+
20
39
### Custom Hash Function
21
40
22
41
You can provide a custom hash function to control how deduplication keys are generated:
@@ -34,12 +53,15 @@ The default hash function considers method, URL, and body. For advanced use case
34
53
35
54
- Deduplication is **off** by default. Enable it via the `dedupe` option.
36
55
- The default hash function is `dedupeRequestHash`, which handles common body types and skips deduplication for streams and FormData.
56
+
-`dedupeTTL` is `undefined` by default (TTL eviction disabled).
57
+
-`dedupeSweepInterval` defaults to `5000` ms.
37
58
38
59
## Limitations
39
60
40
61
-**Stream bodies** (`ReadableStream`, `FormData`): Deduplication is skipped for requests with these body types, as they cannot be reliably hashed or replayed.
41
62
-**Non-idempotent requests**: Use deduplication with caution for non-idempotent methods (e.g., POST), as it may suppress multiple intended requests.
42
63
-**Custom hash function**: Ensure your hash function uniquely identifies requests to avoid accidental deduplication.
64
+
-**TTL scope**: `dedupeTTL` does not cache final responses. It only evicts in-flight dedupe keys from the internal map.
0 commit comments