{
  "type": "module",
  "source": "doc/api/api-diagnosticschannel.md",
  "modules": [
    {
      "textRaw": "Diagnostics Channel Support",
      "name": "diagnostics_channel_support",
      "type": "module",
      "desc": "<p>Stability: Experimental.</p>\n<p>Undici supports the <a href=\"https://nodejs.org/api/diagnostics_channel.html\"><code>diagnostics_channel</code></a> (currently available only on Node.js v16+).\nIt is the preferred way to instrument Undici and retrieve internal information.</p>\n<p>The channels available are the following.</p>",
      "modules": [
        {
          "textRaw": "`undici:request:create`",
          "name": "`undici:request:create`",
          "type": "module",
          "desc": "<p>This message is published when a new outgoing request is created.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {\n  console.log('origin', request.origin)\n  console.log('completed', request.completed)\n  console.log('method', request.method)\n  console.log('path', request.path)\n  console.log('headers', request.headers) // array of strings, e.g: ['foo', 'bar']\n  request.addHeader('hello', 'world')\n  console.log('headers', request.headers) // e.g. ['foo', 'bar', 'hello', 'world']\n})\n</code></pre>\n<p>Note: a request is only loosely completed to a given socket.</p>",
          "displayName": "`undici:request:create`"
        },
        {
          "textRaw": "`undici:request:bodyChunkSent`",
          "name": "`undici:request:bodychunksent`",
          "type": "module",
          "desc": "<p>This message is published when a chunk of the request body is being sent.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:bodyChunkSent').subscribe(({ request, chunk }) => {\n  // request is the same object undici:request:create\n})\n</code></pre>",
          "displayName": "`undici:request:bodyChunkSent`"
        },
        {
          "textRaw": "`undici:request:bodySent`",
          "name": "`undici:request:bodysent`",
          "type": "module",
          "desc": "<p>This message is published after the request body has been fully sent.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:bodySent').subscribe(({ request }) => {\n  // request is the same object undici:request:create\n})\n</code></pre>",
          "displayName": "`undici:request:bodySent`"
        },
        {
          "textRaw": "`undici:request:headers`",
          "name": "`undici:request:headers`",
          "type": "module",
          "desc": "<p>This message is published after the response headers have been received.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:headers').subscribe(({ request, response }) => {\n  // request is the same object undici:request:create\n  console.log('statusCode', response.statusCode)\n  console.log(response.statusText)\n  // response.headers are buffers.\n  console.log(response.headers.map((x) => x.toString()))\n})\n</code></pre>",
          "displayName": "`undici:request:headers`"
        },
        {
          "textRaw": "`undici:request:bodyChunkReceived`",
          "name": "`undici:request:bodychunkreceived`",
          "type": "module",
          "desc": "<p>This message is published after a chunk of the response body has been received.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:bodyChunkReceived').subscribe(({ request, chunk }) => {\n  // request is the same object undici:request:create\n})\n</code></pre>",
          "displayName": "`undici:request:bodyChunkReceived`"
        },
        {
          "textRaw": "`undici:request:trailers`",
          "name": "`undici:request:trailers`",
          "type": "module",
          "desc": "<p>This message is published after the response body and trailers have been received, i.e. the response has been completed.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:trailers').subscribe(({ request, trailers }) => {\n  // request is the same object undici:request:create\n  console.log('completed', request.completed)\n  // trailers are buffers.\n  console.log(trailers.map((x) => x.toString()))\n})\n</code></pre>",
          "displayName": "`undici:request:trailers`"
        },
        {
          "textRaw": "`undici:request:error`",
          "name": "`undici:request:error`",
          "type": "module",
          "desc": "<p>This message is published if the request is going to error, but it has not errored yet.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:error').subscribe(({ request, error }) => {\n  // request is the same object undici:request:create\n})\n</code></pre>",
          "displayName": "`undici:request:error`"
        },
        {
          "textRaw": "`undici:client:sendHeaders`",
          "name": "`undici:client:sendheaders`",
          "type": "module",
          "desc": "<p>This message is published right before the first byte of the request is written to the socket.</p>\n<p><em>Note</em>: It will publish the exact headers that will be sent to the server in raw format.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:client:sendHeaders').subscribe(({ request, headers, socket }) => {\n  // request is the same object undici:request:create\n  console.log(`Full headers list ${headers.split('\\r\\n')}`);\n})\n</code></pre>",
          "displayName": "`undici:client:sendHeaders`"
        },
        {
          "textRaw": "`undici:client:beforeConnect`",
          "name": "`undici:client:beforeconnect`",
          "type": "module",
          "desc": "<p>This message is published before creating a new connection for <strong>any</strong> request.\nYou can not assume that this event is related to any specific request.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => {\n  // const { host, hostname, protocol, port, servername, version } = connectParams\n  // connector is a function that creates the socket\n})\n</code></pre>",
          "displayName": "`undici:client:beforeConnect`"
        },
        {
          "textRaw": "`undici:client:connected`",
          "name": "`undici:client:connected`",
          "type": "module",
          "desc": "<p>This message is published after a connection is established.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => {\n  // const { host, hostname, protocol, port, servername, version } = connectParams\n // connector is a function that creates the socket\n})\n</code></pre>",
          "displayName": "`undici:client:connected`"
        },
        {
          "textRaw": "`undici:client:connectError`",
          "name": "`undici:client:connecterror`",
          "type": "module",
          "desc": "<p>This message is published if it did not succeed to create new connection</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => {\n  // const { host, hostname, protocol, port, servername, version } = connectParams\n  // connector is a function that creates the socket\n  console.log(`Connect failed with ${error.message}`)\n})\n</code></pre>",
          "displayName": "`undici:client:connectError`"
        },
        {
          "textRaw": "`undici:websocket:open`",
          "name": "`undici:websocket:open`",
          "type": "module",
          "desc": "<p>This message is published after the client has successfully connected to a server.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:websocket:open').subscribe(({ \n  address,           // { address: string, family: string, port: number }\n  protocol,          // string - negotiated subprotocol\n  extensions,        // string - negotiated extensions\n  websocket,         // WebSocket - the WebSocket instance\n  handshakeResponse  // object - HTTP response that upgraded the connection\n}) => {\n  console.log(address) // address, family, and port\n  console.log(protocol) // negotiated subprotocols\n  console.log(extensions) // negotiated extensions\n  console.log(websocket) // the WebSocket instance\n  \n  // Handshake response details\n  console.log(handshakeResponse.status) // 101 for HTTP/1.1, 200 for HTTP/2 extended CONNECT\n  console.log(handshakeResponse.statusText) // 'Switching Protocols' for HTTP/1.1, commonly 'OK' for HTTP/2 in Node.js\n  console.log(handshakeResponse.headers) // Object containing response headers\n})\n</code></pre>",
          "modules": [
            {
              "textRaw": "Handshake Response Object",
              "name": "handshake_response_object",
              "type": "module",
              "desc": "<p>The <code>handshakeResponse</code> object contains the HTTP response that established the WebSocket connection:</p>\n<ul>\n<li>\n<p><code>status</code> (number): The HTTP status code (<code>101</code> for HTTP/1.1 upgrade, <code>200</code> for HTTP/2 extended CONNECT)</p>\n</li>\n<li>\n<p><code>statusText</code> (string): The HTTP status message (<code>'Switching Protocols'</code> for HTTP/1.1, commonly <code>'OK'</code> for HTTP/2 in Node.js)</p>\n</li>\n<li>\n<p><code>headers</code> (object): The HTTP response headers from the server, including:</p>\n<ul>\n<li><code>sec-websocket-accept</code> and other WebSocket-related headers</li>\n<li><code>upgrade: 'websocket'</code></li>\n<li><code>connection: 'upgrade'</code></li>\n</ul>\n<p>The <code>upgrade</code> and <code>connection</code> headers are only present for HTTP/1.1 handshakes.</p>\n</li>\n</ul>\n<p>This information is particularly useful for debugging and monitoring WebSocket connections, as it provides access to the initial HTTP handshake response that established the WebSocket connection.</p>",
              "displayName": "Handshake Response Object"
            }
          ],
          "displayName": "`undici:websocket:open`"
        },
        {
          "textRaw": "`undici:websocket:close`",
          "name": "`undici:websocket:close`",
          "type": "module",
          "desc": "<p>This message is published after the connection has closed.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:websocket:close').subscribe(({ websocket, code, reason }) => {\n  console.log(websocket) // the WebSocket instance\n  console.log(code) // the closing status code\n  console.log(reason) // the closing reason\n})\n</code></pre>",
          "displayName": "`undici:websocket:close`"
        },
        {
          "textRaw": "`undici:websocket:socket_error`",
          "name": "`undici:websocket:socket_error`",
          "type": "module",
          "desc": "<p>This message is published if the socket experiences an error.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:websocket:socket_error').subscribe((error) => {\n  console.log(error)\n})\n</code></pre>",
          "displayName": "`undici:websocket:socket_error`"
        },
        {
          "textRaw": "`undici:websocket:ping`",
          "name": "`undici:websocket:ping`",
          "type": "module",
          "desc": "<p>This message is published after the client receives a ping frame, if the connection is not closing.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload, websocket }) => {\n  // a Buffer or undefined, containing the optional application data of the frame\n  console.log(payload)\n  console.log(websocket) // the WebSocket instance\n})\n</code></pre>",
          "displayName": "`undici:websocket:ping`"
        },
        {
          "textRaw": "`undici:websocket:pong`",
          "name": "`undici:websocket:pong`",
          "type": "module",
          "desc": "<p>This message is published after the client receives a pong frame.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload, websocket }) => {\n  // a Buffer or undefined, containing the optional application data of the frame\n  console.log(payload)\n  console.log(websocket) // the WebSocket instance\n})\n</code></pre>",
          "displayName": "`undici:websocket:pong`"
        },
        {
          "textRaw": "`undici:proxy:connected`",
          "name": "`undici:proxy:connected`",
          "type": "module",
          "desc": "<p>This message is published after the <code>ProxyAgent</code> establishes a connection to the proxy server.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:proxy:connected').subscribe(({ socket, connectParams }) => {\n  console.log(socket)\n  console.log(connectParams)\n  // const { origin, port, path, signal, headers, servername } = connectParams\n})\n</code></pre>",
          "displayName": "`undici:proxy:connected`"
        },
        {
          "textRaw": "`undici:request:pending-requests`",
          "name": "`undici:request:pending-requests`",
          "type": "module",
          "desc": "<p>This message is published when the deduplicate interceptor's pending request map changes. This is useful for monitoring and debugging request deduplication behavior.</p>\n<p>The deduplicate interceptor automatically deduplicates concurrent requests for the same resource. When multiple identical requests are made while one is already in-flight, only one request is sent to the origin server, and all waiting handlers receive the same response.</p>\n<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\ndiagnosticsChannel.channel('undici:request:pending-requests').subscribe(({ type, size, key }) => {\n  console.log(type)  // 'added' or 'removed'\n  console.log(size)  // current number of pending requests\n  console.log(key)   // the deduplication key for this request\n})\n</code></pre>",
          "modules": [
            {
              "textRaw": "Event Properties",
              "name": "event_properties",
              "type": "module",
              "desc": "<ul>\n<li><code>type</code> (<code>string</code>): Either <code>'added'</code> when a new pending request is registered, or <code>'removed'</code> when a pending request completes (successfully or with an error).</li>\n<li><code>size</code> (<code>number</code>): The current number of pending requests after the change.</li>\n<li><code>key</code> (<code>string</code>): The deduplication key for the request, composed of the origin, method, path, and request headers.</li>\n</ul>",
              "displayName": "Event Properties"
            },
            {
              "textRaw": "Example: Monitoring Request Deduplication",
              "name": "example:_monitoring_request_deduplication",
              "type": "module",
              "desc": "<pre><code class=\"language-js\">import diagnosticsChannel from 'diagnostics_channel'\n\nconst channel = diagnosticsChannel.channel('undici:request:pending-requests')\n\nchannel.subscribe(({ type, size, key }) => {\n  if (type === 'added') {\n    console.log(`New pending request: ${key} (${size} total pending)`)\n  } else {\n    console.log(`Request completed: ${key} (${size} remaining)`)\n  }\n})\n</code></pre>\n<p>This can be useful for:</p>\n<ul>\n<li>Verifying that request deduplication is working as expected</li>\n<li>Monitoring the number of concurrent in-flight requests</li>\n<li>Debugging deduplication behavior in production environments</li>\n</ul>",
              "displayName": "Example: Monitoring Request Deduplication"
            }
          ],
          "displayName": "`undici:request:pending-requests`"
        }
      ],
      "displayName": "Diagnostics Channel Support"
    }
  ]
}