@nxtedition/nxt-undici 2.0.57 → 2.1.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.
package/lib/index.js CHANGED
@@ -4,6 +4,8 @@ import undici from 'undici'
4
4
  import { parseHeaders, AbortError, isStream } from './utils.js'
5
5
  import { BodyReadable } from './readable.js'
6
6
 
7
+ export { parseHeaders } from './utils.js'
8
+
7
9
  const dispatcherCache = new WeakMap()
8
10
 
9
11
  export const interceptors = {
@@ -134,6 +136,14 @@ export async function request(url, opts) {
134
136
  error: opts.error ?? true,
135
137
  verify: opts.verify ?? true,
136
138
  logger: opts.logger ?? null,
139
+ startTime: performance.now(),
140
+ stats: {
141
+ connect: -1,
142
+ headers: -1,
143
+ data: -1,
144
+ complete: -1,
145
+ error: -1,
146
+ },
137
147
  },
138
148
  {
139
149
  resolve,
@@ -145,6 +155,8 @@ export async function request(url, opts) {
145
155
  /** @type {Function | null} */ abort: null,
146
156
  /** @type {stream.Readable | null} */ body: null,
147
157
  onConnect(abort) {
158
+ this.stats.connect = performance.now() - this.startTime
159
+
148
160
  if (this.signal?.aborted) {
149
161
  abort(this.signal.reason)
150
162
  } else {
@@ -177,12 +189,17 @@ export async function request(url, opts) {
177
189
  statusMessage,
178
190
  headers = parseHeaders(rawHeaders),
179
191
  ) {
192
+ if (this.stats.headers === -1) {
193
+ this.stats.headers = performance.now() - this.startTime - this.stats.connect
194
+ }
195
+
180
196
  assert(statusCode >= 200)
181
197
 
182
198
  const contentLength = headers['content-length']
183
199
  const contentType = headers['content-type']
184
200
 
185
201
  this.body = new BodyReadable(this, {
202
+ stats: this.stats,
186
203
  resume,
187
204
  abort: this.abort,
188
205
  highWaterMark: this.highWaterMark,
@@ -208,12 +225,24 @@ export async function request(url, opts) {
208
225
  return true
209
226
  },
210
227
  onData(chunk) {
228
+ if (this.stats.data === -1) {
229
+ this.stats.data = performance.now() - this.startTime - this.stats.headers
230
+ }
231
+
211
232
  return this.body.push(chunk)
212
233
  },
213
234
  onComplete() {
235
+ if (this.stats.complete === -1) {
236
+ this.stats.complete = performance.now() - this.startTime - this.stats.data
237
+ }
238
+
214
239
  this.body.push(null)
215
240
  },
216
241
  onError(err) {
242
+ if (this.stats.error === -1) {
243
+ this.stats.error = performance.now() - this.startTime - this.stats.data
244
+ }
245
+
217
246
  this.signal?.removeEventListener('abort', this.onAbort)
218
247
  this.signal = null
219
248
 
@@ -20,7 +20,7 @@ class Handler extends DecoratorHandler {
20
20
  {
21
21
  headers: rawHeaders,
22
22
  httpVersion: this.#opts.httpVersion ?? this.#opts.req?.httpVersion,
23
- socket: null,
23
+ socket: this.#opts.socket,
24
24
  proxyName: this.#opts.name,
25
25
  },
26
26
  (acc, key, val) => {
@@ -40,7 +40,7 @@ class Handler extends DecoratorHandler {
40
40
  {
41
41
  headers: rawHeaders,
42
42
  httpVersion: this.#opts.httpVersion ?? this.#opts.req?.httpVersion,
43
- socket: null,
43
+ socket: this.#opts.socket,
44
44
  proxyName: this.#opts.name,
45
45
  },
46
46
  (acc, key, val) => {
package/lib/readable.js CHANGED
@@ -4,6 +4,7 @@ import { errors as undiciErrors } from 'undici'
4
4
 
5
5
  const { RequestAbortedError, NotSupportedError, InvalidArgumentError, AbortError } = undiciErrors
6
6
 
7
+ const kStats = Symbol('kStats')
7
8
  const kConsume = Symbol('kConsume')
8
9
  const kReading = Symbol('kReading')
9
10
  const kBody = Symbol('kBody')
@@ -26,6 +27,7 @@ export class BodyReadable extends Readable {
26
27
  constructor(
27
28
  handler,
28
29
  {
30
+ stats,
29
31
  contentType = '',
30
32
  method,
31
33
  statusCode,
@@ -45,6 +47,7 @@ export class BodyReadable extends Readable {
45
47
 
46
48
  this._readableState.dataEmitted = false
47
49
 
50
+ this[kStats] = stats
48
51
  this[kHandler] = handler
49
52
  this[kStatusCode] = statusCode
50
53
  this[kStatusMessage] = statusMessage
@@ -65,6 +68,10 @@ export class BodyReadable extends Readable {
65
68
  this[kReading] = false
66
69
  }
67
70
 
71
+ get stats() {
72
+ return this[kStats]
73
+ }
74
+
68
75
  get statusCode() {
69
76
  return this[kStatusCode]
70
77
  }
package/lib/utils.js CHANGED
@@ -229,18 +229,20 @@ export function parseHeaders(headers, obj) {
229
229
  let val = obj[key]
230
230
 
231
231
  if (val) {
232
- if (typeof val === 'string') {
232
+ if (!Array.isArray(val)) {
233
233
  val = [val]
234
234
  obj[key] = val
235
235
  }
236
236
 
237
237
  if (Array.isArray(val2)) {
238
- val.push(...val2.map((x) => `${x}`))
238
+ val.push(...val2.filter((x) => x != null).map((x) => `${x}`))
239
239
  } else {
240
240
  val.push(`${val2}`)
241
241
  }
242
242
  } else {
243
- obj[key] = Array.isArray(val2) ? val2.map((x) => `${x}`) : `${val2}`
243
+ obj[key] = Array.isArray(val2)
244
+ ? val2.filter((x) => x != null).map((x) => `${x}`)
245
+ : `${val2}`
244
246
  }
245
247
  }
246
248
  } else if (typeof headers === 'object' && headers !== null) {
@@ -258,17 +260,19 @@ export function parseHeaders(headers, obj) {
258
260
  let val = obj[key]
259
261
 
260
262
  if (val) {
261
- if (typeof val === 'string') {
263
+ if (!Array.isArray(val)) {
262
264
  val = [val]
263
265
  obj[key] = val
264
266
  }
265
267
  if (Array.isArray(val2)) {
266
- val.push(...val2.map((x) => `${x}`))
268
+ val.push(...val2.filter((x) => x != null).map((x) => `${x}`))
267
269
  } else {
268
270
  val.push(`${val2}`)
269
271
  }
270
272
  } else if (val2 != null) {
271
- obj[key] = Array.isArray(val2) ? val2.map((x) => `${x}`) : `${val2}`
273
+ obj[key] = Array.isArray(val2)
274
+ ? val2.filter((x) => x != null).map((x) => `${x}`)
275
+ : `${val2}`
272
276
  }
273
277
  }
274
278
  } else if (headers != null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/nxt-undici",
3
- "version": "2.0.57",
3
+ "version": "2.1.0",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "main": "lib/index.js",