@passcod/faith 0.0.2 → 0.0.5

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 CHANGED
@@ -1,18 +1,19 @@
1
1
  # fáith - Rust-powered fetch API for Node.js
2
2
 
3
- /ˈɸaːθj/ — pronounced FATH, like FATHER without the ER. This is an old irish word with the same
4
- root as "fetch", meaning _poet_, _soothsayer_, _seer_, and later, _prophet_.
3
+ /ˈɸaːθj/ — pronounced FATH, like FATHER without the ER. This is an old irish word that is a folk
4
+ etymology of "fetch", and means _poet_, _soothsayer_, _seer_, and later, _prophet_.
5
5
 
6
6
  Fáith is of course a pun with _faith_, and is meant to be a _faithful_ implementation of the fetch
7
7
  API for Node.js, but using a Rust-based network stack instead of undici + libuv.
8
8
 
9
9
  Most `fetch` implementations for Node.js are based on the Node.js TCP stack (via libuv) and cannot
10
10
  easily work around its limitations. The native fetch implementation, `undici`, explicitly targets
11
- HTTP/1.1, and doesn't support HTTP/2+, among many other complaints.
11
+ HTTP/1.1, and doesn't support HTTP/2+, among many other complaints (of course, for HTTP/1, undici
12
+ is a very good effort! it just feels like a bit of an outdated choice today).
12
13
 
13
14
  Fáith tries to bring a Node.js fetch that is closer to the browser's fetch, notably by having
14
- transparent support for HTTP/2 and HTTP/3, IPv6 and IPv4 using the "Happy Eyeballs" algorithm, an
15
- HTTP cache and a cookie jar, a DNS cache, and actual support for `half` and `full` duplex modes.
15
+ transparent support for HTTP/2 and HTTP/3, IPv6 and IPv4 using the "Happy Eyeballs" algorithm, a
16
+ DNS cache, an optional cookie jar, and your choice of two HTTP caches.
16
17
 
17
18
  ## Installation
18
19
 
@@ -31,7 +32,7 @@ async function example() {
31
32
  const response = await fetch('https://httpbin.org/get');
32
33
  console.log(response.status); // 200
33
34
  console.log(response.ok); // true
34
-
35
+
35
36
  const data = response.json();
36
37
  console.log(data.url); // https://httpbin.org/get
37
38
  }
@@ -40,6 +41,8 @@ async function example() {
40
41
  ### Fetch with options
41
42
 
42
43
  ```javascript
44
+ import { fetch } from '@passcod/faith';
45
+
43
46
  const response = await fetch('https://httpbin.org/post', {
44
47
  method: 'POST',
45
48
  headers: {
@@ -47,7 +50,27 @@ const response = await fetch('https://httpbin.org/post', {
47
50
  'X-Custom-Header': 'value'
48
51
  },
49
52
  body: JSON.stringify({ message: 'Hello' }),
50
- timeout: 30 // seconds
53
+ });
54
+ ```
55
+
56
+ ### Fetch with HTTP cache
57
+
58
+ ```javascript
59
+ import { fetch, Agent } from '@passcod/faith';
60
+
61
+ const agent = new Agent({
62
+ cache: {
63
+ store: 'memory',
64
+ },
65
+ });
66
+ const response = await fetch('https://httpbin.org/post', {
67
+ agent,
68
+ method: 'POST',
69
+ headers: {
70
+ 'Content-Type': 'application/json',
71
+ 'X-Custom-Header': 'value'
72
+ },
73
+ body: JSON.stringify({ message: 'Hello' }),
51
74
  });
52
75
  ```
53
76
 
@@ -90,6 +113,7 @@ practice the `RequestInit` class does not exist in browsers or Node.js, and so t
90
113
 
91
114
  *A `Promise` that resolves to a `Response` object.*
92
115
 
116
+ <!-- //full duplex mode is not yet implemented//
93
117
  In `half` duplex mode (the default), the promise resolves when the request body has been fully sent
94
118
  and the response headers have been received. In `full` duplex mode (supported by Fáith but not yet
95
119
  browsers), the promise resolves as soon as response headers have been received, even if the request
@@ -97,6 +121,7 @@ body has not yet finished sending. Most HTTP servers will not send response head
97
121
  finished receiving the body so this distinction doesn't matter, but some do, and it is possible to
98
122
  take advantage of this behaviour with `full` duplex mode for decreased latency in specific cases.
99
123
  You may even be able to vary the request body stream based on the response body stream.
124
+ -->
100
125
 
101
126
  ## `Request`
102
127
 
@@ -118,7 +143,7 @@ then the value passed directly into `fetch()` is used.*
118
143
 
119
144
  Note that you can include options that Fáith does not support; they will simply be ignored.
120
145
 
121
- ### `agent`
146
+ ### `FetchOptions.agent: Agent`
122
147
 
123
148
  This is custom to Fáith.
124
149
 
@@ -128,11 +153,11 @@ Notably an agent has a DNS cache, and may be configured to handle cookies and/or
128
153
 
129
154
  When not provided, a global default `Agent` is created on first use.
130
155
 
131
- ### `attributionReporting`
156
+ ### `FetchOptions.attributionReporting`
132
157
 
133
158
  Fáith deliberately does not implement this.
134
159
 
135
- ### `body`
160
+ ### `FetchOptions.body`
136
161
 
137
162
  *The request body contains content to send to the server, for example in a `POST` or `PUT` request.
138
163
  It is specified as an instance of any of the following types:*
@@ -144,23 +169,57 @@ It is specified as an instance of any of the following types:*
144
169
  - *`File`*
145
170
  - *`FormData`*
146
171
  - *`TypedArray`*
147
- - *`URLSearchParams`* Not yet implemented.
172
+ - ~~*`URLSearchParams`*~~ Not yet implemented.
148
173
  - *`ReadableStream`* Note that Fáith currently reads this into memory before sending the request.
149
174
 
150
175
  *If `body` is a `ReadableStream`, the `duplex` option must also be set.*
151
176
 
152
- ### `browsingTopics`
177
+ ### `FetchOptions.browsingTopics`
153
178
 
154
179
  Fáith deliberately does not implement this.
155
180
 
156
- ### `cache`
181
+ ### `FetchOptions.cache`
157
182
 
158
- Fáith does not respect this option on the `RequestInit` dictionary. Instead, the option is present
159
- on `Agent` and applies to all requests made with that `Agent`.
183
+ *The cache mode you want to use for the request. This may be any one of the following values:*
184
+
185
+ - *`default`: The client looks in its HTTP cache for a response matching the request.*
186
+ - *If there is a match and it is fresh, it will be returned from the cache.*
187
+ - *If there is a match but it is stale, the client will make a conditional request to the remote
188
+ server. If the server indicates that the resource has not changed, it will be returned from the
189
+ cache. Otherwise the resource will be downloaded from the server and the cache will be updated.*
190
+ - *If there is no match, the client will make a normal request, and will update the cache with
191
+ the downloaded resource.*
160
192
 
161
- ### `credentials`
193
+ - *`no-store`: The client fetches the resource from the remote server without first looking in the
194
+ cache, and will not update the cache with the downloaded resource.*
162
195
 
163
- *Controls whether or not the browser sends credentials with the request, as well as whether any
196
+ - *`reload`: The client fetches the resource from the remote server without first looking in the
197
+ cache, but then will update the cache with the downloaded resource.*
198
+
199
+ - *`no-cache`: The client looks in its HTTP cache for a response matching the request.*
200
+ - *If there is a match, fresh or stale, the client will make a conditional request to the remote
201
+ server. If the server indicates that the resource has not changed, it will be returned from the
202
+ cache. Otherwise the resource will be downloaded from the server and the cache will be updated.*
203
+ - *If there is no match, the client will make a normal request, and will update the cache with
204
+ the downloaded resource.*
205
+
206
+ - *`force-cache`: The client looks in its HTTP cache for a response matching the request.*
207
+ - *If there is a match, fresh or stale, it will be returned from the cache.*
208
+ - *If there is no match, the client will make a normal request, and will update the cache with
209
+ the downloaded resource.*
210
+
211
+ - *`only-if-cached`: The client looks in its HTTP cache for a response matching the request.*
212
+ - *If there is a match, fresh or stale, it will be returned from the cache.*
213
+ - *If there is no match, a network error is returned.*
214
+
215
+ - `ignore-rules`: Custom to Fáith. Overrides the check that determines if a response can be cached
216
+ to always return true on 200. Uses any response in the HTTP cache matching the request, not
217
+ paying attention to staleness. If there was no response, it creates a normal request and updates
218
+ the HTTP cache with the response.
219
+
220
+ ### `FetchOptions.credentials: string`
221
+
222
+ *Controls whether or not the client sends credentials with the request, as well as whether any
164
223
  `Set-Cookie` response headers are respected. Credentials are cookies, ~~TLS client certificates,~~
165
224
  or authentication headers containing a username and password. This option may be any one of the
166
225
  following values:*
@@ -180,14 +239,14 @@ This is an upstream limitation.
180
239
 
181
240
  Defaults to `include` (browsers default to `same-origin`).
182
241
 
183
- ### `duplex`
242
+ ### `FetchOptions.duplex: string`
184
243
 
185
244
  *Controls duplex behavior of the request. If this is present it must have the value `half`, meaning
186
245
  that Fáith will send the entire request before processing the response.*
187
246
 
188
247
  *This option must be present when `body` is a `ReadableStream`.*
189
248
 
190
- ### `headers`
249
+ ### `FetchOptions.headers: Headers | object`
191
250
 
192
251
  *Any headers you want to add to your request, contained within a `Headers` object or an object
193
252
  literal whose keys are the names of headers and whose values are the header values.*
@@ -196,7 +255,7 @@ Fáith allows all request headers to be set (unlike browsers, which [forbid][1]
196
255
 
197
256
  [1]: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_request_header
198
257
 
199
- ### `integrity`
258
+ ### `FetchOptions.integrity: string`
200
259
 
201
260
  Not implemented yet.
202
261
 
@@ -214,7 +273,7 @@ Fáith only checks the integrity when using `bytes()`, `json()`, `text()`, `arra
214
273
  Note that browsers will throw at the `fetch()` call when integrity fails, but Fáith will only throw
215
274
  when the above methods are called, as until then the body contents are not available.
216
275
 
217
- ### `keepalive`
276
+ ### `FetchOptions.keepalive`
218
277
 
219
278
  Not supported.
220
279
 
@@ -223,41 +282,41 @@ single `Agent`, so subsequent requests to the same endpoint are faster until the
223
282
  times out. The `keepalive` option in browsers is instead a way to send a `fetch()` right before the
224
283
  page is unloaded, for tracking or analytics purposes. This concept does not exist in Node.js.
225
284
 
226
- ### `method`
285
+ ### `FetchOptions.method: string`
227
286
 
228
287
  *The request method. Defaults to `GET`.*
229
288
 
230
- ### `mode`
289
+ ### `FetchOptions.mode`
231
290
 
232
291
  Fáith deliberately does not implement this, as there is no CORS/origin.
233
292
 
234
- ### `priority`
293
+ ### `FetchOptions.priority`
235
294
 
236
295
  Not supported.
237
296
 
238
- ### `redirect`
297
+ ### `FetchOptions.redirect`
239
298
 
240
299
  Fáith does not respect this option on the `RequestInit` dictionary. Instead, the option is present
241
300
  on `Agent` and applies to all requests made with that `Agent`.
242
301
 
243
- ### `referrer`
302
+ ### `FetchOptions.referrer`
244
303
 
245
304
  Fáith deliberately does not implement this, as there is no origin.
246
305
 
247
306
  However, Fáith does set the `Referer` header when redirecting automatically.
248
307
 
249
- ### `referrerPolicy`
308
+ ### `FetchOptions.referrerPolicy`
250
309
 
251
310
  Fáith deliberately does not implement this, as there is no origin.
252
311
 
253
312
  However, Fáith does set the `Referer` header when redirecting automatically.
254
313
 
255
- ### `signal`
314
+ ### `FetchOptions.signal: AbortSignal`
256
315
 
257
316
  *An `AbortSignal`. If this option is set, the request can be canceled by calling `abort()` on the
258
317
  corresponding `AbortController`.*
259
318
 
260
- ### `timeout`
319
+ ### `FetchOptions.timeout: number`
261
320
 
262
321
  Custom to Fáith. Cancels the request after this many milliseconds.
263
322
 
@@ -273,7 +332,7 @@ response receipt.
273
332
  Fáith does not allow its `Response` object to be constructed. If you need to, you may use the
274
333
  `webResponse()` method to convert one into a Web API `Response` object; note the caveats.
275
334
 
276
- ### `Response.body`
335
+ ### `Response.body: ReadableStream | null`
277
336
 
278
337
  *The `body` read-only property of the `Response` interface is a `ReadableStream` of the body
279
338
  contents,* or `null` for any actual HTTP response that has no body, such as `HEAD` requests and
@@ -282,7 +341,7 @@ contents,* or `null` for any actual HTTP response that has no body, such as `HEA
282
341
  Note that browsers currently do not return `null` for those responses, but the spec requires it.
283
342
  Fáith chooses to respect the spec rather than the browsers in this case.
284
343
 
285
- ### `Response.bodyUsed`
344
+ ### `Response.bodyUsed: boolean`
286
345
 
287
346
  *The `bodyUsed` read-only property of the `Response` interface is a boolean value that indicates
288
347
  whether the body has been read yet.*
@@ -291,7 +350,7 @@ In Fáith, this indicates whether the body stream has ever been read from or can
291
350
  [in the spec](https://streams.spec.whatwg.org/#is-readable-stream-disturbed). Note that accessing
292
351
  the `.body` property counts as a read, even if you don't actually consume any bytes of content.
293
352
 
294
- ### `Response.headers`
353
+ ### `Response.headers: Headers`
295
354
 
296
355
  *The `headers` read-only property of the `Response` interface contains the `Headers` object
297
356
  associated with the response.*
@@ -299,12 +358,27 @@ associated with the response.*
299
358
  Note that Fáith does not provide a custom `Headers` class; instead the Web API `Headers` structure
300
359
  is used directly and constructed by Fáith when needed.
301
360
 
302
- ### `Response.ok`
361
+ ### `Response.ok: boolean`
303
362
 
304
363
  *The `ok` read-only property of the `Response` interface contains a boolean stating whether the
305
364
  response was successful (status in the range 200-299) or not.*
306
365
 
307
- ### `Response.redirected`
366
+ ### `Response.peer: object`
367
+
368
+ Custom to Fáith.
369
+
370
+ The `peer` read-only property of the `Response` interface contains an object with information about
371
+ the remote peer that sent this response:
372
+
373
+ #### `Response.peer.address: string | null`
374
+
375
+ The IP address and port of the peer, if available.
376
+
377
+ #### `Response.peer.certificate: Buffer | null`
378
+
379
+ When connected over HTTPS, this is the DER-encoded leaf certificate of the peer.
380
+
381
+ ### `Response.redirected: boolean`
308
382
 
309
383
  *The `redirected` read-only property of the `Response` interface indicates whether or not the
310
384
  response is the result of a request you made which was redirected.*
@@ -312,14 +386,12 @@ response is the result of a request you made which was redirected.*
312
386
  *Note that by the time you read this property, the redirect will already have happened, and you
313
387
  cannot prevent it by aborting the fetch at this point.*
314
388
 
315
- ### `Response.status`
389
+ ### `Response.status: number`
316
390
 
317
391
  *The `status` read-only property of the `Response` interface contains the HTTP status codes of the
318
392
  response. For example, 200 for success, 404 if the resource could not be found.*
319
393
 
320
- *A value is `0` is returned for a response whose `type` is `opaque`, `opaqueredirect`, or `error`.*
321
-
322
- ### `Response.statusText`
394
+ ### `Response.statusText: string`
323
395
 
324
396
  *The `statusText` read-only property of the `Response` interface contains the status message
325
397
  corresponding to the HTTP status code in `Response.status`. For example, this would be `OK` for a
@@ -329,58 +401,57 @@ In HTTP/1, servers can send custom status text. This is returned here. In HTTP/2
329
401
  status text is not supported at all, and the `statusText` property is either empty or simulated
330
402
  from well-known status codes.
331
403
 
332
- ### `Response.type`
404
+ ### `Response.type: string`
333
405
 
334
406
  *The `type` read-only property of the `Response` interface contains the type of the response. The
335
407
  type determines whether scripts are able to access the response body and headers.*
336
408
 
337
409
  In Fáith, this is always set to `basic`.
338
410
 
339
- ### `Response.url`
411
+ ### `Response.url: string`
340
412
 
341
413
  *The `url` read-only property of the `Response` interface contains the URL of the response. The
342
414
  value of the `url` property will be the final URL obtained after any redirects.*
343
415
 
344
- ### `Response.version`
416
+ ### `Response.version: string`
345
417
 
346
418
  The `version` read-only property of the `Response` interface contains the HTTP version of the
347
419
  response. The value will be the final HTTP version after any redirects and protocol upgrades.
348
420
 
349
421
  This is custom to Fáith.
350
422
 
351
- ### `Response.arrayBuffer()`
423
+ ### `Response.arrayBuffer(): Promise<ArrayBuffer>`
352
424
 
353
425
  *The `arrayBuffer()` method of the `Response` interface takes a `Response` stream and reads it to
354
426
  completion. It returns a promise that resolves with an `ArrayBuffer`.*
355
427
 
356
- ### `Response.blob()`
428
+ ### `Response.blob(): Promise<Blob>`
357
429
 
358
430
  *The `blob()` method of the `Response` interface takes a `Response` stream and reads it to
359
431
  completion. It returns a promise that resolves with a `Blob`.*
360
432
 
361
433
  *The `type` of the `Blob` is set to the value of the `Content-Type` response header.*
362
434
 
363
- ### `Response.bytes()`
435
+ ### `Response.bytes(): Promise<Buffer>`
364
436
 
365
437
  *The `bytes()` method of the `Response` interface takes a `Response` stream and reads it to
366
438
  completion. It returns a promise that resolves with a `Uint8Array`.*
367
439
 
368
440
  In Fáith, this returns a Node.js `Buffer`, which can be used as (and is a subclass of) a `Uint8Array`.
369
441
 
370
- ### `Response.clone()`
442
+ ### `Response.clone(): Response`
371
443
 
372
444
  *The `clone()` method of the `Response` interface creates a clone of a response object, identical
373
445
  in every way, but stored in a different variable.*
374
446
 
375
- *`clone()` throws* an `Error` *if the response body has already been used.*
447
+ *`clone()` throws an error if the response body has already been used.*
376
448
 
377
- (In-spec, this should throw a `TypeError`, but for technical reasons this is not possible with Fáith.)
449
+ ### `Response.formData(): !`
378
450
 
379
- ### `Response.formData()`
451
+ Fáith deliberately does not implement this. The method exists so the types work out, but it will
452
+ always throw.
380
453
 
381
- Fáith deliberately does not implement this.
382
-
383
- ### `Response.json()`
454
+ ### `Response.json(): Promise<unknown>`
384
455
 
385
456
  *The `json()` method of the `Response` interface takes a `Response` stream and reads it to
386
457
  completion. It returns a promise which resolves with the result of parsing the body text as
@@ -393,13 +464,13 @@ Further note that, at least in Fáith, this method first reads the entire respon
393
464
  and then parses that as JSON. This can use up to double the amount of memory. If you need more
394
465
  efficient access, consider handling the response body as a stream.
395
466
 
396
- ### `Response.text()`
467
+ ### `Response.text(): Promise<string>`
397
468
 
398
469
  *The `text()` method of the `Response` interface takes a `Response` stream and reads it to
399
470
  completion. It returns a promise that resolves with a `String`. The response is always decoded
400
471
  using UTF-8.*
401
472
 
402
- ### `Response.webResponse()`
473
+ ### `Response.webResponse(): globalThis.Response`
403
474
 
404
475
  This is entirely custom to Fáith. It returns a Web API `Response` instead of Fáith's custom
405
476
  `Response` class. However, it's not possible to construct a Web API `Response` that has all the
@@ -429,6 +500,8 @@ For this reason, and also because in browsers this behaviour is standard, **all*
429
500
  Fáith use an `Agent`. For `fetch()` calls that don't specify one explicitly, a global agent with
430
501
  default options is created on first use.
431
502
 
503
+ There are a lot more options that could be exposed here; if you want one, open an issue.
504
+
432
505
  ### Syntax
433
506
 
434
507
  ```javascript
@@ -436,8 +509,45 @@ new Agent()
436
509
  new Agent(options)
437
510
  ```
438
511
 
439
- ### `cache`
440
- ### `cookies: bool`
512
+ ### `AgentOptions.cache: object`
513
+
514
+ Settings related to the HTTP cache. This is a nested object.
515
+
516
+ #### `AgentOptions.cache.store: string`
517
+
518
+ Which cache store to use: either `disk` or `memory`.
519
+
520
+ Default: none (cache disabled).
521
+
522
+ #### `AgentOptions.cache.capacity: number`
523
+
524
+ If `cache.store: "memory"`, the maximum amount of items stored.
525
+
526
+ Default: 10_000.
527
+
528
+ #### `AgentOptions.cache.mode: string`
529
+
530
+ Default cache mode. This is the same as [`FetchOptions.cache`](#fetchoptionscache), and is used if
531
+ no cache mode is set on a request.
532
+
533
+ Default: `"default"`.
534
+
535
+ #### `AgentOptions.cache.path: string`
536
+
537
+ If `cache.store: "disk"`, then this is the path at which the cache data is. Must be writeable.
538
+
539
+ Required if `cache.store: "disk"`.
540
+
541
+ #### `AgentOptions.cache.shared: boolean`
542
+
543
+ If `true`, then the response is evaluated from a perspective of a shared cache (i.e. `private` is
544
+ not cacheable and `s-maxage` is respected). If `false`, then the response is evaluated from a
545
+ perspective of a single-user cache (i.e. `private` is cacheable and `s-maxage` is ignored).
546
+ `shared: true` is required for proxies and multi-user caches.
547
+
548
+ Default: true.
549
+
550
+ ### `AgentOptions.cookies: bool`
441
551
 
442
552
  Enable a persistent cookie store for the agent. Cookies received in responses will be preserved and
443
553
  included in additional requests.
@@ -447,8 +557,36 @@ Default: `false`.
447
557
  You may use `agent.getCookie(url: string)` and `agent.addCookie(url: string, value: string)` to add
448
558
  and retrieve cookies from the store.
449
559
 
450
- ### `dns`
451
- ### `headers: Array<{ name: string, value: string, sensitive?: bool }>`
560
+ ### `AgentOptions.dns: object`
561
+
562
+ Settings related to DNS. This is a nested object.
563
+
564
+ #### `AgentOptions.dns.system: boolean`
565
+
566
+ Use the system's DNS (via `getaddrinfo` or equivalent) rather than Fáith's own DNS client (based on
567
+ [Hickory]). If you experience issues with DNS where Fáith does not work but e.g. curl or native
568
+ fetch does, this should be your first port of call.
569
+
570
+ Enabling this also disables Happy Eyeballs (for IPv6 / IPv4 best-effort resolution), the in-memory
571
+ DNS cache, and may lead to worse performance even discounting the cache.
572
+
573
+ Default: false.
574
+
575
+ [Hickory]: https://hickory-dns.org/
576
+
577
+ #### `AgentOptions.dns.overrides: Array<{ domain: string; addresses: string[] }>`
578
+
579
+ Override DNS resolution for specific domains. This takes effect even with `dns.system: true`.
580
+
581
+ Will throw if addresses are in invalid formats. You may provide a port number as part of the
582
+ address, it will default to port 0 otherwise, which will select the conventional port for the
583
+ protocol in use (e.g. 80 for plaintext HTTP). If the URL passed to `fetch()` has an explicit port
584
+ number, that one will be used instead. Resolving a domain to an empty `addresses` array effectively
585
+ blocks that domain from this agent.
586
+
587
+ Default: no overrides.
588
+
589
+ ### `AgentOptions.headers: Array<{ name: string, value: string, sensitive?: bool }>`
452
590
 
453
591
  Sets the default headers for every request.
454
592
 
@@ -457,23 +595,123 @@ Sensitive headers (e.g. `Authorization`) should be marked.
457
595
 
458
596
  Default: none.
459
597
 
460
- ### `http3`
461
- #### `congestion`
462
- ### `pool`
463
- #### `maxIdlePerHost`
464
- #### `idleTimeout`
465
- ### `redirect`
466
- ### `retry`
467
- ### `timeout`
468
- #### `connect`
469
- #### `read`
470
- #### `total`
471
- ### `tls`
472
- #### `earlyData`
473
- #### `identity`
474
- #### `required`
475
-
476
- ### `userAgent`
598
+ ### `AgentOptions.http3: object`
599
+
600
+ Settings related to HTTP/3. This is a nested object.
601
+
602
+ #### `AgentOptions.http3.congestion: string`
603
+
604
+ The congestion control algorithm. The default is `cubic`, which is the same used in TCP in the
605
+ Linux stack. It's fair for all traffic, but not the most optimal, especially for networks with
606
+ a lot of available bandwidth, high latency, or a lot of packet loss. Cubic reacts to packet loss by
607
+ dropping the speed by 30%, and takes a long time to recover. BBR instead tries to maximise
608
+ bandwidth use and optimises for round-trip time, while ignoring packet loss.
609
+
610
+ In some networks, BBR can lead to pathological degradation of overall network conditions, by
611
+ flooding the network by up to **100 times** more retransmissions. This is fixed in BBRv2 and BBRv3,
612
+ but Fáith (or rather its underlying QUIC library quinn, [does not implement those yet][2]).
613
+
614
+ [2]: https://github.com/quinn-rs/quinn/issues/1254
615
+
616
+ Default: `cubic`. Accepted values: `cubic`, `bbr1`.
617
+
618
+ #### `AgentOptions.http3.maxIdleTimeout: number`
619
+
620
+ Maximum duration of inactivity to accept before timing out the connection, in seconds. Note that
621
+ this only sets the timeout on this side of the connection: the true idle timeout is the _minimum_
622
+ of this and the peer’s own max idle timeout. While the underlying library has no limits, Fáith
623
+ defines bounds for safety: minimum 1 second, maximum 2 minutes (120 seconds).
624
+
625
+ Default: 30.
626
+
627
+ ### `AgentOptions.pool: object`
628
+
629
+ Settings related to the connection pool. This is a nested object.
630
+
631
+ #### `AgentOptions.pool.idleTimeout: number`
632
+
633
+ How many seconds of inactivity before a connection is closed.
634
+
635
+ Default: 90 seconds.
636
+
637
+ #### `AgentOptions.pool.maxIdlePerHost: number | null`
638
+
639
+ The maximum amount of idle connections per host to allow in the pool. Connections will be closed
640
+ to keep the idle connections (per host) under that number.
641
+
642
+ Default: `null` (no limit).
643
+
644
+ ### `AgentOptions.redirect: string`
645
+
646
+ *Determines the behavior in case the server replies with a redirect status.
647
+ One of the following values:*
648
+
649
+ - *`follow`: automatically follow redirects.* Fáith limits this to 10 redirects.
650
+ - *`error`: reject the promise with a network error when a redirect status is returned.*
651
+ - ~~*`manual`*:~~ not supported.
652
+ - `stop`: (Fáith custom) don't follow any redirects, return the responses.
653
+
654
+ *Defaults to `follow`.*
655
+
656
+ ### `AgentOptions.timeout: object`
657
+
658
+ Timeouts for requests made with this agent. This is a nested object.
659
+
660
+ #### `AgentOptions.timeout.connect: number | null`
661
+
662
+ Set a timeout for only the connect phase, in milliseconds.
663
+
664
+ Default: none.
665
+
666
+ #### `AgentOptions.timeout.read: number | null`
667
+
668
+ Set a timeout for read operations, in milliseconds.
669
+
670
+ The timeout applies to each read operation, and resets after a successful read. This is more
671
+ appropriate for detecting stalled connections when the size isn’t known beforehand.
672
+
673
+ Default: none.
674
+
675
+ #### `AgentOptions.timeout.total: number | null`
676
+
677
+ Set a timeout for the entire request-response cycle, in milliseconds.
678
+
679
+ The timeout applies from when the request starts connecting until the response body has finished.
680
+ Also considered a total deadline.
681
+
682
+ Default: none.
683
+
684
+ ### `AgentOptions.tls: object`
685
+
686
+ Settings related to the connection pool. This is a nested object.
687
+
688
+ #### `AgentOptions.tls.earlyData: boolean`
689
+
690
+ Enable TLS 1.3 Early Data. Early data is an optimisation where the client sends the first packet
691
+ of application data alongside the opening packet of the TLS handshake. That can enable the server
692
+ to answer faster, improving latency by up to one round-trip. However, Early Data has significant
693
+ security implications: it's vulnerable to replay attacks and has weaker forward secrecy. It should
694
+ really only be used for static assets or to squeeze out the last drop of performance for endpoints
695
+ that are replay-safe.
696
+
697
+ Default: false.
698
+
699
+ #### `AgentOptions.tls.identity: string | Buffer`
700
+
701
+ Provide a PEM-formatted certificate and private key to present as a TLS client certificate (also
702
+ called mutual TLS or mTLS) authentication.
703
+
704
+ The input should contain a PEM encoded private key and at least one PEM encoded certificate. The
705
+ private key must be in RSA, SEC1 Elliptic Curve or PKCS#8 format. This is one of the few options
706
+ that will cause the `Agent` constructor to throw if the input is in the wrong format.
707
+
708
+ #### `AgentOptions.tls.required`
709
+
710
+ Disables plain-text HTTP.
711
+
712
+ Default: false.
713
+
714
+ ### `AgentOptions.userAgent`
477
715
 
478
716
  Custom user agent string.
479
717
 
@@ -488,7 +726,7 @@ const agent = new Agent({
488
726
  });
489
727
  ```
490
728
 
491
- ### `addCookie(url: string, cookie: string)`
729
+ ### `Agent.addCookie(url: string, cookie: string)`
492
730
 
493
731
  Add a cookie into the agent.
494
732
 
@@ -496,7 +734,7 @@ Does nothing if:
496
734
  - the cookie store is disabled
497
735
  - the url is malformed
498
736
 
499
- ### `getCookie(url: string): string | null`
737
+ ### `Agent.getCookie(url: string): string | null`
500
738
 
501
739
  Retrieve a cookie from the store.
502
740
 
@@ -506,7 +744,7 @@ Returns `null` if:
506
744
  - the url is malformed
507
745
  - the cookie cannot be represented as a string
508
746
 
509
- ### `stats(): object`
747
+ ### `Agent.stats(): object`
510
748
 
511
749
  Returns statistics gathered by this agent:
512
750
 
@@ -524,8 +762,10 @@ error kind, documented in this comprehensive mapping:
524
762
  - `Timeout` — request timed out
525
763
  - JS `NetworkError`:
526
764
  - `Network` — network error
765
+ - `Redirect` — when the agent is configured to error on redirects
527
766
  - JS `SyntaxError`:
528
767
  - `JsonParse` — JSON parse error for `response.json()`
768
+ - `PemParse` — PEM parse error for `AgentOptions.tls.identity`
529
769
  - `Utf8Parse` — UTF8 decoding error for `response.text()`
530
770
  - JS `TypeError`:
531
771
  - `InvalidHeader` — invalid header name or value
@@ -535,6 +775,7 @@ error kind, documented in this comprehensive mapping:
535
775
  - `ResponseBodyNotAvailable` — body is null or not available
536
776
  - JS generic `Error`:
537
777
  - `BodyStream` — internal stream handling error
778
+ - `Config` — invalid agent configuration
538
779
  - `RuntimeThread` — failed to start or schedule threads on the internal tokio runtime
539
780
 
540
781
  The library exports an `ERROR_CODES` object which has every error code the library throws, and
@@ -544,4 +785,4 @@ constant from `ERROR_CODES`, instead of doing string matching on the error messa
544
785
  `instance of` matching.
545
786
 
546
787
  Due to technical limitations, when reading a body stream, reads might fail, but that error
547
- will not have a `.code` property.
788
+ will not have a `code` property.