undici 7.2.3 → 7.3.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.
@@ -15,11 +15,18 @@ const MAX_ENTRY_SIZE = 2 * 1000 * 1000 * 1000
15
15
  * @implements {CacheStore}
16
16
  *
17
17
  * @typedef {{
18
- * id: Readonly<number>
19
- * headers?: Record<string, string | string[]>
20
- * vary?: string | object
21
- * body: string
22
- * } & import('../../types/cache-interceptor.d.ts').default.CacheValue} SqliteStoreValue
18
+ * id: Readonly<number>,
19
+ * body?: Uint8Array
20
+ * statusCode: number
21
+ * statusMessage: string
22
+ * headers?: string
23
+ * vary?: string
24
+ * etag?: string
25
+ * cacheControlDirectives?: string
26
+ * cachedAt: number
27
+ * staleAt: number
28
+ * deleteAt: number
29
+ * }} SqliteStoreValue
23
30
  */
24
31
  module.exports = class SqliteCacheStore {
25
32
  #maxEntrySize = MAX_ENTRY_SIZE
@@ -61,7 +68,7 @@ module.exports = class SqliteCacheStore {
61
68
  #countEntriesQuery
62
69
 
63
70
  /**
64
- * @type {import('node:sqlite').StatementSync}
71
+ * @type {import('node:sqlite').StatementSync | null}
65
72
  */
66
73
  #deleteOldValuesQuery
67
74
 
@@ -163,8 +170,7 @@ module.exports = class SqliteCacheStore {
163
170
  etag = ?,
164
171
  cacheControlDirectives = ?,
165
172
  cachedAt = ?,
166
- staleAt = ?,
167
- deleteAt = ?
173
+ staleAt = ?
168
174
  WHERE
169
175
  id = ?
170
176
  `)
@@ -182,9 +188,8 @@ module.exports = class SqliteCacheStore {
182
188
  cacheControlDirectives,
183
189
  vary,
184
190
  cachedAt,
185
- staleAt,
186
- deleteAt
187
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
191
+ staleAt
192
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
188
193
  `)
189
194
 
190
195
  this.#deleteByUrlQuery = this.#db.prepare(
@@ -219,36 +224,78 @@ module.exports = class SqliteCacheStore {
219
224
 
220
225
  /**
221
226
  * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key
222
- * @returns {import('../../types/cache-interceptor.d.ts').default.GetResult | undefined}
227
+ * @returns {(import('../../types/cache-interceptor.d.ts').default.GetResult & { body?: Buffer }) | undefined}
223
228
  */
224
229
  get (key) {
225
230
  assertCacheKey(key)
226
231
 
227
232
  const value = this.#findValue(key)
233
+ return value
234
+ ? {
235
+ body: value.body ? Buffer.from(value.body.buffer) : undefined,
236
+ statusCode: value.statusCode,
237
+ statusMessage: value.statusMessage,
238
+ headers: value.headers ? JSON.parse(value.headers) : undefined,
239
+ etag: value.etag ? value.etag : undefined,
240
+ vary: value.vary ? JSON.parse(value.vary) : undefined,
241
+ cacheControlDirectives: value.cacheControlDirectives
242
+ ? JSON.parse(value.cacheControlDirectives)
243
+ : undefined,
244
+ cachedAt: value.cachedAt,
245
+ staleAt: value.staleAt,
246
+ deleteAt: value.deleteAt
247
+ }
248
+ : undefined
249
+ }
228
250
 
229
- if (!value) {
230
- return undefined
231
- }
251
+ /**
252
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key
253
+ * @param {import('../../types/cache-interceptor.d.ts').default.CacheValue & { body: null | Buffer | Array<Buffer>}} value
254
+ */
255
+ set (key, value) {
256
+ assertCacheKey(key)
232
257
 
233
- /**
234
- * @type {import('../../types/cache-interceptor.d.ts').default.GetResult}
235
- */
236
- const result = {
237
- body: Buffer.from(value.body),
238
- statusCode: value.statusCode,
239
- statusMessage: value.statusMessage,
240
- headers: value.headers ? JSON.parse(value.headers) : undefined,
241
- etag: value.etag ? value.etag : undefined,
242
- vary: value.vary ?? undefined,
243
- cacheControlDirectives: value.cacheControlDirectives
244
- ? JSON.parse(value.cacheControlDirectives)
245
- : undefined,
246
- cachedAt: value.cachedAt,
247
- staleAt: value.staleAt,
248
- deleteAt: value.deleteAt
258
+ const url = this.#makeValueUrl(key)
259
+ const body = Array.isArray(value.body) ? Buffer.concat(value.body) : value.body
260
+ const size = body?.byteLength
261
+
262
+ if (size && size > this.#maxEntrySize) {
263
+ return
249
264
  }
250
265
 
251
- return result
266
+ const existingValue = this.#findValue(key, true)
267
+ if (existingValue) {
268
+ // Updating an existing response, let's overwrite it
269
+ this.#updateValueQuery.run(
270
+ body,
271
+ value.deleteAt,
272
+ value.statusCode,
273
+ value.statusMessage,
274
+ value.headers ? JSON.stringify(value.headers) : null,
275
+ value.etag ? value.etag : null,
276
+ value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
277
+ value.cachedAt,
278
+ value.staleAt,
279
+ existingValue.id
280
+ )
281
+ } else {
282
+ this.#prune()
283
+ // New response, let's insert it
284
+ this.#insertValueQuery.run(
285
+ url,
286
+ key.method,
287
+ body,
288
+ value.deleteAt,
289
+ value.statusCode,
290
+ value.statusMessage,
291
+ value.headers ? JSON.stringify(value.headers) : null,
292
+ value.etag ? value.etag : null,
293
+ value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
294
+ value.vary ? JSON.stringify(value.vary) : null,
295
+ value.cachedAt,
296
+ value.staleAt
297
+ )
298
+ }
252
299
  }
253
300
 
254
301
  /**
@@ -260,7 +307,6 @@ module.exports = class SqliteCacheStore {
260
307
  assertCacheKey(key)
261
308
  assertCacheValue(value)
262
309
 
263
- const url = this.#makeValueUrl(key)
264
310
  let size = 0
265
311
  /**
266
312
  * @type {Buffer[] | null}
@@ -269,11 +315,8 @@ module.exports = class SqliteCacheStore {
269
315
  const store = this
270
316
 
271
317
  return new Writable({
318
+ decodeStrings: true,
272
319
  write (chunk, encoding, callback) {
273
- if (typeof chunk === 'string') {
274
- chunk = Buffer.from(chunk, encoding)
275
- }
276
-
277
320
  size += chunk.byteLength
278
321
 
279
322
  if (size < store.#maxEntrySize) {
@@ -285,42 +328,7 @@ module.exports = class SqliteCacheStore {
285
328
  callback()
286
329
  },
287
330
  final (callback) {
288
- const existingValue = store.#findValue(key, true)
289
- if (existingValue) {
290
- // Updating an existing response, let's overwrite it
291
- store.#updateValueQuery.run(
292
- Buffer.concat(body),
293
- value.deleteAt,
294
- value.statusCode,
295
- value.statusMessage,
296
- value.headers ? JSON.stringify(value.headers) : null,
297
- value.etag ? value.etag : null,
298
- value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
299
- value.cachedAt,
300
- value.staleAt,
301
- value.deleteAt,
302
- existingValue.id
303
- )
304
- } else {
305
- store.#prune()
306
- // New response, let's insert it
307
- store.#insertValueQuery.run(
308
- url,
309
- key.method,
310
- Buffer.concat(body),
311
- value.deleteAt,
312
- value.statusCode,
313
- value.statusMessage,
314
- value.headers ? JSON.stringify(value.headers) : null,
315
- value.etag ? value.etag : null,
316
- value.cacheControlDirectives ? JSON.stringify(value.cacheControlDirectives) : null,
317
- value.vary ? JSON.stringify(value.vary) : null,
318
- value.cachedAt,
319
- value.staleAt,
320
- value.deleteAt
321
- )
322
- }
323
-
331
+ store.set(key, { ...value, body })
324
332
  callback()
325
333
  }
326
334
  })
@@ -344,14 +352,14 @@ module.exports = class SqliteCacheStore {
344
352
 
345
353
  {
346
354
  const removed = this.#deleteExpiredValuesQuery.run(Date.now()).changes
347
- if (removed > 0) {
355
+ if (removed) {
348
356
  return removed
349
357
  }
350
358
  }
351
359
 
352
360
  {
353
- const removed = this.#deleteOldValuesQuery.run(Math.max(Math.floor(this.#maxCount * 0.1), 1)).changes
354
- if (removed > 0) {
361
+ const removed = this.#deleteOldValuesQuery?.run(Math.max(Math.floor(this.#maxCount * 0.1), 1)).changes
362
+ if (removed) {
355
363
  return removed
356
364
  }
357
365
  }
@@ -379,7 +387,7 @@ module.exports = class SqliteCacheStore {
379
387
  /**
380
388
  * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key
381
389
  * @param {boolean} [canBeExpired=false]
382
- * @returns {(SqliteStoreValue & { vary?: Record<string, string[]> }) | undefined}
390
+ * @returns {SqliteStoreValue | undefined}
383
391
  */
384
392
  #findValue (key, canBeExpired = false) {
385
393
  const url = this.#makeValueUrl(key)
@@ -407,10 +415,10 @@ module.exports = class SqliteCacheStore {
407
415
  return undefined
408
416
  }
409
417
 
410
- value.vary = JSON.parse(value.vary)
418
+ const vary = JSON.parse(value.vary)
411
419
 
412
- for (const header in value.vary) {
413
- if (!headerValueEquals(headers[header], value.vary[header])) {
420
+ for (const header in vary) {
421
+ if (!headerValueEquals(headers[header], vary[header])) {
414
422
  matches = false
415
423
  break
416
424
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "undici",
3
- "version": "7.2.3",
3
+ "version": "7.3.0",
4
4
  "description": "An HTTP/1.1 client, written from scratch for Node.js",
5
5
  "homepage": "https://undici.nodejs.org",
6
6
  "bugs": {
@@ -90,7 +90,7 @@ declare namespace CacheHandler {
90
90
  headers: Record<string, string | string[]>
91
91
  vary?: Record<string, string | string[]>
92
92
  etag?: string
93
- body: null | Readable | Iterable<Buffer> | AsyncIterable<Buffer> | Buffer | Iterable<string> | AsyncIterable<string> | string
93
+ body?: Readable | Iterable<Buffer> | AsyncIterable<Buffer> | Buffer | Iterable<string> | AsyncIterable<string> | string
94
94
  cacheControlDirectives: CacheControlDirectives,
95
95
  cachedAt: number
96
96
  staleAt: number