undici 7.0.0-alpha.2 → 7.0.0-alpha.4

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 (56) hide show
  1. package/README.md +3 -2
  2. package/docs/docs/api/BalancedPool.md +1 -1
  3. package/docs/docs/api/CacheStore.md +100 -0
  4. package/docs/docs/api/Dispatcher.md +32 -2
  5. package/docs/docs/api/MockClient.md +1 -1
  6. package/docs/docs/api/Pool.md +1 -1
  7. package/docs/docs/api/api-lifecycle.md +2 -2
  8. package/docs/docs/best-practices/mocking-request.md +2 -2
  9. package/docs/docs/best-practices/proxy.md +1 -1
  10. package/index.d.ts +1 -1
  11. package/index.js +8 -2
  12. package/lib/api/api-request.js +2 -2
  13. package/lib/api/readable.js +6 -6
  14. package/lib/cache/memory-cache-store.js +325 -0
  15. package/lib/core/connect.js +5 -0
  16. package/lib/core/constants.js +24 -1
  17. package/lib/core/request.js +2 -2
  18. package/lib/core/util.js +13 -1
  19. package/lib/dispatcher/client-h1.js +100 -87
  20. package/lib/dispatcher/client-h2.js +168 -96
  21. package/lib/dispatcher/pool-base.js +3 -3
  22. package/lib/handler/cache-handler.js +389 -0
  23. package/lib/handler/cache-revalidation-handler.js +151 -0
  24. package/lib/handler/redirect-handler.js +5 -3
  25. package/lib/handler/retry-handler.js +3 -3
  26. package/lib/interceptor/cache.js +192 -0
  27. package/lib/interceptor/dns.js +71 -48
  28. package/lib/util/cache.js +249 -0
  29. package/lib/web/cache/cache.js +1 -0
  30. package/lib/web/cache/cachestorage.js +2 -0
  31. package/lib/web/cookies/index.js +12 -1
  32. package/lib/web/cookies/parse.js +6 -1
  33. package/lib/web/eventsource/eventsource.js +2 -0
  34. package/lib/web/fetch/body.js +1 -5
  35. package/lib/web/fetch/constants.js +12 -5
  36. package/lib/web/fetch/data-url.js +2 -2
  37. package/lib/web/fetch/formdata-parser.js +70 -43
  38. package/lib/web/fetch/formdata.js +3 -1
  39. package/lib/web/fetch/headers.js +3 -1
  40. package/lib/web/fetch/index.js +4 -6
  41. package/lib/web/fetch/request.js +3 -1
  42. package/lib/web/fetch/response.js +3 -1
  43. package/lib/web/fetch/util.js +171 -47
  44. package/lib/web/fetch/webidl.js +28 -16
  45. package/lib/web/websocket/constants.js +67 -6
  46. package/lib/web/websocket/events.js +4 -0
  47. package/lib/web/websocket/stream/websocketerror.js +1 -1
  48. package/lib/web/websocket/websocket.js +2 -0
  49. package/package.json +8 -5
  50. package/types/cache-interceptor.d.ts +101 -0
  51. package/types/cookies.d.ts +2 -0
  52. package/types/dispatcher.d.ts +1 -1
  53. package/types/fetch.d.ts +9 -8
  54. package/types/index.d.ts +3 -1
  55. package/types/interceptors.d.ts +4 -1
  56. package/types/webidl.d.ts +7 -1
@@ -0,0 +1,101 @@
1
+ import { Readable, Writable } from 'node:stream'
2
+
3
+ export default CacheHandler
4
+
5
+ declare namespace CacheHandler {
6
+ export type CacheMethods = 'GET' | 'HEAD' | 'OPTIONS' | 'TRACE'
7
+
8
+ export interface CacheOptions {
9
+ store?: CacheStore
10
+
11
+ /**
12
+ * The methods to cache
13
+ * Note we can only cache safe methods. Unsafe methods (i.e. PUT, POST)
14
+ * invalidate the cache for a origin.
15
+ * @see https://www.rfc-editor.org/rfc/rfc9111.html#name-invalidating-stored-respons
16
+ * @see https://www.rfc-editor.org/rfc/rfc9110#section-9.2.1
17
+ */
18
+ methods?: CacheMethods[]
19
+ }
20
+
21
+ export interface CacheKey {
22
+ origin: string
23
+ method: string
24
+ path: string
25
+ headers?: Record<string, string | string[]>
26
+ }
27
+
28
+ export interface DeleteByUri {
29
+ origin: string
30
+ method: string
31
+ path: string
32
+ }
33
+
34
+ type GetResult = CachedResponse & { body: null | Readable | Iterable<Buffer> | Buffer | Iterable<string> | string }
35
+
36
+ /**
37
+ * Underlying storage provider for cached responses
38
+ */
39
+ export interface CacheStore {
40
+ /**
41
+ * Whether or not the cache is full and can not store any more responses
42
+ */
43
+ get isFull(): boolean | undefined
44
+
45
+ get(key: CacheKey): GetResult | Promise<GetResult | undefined> | undefined
46
+
47
+ createWriteStream(key: CacheKey, value: CachedResponse): Writable | undefined
48
+
49
+ delete(key: CacheKey): void | Promise<void>
50
+ }
51
+
52
+ export interface CachedResponse {
53
+ statusCode: number;
54
+ statusMessage: string;
55
+ rawHeaders: Buffer[];
56
+ /**
57
+ * Headers defined by the Vary header and their respective values for
58
+ * later comparison
59
+ */
60
+ vary?: Record<string, string | string[]>
61
+ /**
62
+ * Time in millis that this value was cached
63
+ */
64
+ cachedAt: number
65
+ /**
66
+ * Time in millis that this value is considered stale
67
+ */
68
+ staleAt: number
69
+ /**
70
+ * Time in millis that this value is to be deleted from the cache. This is
71
+ * either the same as staleAt or the `max-stale` caching directive.
72
+ */
73
+ deleteAt: number
74
+ }
75
+
76
+ export interface MemoryCacheStoreOpts {
77
+ /**
78
+ * @default Infinity
79
+ */
80
+ maxCount?: number
81
+
82
+ /**
83
+ * @default Infinity
84
+ */
85
+ maxEntrySize?: number
86
+
87
+ errorCallback?: (err: Error) => void
88
+ }
89
+
90
+ export class MemoryCacheStore implements CacheStore {
91
+ constructor (opts?: MemoryCacheStoreOpts)
92
+
93
+ get isFull (): boolean | undefined
94
+
95
+ get (key: CacheKey): GetResult | Promise<GetResult | undefined> | undefined
96
+
97
+ createWriteStream (key: CacheKey, value: CachedResponse): Writable | undefined
98
+
99
+ delete (key: CacheKey): void | Promise<void>
100
+ }
101
+ }
@@ -26,3 +26,5 @@ export function getCookies (headers: Headers): Record<string, string>
26
26
  export function getSetCookies (headers: Headers): Cookie[]
27
27
 
28
28
  export function setCookie (headers: Headers, cookie: Cookie): void
29
+
30
+ export function parseCookie (cookie: string): Cookie | null
@@ -108,7 +108,7 @@ declare namespace Dispatcher {
108
108
  query?: Record<string, any>;
109
109
  /** Whether the requests can be safely retried or not. If `false` the request won't be sent until all preceding requests in the pipeline have completed. Default: `true` if `method` is `HEAD` or `GET`. */
110
110
  idempotent?: boolean;
111
- /** Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received. */
111
+ /** Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received. Defaults to `method !== 'HEAD'`. */
112
112
  blocking?: boolean;
113
113
  /** Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. Default: `method === 'CONNECT' || null`. */
114
114
  upgrade?: boolean | string | null;
package/types/fetch.d.ts CHANGED
@@ -119,20 +119,21 @@ type RequestDestination =
119
119
  | 'xslt'
120
120
 
121
121
  export interface RequestInit {
122
- method?: string
123
- keepalive?: boolean
124
- headers?: HeadersInit
125
122
  body?: BodyInit | null
126
- redirect?: RequestRedirect
127
- integrity?: string
128
- signal?: AbortSignal | null
123
+ cache?: RequestCache
129
124
  credentials?: RequestCredentials
125
+ dispatcher?: Dispatcher
126
+ duplex?: RequestDuplex
127
+ headers?: HeadersInit
128
+ integrity?: string
129
+ keepalive?: boolean
130
+ method?: string
130
131
  mode?: RequestMode
132
+ redirect?: RequestRedirect
131
133
  referrer?: string
132
134
  referrerPolicy?: ReferrerPolicy
135
+ signal?: AbortSignal | null
133
136
  window?: null
134
- dispatcher?: Dispatcher
135
- duplex?: RequestDuplex
136
137
  }
137
138
 
138
139
  export type ReferrerPolicy =
package/types/index.d.ts CHANGED
@@ -40,7 +40,6 @@ declare namespace Undici {
40
40
  const RedirectHandler: typeof import ('./handlers').RedirectHandler
41
41
  const DecoratorHandler: typeof import ('./handlers').DecoratorHandler
42
42
  const RetryHandler: typeof import ('./retry-handler').default
43
- const createRedirectInterceptor: typeof import ('./interceptors').default.createRedirectInterceptor
44
43
  const BalancedPool: typeof import('./balanced-pool').default
45
44
  const Client: typeof import('./client').default
46
45
  const buildConnector: typeof import('./connector').default
@@ -64,4 +63,7 @@ declare namespace Undici {
64
63
  const FormData: typeof import('./formdata').FormData
65
64
  const caches: typeof import('./cache').caches
66
65
  const interceptors: typeof import('./interceptors').default
66
+ const cacheStores: {
67
+ MemoryCacheStore: typeof import('./cache-interceptor').default.MemoryCacheStore
68
+ }
67
69
  }
@@ -1,3 +1,4 @@
1
+ import CacheHandler from './cache-interceptor'
1
2
  import Dispatcher from './dispatcher'
2
3
  import RetryHandler from './retry-handler'
3
4
  import { LookupOptions } from 'node:dns'
@@ -10,6 +11,8 @@ declare namespace Interceptors {
10
11
  export type RedirectInterceptorOpts = { maxRedirections?: number }
11
12
 
12
13
  export type ResponseErrorInterceptorOpts = { throwOnError: boolean }
14
+ export type CacheInterceptorOpts = CacheHandler.CacheOptions
15
+
13
16
  // DNS interceptor
14
17
  export type DNSInterceptorRecord = { address: string, ttl: number, family: 4 | 6 }
15
18
  export type DNSInterceptorOriginRecords = { 4: { ips: DNSInterceptorRecord[] } | null, 6: { ips: DNSInterceptorRecord[] } | null }
@@ -22,10 +25,10 @@ declare namespace Interceptors {
22
25
  affinity?: 4 | 6
23
26
  }
24
27
 
25
- export function createRedirectInterceptor (opts: RedirectInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
26
28
  export function dump (opts?: DumpInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
27
29
  export function retry (opts?: RetryInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
28
30
  export function redirect (opts?: RedirectInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
29
31
  export function responseError (opts?: ResponseErrorInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
30
32
  export function dns (opts?: DNSInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
33
+ export function cache (opts?: CacheInterceptorOpts): Dispatcher.DispatcherComposeInterceptor
31
34
  }
package/types/webidl.d.ts CHANGED
@@ -84,7 +84,13 @@ interface WebidlUtil {
84
84
  */
85
85
  Stringify (V: any): string
86
86
 
87
- MakeTypeAssertion <T extends { prototype: T }>(Prototype: T['prototype']): (arg: any) => arg is T
87
+ MakeTypeAssertion <I>(I: I): (arg: any) => arg is I
88
+
89
+ /**
90
+ * Mark a value as uncloneable for Node.js.
91
+ * This is only effective in some newer Node.js versions.
92
+ */
93
+ markAsUncloneable (V: any): void
88
94
  }
89
95
 
90
96
  interface WebidlConverters {