undici 7.0.0-alpha.1 → 7.0.0-alpha.2

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 (71) hide show
  1. package/README.md +2 -2
  2. package/docs/docs/api/Client.md +1 -1
  3. package/docs/docs/api/Debug.md +1 -1
  4. package/docs/docs/api/Dispatcher.md +53 -2
  5. package/docs/docs/api/MockAgent.md +2 -0
  6. package/docs/docs/api/MockPool.md +2 -1
  7. package/docs/docs/api/RetryAgent.md +1 -1
  8. package/docs/docs/api/RetryHandler.md +1 -1
  9. package/docs/docs/api/WebSocket.md +45 -3
  10. package/index.js +6 -2
  11. package/lib/api/abort-signal.js +2 -0
  12. package/lib/api/api-pipeline.js +4 -2
  13. package/lib/api/api-request.js +4 -2
  14. package/lib/api/api-stream.js +3 -1
  15. package/lib/api/api-upgrade.js +2 -2
  16. package/lib/api/readable.js +194 -41
  17. package/lib/api/util.js +2 -0
  18. package/lib/core/connect.js +49 -22
  19. package/lib/core/constants.js +11 -9
  20. package/lib/core/diagnostics.js +122 -128
  21. package/lib/core/request.js +4 -4
  22. package/lib/core/symbols.js +2 -0
  23. package/lib/core/tree.js +4 -2
  24. package/lib/core/util.js +220 -39
  25. package/lib/dispatcher/client-h1.js +299 -60
  26. package/lib/dispatcher/client-h2.js +1 -1
  27. package/lib/dispatcher/client.js +24 -7
  28. package/lib/dispatcher/fixed-queue.js +91 -49
  29. package/lib/dispatcher/pool-stats.js +2 -0
  30. package/lib/dispatcher/proxy-agent.js +3 -1
  31. package/lib/handler/redirect-handler.js +2 -2
  32. package/lib/handler/retry-handler.js +2 -2
  33. package/lib/interceptor/dns.js +346 -0
  34. package/lib/mock/mock-agent.js +5 -8
  35. package/lib/mock/mock-client.js +7 -2
  36. package/lib/mock/mock-errors.js +3 -1
  37. package/lib/mock/mock-interceptor.js +8 -6
  38. package/lib/mock/mock-pool.js +7 -2
  39. package/lib/mock/mock-symbols.js +2 -1
  40. package/lib/mock/mock-utils.js +33 -5
  41. package/lib/util/timers.js +50 -6
  42. package/lib/web/cache/cache.js +24 -21
  43. package/lib/web/cache/cachestorage.js +1 -1
  44. package/lib/web/cookies/index.js +6 -4
  45. package/lib/web/fetch/body.js +42 -34
  46. package/lib/web/fetch/constants.js +35 -26
  47. package/lib/web/fetch/formdata-parser.js +14 -3
  48. package/lib/web/fetch/formdata.js +40 -20
  49. package/lib/web/fetch/headers.js +116 -84
  50. package/lib/web/fetch/index.js +65 -59
  51. package/lib/web/fetch/request.js +130 -55
  52. package/lib/web/fetch/response.js +79 -36
  53. package/lib/web/fetch/util.js +104 -57
  54. package/lib/web/fetch/webidl.js +38 -14
  55. package/lib/web/websocket/connection.js +92 -15
  56. package/lib/web/websocket/constants.js +2 -3
  57. package/lib/web/websocket/events.js +4 -2
  58. package/lib/web/websocket/receiver.js +20 -26
  59. package/lib/web/websocket/stream/websocketerror.js +83 -0
  60. package/lib/web/websocket/stream/websocketstream.js +485 -0
  61. package/lib/web/websocket/util.js +115 -10
  62. package/lib/web/websocket/websocket.js +45 -170
  63. package/package.json +6 -6
  64. package/types/interceptors.d.ts +14 -0
  65. package/types/mock-agent.d.ts +3 -0
  66. package/types/readable.d.ts +10 -7
  67. package/types/webidl.d.ts +24 -4
  68. package/types/websocket.d.ts +33 -0
  69. package/lib/mock/pluralizer.js +0 -29
  70. package/lib/web/cache/symbols.js +0 -5
  71. package/lib/web/fetch/symbols.js +0 -8
@@ -1,11 +1,12 @@
1
1
  'use strict'
2
+
2
3
  const diagnosticsChannel = require('node:diagnostics_channel')
3
4
  const util = require('node:util')
4
5
 
5
6
  const undiciDebugLog = util.debuglog('undici')
6
7
  const fetchDebuglog = util.debuglog('fetch')
7
8
  const websocketDebuglog = util.debuglog('websocket')
8
- let isClientSet = false
9
+
9
10
  const channels = {
10
11
  // Client
11
12
  beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'),
@@ -26,102 +27,21 @@ const channels = {
26
27
  pong: diagnosticsChannel.channel('undici:websocket:pong')
27
28
  }
28
29
 
29
- if (undiciDebugLog.enabled || fetchDebuglog.enabled) {
30
- const debuglog = fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog
31
-
32
- // Track all Client events
33
- diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => {
34
- const {
35
- connectParams: { version, protocol, port, host }
36
- } = evt
37
- debuglog(
38
- 'connecting to %s using %s%s',
39
- `${host}${port ? `:${port}` : ''}`,
40
- protocol,
41
- version
42
- )
43
- })
44
-
45
- diagnosticsChannel.channel('undici:client:connected').subscribe(evt => {
46
- const {
47
- connectParams: { version, protocol, port, host }
48
- } = evt
49
- debuglog(
50
- 'connected to %s using %s%s',
51
- `${host}${port ? `:${port}` : ''}`,
52
- protocol,
53
- version
54
- )
55
- })
56
-
57
- diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => {
58
- const {
59
- connectParams: { version, protocol, port, host },
60
- error
61
- } = evt
62
- debuglog(
63
- 'connection to %s using %s%s errored - %s',
64
- `${host}${port ? `:${port}` : ''}`,
65
- protocol,
66
- version,
67
- error.message
68
- )
69
- })
70
-
71
- diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => {
72
- const {
73
- request: { method, path, origin }
74
- } = evt
75
- debuglog('sending request to %s %s/%s', method, origin, path)
76
- })
77
-
78
- // Track Request events
79
- diagnosticsChannel.channel('undici:request:headers').subscribe(evt => {
80
- const {
81
- request: { method, path, origin },
82
- response: { statusCode }
83
- } = evt
84
- debuglog(
85
- 'received response to %s %s/%s - HTTP %d',
86
- method,
87
- origin,
88
- path,
89
- statusCode
90
- )
91
- })
92
-
93
- diagnosticsChannel.channel('undici:request:trailers').subscribe(evt => {
94
- const {
95
- request: { method, path, origin }
96
- } = evt
97
- debuglog('trailers received from %s %s/%s', method, origin, path)
98
- })
99
-
100
- diagnosticsChannel.channel('undici:request:error').subscribe(evt => {
101
- const {
102
- request: { method, path, origin },
103
- error
104
- } = evt
105
- debuglog(
106
- 'request to %s %s/%s errored - %s',
107
- method,
108
- origin,
109
- path,
110
- error.message
111
- )
112
- })
113
-
114
- isClientSet = true
115
- }
30
+ let isTrackingClientEvents = false
116
31
 
117
- if (websocketDebuglog.enabled) {
118
- if (!isClientSet) {
119
- const debuglog = undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog
120
- diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(evt => {
32
+ function trackClientEvents (debugLog = undiciDebugLog) {
33
+ if (isTrackingClientEvents) {
34
+ return
35
+ }
36
+
37
+ isTrackingClientEvents = true
38
+
39
+ diagnosticsChannel.subscribe('undici:client:beforeConnect',
40
+ evt => {
121
41
  const {
122
42
  connectParams: { version, protocol, port, host }
123
43
  } = evt
124
- debuglog(
44
+ debugLog(
125
45
  'connecting to %s%s using %s%s',
126
46
  host,
127
47
  port ? `:${port}` : '',
@@ -130,11 +50,12 @@ if (websocketDebuglog.enabled) {
130
50
  )
131
51
  })
132
52
 
133
- diagnosticsChannel.channel('undici:client:connected').subscribe(evt => {
53
+ diagnosticsChannel.subscribe('undici:client:connected',
54
+ evt => {
134
55
  const {
135
56
  connectParams: { version, protocol, port, host }
136
57
  } = evt
137
- debuglog(
58
+ debugLog(
138
59
  'connected to %s%s using %s%s',
139
60
  host,
140
61
  port ? `:${port}` : '',
@@ -143,12 +64,13 @@ if (websocketDebuglog.enabled) {
143
64
  )
144
65
  })
145
66
 
146
- diagnosticsChannel.channel('undici:client:connectError').subscribe(evt => {
67
+ diagnosticsChannel.subscribe('undici:client:connectError',
68
+ evt => {
147
69
  const {
148
70
  connectParams: { version, protocol, port, host },
149
71
  error
150
72
  } = evt
151
- debuglog(
73
+ debugLog(
152
74
  'connection to %s%s using %s%s errored - %s',
153
75
  host,
154
76
  port ? `:${port}` : '',
@@ -158,43 +80,115 @@ if (websocketDebuglog.enabled) {
158
80
  )
159
81
  })
160
82
 
161
- diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(evt => {
83
+ diagnosticsChannel.subscribe('undici:client:sendHeaders',
84
+ evt => {
85
+ const {
86
+ request: { method, path, origin }
87
+ } = evt
88
+ debugLog('sending request to %s %s/%s', method, origin, path)
89
+ })
90
+ }
91
+
92
+ let isTrackingRequestEvents = false
93
+
94
+ function trackRequestEvents (debugLog = undiciDebugLog) {
95
+ if (isTrackingRequestEvents) {
96
+ return
97
+ }
98
+
99
+ isTrackingRequestEvents = true
100
+
101
+ diagnosticsChannel.subscribe('undici:request:headers',
102
+ evt => {
103
+ const {
104
+ request: { method, path, origin },
105
+ response: { statusCode }
106
+ } = evt
107
+ debugLog(
108
+ 'received response to %s %s/%s - HTTP %d',
109
+ method,
110
+ origin,
111
+ path,
112
+ statusCode
113
+ )
114
+ })
115
+
116
+ diagnosticsChannel.subscribe('undici:request:trailers',
117
+ evt => {
162
118
  const {
163
119
  request: { method, path, origin }
164
120
  } = evt
165
- debuglog('sending request to %s %s/%s', method, origin, path)
121
+ debugLog('trailers received from %s %s/%s', method, origin, path)
122
+ })
123
+
124
+ diagnosticsChannel.subscribe('undici:request:error',
125
+ evt => {
126
+ const {
127
+ request: { method, path, origin },
128
+ error
129
+ } = evt
130
+ debugLog(
131
+ 'request to %s %s/%s errored - %s',
132
+ method,
133
+ origin,
134
+ path,
135
+ error.message
136
+ )
166
137
  })
138
+ }
139
+
140
+ let isTrackingWebSocketEvents = false
141
+
142
+ function trackWebSocketEvents (debugLog = websocketDebuglog) {
143
+ if (isTrackingWebSocketEvents) {
144
+ return
167
145
  }
168
146
 
169
- // Track all WebSocket events
170
- diagnosticsChannel.channel('undici:websocket:open').subscribe(evt => {
171
- const {
172
- address: { address, port }
173
- } = evt
174
- websocketDebuglog('connection opened %s%s', address, port ? `:${port}` : '')
175
- })
176
-
177
- diagnosticsChannel.channel('undici:websocket:close').subscribe(evt => {
178
- const { websocket, code, reason } = evt
179
- websocketDebuglog(
180
- 'closed connection to %s - %s %s',
181
- websocket.url,
182
- code,
183
- reason
184
- )
185
- })
186
-
187
- diagnosticsChannel.channel('undici:websocket:socket_error').subscribe(err => {
188
- websocketDebuglog('connection errored - %s', err.message)
189
- })
190
-
191
- diagnosticsChannel.channel('undici:websocket:ping').subscribe(evt => {
192
- websocketDebuglog('ping received')
193
- })
194
-
195
- diagnosticsChannel.channel('undici:websocket:pong').subscribe(evt => {
196
- websocketDebuglog('pong received')
197
- })
147
+ isTrackingWebSocketEvents = true
148
+
149
+ diagnosticsChannel.subscribe('undici:websocket:open',
150
+ evt => {
151
+ const {
152
+ address: { address, port }
153
+ } = evt
154
+ debugLog('connection opened %s%s', address, port ? `:${port}` : '')
155
+ })
156
+
157
+ diagnosticsChannel.subscribe('undici:websocket:close',
158
+ evt => {
159
+ const { websocket, code, reason } = evt
160
+ debugLog(
161
+ 'closed connection to %s - %s %s',
162
+ websocket.url,
163
+ code,
164
+ reason
165
+ )
166
+ })
167
+
168
+ diagnosticsChannel.subscribe('undici:websocket:socket_error',
169
+ err => {
170
+ debugLog('connection errored - %s', err.message)
171
+ })
172
+
173
+ diagnosticsChannel.subscribe('undici:websocket:ping',
174
+ evt => {
175
+ debugLog('ping received')
176
+ })
177
+
178
+ diagnosticsChannel.subscribe('undici:websocket:pong',
179
+ evt => {
180
+ debugLog('pong received')
181
+ })
182
+ }
183
+
184
+ if (undiciDebugLog.enabled || fetchDebuglog.enabled) {
185
+ trackClientEvents(fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog)
186
+ trackRequestEvents(fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog)
187
+ }
188
+
189
+ if (websocketDebuglog.enabled) {
190
+ trackClientEvents(undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog)
191
+ trackWebSocketEvents(websocketDebuglog)
198
192
  }
199
193
 
200
194
  module.exports = {
@@ -14,8 +14,8 @@ const {
14
14
  isFormDataLike,
15
15
  isIterable,
16
16
  isBlobLike,
17
- buildURL,
18
- validateHandler,
17
+ serializePathWithQuery,
18
+ assertRequestHandler,
19
19
  getServerName,
20
20
  normalizedMethodRecords
21
21
  } = require('./util')
@@ -135,7 +135,7 @@ class Request {
135
135
 
136
136
  this.upgrade = upgrade || null
137
137
 
138
- this.path = query ? buildURL(path, query) : path
138
+ this.path = query ? serializePathWithQuery(path, query) : path
139
139
 
140
140
  this.origin = origin
141
141
 
@@ -183,7 +183,7 @@ class Request {
183
183
  throw new InvalidArgumentError('headers must be an object or an array')
184
184
  }
185
185
 
186
- validateHandler(handler, method, upgrade)
186
+ assertRequestHandler(handler, method, upgrade)
187
187
 
188
188
  this.servername = servername || getServerName(this.host) || null
189
189
 
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  module.exports = {
2
4
  kClose: Symbol('close'),
3
5
  kDestroy: Symbol('destroy'),
package/lib/core/tree.js CHANGED
@@ -40,6 +40,7 @@ class TstNode {
40
40
  /**
41
41
  * @param {string} key
42
42
  * @param {any} value
43
+ * @returns {void}
43
44
  */
44
45
  add (key, value) {
45
46
  const length = key.length
@@ -91,7 +92,7 @@ class TstNode {
91
92
  const keylength = key.length
92
93
  let index = 0
93
94
  /**
94
- * @type {TstNode}
95
+ * @type {TstNode|null}
95
96
  */
96
97
  let node = this
97
98
  while (node !== null && index < keylength) {
@@ -127,6 +128,7 @@ class TernarySearchTree {
127
128
  /**
128
129
  * @param {string} key
129
130
  * @param {any} value
131
+ * @returns {void}
130
132
  * */
131
133
  insert (key, value) {
132
134
  if (this.node === null) {
@@ -138,7 +140,7 @@ class TernarySearchTree {
138
140
 
139
141
  /**
140
142
  * @param {Uint8Array} key
141
- * @return {any}
143
+ * @returns {any}
142
144
  */
143
145
  lookup (key) {
144
146
  return this.node?.search(key)?.value ?? null