Skip to content

Commit 67f3c96

Browse files
authored
feat: new hooks (#3878)
* feat: new hooks * fixup * fixup * fixup * fixup * fixup
1 parent 9b8abb8 commit 67f3c96

32 files changed

+399
-415
lines changed

docs/docs/api/Dispatcher.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,12 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo
205205

206206
#### Parameter: `DispatchHandler`
207207

208-
* **onConnect** `(abort: () => void, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails.
209-
* **onError** `(error: Error) => void` - Invoked when an error has occurred. May not throw.
210-
* **onUpgrade** `(statusCode: number, headers: Buffer[], socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
211-
* **onResponseStarted** `() => void` (optional) - Invoked when response is received, before headers have been read.
212-
* **onHeaders** `(statusCode: number, headers: Buffer[], resume: () => void, statusText: string) => boolean` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
213-
* **onData** `(chunk: Buffer) => boolean` - Invoked when response payload data is received. Not required for `upgrade` requests.
214-
* **onComplete** `(trailers: Buffer[]) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
215-
* **onBodySent** `(chunk: string | Buffer | Uint8Array) => void` - Invoked when a body chunk is sent to the server. Not required. For a stream or iterable body this will be invoked for every chunk. For other body types, it will be invoked once after the body is sent.
208+
* **onRequestStart** `(controller: DispatchController, context: object) => void` - Invoked before request is dispatched on socket. May be invoked multiple times when a request is retried when the request at the head of the pipeline fails.
209+
* **onRequestUpgrade** `(controller: DispatchController, statusCode: number, headers: Record<string, string | string[]>, socket: Duplex) => void` (optional) - Invoked when request is upgraded. Required if `DispatchOptions.upgrade` is defined or `DispatchOptions.method === 'CONNECT'`.
210+
* **onResponseStart** `(controller: DispatchController, statusCode: number, statusMessage?: string, headers: Record<string, string | string []>) => void` - Invoked when statusCode and headers have been received. May be invoked multiple times due to 1xx informational headers. Not required for `upgrade` requests.
211+
* **onResponseData** `(controller: DispatchController, chunk: Buffer) => void` - Invoked when response payload data is received. Not required for `upgrade` requests.
212+
* **onResponseEnd** `(controller: DispatchController, trailers: Record<string, string | string[]>) => void` - Invoked when response payload and trailers have been received and the request has completed. Not required for `upgrade` requests.
213+
* **onResponseError** `(error: Error) => void` - Invoked when an error has occurred. May not throw.
216214

217215
#### Example 1 - Dispatch GET request
218216

docs/docs/api/RedirectHandler.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Returns: `RedirectHandler`
1616

1717
### Parameters
1818

19-
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every redirection.
19+
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandler) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every redirection.
2020
- **maxRedirections** `number` (required) - Maximum number of redirections allowed.
2121
- **opts** `object` (required) - Options for handling redirection.
2222
- **handler** `object` (required) - Handlers for different stages of the request lifecycle.

docs/docs/api/RetryHandler.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ It represents the retry state for a given request.
4343

4444
### Parameter `RetryHandlers`
4545

46-
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every retry.
47-
- **handler** Extends [`Dispatch.DispatchHandlers`](/docs/docs/api/Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted.
46+
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandler) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every retry.
47+
- **handler** Extends [`Dispatch.DispatchHandler`](/docs/docs/api/Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted.
4848

4949
>__Note__: The `RetryHandler` does not retry over stateful bodies (e.g. streams, AsyncIterable) as those, once consumed, are left in a state that cannot be reutilized. For these situations the `RetryHandler` will identify
5050
>the body as stateful and will not retry the request rejecting with the error `UND_ERR_REQ_RETRY`.

lib/cache/memory-cache-store.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class MemoryCacheStore {
8787
: {
8888
statusMessage: entry.statusMessage,
8989
statusCode: entry.statusCode,
90-
rawHeaders: entry.rawHeaders,
90+
headers: entry.headers,
9191
body: entry.body,
9292
etag: entry.etag,
9393
cachedAt: entry.cachedAt,

lib/cache/sqlite-cache-store.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ const { DatabaseSync } = require('node:sqlite')
44
const { Writable } = require('stream')
55
const { assertCacheKey, assertCacheValue } = require('../util/cache.js')
66

7-
const VERSION = 1
7+
const VERSION = 2
88

99
/**
1010
* @typedef {import('../../types/cache-interceptor.d.ts').default.CacheStore} CacheStore
1111
* @implements {CacheStore}
1212
*
1313
* @typedef {{
1414
* id: Readonly<number>
15-
* rawHeaders?: string
15+
* headers?: Record<string, string | string[]>
1616
* vary?: string | object
1717
* body: string
1818
* } & import('../../types/cache-interceptor.d.ts').default.CacheValue} SqliteStoreValue
@@ -107,7 +107,7 @@ class SqliteCacheStore {
107107
deleteAt INTEGER NOT NULL,
108108
statusCode INTEGER NOT NULL,
109109
statusMessage TEXT NOT NULL,
110-
rawHeaders TEXT NULL,
110+
headers TEXT NULL,
111111
etag TEXT NULL,
112112
vary TEXT NULL,
113113
cachedAt INTEGER NOT NULL,
@@ -126,7 +126,7 @@ class SqliteCacheStore {
126126
deleteAt,
127127
statusCode,
128128
statusMessage,
129-
rawHeaders,
129+
headers,
130130
etag,
131131
vary,
132132
cachedAt,
@@ -145,7 +145,7 @@ class SqliteCacheStore {
145145
deleteAt = ?,
146146
statusCode = ?,
147147
statusMessage = ?,
148-
rawHeaders = ?,
148+
headers = ?,
149149
etag = ?,
150150
cachedAt = ?,
151151
staleAt = ?,
@@ -162,7 +162,7 @@ class SqliteCacheStore {
162162
deleteAt,
163163
statusCode,
164164
statusMessage,
165-
rawHeaders,
165+
headers,
166166
etag,
167167
vary,
168168
cachedAt,
@@ -221,7 +221,7 @@ class SqliteCacheStore {
221221
body: value.body ? parseBufferArray(JSON.parse(value.body)) : null,
222222
statusCode: value.statusCode,
223223
statusMessage: value.statusMessage,
224-
rawHeaders: value.rawHeaders ? parseBufferArray(JSON.parse(value.rawHeaders)) : undefined,
224+
headers: value.headers ? JSON.parse(value.headers) : undefined,
225225
etag: value.etag ? value.etag : undefined,
226226
cachedAt: value.cachedAt,
227227
staleAt: value.staleAt,
@@ -273,7 +273,7 @@ class SqliteCacheStore {
273273
value.deleteAt,
274274
value.statusCode,
275275
value.statusMessage,
276-
value.rawHeaders ? JSON.stringify(stringifyBufferArray(value.rawHeaders)) : null,
276+
value.headers ? JSON.stringify(value.headers) : null,
277277
value.etag,
278278
value.cachedAt,
279279
value.staleAt,
@@ -290,7 +290,7 @@ class SqliteCacheStore {
290290
value.deleteAt,
291291
value.statusCode,
292292
value.statusMessage,
293-
value.rawHeaders ? JSON.stringify(stringifyBufferArray(value.rawHeaders)) : null,
293+
value.headers ? JSON.stringify(value.headers) : null,
294294
value.etag ? value.etag : null,
295295
value.vary ? JSON.stringify(value.vary) : null,
296296
value.cachedAt,

lib/core/util.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,11 @@ function assertRequestHandler (handler, method, upgrade) {
511511
throw new InvalidArgumentError('handler must be an object')
512512
}
513513

514+
if (typeof handler.onRequestStart === 'function') {
515+
// TODO (fix): More checks...
516+
return
517+
}
518+
514519
if (typeof handler.onConnect !== 'function') {
515520
throw new InvalidArgumentError('invalid onConnect method')
516521
}

lib/dispatcher/dispatcher-base.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const Dispatcher = require('./dispatcher')
4+
const UnwrapHandler = require('../handler/unwrap-handler')
45
const {
56
ClientDestroyedError,
67
ClientClosedError,
@@ -142,7 +143,7 @@ class DispatcherBase extends Dispatcher {
142143
throw new ClientClosedError()
143144
}
144145

145-
return this[kDispatch](opts, handler)
146+
return this[kDispatch](opts, UnwrapHandler.unwrap(handler))
146147
} catch (err) {
147148
if (typeof handler.onError !== 'function') {
148149
throw new InvalidArgumentError('invalid onError method')

lib/dispatcher/dispatcher.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
'use strict'
22
const EventEmitter = require('node:events')
3+
const WrapHandler = require('../handler/wrap-handler')
4+
5+
const wrapInterceptor = (dispatch) => (opts, handler) => dispatch(opts, WrapHandler.wrap(handler))
36

47
class Dispatcher extends EventEmitter {
58
dispatch () {
@@ -29,6 +32,7 @@ class Dispatcher extends EventEmitter {
2932
}
3033

3134
dispatch = interceptor(dispatch)
35+
dispatch = wrapInterceptor(dispatch)
3236

3337
if (dispatch == null || typeof dispatch !== 'function' || dispatch.length !== 2) {
3438
throw new TypeError('invalid interceptor')

0 commit comments

Comments
 (0)