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
Copy file name to clipboardExpand all lines: README.md
+36-18Lines changed: 36 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,18 +15,21 @@
15
15
16
16
ffetch can wrap any fetch-compatible implementation (native fetch, node-fetch, undici, or framework-provided fetch), making it flexible for SSR, edge, and custom environments.
17
17
18
+
ffetch uses a plugin architecture for optional features, so you only include what you need.
If your environment does not support `AbortSignal.any` (Node.js < 20.6, older browsers), you **must install a polyfill** before using ffetch. See the [compatibility guide](./docs/compatibility.md) for instructions.
164
+
If your environment does not support `AbortSignal.any` (Node.js < 20.6, older browsers), you can still use ffetch by installing an `AbortSignal.any`polyfill. `AbortSignal.timeout` is optional because ffetch includes an internal timeout fallback. See the [compatibility guide](./docs/compatibility.md) for instructions.
148
165
149
166
**Custom fetch support:**
150
167
You can pass any fetch-compatible implementation (native fetch, node-fetch, undici, SvelteKit, Next.js, Nuxt, or a polyfill) via the `fetchHandler` option. This makes ffetch fully compatible with SSR, edge, metaframework environments, custom backends, and test runners.
- Deduplication is **off** by default. Enable it via the `dedupe` option.
190
+
- Deduplication is **off** by default. Enable it via `plugins: [dedupePlugin()]`.
174
191
- 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.
192
+
- Optional stale-entry cleanup: `dedupePlugin({ ttl, sweepInterval })` enables map-entry eviction. TTL eviction only removes dedupe keys; it does not reject already in-flight promises.
176
193
-**Stream bodies** (`ReadableStream`, `FormData`): Deduplication is skipped for requests with these body types, as they cannot be reliably hashed or replayed.
177
194
-**Non-idempotent requests**: Use deduplication with caution for non-idempotent methods (e.g., POST), as it may suppress multiple intended requests.
178
195
-**Custom hash function**: Ensure your hash function uniquely identifies requests to avoid accidental deduplication.
@@ -185,6 +202,7 @@ See [deduplication.md](./docs/deduplication.md) for full details.
// attempt: number (starts at 1 for first retry decision)
130
130
// request: Request
131
131
// response: Response | undefined
132
132
// error: unknown
@@ -198,23 +198,29 @@ This is useful for:
198
198
- Implementing custom fallback or degraded mode logic
199
199
- Integrating with dashboards or metrics
200
200
201
-
> **Note:**If the client is not configured with a circuit breaker (`circuit` option omitted), `client.circuitOpen` will always be `false` and the property is inert.
201
+
> **Note:**`client.circuitOpen` is provided by `circuitPlugin`. If that plugin is not installed, this extension is not available on the client.
202
202
203
203
### How it Works
204
204
205
205
- When the number of consecutive failures reaches the `threshold`, the circuit "opens" and all further requests fail fast with a `CircuitOpenError`
206
206
- After the `reset` period (in milliseconds), the circuit "closes" and requests are allowed again
207
207
- If a request succeeds, the failure count resets
208
+
- If `onCircuitOpen` is configured, it runs both when the circuit opens and when requests are blocked while it is already open
0 commit comments