undici 7.11.0 → 7.13.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.
Files changed (47) hide show
  1. package/README.md +15 -11
  2. package/docs/docs/api/DiagnosticsChannel.md +7 -4
  3. package/docs/docs/api/Dispatcher.md +2 -2
  4. package/docs/docs/api/ProxyAgent.md +1 -1
  5. package/docs/docs/api/SnapshotAgent.md +616 -0
  6. package/docs/docs/api/WebSocket.md +27 -0
  7. package/index.js +5 -1
  8. package/lib/api/readable.js +49 -29
  9. package/lib/core/request.js +6 -1
  10. package/lib/core/tree.js +1 -1
  11. package/lib/core/util.js +0 -1
  12. package/lib/dispatcher/client-h1.js +8 -17
  13. package/lib/dispatcher/proxy-agent.js +67 -71
  14. package/lib/handler/cache-handler.js +4 -1
  15. package/lib/handler/redirect-handler.js +12 -2
  16. package/lib/interceptor/cache.js +2 -2
  17. package/lib/interceptor/dump.js +2 -1
  18. package/lib/interceptor/redirect.js +1 -1
  19. package/lib/mock/mock-agent.js +10 -4
  20. package/lib/mock/snapshot-agent.js +333 -0
  21. package/lib/mock/snapshot-recorder.js +517 -0
  22. package/lib/util/cache.js +1 -1
  23. package/lib/util/promise.js +28 -0
  24. package/lib/web/cache/cache.js +10 -8
  25. package/lib/web/fetch/body.js +35 -24
  26. package/lib/web/fetch/formdata-parser.js +0 -3
  27. package/lib/web/fetch/formdata.js +0 -4
  28. package/lib/web/fetch/index.js +221 -225
  29. package/lib/web/fetch/request.js +15 -7
  30. package/lib/web/fetch/response.js +5 -3
  31. package/lib/web/fetch/util.js +21 -23
  32. package/lib/web/webidl/index.js +1 -1
  33. package/lib/web/websocket/connection.js +0 -9
  34. package/lib/web/websocket/receiver.js +2 -12
  35. package/lib/web/websocket/stream/websocketstream.js +7 -4
  36. package/lib/web/websocket/websocket.js +57 -1
  37. package/package.json +2 -2
  38. package/types/agent.d.ts +0 -4
  39. package/types/client.d.ts +0 -2
  40. package/types/dispatcher.d.ts +0 -6
  41. package/types/h2c-client.d.ts +0 -2
  42. package/types/index.d.ts +3 -1
  43. package/types/mock-interceptor.d.ts +0 -1
  44. package/types/snapshot-agent.d.ts +107 -0
  45. package/types/webidl.d.ts +10 -0
  46. package/types/websocket.d.ts +2 -0
  47. package/lib/web/fetch/dispatcher-weakref.js +0 -5
package/README.md CHANGED
@@ -114,8 +114,10 @@ const response = await fetch('https://api.example.com/data');
114
114
  #### Use Built-in Fetch When:
115
115
  - You want zero dependencies
116
116
  - Building isomorphic code that runs in browsers and Node.js
117
+ - Publishing to npm and want to maximize compatibility with JS runtimes
117
118
  - Simple HTTP requests without advanced configuration
118
- - You're okay with the undici version bundled in your Node.js version
119
+ - You're publishing to npm and you want to maximize compatiblity
120
+ - You don't depend on features from a specific version of undici
119
121
 
120
122
  #### Use Undici Module When:
121
123
  - You need the latest undici features and performance improvements
@@ -209,7 +211,7 @@ The `install()` function adds the following classes to `globalThis`:
209
211
  - `fetch` - The fetch function
210
212
  - `Headers` - HTTP headers management
211
213
  - `Response` - HTTP response representation
212
- - `Request` - HTTP request representation
214
+ - `Request` - HTTP request representation
213
215
  - `FormData` - Form data handling
214
216
  - `WebSocket` - WebSocket client
215
217
  - `CloseEvent`, `ErrorEvent`, `MessageEvent` - WebSocket events
@@ -438,13 +440,14 @@ This behavior is intentional for server-side environments where CORS restriction
438
440
  * https://fetch.spec.whatwg.org/#garbage-collection
439
441
 
440
442
  The [Fetch Standard](https://fetch.spec.whatwg.org) allows users to skip consuming the response body by relying on
441
- [garbage collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection) to release connection resources. Undici does not do the same. Therefore, it is important to always either consume or cancel the response body.
443
+ [garbage collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection) to release connection resources.
442
444
 
443
445
  Garbage collection in Node is less aggressive and deterministic
444
446
  (due to the lack of clear idle periods that browsers have through the rendering refresh rate)
445
447
  which means that leaving the release of connection resources to the garbage collector can lead
446
448
  to excessive connection usage, reduced performance (due to less connection re-use), and even
447
449
  stalls or deadlocks when running out of connections.
450
+ Therefore, __it is important to always either consume or cancel the response body anyway__.
448
451
 
449
452
  ```js
450
453
  // Do
@@ -457,7 +460,15 @@ for await (const chunk of body) {
457
460
  const { headers } = await fetch(url);
458
461
  ```
459
462
 
460
- The same applies for `request` too:
463
+ However, if you want to get only headers, it might be better to use `HEAD` request method. Usage of this method will obviate the need for consumption or cancelling of the response body. See [MDN - HTTP - HTTP request methods - HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) for more details.
464
+
465
+ ```js
466
+ const headers = await fetch(url, { method: 'HEAD' })
467
+ .then(res => res.headers)
468
+ ```
469
+
470
+ Note that consuming the response body is _mandatory_ for `request`:
471
+
461
472
  ```js
462
473
  // Do
463
474
  const { body, headers } = await request(url);
@@ -467,13 +478,6 @@ await res.body.dump(); // force consumption of body
467
478
  const { headers } = await request(url);
468
479
  ```
469
480
 
470
- However, if you want to get only headers, it might be better to use `HEAD` request method. Usage of this method will obviate the need for consumption or cancelling of the response body. See [MDN - HTTP - HTTP request methods - HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) for more details.
471
-
472
- ```js
473
- const headers = await fetch(url, { method: 'HEAD' })
474
- .then(res => res.headers)
475
- ```
476
-
477
481
  #### Forbidden and Safelisted Header Names
478
482
 
479
483
  * https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
@@ -169,10 +169,11 @@ This message is published after the client has successfully connected to a serve
169
169
  ```js
170
170
  import diagnosticsChannel from 'diagnostics_channel'
171
171
 
172
- diagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions }) => {
172
+ diagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions, websocket }) => {
173
173
  console.log(address) // address, family, and port
174
174
  console.log(protocol) // negotiated subprotocols
175
175
  console.log(extensions) // negotiated extensions
176
+ console.log(websocket) // the WebSocket instance
176
177
  })
177
178
  ```
178
179
 
@@ -184,7 +185,7 @@ This message is published after the connection has closed.
184
185
  import diagnosticsChannel from 'diagnostics_channel'
185
186
 
186
187
  diagnosticsChannel.channel('undici:websocket:close').subscribe(({ websocket, code, reason }) => {
187
- console.log(websocket) // the WebSocket object
188
+ console.log(websocket) // the WebSocket instance
188
189
  console.log(code) // the closing status code
189
190
  console.log(reason) // the closing reason
190
191
  })
@@ -209,9 +210,10 @@ This message is published after the client receives a ping frame, if the connect
209
210
  ```js
210
211
  import diagnosticsChannel from 'diagnostics_channel'
211
212
 
212
- diagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload }) => {
213
+ diagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload, websocket }) => {
213
214
  // a Buffer or undefined, containing the optional application data of the frame
214
215
  console.log(payload)
216
+ console.log(websocket) // the WebSocket instance
215
217
  })
216
218
  ```
217
219
 
@@ -222,8 +224,9 @@ This message is published after the client receives a pong frame.
222
224
  ```js
223
225
  import diagnosticsChannel from 'diagnostics_channel'
224
226
 
225
- diagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload }) => {
227
+ diagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload, websocket }) => {
226
228
  // a Buffer or undefined, containing the optional application data of the frame
227
229
  console.log(payload)
230
+ console.log(websocket) // the WebSocket instance
228
231
  })
229
232
  ```
@@ -1103,8 +1103,8 @@ The `cache` interceptor implements client-side response caching as described in
1103
1103
 
1104
1104
  - `store` - The [`CacheStore`](/docs/docs/api/CacheStore.md) to store and retrieve responses from. Default is [`MemoryCacheStore`](/docs/docs/api/CacheStore.md#memorycachestore).
1105
1105
  - `methods` - The [**safe** HTTP methods](https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1) to cache the response of.
1106
- - `cacheByDefault` - The default expiration time to cache responses by if they don't have an explicit expiration. If this isn't present, responses without explicit expiration will not be cached. Default `undefined`.
1107
- - `type` - The type of cache for Undici to act as. Can be `shared` or `private`. Default `shared`.
1106
+ - `cacheByDefault` - The default expiration time to cache responses by if they don't have an explicit expiration and cannot have an heuristic expiry computed. If this isn't present, responses neither with an explicit expiration nor heuristically cacheable will not be cached. Default `undefined`.
1107
+ - `type` - The [type of cache](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching#types_of_caches) for Undici to act as. Can be `shared` or `private`. Default `shared`. `private` implies privately cacheable responses will be cached and potentially shared with other users of your application.
1108
1108
 
1109
1109
  ## Instance Events
1110
1110
 
@@ -27,7 +27,7 @@ For detailed information on the parsing process and potential validation errors,
27
27
  * **clientFactory** `(origin: URL, opts: Object) => Dispatcher` (optional) - Default: `(origin, opts) => new Pool(origin, opts)`
28
28
  * **requestTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the request. It extends from [`Client#ConnectOptions`](/docs/docs/api/Client.md#parameter-connectoptions).
29
29
  * **proxyTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the proxy server. It extends from [`Client#ConnectOptions`](/docs/docs/api/Client.md#parameter-connectoptions).
30
- * **proxyTunnel** `boolean` (optional) - By default, ProxyAgent will request that the Proxy facilitate a tunnel between the endpoint and the agent. Setting `proxyTunnel` to false avoids issuing a CONNECT extension, and includes the endpoint domain and path in each request.
30
+ * **proxyTunnel** `boolean` (optional) - For connections involving secure protocols, Undici will always establish a tunnel via the HTTP2 CONNECT extension. If proxyTunnel is set to true, this will occur for unsecured proxy/endpoint connections as well. Currently, there is no way to facilitate HTTP1 IP tunneling as described in https://www.rfc-editor.org/rfc/rfc9484.html#name-http-11-request. If proxyTunnel is set to false (the default), ProxyAgent connections where both the Proxy and Endpoint are unsecured will issue all requests to the Proxy, and prefix the endpoint request path with the endpoint origin address.
31
31
 
32
32
  Examples:
33
33