undici 7.0.0-alpha.3 → 7.0.0-alpha.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.
Files changed (47) hide show
  1. package/README.md +2 -1
  2. package/docs/docs/api/Agent.md +14 -14
  3. package/docs/docs/api/BalancedPool.md +16 -16
  4. package/docs/docs/api/CacheStore.md +17 -14
  5. package/docs/docs/api/Client.md +11 -11
  6. package/docs/docs/api/Dispatcher.md +30 -10
  7. package/docs/docs/api/EnvHttpProxyAgent.md +12 -12
  8. package/docs/docs/api/MockAgent.md +3 -3
  9. package/docs/docs/api/MockClient.md +5 -5
  10. package/docs/docs/api/MockPool.md +2 -2
  11. package/docs/docs/api/Pool.md +15 -15
  12. package/docs/docs/api/PoolStats.md +1 -1
  13. package/docs/docs/api/ProxyAgent.md +3 -3
  14. package/docs/docs/api/RetryHandler.md +2 -2
  15. package/docs/docs/api/WebSocket.md +1 -1
  16. package/docs/docs/api/api-lifecycle.md +11 -11
  17. package/docs/docs/best-practices/mocking-request.md +2 -2
  18. package/docs/docs/best-practices/proxy.md +1 -1
  19. package/index.d.ts +1 -1
  20. package/index.js +2 -1
  21. package/lib/api/api-request.js +1 -1
  22. package/lib/cache/memory-cache-store.js +106 -342
  23. package/lib/core/connect.js +5 -0
  24. package/lib/core/request.js +2 -2
  25. package/lib/core/util.js +13 -40
  26. package/lib/dispatcher/client-h2.js +53 -33
  27. package/lib/handler/cache-handler.js +126 -85
  28. package/lib/handler/cache-revalidation-handler.js +45 -13
  29. package/lib/handler/redirect-handler.js +5 -3
  30. package/lib/handler/retry-handler.js +3 -3
  31. package/lib/interceptor/cache.js +213 -92
  32. package/lib/interceptor/dns.js +71 -48
  33. package/lib/util/cache.js +73 -13
  34. package/lib/util/timers.js +19 -1
  35. package/lib/web/cookies/index.js +12 -1
  36. package/lib/web/cookies/parse.js +6 -1
  37. package/lib/web/fetch/body.js +1 -5
  38. package/lib/web/fetch/formdata-parser.js +70 -43
  39. package/lib/web/fetch/headers.js +1 -1
  40. package/lib/web/fetch/index.js +4 -6
  41. package/lib/web/fetch/webidl.js +12 -4
  42. package/package.json +2 -3
  43. package/types/cache-interceptor.d.ts +51 -54
  44. package/types/cookies.d.ts +2 -0
  45. package/types/dispatcher.d.ts +1 -1
  46. package/types/index.d.ts +0 -1
  47. package/types/interceptors.d.ts +0 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  Extends: `undici.Dispatcher`
4
4
 
5
- A pool of [Client](Client.md) instances connected to the same upstream target.
5
+ A pool of [Client](/docs/docs/api/Client.md) instances connected to the same upstream target.
6
6
 
7
7
  Requests are not guaranteed to be dispatched in order of invocation.
8
8
 
@@ -15,7 +15,7 @@ Arguments:
15
15
 
16
16
  ### Parameter: `PoolOptions`
17
17
 
18
- Extends: [`ClientOptions`](Client.md#parameter-clientoptions)
18
+ Extends: [`ClientOptions`](/docs/docs/api/Client.md#parameter-clientoptions)
19
19
 
20
20
  * **factory** `(origin: URL, opts: Object) => Dispatcher` - Default: `(origin, opts) => new Client(origin, opts)`
21
21
  * **connections** `number | null` (optional) - Default: `null` - The number of `Client` instances to create. When set to `null`, the `Pool` instance will create an unlimited amount of `Client` instances.
@@ -24,11 +24,11 @@ Extends: [`ClientOptions`](Client.md#parameter-clientoptions)
24
24
 
25
25
  ### `Pool.closed`
26
26
 
27
- Implements [Client.closed](Client.md#clientclosed)
27
+ Implements [Client.closed](/docs/docs/api/Client.md#clientclosed)
28
28
 
29
29
  ### `Pool.destroyed`
30
30
 
31
- Implements [Client.destroyed](Client.md#clientdestroyed)
31
+ Implements [Client.destroyed](/docs/docs/api/Client.md#clientdestroyed)
32
32
 
33
33
  ### `Pool.stats`
34
34
 
@@ -38,46 +38,46 @@ Returns [`PoolStats`](PoolStats.md) instance for this pool.
38
38
 
39
39
  ### `Pool.close([callback])`
40
40
 
41
- Implements [`Dispatcher.close([callback])`](Dispatcher.md#dispatcherclosecallback-promise).
41
+ Implements [`Dispatcher.close([callback])`](/docs/docs/api/Dispatcher.md#dispatcherclosecallback-promise).
42
42
 
43
43
  ### `Pool.destroy([error, callback])`
44
44
 
45
- Implements [`Dispatcher.destroy([error, callback])`](Dispatcher.md#dispatcherdestroyerror-callback-promise).
45
+ Implements [`Dispatcher.destroy([error, callback])`](/docs/docs/api/Dispatcher.md#dispatcherdestroyerror-callback-promise).
46
46
 
47
47
  ### `Pool.connect(options[, callback])`
48
48
 
49
- See [`Dispatcher.connect(options[, callback])`](Dispatcher.md#dispatcherconnectoptions-callback).
49
+ See [`Dispatcher.connect(options[, callback])`](/docs/docs/api/Dispatcher.md#dispatcherconnectoptions-callback).
50
50
 
51
51
  ### `Pool.dispatch(options, handler)`
52
52
 
53
- Implements [`Dispatcher.dispatch(options, handler)`](Dispatcher.md#dispatcherdispatchoptions-handler).
53
+ Implements [`Dispatcher.dispatch(options, handler)`](/docs/docs/api/Dispatcher.md#dispatcherdispatchoptions-handler).
54
54
 
55
55
  ### `Pool.pipeline(options, handler)`
56
56
 
57
- See [`Dispatcher.pipeline(options, handler)`](Dispatcher.md#dispatcherpipelineoptions-handler).
57
+ See [`Dispatcher.pipeline(options, handler)`](/docs/docs/api/Dispatcher.md#dispatcherpipelineoptions-handler).
58
58
 
59
59
  ### `Pool.request(options[, callback])`
60
60
 
61
- See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
61
+ See [`Dispatcher.request(options [, callback])`](/docs/docs/api/Dispatcher.md#dispatcherrequestoptions-callback).
62
62
 
63
63
  ### `Pool.stream(options, factory[, callback])`
64
64
 
65
- See [`Dispatcher.stream(options, factory[, callback])`](Dispatcher.md#dispatcherstreamoptions-factory-callback).
65
+ See [`Dispatcher.stream(options, factory[, callback])`](/docs/docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback).
66
66
 
67
67
  ### `Pool.upgrade(options[, callback])`
68
68
 
69
- See [`Dispatcher.upgrade(options[, callback])`](Dispatcher.md#dispatcherupgradeoptions-callback).
69
+ See [`Dispatcher.upgrade(options[, callback])`](/docs/docs/api/Dispatcher.md#dispatcherupgradeoptions-callback).
70
70
 
71
71
  ## Instance Events
72
72
 
73
73
  ### Event: `'connect'`
74
74
 
75
- See [Dispatcher Event: `'connect'`](Dispatcher.md#event-connect).
75
+ See [Dispatcher Event: `'connect'`](/docs/docs/api/Dispatcher.md#event-connect).
76
76
 
77
77
  ### Event: `'disconnect'`
78
78
 
79
- See [Dispatcher Event: `'disconnect'`](Dispatcher.md#event-disconnect).
79
+ See [Dispatcher Event: `'disconnect'`](/docs/docs/api/Dispatcher.md#event-disconnect).
80
80
 
81
81
  ### Event: `'drain'`
82
82
 
83
- See [Dispatcher Event: `'drain'`](Dispatcher.md#event-drain).
83
+ See [Dispatcher Event: `'drain'`](/docs/docs/api/Dispatcher.md#event-drain).
@@ -1,6 +1,6 @@
1
1
  # Class: PoolStats
2
2
 
3
- Aggregate stats for a [Pool](Pool.md) or [BalancedPool](BalancedPool.md).
3
+ Aggregate stats for a [Pool](/docs/docs/api/Pool.md) or [BalancedPool](/docs/docs/api/BalancedPool.md).
4
4
 
5
5
  ## `new PoolStats(pool)`
6
6
 
@@ -14,7 +14,7 @@ Returns: `ProxyAgent`
14
14
 
15
15
  ### Parameter: `ProxyAgentOptions`
16
16
 
17
- Extends: [`AgentOptions`](Agent.md#parameter-agentoptions)
17
+ Extends: [`AgentOptions`](/docs/docs/api/Agent.md#parameter-agentoptions)
18
18
 
19
19
  * **uri** `string | URL` (required) - The URI of the proxy server. This can be provided as a string, as an instance of the URL class, or as an object with a `uri` property of type string.
20
20
  If the `uri` is provided as a string or `uri` is an object with an `uri` property of type string, then it will be parsed into a `URL` object according to the [WHATWG URL Specification](https://url.spec.whatwg.org).
@@ -123,8 +123,8 @@ await proxyAgent.close()
123
123
 
124
124
  ### `ProxyAgent.dispatch(options, handlers)`
125
125
 
126
- Implements [`Agent.dispatch(options, handlers)`](Agent.md#parameter-agentdispatchoptions).
126
+ Implements [`Agent.dispatch(options, handlers)`](/docs/docs/api/Agent.md#parameter-agentdispatchoptions).
127
127
 
128
128
  ### `ProxyAgent.request(options[, callback])`
129
129
 
130
- See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback).
130
+ See [`Dispatcher.request(options [, callback])`](/docs/docs/api/Dispatcher.md#dispatcherrequestoptions-callback).
@@ -15,7 +15,7 @@ Returns: `retryHandler`
15
15
 
16
16
  ### Parameter: `Dispatch.DispatchOptions & RetryOptions`
17
17
 
18
- Extends: [`Dispatch.DispatchOptions`](Dispatcher.md#parameter-dispatchoptions).
18
+ Extends: [`Dispatch.DispatchOptions`](/docs/docs/api/Dispatcher.md#parameter-dispatchoptions).
19
19
 
20
20
  #### `RetryOptions`
21
21
 
@@ -44,7 +44,7 @@ It represents the retry state for a given request.
44
44
  ### Parameter `RetryHandlers`
45
45
 
46
46
  - **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every retry.
47
- - **handler** Extends [`Dispatch.DispatchHandlers`](Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted.
47
+ - **handler** Extends [`Dispatch.DispatchHandlers`](/docs/docs/api/Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted.
48
48
 
49
49
  >__Note__: The `RetryHandler` does not retry over stateful bodies (e.g. streams, AsyncIterable) as those, once consumed, are left in a state that cannot be reutilized. For these situations the `RetryHandler` will identify
50
50
  >the body as stateful and will not retry the request rejecting with the error `UND_ERR_REQ_RETRY`.
@@ -9,7 +9,7 @@ The WebSocket object provides a way to manage a WebSocket connection to a server
9
9
  Arguments:
10
10
 
11
11
  * **url** `URL | string`
12
- * **protocol** `string | string[] | WebSocketInit` (optional) - Subprotocol(s) to request the server use, or a [`Dispatcher`](./Dispatcher.md).
12
+ * **protocol** `string | string[] | WebSocketInit` (optional) - Subprotocol(s) to request the server use, or a [`Dispatcher`](/docs/docs/api/Dispatcher.md).
13
13
 
14
14
  ### Example:
15
15
 
@@ -1,6 +1,6 @@
1
1
  # Client Lifecycle
2
2
 
3
- An Undici [Client](Client.md) can be best described as a state machine. The following list is a summary of the various state transitions the `Client` will go through in its lifecycle. This document also contains detailed breakdowns of each state.
3
+ An Undici [Client](/docs/docs/api/Client.md) can be best described as a state machine. The following list is a summary of the various state transitions the `Client` will go through in its lifecycle. This document also contains detailed breakdowns of each state.
4
4
 
5
5
  > This diagram is not a perfect representation of the undici Client. Since the Client class is not actually implemented as a state-machine, actual execution may deviate slightly from what is described below. Consider this as a general resource for understanding the inner workings of the Undici client rather than some kind of formal specification.
6
6
 
@@ -28,7 +28,7 @@ stateDiagram-v2
28
28
  [*] --> idle
29
29
  idle --> pending : connect
30
30
  idle --> destroyed : destroy/close
31
-
31
+
32
32
  pending --> idle : timeout
33
33
  pending --> destroyed : destroy
34
34
 
@@ -58,33 +58,33 @@ stateDiagram-v2
58
58
 
59
59
  ### idle
60
60
 
61
- The **idle** state is the initial state of a `Client` instance. While an `origin` is required for instantiating a `Client` instance, the underlying socket connection will not be established until a request is queued using [`Client.dispatch()`](Client.md#clientdispatchoptions-handlers). By calling `Client.dispatch()` directly or using one of the multiple implementations ([`Client.connect()`](Client.md#clientconnectoptions-callback), [`Client.pipeline()`](Client.md#clientpipelineoptions-handler), [`Client.request()`](Client.md#clientrequestoptions-callback), [`Client.stream()`](Client.md#clientstreamoptions-factory-callback), and [`Client.upgrade()`](Client.md#clientupgradeoptions-callback)), the `Client` instance will transition from **idle** to [**pending**](#pending) and then most likely directly to [**processing**](#processing).
61
+ The **idle** state is the initial state of a `Client` instance. While an `origin` is required for instantiating a `Client` instance, the underlying socket connection will not be established until a request is queued using [`Client.dispatch()`](/docs/docs/api/Client.md#clientdispatchoptions-handlers). By calling `Client.dispatch()` directly or using one of the multiple implementations ([`Client.connect()`](Client.md#clientconnectoptions-callback), [`Client.pipeline()`](Client.md#clientpipelineoptions-handler), [`Client.request()`](Client.md#clientrequestoptions-callback), [`Client.stream()`](Client.md#clientstreamoptions-factory-callback), and [`Client.upgrade()`](/docs/docs/api/Client.md#clientupgradeoptions-callback)), the `Client` instance will transition from **idle** to [**pending**](/docs/docs/api/Client.md#pending) and then most likely directly to [**processing**](/docs/docs/api/Client.md#processing).
62
62
 
63
- Calling [`Client.close()`](Client.md#clientclosecallback) or [`Client.destroy()`](Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](#destroyed) state since the `Client` instance will have no queued requests in this state.
63
+ Calling [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) or [`Client.destroy()`](Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](/docs/docs/api/Client.md#destroyed) state since the `Client` instance will have no queued requests in this state.
64
64
 
65
65
  ### pending
66
66
 
67
- The **pending** state signifies a non-processing `Client`. Upon entering this state, the `Client` establishes a socket connection and emits the [`'connect'`](Client.md#event-connect) event signalling a connection was successfully established with the `origin` provided during `Client` instantiation. The internal queue is initially empty, and requests can start queueing.
67
+ The **pending** state signifies a non-processing `Client`. Upon entering this state, the `Client` establishes a socket connection and emits the [`'connect'`](/docs/docs/api/Client.md#event-connect) event signalling a connection was successfully established with the `origin` provided during `Client` instantiation. The internal queue is initially empty, and requests can start queueing.
68
68
 
69
- Calling [`Client.close()`](Client.md#clientclosecallback) with queued requests, transitions the `Client` to the [**processing**](#processing) state. Without queued requests, it transitions to the [**destroyed**](#destroyed) state.
69
+ Calling [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) with queued requests, transitions the `Client` to the [**processing**](/docs/docs/api/Client.md#processing) state. Without queued requests, it transitions to the [**destroyed**](/docs/docs/api/Client.md#destroyed) state.
70
70
 
71
- Calling [`Client.destroy()`](Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](#destroyed) state regardless of existing requests.
71
+ Calling [`Client.destroy()`](/docs/docs/api/Client.md#clientdestroyerror-callback) transitions directly to the [**destroyed**](/docs/docs/api/Client.md#destroyed) state regardless of existing requests.
72
72
 
73
73
  ### processing
74
74
 
75
- The **processing** state is a state machine within itself. It initializes to the [**processing.running**](#running) state. The [`Client.dispatch()`](Client.md#clientdispatchoptions-handlers), [`Client.close()`](Client.md#clientclosecallback), and [`Client.destroy()`](Client.md#clientdestroyerror-callback) can be called at any time while the `Client` is in this state. `Client.dispatch()` will add more requests to the queue while existing requests continue to be processed. `Client.close()` will transition to the [**processing.closing**](#closing) state. And `Client.destroy()` will transition to [**destroyed**](#destroyed).
75
+ The **processing** state is a state machine within itself. It initializes to the [**processing.running**](/docs/docs/api/Client.md#running) state. The [`Client.dispatch()`](/docs/docs/api/Client.md#clientdispatchoptions-handlers), [`Client.close()`](Client.md#clientclosecallback), and [`Client.destroy()`](Client.md#clientdestroyerror-callback) can be called at any time while the `Client` is in this state. `Client.dispatch()` will add more requests to the queue while existing requests continue to be processed. `Client.close()` will transition to the [**processing.closing**](/docs/docs/api/Client.md#closing) state. And `Client.destroy()` will transition to [**destroyed**](/docs/docs/api/Client.md#destroyed).
76
76
 
77
77
  #### running
78
78
 
79
- In the **processing.running** sub-state, queued requests are being processed in a FIFO order. If a request body requires draining, the *needDrain* event transitions to the [**processing.busy**](#busy) sub-state. The *close* event transitions the Client to the [**process.closing**](#closing) sub-state. If all queued requests are processed and neither [`Client.close()`](Client.md#clientclosecallback) nor [`Client.destroy()`](Client.md#clientdestroyerror-callback) are called, then the [**processing**](#processing) machine will trigger a *keepalive* event transitioning the `Client` back to the [**pending**](#pending) state. During this time, the `Client` is waiting for the socket connection to timeout, and once it does, it triggers the *timeout* event and transitions to the [**idle**](#idle) state.
79
+ In the **processing.running** sub-state, queued requests are being processed in a FIFO order. If a request body requires draining, the *needDrain* event transitions to the [**processing.busy**](/docs/docs/api/Client.md#busy) sub-state. The *close* event transitions the Client to the [**process.closing**](/docs/docs/api/Client.md#closing) sub-state. If all queued requests are processed and neither [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) nor [`Client.destroy()`](Client.md#clientdestroyerror-callback) are called, then the [**processing**](/docs/docs/api/Client.md#processing) machine will trigger a *keepalive* event transitioning the `Client` back to the [**pending**](/docs/docs/api/Client.md#pending) state. During this time, the `Client` is waiting for the socket connection to timeout, and once it does, it triggers the *timeout* event and transitions to the [**idle**](/docs/docs/api/Client.md#idle) state.
80
80
 
81
81
  #### busy
82
82
 
83
- This sub-state is only entered when a request body is an instance of [Stream](https://nodejs.org/api/stream.html) and requires draining. The `Client` cannot process additional requests while in this state and must wait until the currently processing request body is completely drained before transitioning back to [**processing.running**](#running).
83
+ This sub-state is only entered when a request body is an instance of [Stream](https://nodejs.org/api/stream.html) and requires draining. The `Client` cannot process additional requests while in this state and must wait until the currently processing request body is completely drained before transitioning back to [**processing.running**](/docs/docs/api/Client.md#running).
84
84
 
85
85
  #### closing
86
86
 
87
- This sub-state is only entered when a `Client` instance has queued requests and the [`Client.close()`](Client.md#clientclosecallback) method is called. In this state, the `Client` instance continues to process requests as usual, with the one exception that no additional requests can be queued. Once all of the queued requests are processed, the `Client` will trigger the *done* event gracefully entering the [**destroyed**](#destroyed) state without an error.
87
+ This sub-state is only entered when a `Client` instance has queued requests and the [`Client.close()`](/docs/docs/api/Client.md#clientclosecallback) method is called. In this state, the `Client` instance continues to process requests as usual, with the one exception that no additional requests can be queued. Once all of the queued requests are processed, the `Client` will trigger the *done* event gracefully entering the [**destroyed**](/docs/docs/api/Client.md#destroyed) state without an error.
88
88
 
89
89
  ### destroyed
90
90
 
@@ -1,6 +1,6 @@
1
1
  # Mocking Request
2
2
 
3
- Undici has its own mocking [utility](../api/MockAgent.md). It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.
3
+ Undici has its own mocking [utility](/docs/docs/api/MockAgent.md). It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.
4
4
 
5
5
  Example:
6
6
 
@@ -73,7 +73,7 @@ const badRequest = await bankTransfer('1234567890', '100')
73
73
  assert.deepEqual(badRequest, { message: 'bank account not found' })
74
74
  ```
75
75
 
76
- Explore other MockAgent functionality [here](../api/MockAgent.md)
76
+ Explore other MockAgent functionality [here](/docs/docs/api/MockAgent.md)
77
77
 
78
78
  ## Debug Mock Value
79
79
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Connecting through a proxy is possible by:
4
4
 
5
- - Using [ProxyAgent](../api/ProxyAgent.md).
5
+ - Using [ProxyAgent](/docs/docs/api/ProxyAgent.md).
6
6
  - Configuring `Client` or `Pool` constructor.
7
7
 
8
8
  The proxy url should be passed to the `Client` or `Pool` constructor, while the upstream server url
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * from './types/index'
2
1
  import Undici from './types/index'
3
2
  export default Undici
3
+ export * from './types/index'
package/index.js CHANGED
@@ -136,12 +136,13 @@ const { kConstruct } = require('./lib/core/symbols')
136
136
  // in an older version of Node, it doesn't have any use without fetch.
137
137
  module.exports.caches = new CacheStorage(kConstruct)
138
138
 
139
- const { deleteCookie, getCookies, getSetCookies, setCookie } = require('./lib/web/cookies')
139
+ const { deleteCookie, getCookies, getSetCookies, setCookie, parseCookie } = require('./lib/web/cookies')
140
140
 
141
141
  module.exports.deleteCookie = deleteCookie
142
142
  module.exports.getCookies = getCookies
143
143
  module.exports.getSetCookies = getSetCookies
144
144
  module.exports.setCookie = setCookie
145
+ module.exports.parseCookie = parseCookie
145
146
 
146
147
  const { parseMIMEType, serializeAMimeType } = require('./lib/web/fetch/data-url')
147
148
 
@@ -153,7 +153,7 @@ class RequestHandler extends AsyncResource {
153
153
  this.res = null
154
154
  // Ensure all queued handlers are invoked before destroying res.
155
155
  queueMicrotask(() => {
156
- util.destroy(res, err)
156
+ util.destroy(res.on('error', noop), err)
157
157
  })
158
158
  }
159
159