undici 6.21.0 → 7.0.0-alpha.10
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 +27 -46
- package/docs/docs/api/Agent.md +14 -17
- package/docs/docs/api/BalancedPool.md +16 -16
- package/docs/docs/api/CacheStore.md +131 -0
- package/docs/docs/api/Client.md +12 -14
- package/docs/docs/api/Debug.md +1 -1
- package/docs/docs/api/Dispatcher.md +98 -194
- package/docs/docs/api/EnvHttpProxyAgent.md +12 -13
- package/docs/docs/api/MockAgent.md +5 -3
- package/docs/docs/api/MockClient.md +5 -5
- package/docs/docs/api/MockPool.md +4 -3
- package/docs/docs/api/Pool.md +15 -16
- package/docs/docs/api/PoolStats.md +1 -1
- package/docs/docs/api/ProxyAgent.md +3 -3
- package/docs/docs/api/RedirectHandler.md +1 -1
- package/docs/docs/api/RetryAgent.md +1 -1
- package/docs/docs/api/RetryHandler.md +4 -4
- package/docs/docs/api/WebSocket.md +46 -4
- package/docs/docs/api/api-lifecycle.md +11 -11
- package/docs/docs/best-practices/mocking-request.md +2 -2
- package/docs/docs/best-practices/proxy.md +1 -1
- package/index.d.ts +1 -1
- package/index.js +23 -7
- package/lib/api/abort-signal.js +2 -0
- package/lib/api/api-connect.js +3 -1
- package/lib/api/api-pipeline.js +7 -6
- package/lib/api/api-request.js +33 -48
- package/lib/api/api-stream.js +39 -50
- package/lib/api/api-upgrade.js +5 -3
- package/lib/api/readable.js +235 -62
- package/lib/api/util.js +2 -0
- package/lib/cache/memory-cache-store.js +177 -0
- package/lib/cache/sqlite-cache-store.js +446 -0
- package/lib/core/constants.js +35 -10
- package/lib/core/diagnostics.js +122 -128
- package/lib/core/errors.js +6 -6
- package/lib/core/request.js +13 -11
- package/lib/core/symbols.js +2 -1
- package/lib/core/tree.js +9 -1
- package/lib/core/util.js +237 -49
- package/lib/dispatcher/agent.js +3 -17
- package/lib/dispatcher/balanced-pool.js +5 -8
- package/lib/dispatcher/client-h1.js +379 -134
- package/lib/dispatcher/client-h2.js +173 -107
- package/lib/dispatcher/client.js +19 -32
- package/lib/dispatcher/dispatcher-base.js +6 -35
- package/lib/dispatcher/dispatcher.js +7 -24
- package/lib/dispatcher/fixed-queue.js +91 -49
- package/lib/dispatcher/pool-stats.js +2 -0
- package/lib/dispatcher/pool.js +3 -6
- package/lib/dispatcher/proxy-agent.js +3 -6
- package/lib/handler/cache-handler.js +393 -0
- package/lib/handler/cache-revalidation-handler.js +124 -0
- package/lib/handler/decorator-handler.js +27 -0
- package/lib/handler/redirect-handler.js +54 -59
- package/lib/handler/retry-handler.js +77 -109
- package/lib/handler/unwrap-handler.js +96 -0
- package/lib/handler/wrap-handler.js +98 -0
- package/lib/interceptor/cache.js +350 -0
- package/lib/interceptor/dns.js +375 -0
- package/lib/interceptor/dump.js +2 -2
- package/lib/interceptor/redirect.js +11 -14
- package/lib/interceptor/response-error.js +18 -7
- package/lib/llhttp/constants.d.ts +97 -0
- package/lib/llhttp/constants.js +412 -192
- package/lib/llhttp/constants.js.map +1 -0
- package/lib/llhttp/llhttp-wasm.js +11 -1
- package/lib/llhttp/llhttp_simd-wasm.js +11 -1
- package/lib/llhttp/utils.d.ts +2 -0
- package/lib/llhttp/utils.js +9 -9
- package/lib/llhttp/utils.js.map +1 -0
- package/lib/mock/mock-agent.js +5 -8
- package/lib/mock/mock-client.js +9 -4
- package/lib/mock/mock-errors.js +3 -1
- package/lib/mock/mock-interceptor.js +8 -6
- package/lib/mock/mock-pool.js +9 -4
- package/lib/mock/mock-symbols.js +3 -1
- package/lib/mock/mock-utils.js +29 -5
- package/lib/util/cache.js +360 -0
- package/lib/web/cache/cache.js +24 -21
- package/lib/web/cache/cachestorage.js +1 -1
- package/lib/web/cookies/index.js +29 -14
- package/lib/web/cookies/parse.js +8 -3
- package/lib/web/eventsource/eventsource-stream.js +9 -8
- package/lib/web/eventsource/eventsource.js +10 -6
- package/lib/web/fetch/body.js +43 -41
- package/lib/web/fetch/constants.js +12 -5
- package/lib/web/fetch/data-url.js +3 -3
- package/lib/web/fetch/formdata-parser.js +72 -45
- package/lib/web/fetch/formdata.js +65 -54
- package/lib/web/fetch/headers.js +118 -86
- package/lib/web/fetch/index.js +58 -67
- package/lib/web/fetch/request.js +136 -77
- package/lib/web/fetch/response.js +87 -56
- package/lib/web/fetch/util.js +259 -109
- package/lib/web/fetch/webidl.js +113 -68
- package/lib/web/websocket/connection.js +76 -147
- package/lib/web/websocket/constants.js +70 -10
- package/lib/web/websocket/events.js +4 -2
- package/lib/web/websocket/frame.js +45 -3
- package/lib/web/websocket/receiver.js +29 -33
- package/lib/web/websocket/sender.js +18 -13
- package/lib/web/websocket/stream/websocketerror.js +83 -0
- package/lib/web/websocket/stream/websocketstream.js +485 -0
- package/lib/web/websocket/util.js +128 -77
- package/lib/web/websocket/websocket.js +234 -135
- package/package.json +24 -36
- package/scripts/strip-comments.js +3 -1
- package/types/agent.d.ts +7 -7
- package/types/api.d.ts +24 -24
- package/types/balanced-pool.d.ts +11 -11
- package/types/cache-interceptor.d.ts +172 -0
- package/types/client.d.ts +11 -12
- package/types/cookies.d.ts +2 -0
- package/types/diagnostics-channel.d.ts +10 -10
- package/types/dispatcher.d.ts +113 -90
- package/types/env-http-proxy-agent.d.ts +2 -2
- package/types/errors.d.ts +53 -47
- package/types/fetch.d.ts +17 -16
- package/types/formdata.d.ts +7 -7
- package/types/global-dispatcher.d.ts +4 -4
- package/types/global-origin.d.ts +5 -5
- package/types/handlers.d.ts +7 -7
- package/types/header.d.ts +157 -1
- package/types/index.d.ts +44 -46
- package/types/interceptors.d.ts +25 -8
- package/types/mock-agent.d.ts +21 -18
- package/types/mock-client.d.ts +4 -4
- package/types/mock-errors.d.ts +3 -3
- package/types/mock-interceptor.d.ts +19 -19
- package/types/mock-pool.d.ts +4 -4
- package/types/patch.d.ts +0 -4
- package/types/pool-stats.d.ts +8 -8
- package/types/pool.d.ts +12 -12
- package/types/proxy-agent.d.ts +4 -4
- package/types/readable.d.ts +18 -15
- package/types/retry-agent.d.ts +1 -1
- package/types/retry-handler.d.ts +10 -10
- package/types/util.d.ts +3 -3
- package/types/utility.d.ts +7 -0
- package/types/webidl.d.ts +44 -6
- package/types/websocket.d.ts +34 -1
- package/docs/docs/api/DispatchInterceptor.md +0 -60
- package/lib/interceptor/redirect-interceptor.js +0 -21
- package/lib/mock/pluralizer.js +0 -29
- package/lib/web/cache/symbols.js +0 -5
- package/lib/web/fetch/file.js +0 -126
- package/lib/web/fetch/symbols.js +0 -9
- package/lib/web/fileapi/encoding.js +0 -290
- package/lib/web/fileapi/filereader.js +0 -344
- package/lib/web/fileapi/progressevent.js +0 -78
- package/lib/web/fileapi/symbols.js +0 -10
- package/lib/web/fileapi/util.js +0 -391
- package/lib/web/websocket/symbols.js +0 -12
- package/types/file.d.ts +0 -39
- package/types/filereader.d.ts +0 -54
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const EventEmitter = require('node:events')
|
|
3
|
+
const WrapHandler = require('../handler/wrap-handler')
|
|
4
|
+
|
|
5
|
+
const wrapInterceptor = (dispatch) => (opts, handler) => dispatch(opts, WrapHandler.wrap(handler))
|
|
3
6
|
|
|
4
7
|
class Dispatcher extends EventEmitter {
|
|
5
8
|
dispatch () {
|
|
@@ -29,36 +32,16 @@ class Dispatcher extends EventEmitter {
|
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
dispatch = interceptor(dispatch)
|
|
35
|
+
dispatch = wrapInterceptor(dispatch)
|
|
32
36
|
|
|
33
37
|
if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) {
|
|
34
38
|
throw new TypeError('invalid interceptor')
|
|
35
39
|
}
|
|
36
40
|
}
|
|
37
41
|
|
|
38
|
-
return new
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
class ComposedDispatcher extends Dispatcher {
|
|
43
|
-
#dispatcher = null
|
|
44
|
-
#dispatch = null
|
|
45
|
-
|
|
46
|
-
constructor (dispatcher, dispatch) {
|
|
47
|
-
super()
|
|
48
|
-
this.#dispatcher = dispatcher
|
|
49
|
-
this.#dispatch = dispatch
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
dispatch (...args) {
|
|
53
|
-
this.#dispatch(...args)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
close (...args) {
|
|
57
|
-
return this.#dispatcher.close(...args)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
destroy (...args) {
|
|
61
|
-
return this.#dispatcher.destroy(...args)
|
|
42
|
+
return new Proxy(this, {
|
|
43
|
+
get: (target, key) => key === 'dispatch' ? dispatch : target[key]
|
|
44
|
+
})
|
|
62
45
|
}
|
|
63
46
|
}
|
|
64
47
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
|
|
3
1
|
'use strict'
|
|
4
2
|
|
|
5
3
|
// Extracted from node/lib/internal/fixed_queue.js
|
|
6
4
|
|
|
7
5
|
// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two.
|
|
8
|
-
const kSize = 2048
|
|
9
|
-
const kMask = kSize - 1
|
|
6
|
+
const kSize = 2048
|
|
7
|
+
const kMask = kSize - 1
|
|
10
8
|
|
|
11
9
|
// The FixedQueue is implemented as a singly-linked list of fixed-size
|
|
12
10
|
// circular buffers. It looks something like this:
|
|
@@ -17,18 +15,18 @@ const kMask = kSize - 1;
|
|
|
17
15
|
// +-----------+ <-----\ +-----------+ <------\ +-----------+
|
|
18
16
|
// | [null] | \----- | next | \------- | next |
|
|
19
17
|
// +-----------+ +-----------+ +-----------+
|
|
20
|
-
// | item | <-- bottom | item | <-- bottom |
|
|
21
|
-
// | item | | item | |
|
|
22
|
-
// | item | | item | |
|
|
23
|
-
// | item | | item | |
|
|
18
|
+
// | item | <-- bottom | item | <-- bottom | undefined |
|
|
19
|
+
// | item | | item | | undefined |
|
|
20
|
+
// | item | | item | | undefined |
|
|
21
|
+
// | item | | item | | undefined |
|
|
24
22
|
// | item | | item | bottom --> | item |
|
|
25
23
|
// | item | | item | | item |
|
|
26
24
|
// | ... | | ... | | ... |
|
|
27
25
|
// | item | | item | | item |
|
|
28
26
|
// | item | | item | | item |
|
|
29
|
-
// |
|
|
30
|
-
// |
|
|
31
|
-
// |
|
|
27
|
+
// | undefined | <-- top | item | | item |
|
|
28
|
+
// | undefined | | item | | item |
|
|
29
|
+
// | undefined | | undefined | <-- top top --> | undefined |
|
|
32
30
|
// +-----------+ +-----------+ +-----------+
|
|
33
31
|
//
|
|
34
32
|
// Or, if there is only one circular buffer, it looks something
|
|
@@ -40,12 +38,12 @@ const kMask = kSize - 1;
|
|
|
40
38
|
// +-----------+ +-----------+
|
|
41
39
|
// | [null] | | [null] |
|
|
42
40
|
// +-----------+ +-----------+
|
|
43
|
-
// |
|
|
44
|
-
// |
|
|
45
|
-
// | item | <-- bottom top --> |
|
|
46
|
-
// | item | |
|
|
47
|
-
// |
|
|
48
|
-
// |
|
|
41
|
+
// | undefined | | item |
|
|
42
|
+
// | undefined | | item |
|
|
43
|
+
// | item | <-- bottom top --> | undefined |
|
|
44
|
+
// | item | | undefined |
|
|
45
|
+
// | undefined | <-- top bottom --> | item |
|
|
46
|
+
// | undefined | | item |
|
|
49
47
|
// +-----------+ +-----------+
|
|
50
48
|
//
|
|
51
49
|
// Adding a value means moving `top` forward by one, removing means
|
|
@@ -56,62 +54,106 @@ const kMask = kSize - 1;
|
|
|
56
54
|
// `top + 1 === bottom` it's full. This wastes a single space of storage
|
|
57
55
|
// but allows much quicker checks.
|
|
58
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @type {FixedCircularBuffer}
|
|
59
|
+
* @template T
|
|
60
|
+
*/
|
|
59
61
|
class FixedCircularBuffer {
|
|
60
|
-
constructor() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.
|
|
62
|
+
constructor () {
|
|
63
|
+
/**
|
|
64
|
+
* @type {number}
|
|
65
|
+
*/
|
|
66
|
+
this.bottom = 0
|
|
67
|
+
/**
|
|
68
|
+
* @type {number}
|
|
69
|
+
*/
|
|
70
|
+
this.top = 0
|
|
71
|
+
/**
|
|
72
|
+
* @type {Array<T|undefined>}
|
|
73
|
+
*/
|
|
74
|
+
this.list = new Array(kSize).fill(undefined)
|
|
75
|
+
/**
|
|
76
|
+
* @type {T|null}
|
|
77
|
+
*/
|
|
78
|
+
this.next = null
|
|
65
79
|
}
|
|
66
80
|
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
/**
|
|
82
|
+
* @returns {boolean}
|
|
83
|
+
*/
|
|
84
|
+
isEmpty () {
|
|
85
|
+
return this.top === this.bottom
|
|
69
86
|
}
|
|
70
87
|
|
|
71
|
-
|
|
72
|
-
|
|
88
|
+
/**
|
|
89
|
+
* @returns {boolean}
|
|
90
|
+
*/
|
|
91
|
+
isFull () {
|
|
92
|
+
return ((this.top + 1) & kMask) === this.bottom
|
|
73
93
|
}
|
|
74
94
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
95
|
+
/**
|
|
96
|
+
* @param {T} data
|
|
97
|
+
* @returns {void}
|
|
98
|
+
*/
|
|
99
|
+
push (data) {
|
|
100
|
+
this.list[this.top] = data
|
|
101
|
+
this.top = (this.top + 1) & kMask
|
|
78
102
|
}
|
|
79
103
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
this.list[this.bottom]
|
|
85
|
-
|
|
86
|
-
|
|
104
|
+
/**
|
|
105
|
+
* @returns {T|null}
|
|
106
|
+
*/
|
|
107
|
+
shift () {
|
|
108
|
+
const nextItem = this.list[this.bottom]
|
|
109
|
+
if (nextItem === undefined) { return null }
|
|
110
|
+
this.list[this.bottom] = undefined
|
|
111
|
+
this.bottom = (this.bottom + 1) & kMask
|
|
112
|
+
return nextItem
|
|
87
113
|
}
|
|
88
114
|
}
|
|
89
115
|
|
|
116
|
+
/**
|
|
117
|
+
* @template T
|
|
118
|
+
*/
|
|
90
119
|
module.exports = class FixedQueue {
|
|
91
|
-
constructor() {
|
|
92
|
-
|
|
120
|
+
constructor () {
|
|
121
|
+
/**
|
|
122
|
+
* @type {FixedCircularBuffer<T>}
|
|
123
|
+
*/
|
|
124
|
+
this.head = this.tail = new FixedCircularBuffer()
|
|
93
125
|
}
|
|
94
126
|
|
|
95
|
-
|
|
96
|
-
|
|
127
|
+
/**
|
|
128
|
+
* @returns {boolean}
|
|
129
|
+
*/
|
|
130
|
+
isEmpty () {
|
|
131
|
+
return this.head.isEmpty()
|
|
97
132
|
}
|
|
98
133
|
|
|
99
|
-
|
|
134
|
+
/**
|
|
135
|
+
* @param {T} data
|
|
136
|
+
*/
|
|
137
|
+
push (data) {
|
|
100
138
|
if (this.head.isFull()) {
|
|
101
139
|
// Head is full: Creates a new queue, sets the old queue's `.next` to it,
|
|
102
140
|
// and sets it as the new main queue.
|
|
103
|
-
this.head = this.head.next = new FixedCircularBuffer()
|
|
141
|
+
this.head = this.head.next = new FixedCircularBuffer()
|
|
104
142
|
}
|
|
105
|
-
this.head.push(data)
|
|
143
|
+
this.head.push(data)
|
|
106
144
|
}
|
|
107
145
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
146
|
+
/**
|
|
147
|
+
* @returns {T|null}
|
|
148
|
+
*/
|
|
149
|
+
shift () {
|
|
150
|
+
const tail = this.tail
|
|
151
|
+
const next = tail.shift()
|
|
111
152
|
if (tail.isEmpty() && tail.next !== null) {
|
|
112
153
|
// If there is another queue, it forms the new tail.
|
|
113
|
-
this.tail = tail.next
|
|
154
|
+
this.tail = tail.next
|
|
155
|
+
tail.next = null
|
|
114
156
|
}
|
|
115
|
-
return next
|
|
157
|
+
return next
|
|
116
158
|
}
|
|
117
|
-
}
|
|
159
|
+
}
|
package/lib/dispatcher/pool.js
CHANGED
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
InvalidArgumentError
|
|
13
13
|
} = require('../core/errors')
|
|
14
14
|
const util = require('../core/util')
|
|
15
|
-
const { kUrl
|
|
15
|
+
const { kUrl } = require('../core/symbols')
|
|
16
16
|
const buildConnector = require('../core/connect')
|
|
17
17
|
|
|
18
18
|
const kOptions = Symbol('options')
|
|
@@ -37,8 +37,6 @@ class Pool extends PoolBase {
|
|
|
37
37
|
allowH2,
|
|
38
38
|
...options
|
|
39
39
|
} = {}) {
|
|
40
|
-
super()
|
|
41
|
-
|
|
42
40
|
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
|
|
43
41
|
throw new InvalidArgumentError('invalid connections')
|
|
44
42
|
}
|
|
@@ -51,6 +49,8 @@ class Pool extends PoolBase {
|
|
|
51
49
|
throw new InvalidArgumentError('connect must be a function or an object')
|
|
52
50
|
}
|
|
53
51
|
|
|
52
|
+
super()
|
|
53
|
+
|
|
54
54
|
if (typeof connect !== 'function') {
|
|
55
55
|
connect = buildConnector({
|
|
56
56
|
...tls,
|
|
@@ -63,9 +63,6 @@ class Pool extends PoolBase {
|
|
|
63
63
|
})
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool)
|
|
67
|
-
? options.interceptors.Pool
|
|
68
|
-
: []
|
|
69
66
|
this[kConnections] = connections || null
|
|
70
67
|
this[kUrl] = util.parseOrigin(origin)
|
|
71
68
|
this[kOptions] = { ...util.deepClone(options), connect, allowH2 }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { kProxy, kClose, kDestroy
|
|
3
|
+
const { kProxy, kClose, kDestroy } = require('../core/symbols')
|
|
4
4
|
const { URL } = require('node:url')
|
|
5
5
|
const Agent = require('./agent')
|
|
6
6
|
const Pool = require('./pool')
|
|
@@ -27,8 +27,6 @@ const noop = () => {}
|
|
|
27
27
|
|
|
28
28
|
class ProxyAgent extends DispatcherBase {
|
|
29
29
|
constructor (opts) {
|
|
30
|
-
super()
|
|
31
|
-
|
|
32
30
|
if (!opts || (typeof opts === 'object' && !(opts instanceof URL) && !opts.uri)) {
|
|
33
31
|
throw new InvalidArgumentError('Proxy uri is mandatory')
|
|
34
32
|
}
|
|
@@ -38,13 +36,12 @@ class ProxyAgent extends DispatcherBase {
|
|
|
38
36
|
throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.')
|
|
39
37
|
}
|
|
40
38
|
|
|
39
|
+
super()
|
|
40
|
+
|
|
41
41
|
const url = this.#getUrl(opts)
|
|
42
42
|
const { href, origin, port, protocol, username, password, hostname: proxyHostname } = url
|
|
43
43
|
|
|
44
44
|
this[kProxy] = { uri: href, protocol }
|
|
45
|
-
this[kInterceptors] = opts.interceptors?.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent)
|
|
46
|
-
? opts.interceptors.ProxyAgent
|
|
47
|
-
: []
|
|
48
45
|
this[kRequestTls] = opts.requestTls
|
|
49
46
|
this[kProxyTls] = opts.proxyTls
|
|
50
47
|
this[kProxyHeaders] = opts.headers || {}
|