declare module "node:quic" { import { NonSharedBuffer } from "node:buffer"; import { KeyObject } from "node:crypto"; import { FileHandle } from "node:fs/promises"; import { SocketAddress } from "node:net"; import { Writer } from "node:stream/iter"; import { EphemeralKeyInfo, PeerCertificate } from "node:tls"; /** * @since v23.8.0 */ type OnSessionCallback = (this: QuicEndpoint, session: QuicSession) => void; /** * @since v23.8.0 */ type OnStreamCallback = (this: QuicSession, stream: QuicStream) => void; /** * @since v23.8.0 */ type OnDatagramCallback = (this: QuicSession, datagram: NodeJS.NonSharedUint8Array, early: boolean) => void; /** * @since v23.8.0 */ type OnDatagramStatusCallback = ( this: QuicSession, id: bigint, status: "acknowledged" | "lost" | "abandoned", ) => void; /** * @since v23.8.0 */ type OnPathValidationCallback = ( this: QuicSession, result: "success" | "failure" | "aborted", newLocalAddress: SocketAddress, newRemoteAddress: SocketAddress, oldLocalAddress: SocketAddress | null, oldRemoteAddress: SocketAddress | null, preferredAddress: boolean, ) => void; /** * @since v23.8.0 */ type OnSessionTicketCallback = (this: QuicSession, ticket: object) => void; /** * @since v23.8.0 */ type OnVersionNegotiationCallback = ( this: QuicSession, version: number, requestedVersions: number[], supportedVersions: number[], ) => void; /** * @since v23.8.0 */ type OnHandshakeCallback = (this: QuicSession, info: SessionHandshakeInfo) => void; /** * @since v26.2.0 */ type OnNewTokenCallback = (this: QuicSession, token: NonSharedBuffer, address: SocketAddress) => void; /** * @since v26.2.0 */ type OnOriginCallback = (this: QuicSession, origins: string[]) => void; /** * Called when TLS key material is available. Only fires when * `sessionOptions.keylog` is `true`. Multiple lines are emitted during the * TLS 1.3 handshake, each containing a secret label, the client random, and * the secret value. * @since v26.2.0 */ type OnKeylogCallback = (this: QuicSession, line: string) => void; /** * Called when qlog diagnostic data is available. Only fires when * `sessionOptions.qlog` is `true`. The `data` chunks should be * concatenated in order to produce the complete qlog output. When `fin` is * `true`, no more chunks will be emitted and the concatenated result is a * complete JSON-SEQ document. * @since v26.2.0 */ type OnQlogCallback = (this: QuicSession, data: string, fin: boolean) => void; /** * @since v23.8.0 */ type OnBlockedCallback = (this: QuicStream) => void; /** * @since v23.8.0 */ type OnStreamErrorCallback = (this: QuicStream, error: any) => void; /** * Called when initial request or response headers are received. For HTTP/3, * this delivers request pseudo-headers on the server and response headers * on the client. * @since v26.2.0 */ type OnHeadersCallback = (this: QuicStream, headers: NodeJS.Dict) => void; /** * Called when trailing headers are received from the peer. * @since v26.2.0 */ type OnTrailersCallback = (this: QuicStream, trailers: NodeJS.Dict) => void; /** * Called when informational (1xx) headers are received from the server * (e.g., 103 Early Hints). * @since v26.2.0 */ type OnInfoCallback = (this: QuicStream, headers: NodeJS.Dict) => void; /** * @since v23.8.0 */ interface TransportParams { /** * The preferred IPv4 address to advertise (only used by servers). * @since v23.8.0 */ preferredAddressIpv4?: SocketAddress | undefined; /** * The preferred IPv6 address to advertise (only used by servers) * @since v23.8.0 */ preferredAddressIpv6?: SocketAddress | undefined; /** * @since v23.8.0 */ initialMaxStreamDataBidiLocal?: bigint | number | undefined; /** * @since v23.8.0 */ initialMaxStreamDataBidiRemote?: bigint | number | undefined; /** * @since v23.8.0 */ initialMaxStreamDataUni?: bigint | number | undefined; /** * @since v23.8.0 */ initialMaxData?: bigint | number | undefined; /** * @since v23.8.0 */ initialMaxStreamsBidi?: bigint | number | undefined; /** * @since v23.8.0 */ initialMaxStreamsUni?: bigint | number | undefined; /** * @since v23.8.0 */ maxIdleTimeout?: bigint | number | undefined; /** * @since v23.8.0 */ activeConnectionIDLimit?: bigint | number | undefined; /** * @since v23.8.0 */ ackDelayExponent?: bigint | number | undefined; /** * @since v23.8.0 */ maxAckDelay?: bigint | number | undefined; /** * The maximum size in bytes of a DATAGRAM frame payload that this endpoint * is willing to receive. Set to `0` to disable datagram support. The peer * will not send datagrams larger than this value. The actual maximum size of * a datagram that can be _sent_ is determined by the peer's * `maxDatagramFrameSize`, not this endpoint's value. * @since v23.8.0 */ maxDatagramFrameSize?: bigint | number | undefined; } interface SNIEntry { /** * The TLS private keys. **Required.** */ keys: KeyObject | readonly KeyObject[]; /** * The TLS certificates. **Required.** */ certs: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray; /** * Verify the private key. Default: `false`. */ verifyPrivateKey?: boolean | undefined; /** * The port to advertise in ORIGIN frames (RFC 9412) for this host name. **Default:** `443`. Only used for HTTP/3 sessions. */ port?: number | undefined; /** * Whether to include this host name in ORIGIN frames. **Default:** `true`. Set to `false` to exclude a host name * from ORIGIN advertisements. Wildcard (`'*'`) entries are always excluded regardless of this setting. */ authoritative?: boolean | undefined; } interface ApplicationOptions { /** * Maximum number of header name-value pairs accepted per header block. Headers beyond this limit are silently * dropped. **Default:** `128` */ maxHeaderPairs?: number | undefined; /** * Maximum total byte length of all header names and values combined per header block. Headers that would push * the total over this limit are silently dropped. **Default:** `8192` */ maxHeaderLength?: number | undefined; /** * Maximum size of a compressed header field section (QPACK). `0` means unlimited. **Default:** `0` */ maxFieldSectionSize?: number | undefined; /** * QPACK dynamic table capacity in bytes. Set to `0` to disable the dynamic table. **Default:** `4096` */ qpackMaxDTableCapacity?: number | undefined; /** * QPACK encoder maximum dynamic table capacity. **Default:** `4096` */ qpackEncoderMaxDTableCapacity?: number | undefined; /** * Maximum number of streams that can be blocked waiting for QPACK dynamic table updates. * **Default:** `100` */ qpackBlockedStreams?: number | undefined; /** * Enable the extended CONNECT protocol (RFC 9220). **Default:** `false` */ enableConnectProtocol?: boolean | undefined; /** * Enable HTTP/3 datagrams (RFC 9297). **Default:** `false` */ enableDatagrams?: boolean | undefined; } /** * @since v23.8.0 */ interface SessionOptions { /** * An endpoint to use. * @since v23.8.0 */ endpoint?: EndpointOptions | QuicEndpoint | undefined; /** * The ALPN (Application-Layer Protocol Negotiation) identifier(s). * * For **client** sessions, this is a single string specifying the protocol * the client wants to use (e.g. `'h3'`). * * For **server** sessions, this is an array of protocol names in preference * order that the server supports (e.g. `['h3', 'h3-29']`). During the TLS * handshake, the server selects the first protocol from its list that the * client also supports. * * The negotiated ALPN determines which Application implementation is used * for the session. `'h3'` and `'h3-*'` variants select the HTTP/3 * application; all other values select the default application. * @since v26.1.0 */ alpn?: string | readonly string[] | undefined; /** * HTTP/3 application-specific options. These only apply when the negotiated * ALPN selects the HTTP/3 application (`'h3'`). * @since v26.2.0 */ application?: ApplicationOptions | undefined; /** * The CA certificates to use for client sessions. For server sessions, CA * certificates are specified per-identity in the `sessionOptions.sni` map. * @since v23.8.0 */ ca?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray | undefined; /** * Specifies the congestion control algorithm that will be used. * Must be set to one of either `'reno'`, `'cubic'`, or `'bbr'`. * * This is an advanced option that users typically won't have need to specify. * @since v23.8.0 */ cc?: `${constants.cc}` | undefined; /** * The TLS certificates to use for client sessions. For server sessions, * certificates are specified per-identity in the `sessionOptions.sni` map. * @since v23.8.0 */ certs?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray | undefined; /** * The list of supported TLS 1.3 cipher algorithms. * @since v23.8.0 */ ciphers?: string | undefined; /** * The CRL to use for client sessions. For server sessions, CRLs are specified * per-identity in the `sessionOptions.sni` map. * @since v23.8.0 */ crl?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray | undefined; /** * When `true`, enables TLS 0-RTT early data for this session. Early data * allows the client to send application data before the TLS handshake * completes, reducing latency on reconnection when a valid session ticket * is available. Set to `false` to disable early data support. * @since v26.2.0 */ enableEarlyData?: boolean | undefined; /** * The list of supported TLS 1.3 cipher groups. * @since v23.8.0 */ groups?: string | undefined; /** * When `true`, enables TLS key logging for the session. Key material is * delivered to the `session.onkeylog` callback in [NSS Key Log Format](https://udn.realityripple.com/docs/Mozilla/Projects/NSS/Key_Log_Format). * Each callback invocation receives a single line of key material. The output * can be used with tools such as Wireshark to decrypt captured QUIC traffic. * @since v23.8.0 */ keylog?: boolean | undefined; /** * The TLS crypto keys to use for client sessions. For server sessions, * keys are specified per-identity in the `sessionOptions.sni` map. * @since v23.8.0 */ keys?: KeyObject | readonly KeyObject[] | undefined; /** * Specifies the maximum UDP packet payload size. * @since v23.8.0 */ maxPayloadSize?: bigint | number | undefined; /** * Specifies the maximum stream flow-control window size. * @since v23.8.0 */ maxStreamWindow?: bigint | number | undefined; /** * Specifies the maximum session flow-control window size. * @since v23.8.0 */ maxWindow?: bigint | number | undefined; /** * The minimum QUIC version number to allow. This is an advanced option that users * typically won't have need to specify. * @since v23.8.0 */ minVersion?: number | undefined; /** * When the remote peer advertises a preferred address, this option specifies whether * to use it or ignore it. * @since v23.8.0 */ preferredAddressPolicy?: "use" | "ignore" | "default" | undefined; /** * When `true`, enables [qlog](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-main-schema/) diagnostic output for the session. Qlog data * is delivered to the `session.onqlog` callback as chunks of [JSON-SEQ](https://www.rfc-editor.org/rfc/rfc7464) * formatted text. The output can be analyzed with qlog visualization tools * such as [qvis](https://qvis.quictools.info/). * @since v23.8.0 */ qlog?: boolean | undefined; /** * A session ticket to use for 0RTT session resumption. * @since v23.8.0 */ sessionTicket?: NodeJS.ArrayBufferView | undefined; /** * Controls which datagram to drop when the pending datagram queue * (sized by `session.maxPendingDatagrams`) is full. Must be one of * `'drop-oldest'` (discard the oldest queued datagram to make room) or * `'drop-newest'` (reject the incoming datagram). Dropped datagrams are * reported as lost via the `ondatagramstatus` callback. * * This option is immutable after session creation. * @since v26.2.0 */ datagramDropPolicy?: "drop-oldest" | "drop-newest" | undefined; /** * The maximum number of `SendPendingData` cycles a datagram can survive * without being sent before it is abandoned. When a datagram cannot be * sent due to congestion control or packet size constraints, it remains * in the queue and the attempt counter increments. Once the limit is * reached, the datagram is dropped and reported as `'abandoned'` via the * `ondatagramstatus` callback. Valid range: `1` to `255`. * @since v26.2.0 */ maxDatagramSendAttempts?: number | undefined; /** * A multiplier applied to the Probe Timeout (PTO) to compute the draining * period duration after receiving a `CONNECTION_CLOSE` frame from the peer. * RFC 9000 Section 10.2 requires the draining period to persist for at least * three times the current PTO. The valid range is `3` to `255`. Values below * `3` are clamped to `3`. * @since v26.2.0 */ drainingPeriodMultiplier?: number | undefined; /** * Specifies the keep-alive timeout in milliseconds. When set to a non-zero * value, PING frames will be sent automatically to keep the connection alive * before the idle timeout fires. The value should be less than the effective * idle timeout (`maxIdleTimeout` transport parameter) to be useful. * @since v23.8.0 */ handshakeTimeout?: bigint | number | undefined; /** * The peer server name to target (SNI). Defaults to `'localhost'`. * @since v26.1.0 */ servername?: string | undefined; /** * An object mapping host names to TLS identity options for Server Name * Indication (SNI) support. This is required for server sessions and must * contain at least one entry. The special key `'*'` specifies the optional * default/fallback identity used when no other host name matches. If no * wildcard entry is provided, connections with unrecognized server names * will be rejected with a TLS `unrecognized_name` alert. Each entry may * contain: * @since v26.1.0 */ sni?: Record | undefined; /** * True to enable TLS tracing output. * @since v23.8.0 */ tlsTrace?: boolean | undefined; /** * An opaque address validation token previously received from the server * via the `session.onnewtoken` callback. Providing a valid token on * reconnection allows the client to skip the server's address validation, * reducing handshake latency. * @since v26.2.0 */ token?: NodeJS.ArrayBufferView | undefined; /** * The QUIC transport parameters to use for the session. * @since v23.8.0 */ transportParams?: TransportParams | undefined; /** * Specifies the maximum number of unacknowledged packets a session should allow. * @since v23.8.0 */ unacknowledgedPacketThreshold?: bigint | number | undefined; /** * If `true`, the peer certificate is verified against the list of supplied CAs. * An error is emitted if verification fails; the error can be inspected via * the `validationErrorReason` and `validationErrorCode` fields in the * handshake callback. If `false`, peer certificate verification errors are * ignored. */ rejectUnauthorized?: boolean | undefined; /** * When `true` (the default), `connect()` will attempt to reuse an existing * endpoint rather than creating a new one for each session. This provides * connection pooling behavior — multiple sessions can share a single UDP * socket. The reuse logic will not return an endpoint that is listening on * the same address as the connect target (to prevent CID routing conflicts). * * Set to `false` to force creation of a new endpoint for the session. This * is useful when endpoint isolation is required (e.g., testing stateless * reset behavior where source port identity matters). * @since v26.2.0 */ reuseEndpoint?: boolean | undefined; /** * True to require verification of TLS client certificate. * @since v23.8.0 */ verifyClient?: boolean | undefined; /** * True to require private key verification for client sessions. For server * sessions, this option is specified per-identity in the * `sessionOptions.sni` map. * @since v23.8.0 */ verifyPrivateKey?: boolean | undefined; /** * The QUIC version number to use. This is an advanced option that users typically * won't have need to specify. * @since v23.8.0 */ version?: number | undefined; // Undocumented onerror?: QuicSession["onerror"] | undefined; onstream?: QuicSession["onstream"] | undefined; ondatagram?: QuicSession["ondatagram"] | undefined; ondatagramstatus?: QuicSession["ondatagramstatus"] | undefined; onpathvalidation?: QuicSession["onpathvalidation"] | undefined; onsessionticket?: QuicSession["onsessionticket"] | undefined; onversionnegotiation?: QuicSession["onversionnegotiation"] | undefined; onhandshake?: QuicSession["onhandshake"] | undefined; onnewtoken?: QuicSession["onnewtoken"] | undefined; onearlyrejected?: QuicSession["onearlyrejected"] | undefined; onorigin?: QuicSession["onorigin"] | undefined; ongoaway?: QuicSession["ongoaway"] | undefined; onkeylog?: QuicSession["onkeylog"] | undefined; onqlog?: QuicSession["onqlog"] | undefined; onheaders?: QuicStream["onheaders"] | undefined; ontrailers?: QuicStream["ontrailers"] | undefined; oninfo?: QuicStream["oninfo"] | undefined; onwanttrailers?: QuicStream["onwanttrailers"] | undefined; } /** * Initiate a new client-side session. * * ```js * import { connect } from 'node:quic'; * import { Buffer } from 'node:buffer'; * * const enc = new TextEncoder(); * const alpn = 'foo'; * const client = await connect('123.123.123.123:8888', { alpn }); * await client.createUnidirectionalStream({ * body: enc.encode('hello world'), * }); * ``` * * By default, every call to `connect(...)` will create a new local * `QuicEndpoint` instance bound to a new random local IP port. To * specify the exact local address to use, or to multiplex multiple * QUIC sessions over a single local port, pass the `endpoint` option * with either a `QuicEndpoint` or `EndpointOptions` as the argument. * * ```js * import { QuicEndpoint, connect } from 'node:quic'; * * const endpoint = new QuicEndpoint({ * address: '127.0.0.1:1234', * }); * * const client = await connect('123.123.123.123:8888', { endpoint }); * ``` * @since v23.8.0 */ function connect(address: string | SocketAddress, options?: SessionOptions): Promise; /** * Configures the endpoint to listen as a server. When a new session is initiated by * a remote peer, the given `onsession` callback will be invoked with the created * session. * * ```js * import { listen } from 'node:quic'; * * const endpoint = await listen((session) => { * // ... handle the session * }); * * // Closing the endpoint allows any sessions open when close is called * // to complete naturally while preventing new sessions from being * // initiated. Once all existing sessions have finished, the endpoint * // will be destroyed. The call returns a promise that is resolved once * // the endpoint is destroyed. * await endpoint.close(); * ``` * * By default, every call to `listen(...)` will create a new local * `QuicEndpoint` instance bound to a new random local IP port. To * specify the exact local address to use, or to multiplex multiple * QUIC sessions over a single local port, pass the `endpoint` option * with either a `QuicEndpoint` or `EndpointOptions` as the argument. * * At most, any single `QuicEndpoint` can only be configured to listen as * a server once. * @since v23.8.0 */ function listen(onsession: OnSessionCallback, options?: SessionOptions): Promise; /** * The endpoint configuration options passed when constructing a new `QuicEndpoint` instance. * @since v23.8.0 */ interface EndpointOptions { /** * If not specified the endpoint will bind to IPv4 `localhost` on a random port. * @since v23.8.0 */ address?: SocketAddress | string | undefined; /** * The endpoint maintains an internal cache of validated socket addresses as a * performance optimization. This option sets the maximum number of addresses * that are cached. This is an advanced option that users typically won't have * need to specify. * @since v23.8.0 */ addressLRUSize?: bigint | number | undefined; /** * When `true`, the endpoint will not send stateless reset packets in response * to packets from unknown connections. Stateless resets allow a peer to detect * that a connection has been lost even when the server has no state for it. * Disabling them may be useful in testing or when stateless resets are handled * at a different layer. * @since v26.2.0 */ disableStatelessReset?: boolean | undefined; /** * The number of seconds an endpoint will remain alive after all sessions have * closed and it is no longer listening. A value of `0` (default) means the * endpoint is only destroyed when explicitly closed via `endpoint.close()` or * `endpoint.destroy()`. A positive value starts an idle timer when the endpoint * becomes idle; if no new sessions are created before the timer fires, the * endpoint is automatically destroyed. This is useful for connection pooling * where endpoints should linger briefly for reuse by future `connect()` calls. * @since v26.2.0 */ idleTimeout?: number | undefined; /** * When `true`, indicates that the endpoint should bind only to IPv6 addresses. * @since v23.8.0 */ ipv6Only?: boolean | undefined; /** * Specifies the maximum number of concurrent sessions allowed per remote IP * address (ignoring port). When the limit is reached, new connections from the * same IP are refused with `CONNECTION_REFUSED`. A value of `0` disables the * limit. The maximum value is `65535`. * * This limit can also be changed dynamically after construction via * `endpoint.maxConnectionsPerHost`. * @since v23.8.0 */ maxConnectionsPerHost?: number | undefined; /** * Specifies the maximum total number of concurrent sessions across all remote * addresses. When the limit is reached, new connections are refused with * `CONNECTION_REFUSED`. A value of `0` disables the limit. The maximum value is * `65535`. * * This limit can also be changed dynamically after construction via * `endpoint.maxConnectionsTotal`. * @since v23.8.0 */ maxConnectionsTotal?: number | undefined; /** * Specifies the maximum number of QUIC retry attempts allowed per remote peer address. * @since v23.8.0 */ maxRetries?: bigint | number | undefined; /** * Specifies the maximum number of stateless resets that are allowed per remote peer address. * @since v23.8.0 */ maxStatelessResetsPerHost?: bigint | number | undefined; /** * Specifies the length of time a QUIC retry token is considered valid. * @since v23.8.0 */ retryTokenExpiration?: bigint | number | undefined; /** * Specifies the 16-byte secret used to generate QUIC retry tokens. * @since v23.8.0 */ resetTokenSecret?: NodeJS.ArrayBufferView | undefined; /** * Specifies the length of time a QUIC token is considered valid. * @since v23.8.0 */ tokenExpiration?: bigint | number | undefined; /** * Specifies the 16-byte secret used to generate QUIC tokens. * @since v23.8.0 */ tokenSecret?: NodeJS.ArrayBufferView | undefined; /** * @since v23.8.0 */ udpReceiveBufferSize?: number | undefined; /** * @since v23.8.0 */ udpSendBufferSize?: number | undefined; /** * @since v23.8.0 */ udpTTL?: number | undefined; /** * When `true`, requires that the endpoint validate peer addresses using retry packets * while establishing a new connection. * @since v23.8.0 */ validateAddress?: boolean | undefined; } interface SetSNIContextsOptions { replace?: boolean | undefined; } /** * A `QuicEndpoint` encapsulates the local UDP-port binding for QUIC. It can be * used as both a client and a server. * @since v23.8.0 */ class QuicEndpoint implements AsyncDisposable { constructor(options?: EndpointOptions); /** * The local UDP socket address to which the endpoint is bound, if any. * * If the endpoint is not currently bound then the value will be `undefined`. Read only. * @since v23.8.0 */ readonly address: SocketAddress | undefined; /** * When `endpoint.busy` is set to true, the endpoint will temporarily reject * new sessions from being created. Read/write. * * ```js * // Mark the endpoint busy. New sessions will be prevented. * endpoint.busy = true; * * // Mark the endpoint free. New session will be allowed. * endpoint.busy = false; * ``` * * The `busy` property is useful when the endpoint is under heavy load and needs to * temporarily reject new sessions while it catches up. * @since v23.8.0 */ busy: boolean; /** * Gracefully close the endpoint. The endpoint will close and destroy itself when * all currently open sessions close. Once called, new sessions will be rejected. * * Returns a promise that is fulfilled when the endpoint is destroyed. * @since v23.8.0 */ close(): Promise; /** * A promise that is fulfilled when the endpoint is destroyed. This will be the same promise that is * returned by the `endpoint.close()` function. Read only. * @since v23.8.0 */ readonly closed: Promise; /** * True if `endpoint.close()` has been called and closing the endpoint has not yet completed. * Read only. * @since v23.8.0 */ readonly closing: boolean; /** * Forcefully closes the endpoint by forcing all open sessions to be immediately * closed. * @since v23.8.0 */ destroy(error?: any): void; /** * True if `endpoint.destroy()` has been called. Read only. * @since v23.8.0 */ readonly destroyed: boolean; /** * True if the endpoint is actively listening for incoming connections. Read only. * @since v26.2.0 */ readonly listening: boolean; /** * The maximum number of concurrent connections allowed per remote IP address. * `0` means unlimited (default). Can be set at construction time via the * `maxConnectionsPerHost` option and changed dynamically at any time. * The valid range is `0` to `65535`. * @since v26.2.0 */ maxConnectionsPerHost: number; /** * The maximum total number of concurrent connections across all remote * addresses. `0` means unlimited (default). Can be set at construction time via * the `maxConnectionsTotal` option and changed dynamically at any time. * The valid range is `0` to `65535`. * @since v26.2.0 */ maxConnectionsTotal: number; /** * Replaces or updates the SNI TLS contexts for this endpoint. This allows * changing the TLS identity (key/certificate) used for specific host names * without restarting the endpoint. Existing sessions are unaffected — only * new sessions will use the updated contexts. * * ```js * endpoint.setSNIContexts({ * 'api.example.com': { keys: [newApiKey], certs: [newApiCert] }, * }); * * // Replace the entire SNI map * endpoint.setSNIContexts({ * 'api.example.com': { keys: [newApiKey], certs: [newApiCert] }, * }, { replace: true }); * ``` * @since v26.1.0 * @param entries An object mapping host names to TLS identity options. * Each entry must include `keys` and `certs`. */ setSNIContexts(entries: Record, options?: SetSNIContextsOptions): void; /** * The statistics collected for an active endpoint. Read only. * @since v23.8.0 */ readonly stats: QuicEndpoint.Stats; /** * Calls `endpoint.close()` and returns a promise that fulfills when the * endpoint has closed. * @since v23.8.0 */ [Symbol.asyncDispose](): Promise; } namespace QuicEndpoint { /** * A view of the collected statistics for an endpoint. * @since v23.8.0 */ class Stats { private constructor(); /** * A timestamp indicating the moment the endpoint was created. Read only. * @since v23.8.0 */ readonly createdAt: bigint; /** * A timestamp indicating the moment the endpoint was destroyed. Read only. * @since v23.8.0 */ readonly destroyedAt: bigint; /** * The total number of bytes received by this endpoint. Read only. * @since v23.8.0 */ readonly bytesReceived: bigint; /** * The total number of bytes sent by this endpoint. Read only. * @since v23.8.0 */ readonly bytesSent: bigint; /** * The total number of QUIC packets successfully received by this endpoint. Read only. * @since v23.8.0 */ readonly packetsReceived: bigint; /** * The total number of QUIC packets successfully sent by this endpoint. Read only. * @since v23.8.0 */ readonly packetsSent: bigint; /** * The total number of peer-initiated sessions received by this endpoint. Read only. * @since v23.8.0 */ readonly serverSessions: bigint; /** * The total number of sessions initiated by this endpoint. Read only. * @since v23.8.0 */ readonly clientSessions: bigint; /** * The total number of times an initial packet was rejected due to the * endpoint being marked busy. Read only. * @since v23.8.0 */ readonly serverBusyCount: bigint; /** * The total number of QUIC retry attempts on this endpoint. Read only. * @since v23.8.0 */ readonly retryCount: bigint; /** * The total number of sessions rejected due to QUIC version mismatch. Read only. * @since v23.8.0 */ readonly versionNegotiationCount: bigint; /** * The total number of stateless resets handled by this endpoint. Read only. * @since v23.8.0 */ readonly statelessResetCount: bigint; /** * The total number of sessions that were closed before handshake completed. Read only. * @since v23.8.0 */ readonly immediateCloseCount: bigint; } } interface CreateStreamOptions { /** * The outbound body source. See `stream.setBody()` for details on * supported types. When omitted, the stream starts half-closed (writable * side open, no body queued). */ body?: StreamBody | undefined; /** * Initial request or response headers to send. Only * used when the session supports headers (e.g. HTTP/3). If `body` is not * specified and `headers` is provided, the stream is treated as * headers-only (terminal). */ headers?: NodeJS.Dict | readonly string[] | undefined; /** * The priority level of the stream. One of `'high'`, * `'default'`, or `'low'`. **Default:** `'default'`. */ priority?: "high" | "default" | "low" | undefined; /** * When `true`, data from this stream may be * interleaved with data from other streams of the same priority level. * When `false`, the stream should be completed before same-priority peers. * **Default:** `false`. */ incremental?: boolean | undefined; /** * The maximum number of bytes that the writer * will buffer before `writeSync()` returns `false`. When the buffered * data exceeds this limit, the caller should wait for drain before * writing more. **Default:** `65536` (64 KB). */ highWaterMark?: number | undefined; /** * Callback for received initial response headers. * Called with `(headers)`. */ onheaders?: QuicStream["onheaders"] | undefined; /** * Callback for received trailing headers. * Called with `(trailers)`. */ ontrailers?: QuicStream["ontrailers"] | undefined; /** * Callback for received informational (1xx) headers. * Called with `(headers)`. */ oninfo?: QuicStream["oninfo"] | undefined; /** * Callback when trailers should be sent. */ onwanttrailers?: QuicStream["onwanttrailers"] | undefined; } interface SessionDestroyOptions { /** * The error code to include in the `CONNECTION_CLOSE` * frame sent to the peer. **Default:** `0` (no error). */ code?: bigint | number | undefined; /** * Either `'transport'` or `'application'`. Determines the * error code namespace used in the `CONNECTION_CLOSE` frame. When `'transport'` * (the default), the frame type is `0x1c` and the code is interpreted as a QUIC * transport error. When `'application'`, the frame type is `0x1d` and the code * is application-specific. **Default:** `'transport'`. */ type?: "transport" | "application" | undefined; /** * An optional human-readable reason string included in * the `CONNECTION_CLOSE` frame. Per RFC 9000, this is for diagnostic purposes * only and should not be used for machine-readable error descriptions. */ reason?: string | undefined; } interface SessionHandshakeInfo { /** * The local socket address. */ local: SocketAddress; /** * The remote socket address. */ remote: SocketAddress; /** * The SNI server name negotiated during the handshake. */ servername: string; /** * The ALPN protocol negotiated during the handshake. */ protocol: string; /** * The name of the negotiated TLS cipher suite. */ cipher: string; /** * The TLS protocol version of the cipher suite * (e.g., `'TLSv1.3'`). */ cipherVersion: string; /** * If certificate validation failed, the * reason string. Empty string if validation succeeded. */ validationErrorReason: string; /** * If certificate validation failed, the * error code. `0` if validation succeeded. */ validationErrorCode: number; /** * Whether 0-RTT early data was attempted. */ earlyDataAttempted: boolean; /** * Whether 0-RTT early data was accepted by * the server. */ earlyDataAccepted: boolean; } interface SessionPath { local: SocketAddress; remote: SocketAddress; } /** * A `QuicSession` represents the local side of a QUIC connection. * @since v23.8.0 */ class QuicSession implements AsyncDisposable { private constructor(); /** * Initiate a graceful close of the session. Existing streams will be allowed * to complete but no new streams will be opened. Once all streams have closed, * the session will be destroyed. The returned promise will be fulfilled once * the session has been destroyed. If a non-zero `code` is specified, the * promise will reject with an `ERR_QUIC_TRANSPORT_ERROR` or * `ERR_QUIC_APPLICATION_ERROR` depending on the `type`. * @since v23.8.0 */ close(options?: SessionDestroyOptions): Promise; /** * A promise that is fulfilled once the TLS handshake completes successfully. * The resolved value contains information about the established session * including the negotiated protocol, cipher suite, certificate validation * status, and 0-RTT early data status. * * If the handshake fails or the session is destroyed before the handshake * completes, the promise will be rejected. * @since v26.2.0 */ readonly opened: Promise; /** * A promise that is fulfilled once the session is destroyed. * @since v23.8.0 */ readonly closed: Promise; /** * True if `session.close()` has been called and the session has not yet * been destroyed. Read only. * @since v26.2.0 */ readonly closing: boolean; /** * Immediately destroy the session. All streams will be destroyed and the * session will be closed. If `error` is provided and [`session.onerror`][] is * set, the `onerror` callback is invoked before destruction. The * `session.closed` promise will reject with the error. If `options` is * provided, the `CONNECTION_CLOSE` frame sent to the peer will include the * specified error code, type, and reason. * @since v23.8.0 */ destroy(error?: any, options?: SessionDestroyOptions): void; /** * True if `session.destroy()` has been called. Read only. * @since v23.8.0 */ readonly destroyed: boolean; /** * The endpoint that created this session. Returns `null` if the session * has been destroyed. Read only. * @since v23.8.0 */ readonly endpoint: QuicEndpoint | null; /** * An optional callback invoked when the session is destroyed with an error. * This includes errors caused by user callbacks that throw or reject (see * [Callback error handling](https://nodejs.org/docs/latest-v26.x/api/quic.html#callback-error-handling)). The callback receives a single argument: the * error that triggered the destruction. If the `onerror` callback itself throws * or returns a promise that rejects, the error is surfaced as an uncaught * exception. Read/write. * * Can also be set via the `onerror` option in `quic.connect()` or * `quic.listen()`. * @since v26.2.0 */ onerror: ((this: QuicSession, error: any) => void) | undefined; /** * The callback to invoke when a new stream is initiated by a remote peer. Read/write. * @since v23.8.0 */ onstream: OnStreamCallback | undefined; /** * The callback to invoke when the server rejects 0-RTT early data. When * this fires, all streams that were opened during the 0-RTT phase have * been destroyed. The application should re-open streams if needed. * Read/write. * * This callback only fires on the client side when the server rejects * the client's 0-RTT attempt. The connection falls back to 1-RTT and * continues normally. * @since v26.2.0 */ onearlyrejected: ((this: QuicSession) => void) | undefined; /** * The callback to invoke when a new datagram is received from a remote peer. Read/write. * @since v23.8.0 */ ondatagram: OnDatagramCallback | undefined; /** * The callback to invoke when the status of a datagram is updated. Read/write. * @since v23.8.0 */ ondatagramstatus: OnDatagramStatusCallback | undefined; /** * The callback to invoke when the path validation is updated. Read/write. * @since v23.8.0 */ onpathvalidation: OnPathValidationCallback | undefined; /** * The callback to invoke when a new session ticket is received. Read/write. * @since v23.8.0 */ onsessionticket: OnSessionTicketCallback | undefined; /** * The callback to invoke when a version negotiation is initiated. Read/write. * @since v23.8.0 */ onversionnegotiation: OnVersionNegotiationCallback | undefined; /** * The callback to invoke when the TLS handshake is completed. Read/write. * @since v23.8.0 */ onhandshake: OnHandshakeCallback | undefined; /** * The callback to invoke when a NEW\_TOKEN token is received from the server. * The token can be passed as the `token` option on a future connection to * the same server to skip address validation. Read/write. * @since v26.2.0 */ onnewtoken: OnNewTokenCallback | undefined; /** * The callback to invoke when an ORIGIN frame (RFC 9412) is received from * the server, indicating which origins the server is authoritative for. * Read/write. * @since v26.2.0 */ onorigin: OnOriginCallback | undefined; /** * The callback to invoke when the peer sends an HTTP/3 GOAWAY frame, * indicating it is initiating a graceful shutdown. The callback receives * `(lastStreamId)` where `lastStreamId` is a `{bigint}`: * * * When `lastStreamId` is `-1n`, the peer sent a shutdown notice (intent * to close) without specifying a stream boundary. All existing streams * may still be processed. * * When `lastStreamId` is `>= 0n`, it is the highest stream ID the peer * may have processed. Streams with IDs above this value were NOT * processed and can be safely retried on a new connection. * * After GOAWAY is received, `session.createBidirectionalStream()` will * throw `ERR_INVALID_STATE`. Existing streams continue until they * complete or the session closes. * * This callback is only relevant for HTTP/3 sessions. Read/write. * @since v26.2.0 */ ongoaway: ((this: QuicSession, lastStreamId: bigint) => void) | undefined; /** * The callback to invoke when TLS key material is available. Requires * `sessionOptions.keylog` to be `true`. Each invocation receives a single * line of [NSS Key Log Format](https://udn.realityripple.com/docs/Mozilla/Projects/NSS/Key_Log_Format) text (including a trailing newline). This is * useful for decrypting packet captures with tools like Wireshark. Read/write. * * Can also be set via the `onkeylog` option in `quic.connect()` or * `quic.listen()`. * @since v26.2.0 */ onkeylog: OnKeylogCallback | undefined; /** * The callback to invoke when qlog data is available. Requires * `sessionOptions.qlog` to be `true`. The callback receives a string * chunk of [JSON-SEQ](https://www.rfc-editor.org/rfc/rfc7464) formatted qlog data and a boolean `fin` flag. When * `fin` is `true`, the chunk is the final qlog output for this session and * the concatenated chunks form a complete qlog trace. Read/write. * * Qlog data arrives during the connection lifecycle. The first chunk contains * the qlog header with format metadata. Subsequent chunks contain trace * events. The final chunk (with `fin` set to `true`) is emitted during * session destruction and completes the JSON-SEQ output. * * Can also be set via the `onqlog` option in `quic.connect()` or * `quic.listen()`. * @since v26.2.0 */ onqlog: OnQlogCallback | undefined; /** * Open a new bidirectional stream. If the `body` option is not specified, * the outgoing stream will be half-closed. The `priority` and `incremental` * options are only used when the session supports priority (e.g. HTTP/3). * The `headers`, `onheaders`, `ontrailers`, `oninfo`, and `onwanttrailers` * options are only used when the session supports headers (e.g. HTTP/3). * @since v23.8.0 */ createBidirectionalStream(options?: CreateStreamOptions): Promise; /** * Open a new unidirectional stream. If the `body` option is not specified, * the outgoing stream will be closed. The `priority` and `incremental` * options are only used when the session supports priority (e.g. HTTP/3). * @since v23.8.0 */ createUnidirectionalStream(options?: CreateStreamOptions): Promise; /** * The local and remote socket addresses associated with the session. Read only. * @since v23.8.0 */ path: SessionPath | undefined; /** * Sends an unreliable datagram to the remote peer, returning a promise for * the datagram ID. * * If `datagram` is a string, it will be encoded using the specified `encoding`. * * If `datagram` is an `ArrayBufferView`, the bytes are copied into an * internal buffer; the caller's source buffer is unchanged and may be reused * or mutated immediately after the call returns. Callers that want to ensure * their source cannot be mutated after the call (for example, when handing * the buffer off to another async consumer) can call * `ArrayBuffer.prototype.transfer()` themselves before passing the buffer. * * If `datagram` is a `Promise`, it will be awaited before sending. If the * session closes while awaiting, `0n` is returned silently (datagrams are * inherently unreliable). * * If the datagram payload is zero-length (empty string after encoding, detached * buffer, or zero-length view), `0n` is returned and no datagram is sent. * * For HTTP/3 sessions, the peer must advertise `SETTINGS_H3_DATAGRAM=1` * (via `application: { enableDatagrams: true }`) for datagrams to be sent. * If the peer's setting is `0`, `sendDatagram()` returns `0n` (per RFC 9297 * §3, an endpoint MUST NOT send HTTP Datagrams unless the peer indicated * support). * * Datagrams cannot be fragmented — each must fit within a single QUIC packet. * The maximum datagram size is determined by the peer's * `maxDatagramFrameSize` transport parameter (which the peer advertises during * the handshake). If the peer sets this to `0`, datagrams are not supported * and `0n` will be returned. If the datagram exceeds the peer's limit, it * will be silently dropped and `0n` returned. The local * `maxDatagramFrameSize` transport parameter (default: `1200` bytes) controls * what this endpoint advertises to the peer as its own maximum. * @since v23.8.0 * @param encoding The encoding to use if `datagram` is a string. * **Default:** `'utf8'`. */ sendDatagram( datagram: string | NodeJS.ArrayBufferView | Promise, encoding?: BufferEncoding, ): Promise; /** * The local certificate as an object with properties such as `subject`, * `issuer`, `valid_from`, `valid_to`, `fingerprint`, etc. Returns `undefined` * if the session is destroyed or no certificate is available. * @since v26.2.0 */ readonly certificate: PeerCertificate | undefined; /** * The peer's certificate as an object with properties such as `subject`, * `issuer`, `valid_from`, `valid_to`, `fingerprint`, etc. Returns `undefined` * if the session is destroyed or the peer did not present a certificate. * @since v26.2.0 */ readonly peerCertificate: PeerCertificate | undefined; /** * The ephemeral key information for the session, with properties such as * `type`, `name`, and `size`. Only available on client sessions. Returns * `undefined` for server sessions or if the session is destroyed. * @since v26.2.0 */ readonly ephemeralKeyInfo: EphemeralKeyInfo | undefined; /** * The maximum datagram payload size in bytes that the peer will accept. * This is derived from the peer's `maxDatagramFrameSize` transport * parameter minus the DATAGRAM frame overhead (type byte and variable-length * integer encoding). Returns `0` if the peer does not support datagrams or * if the handshake has not yet completed. Datagrams larger than this value * will not be sent. * @since v26.2.0 */ readonly maxDatagramSize: number; /** * The maximum number of datagrams that can be queued for sending. Datagrams * are queued when `sendDatagram()` is called and sent opportunistically * alongside stream data by the packet serialization loop. When the queue * is full, the `sessionOptions.datagramDropPolicy` determines whether * the oldest or newest datagram is dropped. Dropped datagrams are reported * as lost via the `ondatagramstatus` callback. * * This property can be changed dynamically to adjust queue capacity * based on application activity or memory pressure. The valid range * is `0` to `65535`. * @since v26.2.0 */ maxPendingDatagrams: number; /** * Return the current statistics for the session. Read only. * @since v23.8.0 */ readonly stats: QuicSession.Stats; /** * Initiate a key update for the session. * @since v23.8.0 */ updateKey(): void; /** * Calls `session.close()` and returns a promise that fulfills when the * session has closed. * @since v23.8.0 */ [Symbol.asyncDispose](): Promise; } namespace QuicSession { /** * @since v23.8.0 */ class Stats { private constructor(); /** * @since v23.8.0 */ readonly createdAt: bigint; /** * @since v23.8.0 */ readonly closingAt: bigint; /** * @since v23.8.0 */ readonly handshakeCompletedAt: bigint; /** * @since v23.8.0 */ readonly handshakeConfirmedAt: bigint; /** * @since v23.8.0 */ readonly bytesReceived: bigint; /** * @since v23.8.0 */ readonly bytesSent: bigint; /** * @since v23.8.0 */ readonly bidiInStreamCount: bigint; /** * @since v23.8.0 */ readonly bidiOutStreamCount: bigint; /** * @since v23.8.0 */ readonly uniInStreamCount: bigint; /** * @since v23.8.0 */ readonly uniOutStreamCount: bigint; /** * @since v23.8.0 */ readonly maxBytesInFlight: bigint; /** * @since v23.8.0 */ readonly bytesInFlight: bigint; /** * @since v23.8.0 */ readonly blockCount: bigint; /** * @since v23.8.0 */ readonly cwnd: bigint; /** * @since v23.8.0 */ readonly latestRtt: bigint; /** * @since v23.8.0 */ readonly minRtt: bigint; /** * @since v23.8.0 */ readonly rttVar: bigint; /** * @since v23.8.0 */ readonly smoothedRtt: bigint; /** * @since v23.8.0 */ readonly ssthresh: bigint; /** * @since v23.8.0 */ readonly datagramsReceived: bigint; /** * @since v23.8.0 */ readonly datagramsSent: bigint; /** * @since v23.8.0 */ readonly datagramsAcknowledged: bigint; /** * @since v23.8.0 */ readonly datagramsLost: bigint; } } interface QuicErrorOptions { /** * The numeric QUIC error code. Numbers * are coerced to `BigInt`. Must be a non-negative 62-bit unsigned * varint (`0n <= errorCode <= 2n ** 62n - 1n`). */ errorCode?: bigint | number | undefined; /** * The Node.js-style error code string assigned to * `error.code`. Defaults to `'ERR_QUIC_STREAM_ABORTED'`. */ code?: string | undefined; /** * Either `'application'` (default) or `'transport'`. * Indicates whether the code is defined by the negotiated * application protocol (e.g. RFC 9114 for HTTP/3) or by the QUIC * transport layer (RFC 9000). Stream resets always carry application * codes, so the default is `'application'`. */ type?: "application" | "transport" | undefined; } /** * A `QuicError` is an `Error` subclass that carries an explicit numeric * QUIC error code. Use it to abort a QUIC stream or session with a * specific application-protocol-defined error code rather than letting * the implementation pick a generic fallback. * * The class is exported from `node:quic`: * * ```js * import { QuicError } from 'node:quic'; * ``` * * When a `QuicError` is supplied to APIs that emit a wire frame * (`writer.fail()`, `stream.destroy()`), the QUIC stack uses * `error.errorCode` as the wire code for the resulting frame. * When any other value is supplied (for example a plain `Error`), the * implementation falls back to the negotiated application protocol's * "internal error" code (`H3_INTERNAL_ERROR` (`0x102`) for HTTP/3, or * the QUIC transport-layer `INTERNAL_ERROR` (`0x1`) for raw QUIC). * * The Node.js error code (`error.code`) defaults to * `'ERR_QUIC_STREAM_ABORTED'`. Callers who need a more specific code * string can override it via `options.code` — the numeric QUIC code * is unaffected. * * The Node.js error code is fixed at `'ERR_QUIC_STREAM_ABORTED'` so that * catch blocks can distinguish a `QuicError` from other Node.js errors * without checking the prototype chain. The numeric QUIC code lives on * the separate `error.errorCode` property to avoid colliding with * the Node.js convention that `error.code` is a string. * @since v26.2.0 * @experimental */ class QuicError extends Error { /** * ```js * import { QuicError } from 'node:quic'; * * const err = new QuicError('rejecting stream', { errorCode: 0x10cn }); * console.log(err.code); // 'ERR_QUIC_STREAM_ABORTED' * console.log(err.errorCode); // 268n * console.log(err.type); // 'application' * * const custom = new QuicError('custom failure', { * errorCode: 0x10cn, * code: 'ERR_MY_QUIC_FAILURE', * }); * console.log(custom.code); // 'ERR_MY_QUIC_FAILURE' * ``` * @param message A human-readable description of the error. */ constructor(message: string, options?: QuicErrorOptions); /** * The numeric QUIC error code carried by this error. * @since v26.2.0 */ readonly errorCode: bigint; /** * Either `'application'` or `'transport'`. Indicates the namespace of * `error.errorCode`. * @since v26.2.0 */ readonly type: "application" | "transport"; } type StreamBody = | null | string | ArrayBufferLike | NodeJS.ArrayBufferView | Blob | FileHandle | Iterable | AsyncIterable | Promise; interface StreamPriority { /** * One of `'high'`, `'default'`, or `'low'`. */ level: "high" | "default" | "low"; /** * Whether the stream data should be interleaved * with other streams of the same priority level. */ incremental: boolean; } interface StreamDestroyOptions { /** * The application error code to include in the * `RESET_STREAM` and `STOP_SENDING` frames sent to the peer. Numbers are * coerced to `BigInt`. When omitted, the wire code is derived from `error` * (see below). */ code?: bigint | number | undefined; /** * An optional human-readable reason string. Accepted for * symmetry with `session.close()` and `session.destroy()`, but * **not transmitted on the wire** — neither `RESET_STREAM` nor * `STOP_SENDING` carry a reason field. Provided for application logging * and for use by the `stream.onerror` callback. */ reason?: string | undefined; } interface StreamSendHeadersOptions { /** * If `true`, the stream is closed for sending * after the headers (no body will follow). **Default:** `false`. */ terminal?: boolean | undefined; } /** * @since v23.8.0 */ class QuicStream { private constructor(); /** * A promise that is fulfilled when the stream is fully closed. It resolves * when the stream closes cleanly (including idle timeout). It rejects with * an `ERR_QUIC_APPLICATION_ERROR` or `ERR_QUIC_TRANSPORT_ERROR` when the * stream is closed due to a QUIC error (e.g., stream reset by the peer, * CONNECTION\_CLOSE with a non-zero error code). * @since v23.8.0 */ readonly closed: Promise; /** * Immediately and abruptly destroys the stream. If `error` is provided and * `stream.onerror` is set, the `onerror` callback is invoked before * destruction. The `stream.closed` promise rejects with the error. * * When the stream is destroyed with an `error` (or with an explicit * `options.code`), the QUIC stack signals the abort to the peer: * * * If the writable side is still open, a `RESET_STREAM` frame is sent. * * If the readable side is still open (a bidirectional stream, or a * remote-initiated unidirectional stream), a `STOP_SENDING` frame is sent. * * Both frames carry the same wire code, resolved with the following * precedence: * * 1. `options.code`, when explicitly provided. * 2. [`error.errorCode`][], when `error` is a [`QuicError`][]. * 3. The negotiated application protocol's "internal error" code * (`H3_INTERNAL_ERROR` (`0x102`) for HTTP/3, or the QUIC transport-layer * `INTERNAL_ERROR` (`0x1`) for raw QUIC). * * A clean destroy — no `error` and no `options.code` — does not emit * `RESET_STREAM` or `STOP_SENDING`; the stream's existing close machinery * handles teardown. * * See [Aborting a stream](https://nodejs.org/docs/latest-v26.x/api/quic.html#aborting-a-stream) for an overview of the available stream-abort * APIs. * @since v23.8.0 */ destroy(error?: any, options?: StreamDestroyOptions): void; /** * True if `stream.destroy()` has been called. * @since v23.8.0 */ readonly destroyed: boolean; /** * True if any data on this stream was received as 0-RTT (early data) * before the TLS handshake completed. Early data is less secure and * could potentially be replayed by an attacker. Applications should * treat early data with appropriate caution. * * This property is only meaningful on the server side. On the client * side, it is always `false`. * @since v26.2.0 */ readonly early: boolean; /** * The directionality of the stream, or `null` if the stream has been destroyed * or is still pending. Read only. * @since v23.8.0 */ readonly direction: "bidi" | "uni" | null; /** * The maximum number of bytes that the writer will buffer before * `writeSync()` returns `false`. When the buffered data exceeds this limit, * the caller should wait for drain before writing more. * * The value can be changed dynamically at any time. This is particularly * useful for streams received via the `onstream` callback, where the * default (65536) may need to be adjusted based on application needs. * The valid range is `0` to `4294967295`. * @since v26.2.0 */ highWaterMark: number; /** * The stream ID, or `null` if the stream has been destroyed or is still * pending. Read only. * @since v23.8.0 */ readonly id: bigint | null; /** * An optional callback invoked when the stream is destroyed with an error. * This includes errors caused by user callbacks that throw or reject (see * [Callback error handling](https://nodejs.org/docs/latest-26.x/api/quic.html#callback-error-handling)). The callback receives a single argument: the * error that triggered the destruction. If the `onerror` callback itself throws * or returns a promise that rejects, the error is surfaced as an uncaught * exception. Read/write. * @since v26.2.0 */ onerror: ((this: QuicStream, error: any) => void) | undefined; /** * The callback to invoke when the stream is blocked. Read/write. * @since v23.8.0 */ onblocked: OnBlockedCallback | undefined; /** * The callback to invoke when the peer aborts a direction of the stream by * sending a `RESET_STREAM` frame (the peer abandons their writable side, so * no further data will arrive on our readable side) or a `STOP_SENDING` * frame (the peer asks us to stop writing on our writable side). * * The callback receives a Node.js error whose `errorCode` (`bigint`) * property carries the application error code from the wire frame. * * The stream is **not** automatically destroyed when this callback fires — * the application chooses how to react. Common patterns are: ignore (and * continue using the still-active direction on a bidirectional stream), * abort the other direction with `writer.fail()`, or tear down the * whole stream with `stream.destroy()`. Read/write. * @since v23.8.0 */ onreset: OnStreamErrorCallback | undefined; /** * The buffered initial headers received on this stream, or `undefined` if the * application does not support headers or no headers have been received yet. * For server-side streams, this contains the request headers (e.g., `:method`, * `:path`, `:scheme`). For client-side streams, this contains the response * headers (e.g., `:status`). * * Header names are lowercase strings. Multi-value headers are represented as * arrays. The object has `__proto__: null`. * @since v26.2.0 */ readonly headers: NodeJS.Dict | undefined; /** * The callback to invoke when initial headers are received on the stream. The * callback receives `(headers)` where `headers` is an object (same format as * `stream.headers`). For HTTP/3, this delivers request pseudo-headers on the * server side and response headers on the client side. Throws * `ERR_INVALID_STATE` if set on a session that does not support headers. * Read/write. * @since v26.2.0 */ onheaders: ((this: QuicStream, headers: NodeJS.Dict) => void) | undefined; /** * The callback to invoke when trailing headers are received from the peer. * The callback receives `(trailers)` where `trailers` is an object in the * same format as `stream.headers`. Throws `ERR_INVALID_STATE` if set on a * session that does not support headers. Read/write. * @since v26.2.0 */ ontrailers: ((this: QuicStream, trailers: NodeJS.Dict) => void) | undefined; /** * The callback to invoke when informational (1xx) headers are received from * the server. The callback receives `(headers)` where `headers` is an object * in the same format as `stream.headers`. Informational headers are sent * before the final response (e.g., 103 Early Hints). Throws * `ERR_INVALID_STATE` if set on a session that does not support headers. * Read/write. * @since v26.2.0 */ oninfo: ((this: QuicStream, headers: NodeJS.Dict) => void) | undefined; /** * The callback to invoke when the application is ready for trailing headers * to be sent. This is called synchronously — the user must call * `stream.sendTrailers()` within this callback. Throws * `ERR_INVALID_STATE` if set on a session that does not support headers. * Read/write. * @since v26.2.0 */ onwanttrailers: ((this: QuicStream) => void) | undefined; /** * Set trailing headers to be sent automatically when the application requests * them. This is an alternative to the `stream.onwanttrailers` callback * for cases where the trailers are known before the body completes. Throws * `ERR_INVALID_STATE` if set on a session that does not support headers. * Read/write. * @since v26.2.0 */ pendingTrailers: NodeJS.Dict | undefined; /** * Sends initial or response headers on the stream. For client-side streams, * this sends request headers. For server-side streams, this sends response * headers. Throws `ERR_INVALID_STATE` if the session does not support headers. * @since v26.2.0 * @param headers Header object with string keys and string or * string-array values. Pseudo-headers (`:method`, `:path`, etc.) must * appear before regular headers. */ sendHeaders(headers: NodeJS.Dict, options?: StreamSendHeadersOptions): boolean; /** * Sends informational (1xx) response headers. Server only. Throws * `ERR_INVALID_STATE` if the session does not support headers. * @since v26.2.0 * @param headers Header object. Must include `:status` with a 1xx * value (e.g., `{ ':status': '103', 'link': '; rel=preload' }`). */ sendInformationalHeaders(headers: NodeJS.Dict): boolean; /** * Sends trailing headers on the stream. Must be called synchronously during * the `stream.onwanttrailers` callback, or set ahead of time via * `stream.pendingTrailers`. Throws `ERR_INVALID_STATE` if the session * does not support headers. * @since v26.2.0 * @param headers Trailing header object. Pseudo-headers must not be * included in trailers. */ sendTrailers(headers: NodeJS.Dict): boolean; /** * The current priority of the stream. Returns `null` if the session does not * support priority (e.g. non-HTTP/3) or if the stream has been destroyed. * Read only. Use `stream.setPriority()` to change the priority. * * On client-side HTTP/3 sessions, the value reflects what was set via * `stream.setPriority()`. On server-side HTTP/3 sessions, the value * reflects the peer's requested priority (e.g., from `PRIORITY_UPDATE` frames). * @since v26.2.0 */ readonly priority: StreamPriority | null; /** * Sets the priority of the stream. Throws `ERR_INVALID_STATE` if the session * does not support priority (e.g. non-HTTP/3). Has no effect if the stream * has been destroyed. * @since v26.2.0 */ setPriority(options?: NodeJS.PartialOptions): void; /** * The stream implements `Symbol.asyncIterator`, making it directly usable * in `for await...of` loops. Each iteration yields a batch of `Uint8Array` * chunks. * * Only one async iterator can be obtained per stream. A second call throws * `ERR_INVALID_STATE`. Non-readable streams (outbound-only unidirectional * or closed) return an immediately-finished iterator. * * ```js * for await (const chunks of stream) { * for (const chunk of chunks) { * // Process each Uint8Array chunk * } * } * ``` * * Compatible with stream/iter utilities: * * ```js * import Stream from 'node:stream/iter'; * const body = await Stream.bytes(stream); * const text = await Stream.text(stream); * await Stream.pipeTo(stream, someWriter); * ``` * @since v26.2.0 */ [Symbol.asyncIterator](): NodeJS.AsyncIterator; /** * Returns a Writer object for pushing data to the stream incrementally. * The Writer implements the stream/iter Writer interface with the * try-sync-fallback-to-async pattern. * * Only available when no `body` source was provided at creation time or via * `stream.setBody()`. Non-writable streams return an already-closed * Writer. Throws `ERR_INVALID_STATE` if the outbound is already configured. * * The Writer has the following methods: * * * `writeSync(chunk)` — Synchronous write. Returns `true` if accepted, * `false` if flow-controlled. Data is NOT accepted on `false`. * * `write(chunk[, options])` — Async write with drain wait. `options.signal` * is checked at entry but not observed during the write. * * `writevSync(chunks)` — Synchronous vectored write. All-or-nothing. * * `writev(chunks[, options])` — Async vectored write. * * `endSync()` — Synchronous close. Returns total bytes or `-1`. * * `end([options])` — Async close. * * `fail(reason)` — Errors the stream (sends `RESET_STREAM` to peer). * When `reason` is a `QuicError`, its `error.errorCode` is used * as the wire code on the resulting `RESET_STREAM` frame; otherwise * the wire code falls back to the negotiated application protocol's * "internal error" code (`H3_INTERNAL_ERROR` (`0x102`) for HTTP/3, or * the QUIC transport-layer `INTERNAL_ERROR` (`0x1`) for raw QUIC). * See `stream.destroy()` for a full-stream abort that also resets * the readable side via `STOP_SENDING`. * * `desiredSize` — Available capacity in bytes, or `null` if closed/errored. * * The bytes from each `writeSync()` / `writevSync()` / `write()` / `writev()` * input chunk are copied into an internal buffer, so the caller's source * buffer is unchanged and may be reused or mutated immediately after the * call returns. Callers that want to ensure a source buffer cannot be * mutated after handing it off can call `ArrayBuffer.prototype.transfer()` * themselves before passing the buffer. * @since v26.2.0 */ readonly writer: Writer; /** * Sets the outbound body source for the stream. Can only be called once. * Mutually exclusive with `stream.writer`. * * The following body source types are supported: * * * `null` — The writable side is closed immediately (FIN sent with no data). * * `string` — UTF-8 encoded and sent as a single chunk. * * `ArrayBuffer`, `SharedArrayBuffer`, `ArrayBufferView` — Sent as a single * chunk. The bytes are copied into an internal buffer, so the caller's * source buffer is unchanged and may be reused or mutated immediately * after the call returns. Callers wanting to ensure their source cannot * be mutated after handing it off can call * `ArrayBuffer.prototype.transfer()` themselves before passing the buffer. * * `Blob` — Sent from the Blob's underlying data queue. * * {FileHandle} — The file contents are read asynchronously via an * fd-backed data source. The `FileHandle` must be opened for reading * (e.g. via [`fs.promises.open(path, 'r')`][]). Once passed as a body, the * `FileHandle` is locked and cannot be used as a body for another stream. * The `FileHandle` is automatically closed when the stream finishes. * * `AsyncIterable`, `Iterable` — Each yielded chunk (string or * `Uint8Array`) is written incrementally in streaming mode. * * `Promise` — Awaited; the resolved value is used as the body (subject * to the same type rules). * * Throws `ERR_INVALID_STATE` if the outbound is already configured or if * the writer has been accessed. * @since v26.2.0 */ setBody(body: StreamBody): void; /** * The session that created this stream, or `null` if the stream has been * destroyed. Read only. * @since v23.8.0 */ readonly session: QuicSession | null; /** * The current statistics for the stream. Read only. * @since v23.8.0 */ readonly stats: QuicStream.Stats; } namespace QuicStream { /** * @since v23.8.0 */ class Stats { private constructor(); /** * @since v23.8.0 */ readonly ackedAt: bigint; /** * @since v23.8.0 */ readonly bytesReceived: bigint; /** * @since v23.8.0 */ readonly bytesSent: bigint; /** * @since v23.8.0 */ readonly createdAt: bigint; /** * @since v23.8.0 */ readonly destroyedAt: bigint; /** * @since v23.8.0 */ readonly finalSize: bigint; /** * @since v23.8.0 */ readonly isConnected: bigint; /** * @since v23.8.0 */ readonly maxOffset: bigint; /** * @since v23.8.0 */ readonly maxOffsetAcknowledged: bigint; /** * @since v23.8.0 */ readonly maxOffsetReceived: bigint; /** * @since v23.8.0 */ readonly openedAt: bigint; /** * @since v23.8.0 */ readonly receivedAt: bigint; } } /** * An object containing commonly used constants for QUIC configuration. * @since v26.2.0 */ namespace constants { /** * Congestion control algorithm identifiers, for use with the * `sessionOptions.cc` option: * * * `quic.constants.cc.RENO` — Reno congestion control. * * `quic.constants.cc.CUBIC` — CUBIC congestion control. * * `quic.constants.cc.BBR` — BBR congestion control. */ enum cc { RENO = "reno", CUBIC = "cubic", BBR = "bbr", } /** * The default TLS 1.3 cipher suite list used when `sessionOptions.ciphers` * is not specified. */ const DEFAULT_CIPHERS: string; /** * The default TLS 1.3 key-exchange group list used when * `sessionOptions.groups` is not specified. */ const DEFAULT_GROUPS: string; } }