@types/node 26.1.1 → 26.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
node/quic.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  declare module "node:quic" {
2
- import { KeyObject, webcrypto } from "node:crypto";
2
+ import { NonSharedBuffer } from "node:buffer";
3
+ import { KeyObject } from "node:crypto";
4
+ import { FileHandle } from "node:fs/promises";
3
5
  import { SocketAddress } from "node:net";
4
- import { ReadableStream } from "node:stream/web";
6
+ import { Writer } from "node:stream/iter";
7
+ import { EphemeralKeyInfo, PeerCertificate } from "node:tls";
5
8
  /**
6
9
  * @since v23.8.0
7
10
  */
@@ -13,11 +16,15 @@ declare module "node:quic" {
13
16
  /**
14
17
  * @since v23.8.0
15
18
  */
16
- type OnDatagramCallback = (this: QuicSession, datagram: Uint8Array, early: boolean) => void;
19
+ type OnDatagramCallback = (this: QuicSession, datagram: NodeJS.NonSharedUint8Array, early: boolean) => void;
17
20
  /**
18
21
  * @since v23.8.0
19
22
  */
20
- type OnDatagramStatusCallback = (this: QuicSession, id: bigint, status: "lost" | "acknowledged") => void;
23
+ type OnDatagramStatusCallback = (
24
+ this: QuicSession,
25
+ id: bigint,
26
+ status: "acknowledged" | "lost" | "abandoned",
27
+ ) => void;
21
28
  /**
22
29
  * @since v23.8.0
23
30
  */
@@ -26,8 +33,8 @@ declare module "node:quic" {
26
33
  result: "success" | "failure" | "aborted",
27
34
  newLocalAddress: SocketAddress,
28
35
  newRemoteAddress: SocketAddress,
29
- oldLocalAddress: SocketAddress,
30
- oldRemoteAddress: SocketAddress,
36
+ oldLocalAddress: SocketAddress | null,
37
+ oldRemoteAddress: SocketAddress | null,
31
38
  preferredAddress: boolean,
32
39
  ) => void;
33
40
  /**
@@ -46,16 +53,32 @@ declare module "node:quic" {
46
53
  /**
47
54
  * @since v23.8.0
48
55
  */
49
- type OnHandshakeCallback = (
50
- this: QuicSession,
51
- sni: string,
52
- alpn: string,
53
- cipher: string,
54
- cipherVersion: string,
55
- validationErrorReason: string,
56
- validationErrorCode: number,
57
- earlyDataAccepted: boolean,
58
- ) => void;
56
+ type OnHandshakeCallback = (this: QuicSession, info: SessionHandshakeInfo) => void;
57
+ /**
58
+ * @since v26.2.0
59
+ */
60
+ type OnNewTokenCallback = (this: QuicSession, token: NonSharedBuffer, address: SocketAddress) => void;
61
+ /**
62
+ * @since v26.2.0
63
+ */
64
+ type OnOriginCallback = (this: QuicSession, origins: string[]) => void;
65
+ /**
66
+ * Called when TLS key material is available. Only fires when
67
+ * `sessionOptions.keylog` is `true`. Multiple lines are emitted during the
68
+ * TLS 1.3 handshake, each containing a secret label, the client random, and
69
+ * the secret value.
70
+ * @since v26.2.0
71
+ */
72
+ type OnKeylogCallback = (this: QuicSession, line: string) => void;
73
+ /**
74
+ * Called when qlog diagnostic data is available. Only fires when
75
+ * `sessionOptions.qlog` is `true`. The `data` chunks should be
76
+ * concatenated in order to produce the complete qlog output. When `fin` is
77
+ * `true`, no more chunks will be emitted and the concatenated result is a
78
+ * complete JSON-SEQ document.
79
+ * @since v26.2.0
80
+ */
81
+ type OnQlogCallback = (this: QuicSession, data: string, fin: boolean) => void;
59
82
  /**
60
83
  * @since v23.8.0
61
84
  */
@@ -64,17 +87,35 @@ declare module "node:quic" {
64
87
  * @since v23.8.0
65
88
  */
66
89
  type OnStreamErrorCallback = (this: QuicStream, error: any) => void;
90
+ /**
91
+ * Called when initial request or response headers are received. For HTTP/3,
92
+ * this delivers request pseudo-headers on the server and response headers
93
+ * on the client.
94
+ * @since v26.2.0
95
+ */
96
+ type OnHeadersCallback = (this: QuicStream, headers: NodeJS.Dict<string | string[]>) => void;
97
+ /**
98
+ * Called when trailing headers are received from the peer.
99
+ * @since v26.2.0
100
+ */
101
+ type OnTrailersCallback = (this: QuicStream, trailers: NodeJS.Dict<string | string[]>) => void;
102
+ /**
103
+ * Called when informational (1xx) headers are received from the server
104
+ * (e.g., 103 Early Hints).
105
+ * @since v26.2.0
106
+ */
107
+ type OnInfoCallback = (this: QuicStream, headers: NodeJS.Dict<string | string[]>) => void;
67
108
  /**
68
109
  * @since v23.8.0
69
110
  */
70
111
  interface TransportParams {
71
112
  /**
72
- * The preferred IPv4 address to advertise.
113
+ * The preferred IPv4 address to advertise (only used by servers).
73
114
  * @since v23.8.0
74
115
  */
75
116
  preferredAddressIpv4?: SocketAddress | undefined;
76
117
  /**
77
- * The preferred IPv6 address to advertise.
118
+ * The preferred IPv6 address to advertise (only used by servers)
78
119
  * @since v23.8.0
79
120
  */
80
121
  preferredAddressIpv6?: SocketAddress | undefined;
@@ -119,16 +160,74 @@ declare module "node:quic" {
119
160
  */
120
161
  maxAckDelay?: bigint | number | undefined;
121
162
  /**
163
+ * The maximum size in bytes of a DATAGRAM frame payload that this endpoint
164
+ * is willing to receive. Set to `0` to disable datagram support. The peer
165
+ * will not send datagrams larger than this value. The actual maximum size of
166
+ * a datagram that can be _sent_ is determined by the peer's
167
+ * `maxDatagramFrameSize`, not this endpoint's value.
122
168
  * @since v23.8.0
123
169
  */
124
170
  maxDatagramFrameSize?: bigint | number | undefined;
125
171
  }
126
172
  interface SNIEntry {
173
+ /**
174
+ * The TLS private keys. **Required.**
175
+ */
127
176
  keys: KeyObject | readonly KeyObject[];
177
+ /**
178
+ * The TLS certificates. **Required.**
179
+ */
128
180
  certs: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray<ArrayBuffer | NodeJS.ArrayBufferView>;
129
- ca?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray<ArrayBuffer | NodeJS.ArrayBufferView> | undefined;
130
- crl?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray<ArrayBuffer | NodeJS.ArrayBufferView> | undefined;
181
+ /**
182
+ * Verify the private key. Default: `false`.
183
+ */
131
184
  verifyPrivateKey?: boolean | undefined;
185
+ /**
186
+ * The port to advertise in ORIGIN frames (RFC 9412) for this host name. **Default:** `443`. Only used for HTTP/3 sessions.
187
+ */
188
+ port?: number | undefined;
189
+ /**
190
+ * Whether to include this host name in ORIGIN frames. **Default:** `true`. Set to `false` to exclude a host name
191
+ * from ORIGIN advertisements. Wildcard (`'*'`) entries are always excluded regardless of this setting.
192
+ */
193
+ authoritative?: boolean | undefined;
194
+ }
195
+ interface ApplicationOptions {
196
+ /**
197
+ * Maximum number of header name-value pairs accepted per header block. Headers beyond this limit are silently
198
+ * dropped. **Default:** `128`
199
+ */
200
+ maxHeaderPairs?: number | undefined;
201
+ /**
202
+ * Maximum total byte length of all header names and values combined per header block. Headers that would push
203
+ * the total over this limit are silently dropped. **Default:** `8192`
204
+ */
205
+ maxHeaderLength?: number | undefined;
206
+ /**
207
+ * Maximum size of a compressed header field section (QPACK). `0` means unlimited. **Default:** `0`
208
+ */
209
+ maxFieldSectionSize?: number | undefined;
210
+ /**
211
+ * QPACK dynamic table capacity in bytes. Set to `0` to disable the dynamic table. **Default:** `4096`
212
+ */
213
+ qpackMaxDTableCapacity?: number | undefined;
214
+ /**
215
+ * QPACK encoder maximum dynamic table capacity. **Default:** `4096`
216
+ */
217
+ qpackEncoderMaxDTableCapacity?: number | undefined;
218
+ /**
219
+ * Maximum number of streams that can be blocked waiting for QPACK dynamic table updates.
220
+ * **Default:** `100`
221
+ */
222
+ qpackBlockedStreams?: number | undefined;
223
+ /**
224
+ * Enable the extended CONNECT protocol (RFC 9220). **Default:** `false`
225
+ */
226
+ enableConnectProtocol?: boolean | undefined;
227
+ /**
228
+ * Enable HTTP/3 datagrams (RFC 9297). **Default:** `false`
229
+ */
230
+ enableDatagrams?: boolean | undefined;
132
231
  }
133
232
  /**
134
233
  * @since v23.8.0
@@ -156,6 +255,12 @@ declare module "node:quic" {
156
255
  * @since v26.1.0
157
256
  */
158
257
  alpn?: string | readonly string[] | undefined;
258
+ /**
259
+ * HTTP/3 application-specific options. These only apply when the negotiated
260
+ * ALPN selects the HTTP/3 application (`'h3'`).
261
+ * @since v26.2.0
262
+ */
263
+ application?: ApplicationOptions | undefined;
159
264
  /**
160
265
  * The CA certificates to use for client sessions. For server sessions, CA
161
266
  * certificates are specified per-identity in the `sessionOptions.sni` map.
@@ -188,12 +293,23 @@ declare module "node:quic" {
188
293
  */
189
294
  crl?: ArrayBuffer | NodeJS.ArrayBufferView | ReadonlyArray<ArrayBuffer | NodeJS.ArrayBufferView> | undefined;
190
295
  /**
191
- * The list of support TLS 1.3 cipher groups.
296
+ * When `true`, enables TLS 0-RTT early data for this session. Early data
297
+ * allows the client to send application data before the TLS handshake
298
+ * completes, reducing latency on reconnection when a valid session ticket
299
+ * is available. Set to `false` to disable early data support.
300
+ * @since v26.2.0
301
+ */
302
+ enableEarlyData?: boolean | undefined;
303
+ /**
304
+ * The list of supported TLS 1.3 cipher groups.
192
305
  * @since v23.8.0
193
306
  */
194
307
  groups?: string | undefined;
195
308
  /**
196
- * True to enable TLS keylogging output.
309
+ * When `true`, enables TLS key logging for the session. Key material is
310
+ * delivered to the `session.onkeylog` callback in [NSS Key Log Format](https://udn.realityripple.com/docs/Mozilla/Projects/NSS/Key_Log_Format).
311
+ * Each callback invocation receives a single line of key material. The output
312
+ * can be used with tools such as Wireshark to decrypt captured QUIC traffic.
197
313
  * @since v23.8.0
198
314
  */
199
315
  keylog?: boolean | undefined;
@@ -231,7 +347,10 @@ declare module "node:quic" {
231
347
  */
232
348
  preferredAddressPolicy?: "use" | "ignore" | "default" | undefined;
233
349
  /**
234
- * True if qlog output should be enabled.
350
+ * When `true`, enables [qlog](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-main-schema/) diagnostic output for the session. Qlog data
351
+ * is delivered to the `session.onqlog` callback as chunks of [JSON-SEQ](https://www.rfc-editor.org/rfc/rfc7464)
352
+ * formatted text. The output can be analyzed with qlog visualization tools
353
+ * such as [qvis](https://qvis.quictools.info/).
235
354
  * @since v23.8.0
236
355
  */
237
356
  qlog?: boolean | undefined;
@@ -241,8 +360,40 @@ declare module "node:quic" {
241
360
  */
242
361
  sessionTicket?: NodeJS.ArrayBufferView | undefined;
243
362
  /**
244
- * Specifies the maximum number of milliseconds a TLS handshake is permitted to take
245
- * to complete before timing out.
363
+ * Controls which datagram to drop when the pending datagram queue
364
+ * (sized by `session.maxPendingDatagrams`) is full. Must be one of
365
+ * `'drop-oldest'` (discard the oldest queued datagram to make room) or
366
+ * `'drop-newest'` (reject the incoming datagram). Dropped datagrams are
367
+ * reported as lost via the `ondatagramstatus` callback.
368
+ *
369
+ * This option is immutable after session creation.
370
+ * @since v26.2.0
371
+ */
372
+ datagramDropPolicy?: "drop-oldest" | "drop-newest" | undefined;
373
+ /**
374
+ * The maximum number of `SendPendingData` cycles a datagram can survive
375
+ * without being sent before it is abandoned. When a datagram cannot be
376
+ * sent due to congestion control or packet size constraints, it remains
377
+ * in the queue and the attempt counter increments. Once the limit is
378
+ * reached, the datagram is dropped and reported as `'abandoned'` via the
379
+ * `ondatagramstatus` callback. Valid range: `1` to `255`.
380
+ * @since v26.2.0
381
+ */
382
+ maxDatagramSendAttempts?: number | undefined;
383
+ /**
384
+ * A multiplier applied to the Probe Timeout (PTO) to compute the draining
385
+ * period duration after receiving a `CONNECTION_CLOSE` frame from the peer.
386
+ * RFC 9000 Section 10.2 requires the draining period to persist for at least
387
+ * three times the current PTO. The valid range is `3` to `255`. Values below
388
+ * `3` are clamped to `3`.
389
+ * @since v26.2.0
390
+ */
391
+ drainingPeriodMultiplier?: number | undefined;
392
+ /**
393
+ * Specifies the keep-alive timeout in milliseconds. When set to a non-zero
394
+ * value, PING frames will be sent automatically to keep the connection alive
395
+ * before the idle timeout fires. The value should be less than the effective
396
+ * idle timeout (`maxIdleTimeout` transport parameter) to be useful.
246
397
  * @since v23.8.0
247
398
  */
248
399
  handshakeTimeout?: bigint | number | undefined;
@@ -253,28 +404,12 @@ declare module "node:quic" {
253
404
  servername?: string | undefined;
254
405
  /**
255
406
  * An object mapping host names to TLS identity options for Server Name
256
- * Indication (SNI) support. This is required for server sessions. The
257
- * special key `'*'` specifies the default/fallback identity used when
258
- * no other host name matches. Each entry may contain:
259
- *
260
- * ```js
261
- * const endpoint = await listen(callback, {
262
- * sni: {
263
- * '*': { keys: [defaultKey], certs: [defaultCert] },
264
- * 'api.example.com': { keys: [apiKey], certs: [apiCert] },
265
- * 'www.example.com': { keys: [wwwKey], certs: [wwwCert], ca: [customCA] },
266
- * },
267
- * });
268
- * ```
269
- *
270
- * Shared TLS options (such as `ciphers`, `groups`, `keylog`, and `verifyClient`)
271
- * are specified at the top level of the session options and apply to all
272
- * identities. Each SNI entry overrides only the per-identity certificate
273
- * fields.
274
- *
275
- * The SNI map can be replaced at runtime using `endpoint.setSNIContexts()`,
276
- * which atomically swaps the map for new sessions while existing sessions
277
- * continue to use their original identity.
407
+ * Indication (SNI) support. This is required for server sessions and must
408
+ * contain at least one entry. The special key `'*'` specifies the optional
409
+ * default/fallback identity used when no other host name matches. If no
410
+ * wildcard entry is provided, connections with unrecognized server names
411
+ * will be rejected with a TLS `unrecognized_name` alert. Each entry may
412
+ * contain:
278
413
  * @since v26.1.0
279
414
  */
280
415
  sni?: Record<string, SNIEntry> | undefined;
@@ -283,6 +418,14 @@ declare module "node:quic" {
283
418
  * @since v23.8.0
284
419
  */
285
420
  tlsTrace?: boolean | undefined;
421
+ /**
422
+ * An opaque address validation token previously received from the server
423
+ * via the `session.onnewtoken` callback. Providing a valid token on
424
+ * reconnection allows the client to skip the server's address validation,
425
+ * reducing handshake latency.
426
+ * @since v26.2.0
427
+ */
428
+ token?: NodeJS.ArrayBufferView | undefined;
286
429
  /**
287
430
  * The QUIC transport parameters to use for the session.
288
431
  * @since v23.8.0
@@ -293,6 +436,27 @@ declare module "node:quic" {
293
436
  * @since v23.8.0
294
437
  */
295
438
  unacknowledgedPacketThreshold?: bigint | number | undefined;
439
+ /**
440
+ * If `true`, the peer certificate is verified against the list of supplied CAs.
441
+ * An error is emitted if verification fails; the error can be inspected via
442
+ * the `validationErrorReason` and `validationErrorCode` fields in the
443
+ * handshake callback. If `false`, peer certificate verification errors are
444
+ * ignored.
445
+ */
446
+ rejectUnauthorized?: boolean | undefined;
447
+ /**
448
+ * When `true` (the default), `connect()` will attempt to reuse an existing
449
+ * endpoint rather than creating a new one for each session. This provides
450
+ * connection pooling behavior — multiple sessions can share a single UDP
451
+ * socket. The reuse logic will not return an endpoint that is listening on
452
+ * the same address as the connect target (to prevent CID routing conflicts).
453
+ *
454
+ * Set to `false` to force creation of a new endpoint for the session. This
455
+ * is useful when endpoint isolation is required (e.g., testing stateless
456
+ * reset behavior where source port identity matters).
457
+ * @since v26.2.0
458
+ */
459
+ reuseEndpoint?: boolean | undefined;
296
460
  /**
297
461
  * True to require verification of TLS client certificate.
298
462
  * @since v23.8.0
@@ -311,6 +475,25 @@ declare module "node:quic" {
311
475
  * @since v23.8.0
312
476
  */
313
477
  version?: number | undefined;
478
+ // Undocumented
479
+ onerror?: QuicSession["onerror"] | undefined;
480
+ onstream?: QuicSession["onstream"] | undefined;
481
+ ondatagram?: QuicSession["ondatagram"] | undefined;
482
+ ondatagramstatus?: QuicSession["ondatagramstatus"] | undefined;
483
+ onpathvalidation?: QuicSession["onpathvalidation"] | undefined;
484
+ onsessionticket?: QuicSession["onsessionticket"] | undefined;
485
+ onversionnegotiation?: QuicSession["onversionnegotiation"] | undefined;
486
+ onhandshake?: QuicSession["onhandshake"] | undefined;
487
+ onnewtoken?: QuicSession["onnewtoken"] | undefined;
488
+ onearlyrejected?: QuicSession["onearlyrejected"] | undefined;
489
+ onorigin?: QuicSession["onorigin"] | undefined;
490
+ ongoaway?: QuicSession["ongoaway"] | undefined;
491
+ onkeylog?: QuicSession["onkeylog"] | undefined;
492
+ onqlog?: QuicSession["onqlog"] | undefined;
493
+ onheaders?: QuicStream["onheaders"] | undefined;
494
+ ontrailers?: QuicStream["ontrailers"] | undefined;
495
+ oninfo?: QuicStream["oninfo"] | undefined;
496
+ onwanttrailers?: QuicStream["onwanttrailers"] | undefined;
314
497
  }
315
498
  /**
316
499
  * Initiate a new client-side session.
@@ -389,26 +572,58 @@ declare module "node:quic" {
389
572
  /**
390
573
  * The endpoint maintains an internal cache of validated socket addresses as a
391
574
  * performance optimization. This option sets the maximum number of addresses
392
- * that are cache. This is an advanced option that users typically won't have
575
+ * that are cached. This is an advanced option that users typically won't have
393
576
  * need to specify.
394
577
  * @since v23.8.0
395
578
  */
396
579
  addressLRUSize?: bigint | number | undefined;
580
+ /**
581
+ * When `true`, the endpoint will not send stateless reset packets in response
582
+ * to packets from unknown connections. Stateless resets allow a peer to detect
583
+ * that a connection has been lost even when the server has no state for it.
584
+ * Disabling them may be useful in testing or when stateless resets are handled
585
+ * at a different layer.
586
+ * @since v26.2.0
587
+ */
588
+ disableStatelessReset?: boolean | undefined;
589
+ /**
590
+ * The number of seconds an endpoint will remain alive after all sessions have
591
+ * closed and it is no longer listening. A value of `0` (default) means the
592
+ * endpoint is only destroyed when explicitly closed via `endpoint.close()` or
593
+ * `endpoint.destroy()`. A positive value starts an idle timer when the endpoint
594
+ * becomes idle; if no new sessions are created before the timer fires, the
595
+ * endpoint is automatically destroyed. This is useful for connection pooling
596
+ * where endpoints should linger briefly for reuse by future `connect()` calls.
597
+ * @since v26.2.0
598
+ */
599
+ idleTimeout?: number | undefined;
397
600
  /**
398
601
  * When `true`, indicates that the endpoint should bind only to IPv6 addresses.
399
602
  * @since v23.8.0
400
603
  */
401
604
  ipv6Only?: boolean | undefined;
402
605
  /**
403
- * Specifies the maximum number of concurrent sessions allowed per remote peer address.
606
+ * Specifies the maximum number of concurrent sessions allowed per remote IP
607
+ * address (ignoring port). When the limit is reached, new connections from the
608
+ * same IP are refused with `CONNECTION_REFUSED`. A value of `0` disables the
609
+ * limit. The maximum value is `65535`.
610
+ *
611
+ * This limit can also be changed dynamically after construction via
612
+ * `endpoint.maxConnectionsPerHost`.
404
613
  * @since v23.8.0
405
614
  */
406
- maxConnectionsPerHost?: bigint | number | undefined;
615
+ maxConnectionsPerHost?: number | undefined;
407
616
  /**
408
- * Specifies the maximum total number of concurrent sessions.
617
+ * Specifies the maximum total number of concurrent sessions across all remote
618
+ * addresses. When the limit is reached, new connections are refused with
619
+ * `CONNECTION_REFUSED`. A value of `0` disables the limit. The maximum value is
620
+ * `65535`.
621
+ *
622
+ * This limit can also be changed dynamically after construction via
623
+ * `endpoint.maxConnectionsTotal`.
409
624
  * @since v23.8.0
410
625
  */
411
- maxConnectionsTotal?: bigint | number | undefined;
626
+ maxConnectionsTotal?: number | undefined;
412
627
  /**
413
628
  * Specifies the maximum number of QUIC retry attempts allowed per remote peer address.
414
629
  * @since v23.8.0
@@ -525,9 +740,25 @@ declare module "node:quic" {
525
740
  readonly destroyed: boolean;
526
741
  /**
527
742
  * True if the endpoint is actively listening for incoming connections. Read only.
528
- * @since v26.1.0
743
+ * @since v26.2.0
529
744
  */
530
745
  readonly listening: boolean;
746
+ /**
747
+ * The maximum number of concurrent connections allowed per remote IP address.
748
+ * `0` means unlimited (default). Can be set at construction time via the
749
+ * `maxConnectionsPerHost` option and changed dynamically at any time.
750
+ * The valid range is `0` to `65535`.
751
+ * @since v26.2.0
752
+ */
753
+ maxConnectionsPerHost: number;
754
+ /**
755
+ * The maximum total number of concurrent connections across all remote
756
+ * addresses. `0` means unlimited (default). Can be set at construction time via
757
+ * the `maxConnectionsTotal` option and changed dynamically at any time.
758
+ * The valid range is `0` to `65535`.
759
+ * @since v26.2.0
760
+ */
761
+ maxConnectionsTotal: number;
531
762
  /**
532
763
  * Replaces or updates the SNI TLS contexts for this endpoint. This allows
533
764
  * changing the TLS identity (key/certificate) used for specific host names
@@ -550,7 +781,7 @@ declare module "node:quic" {
550
781
  */
551
782
  setSNIContexts(entries: Record<string, SNIEntry>, options?: SetSNIContextsOptions): void;
552
783
  /**
553
- * The statistics collected for an active session. Read only.
784
+ * The statistics collected for an active endpoint. Read only.
554
785
  * @since v23.8.0
555
786
  */
556
787
  readonly stats: QuicEndpoint.Stats;
@@ -620,7 +851,7 @@ declare module "node:quic" {
620
851
  */
621
852
  readonly retryCount: bigint;
622
853
  /**
623
- * The total number sessions rejected due to QUIC version mismatch. Read only.
854
+ * The total number of sessions rejected due to QUIC version mismatch. Read only.
624
855
  * @since v23.8.0
625
856
  */
626
857
  readonly versionNegotiationCount: bigint;
@@ -637,8 +868,124 @@ declare module "node:quic" {
637
868
  }
638
869
  }
639
870
  interface CreateStreamOptions {
640
- body?: ArrayBuffer | NodeJS.ArrayBufferView | Blob | undefined;
641
- sendOrder?: number | undefined;
871
+ /**
872
+ * The outbound body source. See `stream.setBody()` for details on
873
+ * supported types. When omitted, the stream starts half-closed (writable
874
+ * side open, no body queued).
875
+ */
876
+ body?: StreamBody | undefined;
877
+ /**
878
+ * Initial request or response headers to send. Only
879
+ * used when the session supports headers (e.g. HTTP/3). If `body` is not
880
+ * specified and `headers` is provided, the stream is treated as
881
+ * headers-only (terminal).
882
+ */
883
+ headers?: NodeJS.Dict<string | readonly string[]> | readonly string[] | undefined;
884
+ /**
885
+ * The priority level of the stream. One of `'high'`,
886
+ * `'default'`, or `'low'`. **Default:** `'default'`.
887
+ */
888
+ priority?: "high" | "default" | "low" | undefined;
889
+ /**
890
+ * When `true`, data from this stream may be
891
+ * interleaved with data from other streams of the same priority level.
892
+ * When `false`, the stream should be completed before same-priority peers.
893
+ * **Default:** `false`.
894
+ */
895
+ incremental?: boolean | undefined;
896
+ /**
897
+ * The maximum number of bytes that the writer
898
+ * will buffer before `writeSync()` returns `false`. When the buffered
899
+ * data exceeds this limit, the caller should wait for drain before
900
+ * writing more. **Default:** `65536` (64 KB).
901
+ */
902
+ highWaterMark?: number | undefined;
903
+ /**
904
+ * Callback for received initial response headers.
905
+ * Called with `(headers)`.
906
+ */
907
+ onheaders?: QuicStream["onheaders"] | undefined;
908
+ /**
909
+ * Callback for received trailing headers.
910
+ * Called with `(trailers)`.
911
+ */
912
+ ontrailers?: QuicStream["ontrailers"] | undefined;
913
+ /**
914
+ * Callback for received informational (1xx) headers.
915
+ * Called with `(headers)`.
916
+ */
917
+ oninfo?: QuicStream["oninfo"] | undefined;
918
+ /**
919
+ * Callback when trailers should be sent.
920
+ */
921
+ onwanttrailers?: QuicStream["onwanttrailers"] | undefined;
922
+ }
923
+ interface SessionDestroyOptions {
924
+ /**
925
+ * The error code to include in the `CONNECTION_CLOSE`
926
+ * frame sent to the peer. **Default:** `0` (no error).
927
+ */
928
+ code?: bigint | number | undefined;
929
+ /**
930
+ * Either `'transport'` or `'application'`. Determines the
931
+ * error code namespace used in the `CONNECTION_CLOSE` frame. When `'transport'`
932
+ * (the default), the frame type is `0x1c` and the code is interpreted as a QUIC
933
+ * transport error. When `'application'`, the frame type is `0x1d` and the code
934
+ * is application-specific. **Default:** `'transport'`.
935
+ */
936
+ type?: "transport" | "application" | undefined;
937
+ /**
938
+ * An optional human-readable reason string included in
939
+ * the `CONNECTION_CLOSE` frame. Per RFC 9000, this is for diagnostic purposes
940
+ * only and should not be used for machine-readable error descriptions.
941
+ */
942
+ reason?: string | undefined;
943
+ }
944
+ interface SessionHandshakeInfo {
945
+ /**
946
+ * The local socket address.
947
+ */
948
+ local: SocketAddress;
949
+ /**
950
+ * The remote socket address.
951
+ */
952
+ remote: SocketAddress;
953
+ /**
954
+ * The SNI server name negotiated during the handshake.
955
+ */
956
+ servername: string;
957
+ /**
958
+ * The ALPN protocol negotiated during the handshake.
959
+ */
960
+ protocol: string;
961
+ /**
962
+ * The name of the negotiated TLS cipher suite.
963
+ */
964
+ cipher: string;
965
+ /**
966
+ * The TLS protocol version of the cipher suite
967
+ * (e.g., `'TLSv1.3'`).
968
+ */
969
+ cipherVersion: string;
970
+ /**
971
+ * If certificate validation failed, the
972
+ * reason string. Empty string if validation succeeded.
973
+ */
974
+ validationErrorReason: string;
975
+ /**
976
+ * If certificate validation failed, the
977
+ * error code. `0` if validation succeeded.
978
+ */
979
+ validationErrorCode: number;
980
+ /**
981
+ * Whether 0-RTT early data was attempted.
982
+ */
983
+ earlyDataAttempted: boolean;
984
+ /**
985
+ * Whether 0-RTT early data was accepted by
986
+ * the server.
987
+ */
988
+ earlyDataAccepted: boolean;
642
989
  }
643
990
  interface SessionPath {
644
991
  local: SocketAddress;
@@ -654,36 +1001,85 @@ declare module "node:quic" {
654
1001
  * Initiate a graceful close of the session. Existing streams will be allowed
655
1002
  * to complete but no new streams will be opened. Once all streams have closed,
656
1003
  * the session will be destroyed. The returned promise will be fulfilled once
657
- * the session has been destroyed.
1004
+ * the session has been destroyed. If a non-zero `code` is specified, the
1005
+ * promise will reject with an `ERR_QUIC_TRANSPORT_ERROR` or
1006
+ * `ERR_QUIC_APPLICATION_ERROR` depending on the `type`.
658
1007
  * @since v23.8.0
659
1008
  */
660
- close(): Promise<void>;
1009
+ close(options?: SessionDestroyOptions): Promise<void>;
1010
+ /**
1011
+ * A promise that is fulfilled once the TLS handshake completes successfully.
1012
+ * The resolved value contains information about the established session
1013
+ * including the negotiated protocol, cipher suite, certificate validation
1014
+ * status, and 0-RTT early data status.
1015
+ *
1016
+ * If the handshake fails or the session is destroyed before the handshake
1017
+ * completes, the promise will be rejected.
1018
+ * @since v26.2.0
1019
+ */
1020
+ readonly opened: Promise<SessionHandshakeInfo>;
661
1021
  /**
662
1022
  * A promise that is fulfilled once the session is destroyed.
663
1023
  * @since v23.8.0
664
1024
  */
665
1025
  readonly closed: Promise<void>;
666
1026
  /**
667
- * Immediately destroy the session. All streams will be destroys and the
668
- * session will be closed.
1027
+ * True if `session.close()` has been called and the session has not yet
1028
+ * been destroyed. Read only.
1029
+ * @since v26.2.0
1030
+ */
1031
+ readonly closing: boolean;
1032
+ /**
1033
+ * Immediately destroy the session. All streams will be destroyed and the
1034
+ * session will be closed. If `error` is provided and [`session.onerror`][] is
1035
+ * set, the `onerror` callback is invoked before destruction. The
1036
+ * `session.closed` promise will reject with the error. If `options` is
1037
+ * provided, the `CONNECTION_CLOSE` frame sent to the peer will include the
1038
+ * specified error code, type, and reason.
669
1039
  * @since v23.8.0
670
1040
  */
671
- destroy(error?: any): void;
1041
+ destroy(error?: any, options?: SessionDestroyOptions): void;
672
1042
  /**
673
1043
  * True if `session.destroy()` has been called. Read only.
674
1044
  * @since v23.8.0
675
1045
  */
676
1046
  readonly destroyed: boolean;
677
1047
  /**
678
- * The endpoint that created this session. Read only.
1048
+ * The endpoint that created this session. Returns `null` if the session
1049
+ * has been destroyed. Read only.
679
1050
  * @since v23.8.0
680
1051
  */
681
- readonly endpoint: QuicEndpoint;
1052
+ readonly endpoint: QuicEndpoint | null;
1053
+ /**
1054
+ * An optional callback invoked when the session is destroyed with an error.
1055
+ * This includes errors caused by user callbacks that throw or reject (see
1056
+ * [Callback error handling](https://nodejs.org/docs/latest-v26.x/api/quic.html#callback-error-handling)). The callback receives a single argument: the
1057
+ * error that triggered the destruction. If the `onerror` callback itself throws
1058
+ * or returns a promise that rejects, the error is surfaced as an uncaught
1059
+ * exception. Read/write.
1060
+ *
1061
+ * Can also be set via the `onerror` option in `quic.connect()` or
1062
+ * `quic.listen()`.
1063
+ * @since v26.2.0
1064
+ */
1065
+ onerror: ((this: QuicSession, error: any) => void) | undefined;
682
1066
  /**
683
1067
  * The callback to invoke when a new stream is initiated by a remote peer. Read/write.
684
1068
  * @since v23.8.0
685
1069
  */
686
1070
  onstream: OnStreamCallback | undefined;
1071
+ /**
1072
+ * The callback to invoke when the server rejects 0-RTT early data. When
1073
+ * this fires, all streams that were opened during the 0-RTT phase have
1074
+ * been destroyed. The application should re-open streams if needed.
1075
+ * Read/write.
1076
+ *
1077
+ * This callback only fires on the client side when the server rejects
1078
+ * the client's 0-RTT attempt. The connection falls back to 1-RTT and
1079
+ * continues normally.
1080
+ * @since v26.2.0
1081
+ */
1082
+ onearlyrejected: ((this: QuicSession) => void) | undefined;
687
1083
  /**
688
1084
  * The callback to invoke when a new datagram is received from a remote peer. Read/write.
689
1085
  * @since v23.8.0
@@ -714,15 +1110,81 @@ declare module "node:quic" {
714
1110
  * @since v23.8.0
715
1111
  */
716
1112
  onhandshake: OnHandshakeCallback | undefined;
1113
+ /**
1114
+ * The callback to invoke when a NEW\_TOKEN token is received from the server.
1115
+ * The token can be passed as the `token` option on a future connection to
1116
+ * the same server to skip address validation. Read/write.
1117
+ * @since v26.2.0
1118
+ */
1119
+ onnewtoken: OnNewTokenCallback | undefined;
1120
+ /**
1121
+ * The callback to invoke when an ORIGIN frame (RFC 9412) is received from
1122
+ * the server, indicating which origins the server is authoritative for.
1123
+ * Read/write.
1124
+ * @since v26.2.0
1125
+ */
1126
+ onorigin: OnOriginCallback | undefined;
1127
+ /**
1128
+ * The callback to invoke when the peer sends an HTTP/3 GOAWAY frame,
1129
+ * indicating it is initiating a graceful shutdown. The callback receives
1130
+ * `(lastStreamId)` where `lastStreamId` is a `{bigint}`:
1131
+ *
1132
+ * * When `lastStreamId` is `-1n`, the peer sent a shutdown notice (intent
1133
+ * to close) without specifying a stream boundary. All existing streams
1134
+ * may still be processed.
1135
+ * * When `lastStreamId` is `>= 0n`, it is the highest stream ID the peer
1136
+ * may have processed. Streams with IDs above this value were NOT
1137
+ * processed and can be safely retried on a new connection.
1138
+ *
1139
+ * After GOAWAY is received, `session.createBidirectionalStream()` will
1140
+ * throw `ERR_INVALID_STATE`. Existing streams continue until they
1141
+ * complete or the session closes.
1142
+ *
1143
+ * This callback is only relevant for HTTP/3 sessions. Read/write.
1144
+ * @since v26.2.0
1145
+ */
1146
+ ongoaway: ((this: QuicSession, lastStreamId: bigint) => void) | undefined;
1147
+ /**
1148
+ * The callback to invoke when TLS key material is available. Requires
1149
+ * `sessionOptions.keylog` to be `true`. Each invocation receives a single
1150
+ * line of [NSS Key Log Format](https://udn.realityripple.com/docs/Mozilla/Projects/NSS/Key_Log_Format) text (including a trailing newline). This is
1151
+ * useful for decrypting packet captures with tools like Wireshark. Read/write.
1152
+ *
1153
+ * Can also be set via the `onkeylog` option in `quic.connect()` or
1154
+ * `quic.listen()`.
1155
+ * @since v26.2.0
1156
+ */
1157
+ onkeylog: OnKeylogCallback | undefined;
1158
+ /**
1159
+ * The callback to invoke when qlog data is available. Requires
1160
+ * `sessionOptions.qlog` to be `true`. The callback receives a string
1161
+ * chunk of [JSON-SEQ](https://www.rfc-editor.org/rfc/rfc7464) formatted qlog data and a boolean `fin` flag. When
1162
+ * `fin` is `true`, the chunk is the final qlog output for this session and
1163
+ * the concatenated chunks form a complete qlog trace. Read/write.
1164
+ *
1165
+ * Qlog data arrives during the connection lifecycle. The first chunk contains
1166
+ * the qlog header with format metadata. Subsequent chunks contain trace
1167
+ * events. The final chunk (with `fin` set to `true`) is emitted during
1168
+ * session destruction and completes the JSON-SEQ output.
1169
+ *
1170
+ * Can also be set via the `onqlog` option in `quic.connect()` or
1171
+ * `quic.listen()`.
1172
+ * @since v26.2.0
1173
+ */
1174
+ onqlog: OnQlogCallback | undefined;
717
1175
  /**
718
1176
  * Open a new bidirectional stream. If the `body` option is not specified,
719
- * the outgoing stream will be half-closed.
1177
+ * the outgoing stream will be half-closed. The `priority` and `incremental`
1178
+ * options are only used when the session supports priority (e.g. HTTP/3).
1179
+ * The `headers`, `onheaders`, `ontrailers`, `oninfo`, and `onwanttrailers`
1180
+ * options are only used when the session supports headers (e.g. HTTP/3).
720
1181
  * @since v23.8.0
721
1182
  */
722
1183
  createBidirectionalStream(options?: CreateStreamOptions): Promise<QuicStream>;
723
1184
  /**
724
1185
  * Open a new unidirectional stream. If the `body` option is not specified,
725
- * the outgoing stream will be closed.
1186
+ * the outgoing stream will be closed. The `priority` and `incremental`
1187
+ * options are only used when the session supports priority (e.g. HTTP/3).
726
1188
  * @since v23.8.0
727
1189
  */
728
1190
  createUnidirectionalStream(options?: CreateStreamOptions): Promise<QuicStream>;
@@ -732,12 +1194,92 @@ declare module "node:quic" {
732
1194
  */
733
1195
  path: SessionPath | undefined;
734
1196
  /**
735
- * Sends an unreliable datagram to the remote peer, returning the datagram ID.
736
- * If the datagram payload is specified as an `ArrayBufferView`, then ownership of
737
- * that view will be transferred to the underlying stream.
738
- * @since v23.8.0
1197
+ * Sends an unreliable datagram to the remote peer, returning a promise for
1198
+ * the datagram ID.
1199
+ *
1200
+ * If `datagram` is a string, it will be encoded using the specified `encoding`.
1201
+ *
1202
+ * If `datagram` is an `ArrayBufferView`, the bytes are copied into an
1203
+ * internal buffer; the caller's source buffer is unchanged and may be reused
1204
+ * or mutated immediately after the call returns. Callers that want to ensure
1205
+ * their source cannot be mutated after the call (for example, when handing
1206
+ * the buffer off to another async consumer) can call
1207
+ * `ArrayBuffer.prototype.transfer()` themselves before passing the buffer.
1208
+ *
1209
+ * If `datagram` is a `Promise`, it will be awaited before sending. If the
1210
+ * session closes while awaiting, `0n` is returned silently (datagrams are
1211
+ * inherently unreliable).
1212
+ *
1213
+ * If the datagram payload is zero-length (empty string after encoding, detached
1214
+ * buffer, or zero-length view), `0n` is returned and no datagram is sent.
1215
+ *
1216
+ * For HTTP/3 sessions, the peer must advertise `SETTINGS_H3_DATAGRAM=1`
1217
+ * (via `application: { enableDatagrams: true }`) for datagrams to be sent.
1218
+ * If the peer's setting is `0`, `sendDatagram()` returns `0n` (per RFC 9297
1219
+ * §3, an endpoint MUST NOT send HTTP Datagrams unless the peer indicated
1220
+ * support).
1221
+ *
1222
+ * Datagrams cannot be fragmented — each must fit within a single QUIC packet.
1223
+ * The maximum datagram size is determined by the peer's
1224
+ * `maxDatagramFrameSize` transport parameter (which the peer advertises during
1225
+ * the handshake). If the peer sets this to `0`, datagrams are not supported
1226
+ * and `0n` will be returned. If the datagram exceeds the peer's limit, it
1227
+ * will be silently dropped and `0n` returned. The local
1228
+ * `maxDatagramFrameSize` transport parameter (default: `1200` bytes) controls
1229
+ * what this endpoint advertises to the peer as its own maximum.
1230
+ * @since v23.8.0
1231
+ * @param encoding The encoding to use if `datagram` is a string.
1232
+ * **Default:** `'utf8'`.
1233
+ */
1234
+ sendDatagram(
1235
+ datagram: string | NodeJS.ArrayBufferView | Promise<string | NodeJS.ArrayBufferView>,
1236
+ encoding?: BufferEncoding,
1237
+ ): Promise<bigint>;
1238
+ /**
1239
+ * The local certificate as an object with properties such as `subject`,
1240
+ * `issuer`, `valid_from`, `valid_to`, `fingerprint`, etc. Returns `undefined`
1241
+ * if the session is destroyed or no certificate is available.
1242
+ * @since v26.2.0
1243
+ */
1244
+ readonly certificate: PeerCertificate | undefined;
1245
+ /**
1246
+ * The peer's certificate as an object with properties such as `subject`,
1247
+ * `issuer`, `valid_from`, `valid_to`, `fingerprint`, etc. Returns `undefined`
1248
+ * if the session is destroyed or the peer did not present a certificate.
1249
+ * @since v26.2.0
1250
+ */
1251
+ readonly peerCertificate: PeerCertificate | undefined;
1252
+ /**
1253
+ * The ephemeral key information for the session, with properties such as
1254
+ * `type`, `name`, and `size`. Only available on client sessions. Returns
1255
+ * `undefined` for server sessions or if the session is destroyed.
1256
+ * @since v26.2.0
1257
+ */
1258
+ readonly ephemeralKeyInfo: EphemeralKeyInfo | undefined;
1259
+ /**
1260
+ * The maximum datagram payload size in bytes that the peer will accept.
1261
+ * This is derived from the peer's `maxDatagramFrameSize` transport
1262
+ * parameter minus the DATAGRAM frame overhead (type byte and variable-length
1263
+ * integer encoding). Returns `0` if the peer does not support datagrams or
1264
+ * if the handshake has not yet completed. Datagrams larger than this value
1265
+ * will not be sent.
1266
+ * @since v26.2.0
1267
+ */
1268
+ readonly maxDatagramSize: number;
1269
+ /**
1270
+ * The maximum number of datagrams that can be queued for sending. Datagrams
1271
+ * are queued when `sendDatagram()` is called and sent opportunistically
1272
+ * alongside stream data by the packet serialization loop. When the queue
1273
+ * is full, the `sessionOptions.datagramDropPolicy` determines whether
1274
+ * the oldest or newest datagram is dropped. Dropped datagrams are reported
1275
+ * as lost via the `ondatagramstatus` callback.
1276
+ *
1277
+ * This property can be changed dynamically to adjust queue capacity
1278
+ * based on application activity or memory pressure. The valid range
1279
+ * is `0` to `65535`.
1280
+ * @since v26.2.0
739
1281
  */
740
- sendDatagram(datagram: string | NodeJS.ArrayBufferView): bigint;
1282
+ maxPendingDatagrams: number;
741
1283
  /**
742
1284
  * Return the current statistics for the session. Read only.
743
1285
  * @since v23.8.0
@@ -804,7 +1346,7 @@ declare module "node:quic" {
804
1346
  /**
805
1347
  * @since v23.8.0
806
1348
  */
807
- readonly maxBytesInFlights: bigint;
1349
+ readonly maxBytesInFlight: bigint;
808
1350
  /**
809
1351
  * @since v23.8.0
810
1352
  */
@@ -855,55 +1397,458 @@ declare module "node:quic" {
855
1397
  readonly datagramsLost: bigint;
856
1398
  }
857
1399
  }
1400
+ interface QuicErrorOptions {
1401
+ /**
1402
+ * The numeric QUIC error code. Numbers
1403
+ * are coerced to `BigInt`. Must be a non-negative 62-bit unsigned
1404
+ * varint (`0n <= errorCode <= 2n ** 62n - 1n`).
1405
+ */
1406
+ errorCode?: bigint | number | undefined;
1407
+ /**
1408
+ * The Node.js-style error code string assigned to
1409
+ * `error.code`. Defaults to `'ERR_QUIC_STREAM_ABORTED'`.
1410
+ */
1411
+ code?: string | undefined;
1412
+ /**
1413
+ * Either `'application'` (default) or `'transport'`.
1414
+ * Indicates whether the code is defined by the negotiated
1415
+ * application protocol (e.g. RFC 9114 for HTTP/3) or by the QUIC
1416
+ * transport layer (RFC 9000). Stream resets always carry application
1417
+ * codes, so the default is `'application'`.
1418
+ */
1419
+ type?: "application" | "transport" | undefined;
1420
+ }
1421
+ /**
1422
+ * A `QuicError` is an `Error` subclass that carries an explicit numeric
1423
+ * QUIC error code. Use it to abort a QUIC stream or session with a
1424
+ * specific application-protocol-defined error code rather than letting
1425
+ * the implementation pick a generic fallback.
1426
+ *
1427
+ * The class is exported from `node:quic`:
1428
+ *
1429
+ * ```js
1430
+ * import { QuicError } from 'node:quic';
1431
+ * ```
1432
+ *
1433
+ * When a `QuicError` is supplied to APIs that emit a wire frame
1434
+ * (`writer.fail()`, `stream.destroy()`), the QUIC stack uses
1435
+ * `error.errorCode` as the wire code for the resulting frame.
1436
+ * When any other value is supplied (for example a plain `Error`), the
1437
+ * implementation falls back to the negotiated application protocol's
1438
+ * "internal error" code (`H3_INTERNAL_ERROR` (`0x102`) for HTTP/3, or
1439
+ * the QUIC transport-layer `INTERNAL_ERROR` (`0x1`) for raw QUIC).
1440
+ *
1441
+ * The Node.js error code (`error.code`) defaults to
1442
+ * `'ERR_QUIC_STREAM_ABORTED'`. Callers who need a more specific code
1443
+ * string can override it via `options.code` — the numeric QUIC code
1444
+ * is unaffected.
1445
+ *
1446
+ * The Node.js error code is fixed at `'ERR_QUIC_STREAM_ABORTED'` so that
1447
+ * catch blocks can distinguish a `QuicError` from other Node.js errors
1448
+ * without checking the prototype chain. The numeric QUIC code lives on
1449
+ * the separate `error.errorCode` property to avoid colliding with
1450
+ * the Node.js convention that `error.code` is a string.
1451
+ * @since v26.2.0
1452
+ * @experimental
1453
+ */
1454
+ class QuicError extends Error {
1455
+ /**
1456
+ * ```js
1457
+ * import { QuicError } from 'node:quic';
1458
+ *
1459
+ * const err = new QuicError('rejecting stream', { errorCode: 0x10cn });
1460
+ * console.log(err.code); // 'ERR_QUIC_STREAM_ABORTED'
1461
+ * console.log(err.errorCode); // 268n
1462
+ * console.log(err.type); // 'application'
1463
+ *
1464
+ * const custom = new QuicError('custom failure', {
1465
+ * errorCode: 0x10cn,
1466
+ * code: 'ERR_MY_QUIC_FAILURE',
1467
+ * });
1468
+ * console.log(custom.code); // 'ERR_MY_QUIC_FAILURE'
1469
+ * ```
1470
+ * @param message A human-readable description of the error.
1471
+ */
1472
+ constructor(message: string, options?: QuicErrorOptions);
1473
+ /**
1474
+ * The numeric QUIC error code carried by this error.
1475
+ * @since v26.2.0
1476
+ */
1477
+ readonly errorCode: bigint;
1478
+ /**
1479
+ * Either `'application'` or `'transport'`. Indicates the namespace of
1480
+ * `error.errorCode`.
1481
+ * @since v26.2.0
1482
+ */
1483
+ readonly type: "application" | "transport";
1484
+ }
1485
+ type StreamBody =
1486
+ | null
1487
+ | string
1488
+ | ArrayBufferLike
1489
+ | NodeJS.ArrayBufferView
1490
+ | Blob
1491
+ | FileHandle
1492
+ | Iterable<string | Uint8Array>
1493
+ | AsyncIterable<string | Uint8Array>
1494
+ | Promise<StreamBody>;
1495
+ interface StreamPriority {
1496
+ /**
1497
+ * One of `'high'`, `'default'`, or `'low'`.
1498
+ */
1499
+ level: "high" | "default" | "low";
1500
+ /**
1501
+ * Whether the stream data should be interleaved
1502
+ * with other streams of the same priority level.
1503
+ */
1504
+ incremental: boolean;
1505
+ }
1506
+ interface StreamDestroyOptions {
1507
+ /**
1508
+ * The application error code to include in the
1509
+ * `RESET_STREAM` and `STOP_SENDING` frames sent to the peer. Numbers are
1510
+ * coerced to `BigInt`. When omitted, the wire code is derived from `error`
1511
+ * (see below).
1512
+ */
1513
+ code?: bigint | number | undefined;
1514
+ /**
1515
+ * An optional human-readable reason string. Accepted for
1516
+ * symmetry with `session.close()` and `session.destroy()`, but
1517
+ * **not transmitted on the wire** — neither `RESET_STREAM` nor
1518
+ * `STOP_SENDING` carry a reason field. Provided for application logging
1519
+ * and for use by the `stream.onerror` callback.
1520
+ */
1521
+ reason?: string | undefined;
1522
+ }
1523
+ interface StreamSendHeadersOptions {
1524
+ /**
1525
+ * If `true`, the stream is closed for sending
1526
+ * after the headers (no body will follow). **Default:** `false`.
1527
+ */
1528
+ terminal?: boolean | undefined;
1529
+ }
858
1530
  /**
859
1531
  * @since v23.8.0
860
1532
  */
861
1533
  class QuicStream {
862
1534
  private constructor();
863
1535
  /**
864
- * A promise that is fulfilled when the stream is fully closed.
1536
+ * A promise that is fulfilled when the stream is fully closed. It resolves
1537
+ * when the stream closes cleanly (including idle timeout). It rejects with
1538
+ * an `ERR_QUIC_APPLICATION_ERROR` or `ERR_QUIC_TRANSPORT_ERROR` when the
1539
+ * stream is closed due to a QUIC error (e.g., stream reset by the peer,
1540
+ * CONNECTION\_CLOSE with a non-zero error code).
865
1541
  * @since v23.8.0
866
1542
  */
867
1543
  readonly closed: Promise<void>;
868
1544
  /**
869
- * Immediately and abruptly destroys the stream.
1545
+ * Immediately and abruptly destroys the stream. If `error` is provided and
1546
+ * `stream.onerror` is set, the `onerror` callback is invoked before
1547
+ * destruction. The `stream.closed` promise rejects with the error.
1548
+ *
1549
+ * When the stream is destroyed with an `error` (or with an explicit
1550
+ * `options.code`), the QUIC stack signals the abort to the peer:
1551
+ *
1552
+ * * If the writable side is still open, a `RESET_STREAM` frame is sent.
1553
+ * * If the readable side is still open (a bidirectional stream, or a
1554
+ * remote-initiated unidirectional stream), a `STOP_SENDING` frame is sent.
1555
+ *
1556
+ * Both frames carry the same wire code, resolved with the following
1557
+ * precedence:
1558
+ *
1559
+ * 1. `options.code`, when explicitly provided.
1560
+ * 2. [`error.errorCode`][], when `error` is a [`QuicError`][].
1561
+ * 3. The negotiated application protocol's "internal error" code
1562
+ * (`H3_INTERNAL_ERROR` (`0x102`) for HTTP/3, or the QUIC transport-layer
1563
+ * `INTERNAL_ERROR` (`0x1`) for raw QUIC).
1564
+ *
1565
+ * A clean destroy — no `error` and no `options.code` — does not emit
1566
+ * `RESET_STREAM` or `STOP_SENDING`; the stream's existing close machinery
1567
+ * handles teardown.
1568
+ *
1569
+ * 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
1570
+ * APIs.
870
1571
  * @since v23.8.0
871
1572
  */
872
- destroy(error?: any): void;
1573
+ destroy(error?: any, options?: StreamDestroyOptions): void;
873
1574
  /**
874
1575
  * True if `stream.destroy()` has been called.
875
1576
  * @since v23.8.0
876
1577
  */
877
1578
  readonly destroyed: boolean;
878
1579
  /**
879
- * The directionality of the stream. Read only.
1580
+ * True if any data on this stream was received as 0-RTT (early data)
1581
+ * before the TLS handshake completed. Early data is less secure and
1582
+ * could potentially be replayed by an attacker. Applications should
1583
+ * treat early data with appropriate caution.
1584
+ *
1585
+ * This property is only meaningful on the server side. On the client
1586
+ * side, it is always `false`.
1587
+ * @since v26.2.0
1588
+ */
1589
+ readonly early: boolean;
1590
+ /**
1591
+ * The directionality of the stream, or `null` if the stream has been destroyed
1592
+ * or is still pending. Read only.
880
1593
  * @since v23.8.0
881
1594
  */
882
- readonly direction: "bidi" | "uni";
1595
+ readonly direction: "bidi" | "uni" | null;
1596
+ /**
1597
+ * The maximum number of bytes that the writer will buffer before
1598
+ * `writeSync()` returns `false`. When the buffered data exceeds this limit,
1599
+ * the caller should wait for drain before writing more.
1600
+ *
1601
+ * The value can be changed dynamically at any time. This is particularly
1602
+ * useful for streams received via the `onstream` callback, where the
1603
+ * default (65536) may need to be adjusted based on application needs.
1604
+ * The valid range is `0` to `4294967295`.
1605
+ * @since v26.2.0
1606
+ */
1607
+ highWaterMark: number;
883
1608
  /**
884
- * The stream ID. Read only.
1609
+ * The stream ID, or `null` if the stream has been destroyed or is still
1610
+ * pending. Read only.
885
1611
  * @since v23.8.0
886
1612
  */
887
- readonly id: bigint;
1613
+ readonly id: bigint | null;
1614
+ /**
1615
+ * An optional callback invoked when the stream is destroyed with an error.
1616
+ * This includes errors caused by user callbacks that throw or reject (see
1617
+ * [Callback error handling](https://nodejs.org/docs/latest-26.x/api/quic.html#callback-error-handling)). The callback receives a single argument: the
1618
+ * error that triggered the destruction. If the `onerror` callback itself throws
1619
+ * or returns a promise that rejects, the error is surfaced as an uncaught
1620
+ * exception. Read/write.
1621
+ * @since v26.2.0
1622
+ */
1623
+ onerror: ((this: QuicStream, error: any) => void) | undefined;
888
1624
  /**
889
1625
  * The callback to invoke when the stream is blocked. Read/write.
890
1626
  * @since v23.8.0
891
1627
  */
892
1628
  onblocked: OnBlockedCallback | undefined;
893
1629
  /**
894
- * The callback to invoke when the stream is reset. Read/write.
1630
+ * The callback to invoke when the peer aborts a direction of the stream by
1631
+ * sending a `RESET_STREAM` frame (the peer abandons their writable side, so
1632
+ * no further data will arrive on our readable side) or a `STOP_SENDING`
1633
+ * frame (the peer asks us to stop writing on our writable side).
1634
+ *
1635
+ * The callback receives a Node.js error whose `errorCode` (`bigint`)
1636
+ * property carries the application error code from the wire frame.
1637
+ *
1638
+ * The stream is **not** automatically destroyed when this callback fires —
1639
+ * the application chooses how to react. Common patterns are: ignore (and
1640
+ * continue using the still-active direction on a bidirectional stream),
1641
+ * abort the other direction with `writer.fail()`, or tear down the
1642
+ * whole stream with `stream.destroy()`. Read/write.
895
1643
  * @since v23.8.0
896
1644
  */
897
1645
  onreset: OnStreamErrorCallback | undefined;
898
1646
  /**
899
- * @since v23.8.0
1647
+ * The buffered initial headers received on this stream, or `undefined` if the
1648
+ * application does not support headers or no headers have been received yet.
1649
+ * For server-side streams, this contains the request headers (e.g., `:method`,
1650
+ * `:path`, `:scheme`). For client-side streams, this contains the response
1651
+ * headers (e.g., `:status`).
1652
+ *
1653
+ * Header names are lowercase strings. Multi-value headers are represented as
1654
+ * arrays. The object has `__proto__: null`.
1655
+ * @since v26.2.0
1656
+ */
1657
+ readonly headers: NodeJS.Dict<string | string[]> | undefined;
1658
+ /**
1659
+ * The callback to invoke when initial headers are received on the stream. The
1660
+ * callback receives `(headers)` where `headers` is an object (same format as
1661
+ * `stream.headers`). For HTTP/3, this delivers request pseudo-headers on the
1662
+ * server side and response headers on the client side. Throws
1663
+ * `ERR_INVALID_STATE` if set on a session that does not support headers.
1664
+ * Read/write.
1665
+ * @since v26.2.0
1666
+ */
1667
+ onheaders: ((this: QuicStream, headers: NodeJS.Dict<string | string[]>) => void) | undefined;
1668
+ /**
1669
+ * The callback to invoke when trailing headers are received from the peer.
1670
+ * The callback receives `(trailers)` where `trailers` is an object in the
1671
+ * same format as `stream.headers`. Throws `ERR_INVALID_STATE` if set on a
1672
+ * session that does not support headers. Read/write.
1673
+ * @since v26.2.0
1674
+ */
1675
+ ontrailers: ((this: QuicStream, trailers: NodeJS.Dict<string | string[]>) => void) | undefined;
1676
+ /**
1677
+ * The callback to invoke when informational (1xx) headers are received from
1678
+ * the server. The callback receives `(headers)` where `headers` is an object
1679
+ * in the same format as `stream.headers`. Informational headers are sent
1680
+ * before the final response (e.g., 103 Early Hints). Throws
1681
+ * `ERR_INVALID_STATE` if set on a session that does not support headers.
1682
+ * Read/write.
1683
+ * @since v26.2.0
1684
+ */
1685
+ oninfo: ((this: QuicStream, headers: NodeJS.Dict<string | string[]>) => void) | undefined;
1686
+ /**
1687
+ * The callback to invoke when the application is ready for trailing headers
1688
+ * to be sent. This is called synchronously — the user must call
1689
+ * `stream.sendTrailers()` within this callback. Throws
1690
+ * `ERR_INVALID_STATE` if set on a session that does not support headers.
1691
+ * Read/write.
1692
+ * @since v26.2.0
1693
+ */
1694
+ onwanttrailers: ((this: QuicStream) => void) | undefined;
1695
+ /**
1696
+ * Set trailing headers to be sent automatically when the application requests
1697
+ * them. This is an alternative to the `stream.onwanttrailers` callback
1698
+ * for cases where the trailers are known before the body completes. Throws
1699
+ * `ERR_INVALID_STATE` if set on a session that does not support headers.
1700
+ * Read/write.
1701
+ * @since v26.2.0
1702
+ */
1703
+ pendingTrailers: NodeJS.Dict<string | string[]> | undefined;
1704
+ /**
1705
+ * Sends initial or response headers on the stream. For client-side streams,
1706
+ * this sends request headers. For server-side streams, this sends response
1707
+ * headers. Throws `ERR_INVALID_STATE` if the session does not support headers.
1708
+ * @since v26.2.0
1709
+ * @param headers Header object with string keys and string or
1710
+ * string-array values. Pseudo-headers (`:method`, `:path`, etc.) must
1711
+ * appear before regular headers.
1712
+ */
1713
+ sendHeaders(headers: NodeJS.Dict<string | string[]>, options?: StreamSendHeadersOptions): boolean;
1714
+ /**
1715
+ * Sends informational (1xx) response headers. Server only. Throws
1716
+ * `ERR_INVALID_STATE` if the session does not support headers.
1717
+ * @since v26.2.0
1718
+ * @param headers Header object. Must include `:status` with a 1xx
1719
+ * value (e.g., `{ ':status': '103', 'link': '</style.css>; rel=preload' }`).
1720
+ */
1721
+ sendInformationalHeaders(headers: NodeJS.Dict<string | string[]>): boolean;
1722
+ /**
1723
+ * Sends trailing headers on the stream. Must be called synchronously during
1724
+ * the `stream.onwanttrailers` callback, or set ahead of time via
1725
+ * `stream.pendingTrailers`. Throws `ERR_INVALID_STATE` if the session
1726
+ * does not support headers.
1727
+ * @since v26.2.0
1728
+ * @param headers Trailing header object. Pseudo-headers must not be
1729
+ * included in trailers.
1730
+ */
1731
+ sendTrailers(headers: NodeJS.Dict<string | string[]>): boolean;
1732
+ /**
1733
+ * The current priority of the stream. Returns `null` if the session does not
1734
+ * support priority (e.g. non-HTTP/3) or if the stream has been destroyed.
1735
+ * Read only. Use `stream.setPriority()` to change the priority.
1736
+ *
1737
+ * On client-side HTTP/3 sessions, the value reflects what was set via
1738
+ * `stream.setPriority()`. On server-side HTTP/3 sessions, the value
1739
+ * reflects the peer's requested priority (e.g., from `PRIORITY_UPDATE` frames).
1740
+ * @since v26.2.0
1741
+ */
1742
+ readonly priority: StreamPriority | null;
1743
+ /**
1744
+ * Sets the priority of the stream. Throws `ERR_INVALID_STATE` if the session
1745
+ * does not support priority (e.g. non-HTTP/3). Has no effect if the stream
1746
+ * has been destroyed.
1747
+ * @since v26.2.0
1748
+ */
1749
+ setPriority(options?: NodeJS.PartialOptions<StreamPriority>): void;
1750
+ /**
1751
+ * The stream implements `Symbol.asyncIterator`, making it directly usable
1752
+ * in `for await...of` loops. Each iteration yields a batch of `Uint8Array`
1753
+ * chunks.
1754
+ *
1755
+ * Only one async iterator can be obtained per stream. A second call throws
1756
+ * `ERR_INVALID_STATE`. Non-readable streams (outbound-only unidirectional
1757
+ * or closed) return an immediately-finished iterator.
1758
+ *
1759
+ * ```js
1760
+ * for await (const chunks of stream) {
1761
+ * for (const chunk of chunks) {
1762
+ * // Process each Uint8Array chunk
1763
+ * }
1764
+ * }
1765
+ * ```
1766
+ *
1767
+ * Compatible with stream/iter utilities:
1768
+ *
1769
+ * ```js
1770
+ * import Stream from 'node:stream/iter';
1771
+ * const body = await Stream.bytes(stream);
1772
+ * const text = await Stream.text(stream);
1773
+ * await Stream.pipeTo(stream, someWriter);
1774
+ * ```
1775
+ * @since v26.2.0
900
1776
  */
901
- readonly readable: ReadableStream<Uint8Array>;
1777
+ [Symbol.asyncIterator](): NodeJS.AsyncIterator<NodeJS.NonSharedUint8Array[]>;
902
1778
  /**
903
- * The session that created this stream. Read only.
1779
+ * Returns a Writer object for pushing data to the stream incrementally.
1780
+ * The Writer implements the stream/iter Writer interface with the
1781
+ * try-sync-fallback-to-async pattern.
1782
+ *
1783
+ * Only available when no `body` source was provided at creation time or via
1784
+ * `stream.setBody()`. Non-writable streams return an already-closed
1785
+ * Writer. Throws `ERR_INVALID_STATE` if the outbound is already configured.
1786
+ *
1787
+ * The Writer has the following methods:
1788
+ *
1789
+ * * `writeSync(chunk)` — Synchronous write. Returns `true` if accepted,
1790
+ * `false` if flow-controlled. Data is NOT accepted on `false`.
1791
+ * * `write(chunk[, options])` — Async write with drain wait. `options.signal`
1792
+ * is checked at entry but not observed during the write.
1793
+ * * `writevSync(chunks)` — Synchronous vectored write. All-or-nothing.
1794
+ * * `writev(chunks[, options])` — Async vectored write.
1795
+ * * `endSync()` — Synchronous close. Returns total bytes or `-1`.
1796
+ * * `end([options])` — Async close.
1797
+ * * `fail(reason)` — Errors the stream (sends `RESET_STREAM` to peer).
1798
+ * When `reason` is a `QuicError`, its `error.errorCode` is used
1799
+ * as the wire code on the resulting `RESET_STREAM` frame; otherwise
1800
+ * the wire code falls back to the negotiated application protocol's
1801
+ * "internal error" code (`H3_INTERNAL_ERROR` (`0x102`) for HTTP/3, or
1802
+ * the QUIC transport-layer `INTERNAL_ERROR` (`0x1`) for raw QUIC).
1803
+ * See `stream.destroy()` for a full-stream abort that also resets
1804
+ * the readable side via `STOP_SENDING`.
1805
+ * * `desiredSize` — Available capacity in bytes, or `null` if closed/errored.
1806
+ *
1807
+ * The bytes from each `writeSync()` / `writevSync()` / `write()` / `writev()`
1808
+ * input chunk are copied into an internal buffer, so the caller's source
1809
+ * buffer is unchanged and may be reused or mutated immediately after the
1810
+ * call returns. Callers that want to ensure a source buffer cannot be
1811
+ * mutated after handing it off can call `ArrayBuffer.prototype.transfer()`
1812
+ * themselves before passing the buffer.
1813
+ * @since v26.2.0
1814
+ */
1815
+ readonly writer: Writer;
1816
+ /**
1817
+ * Sets the outbound body source for the stream. Can only be called once.
1818
+ * Mutually exclusive with `stream.writer`.
1819
+ *
1820
+ * The following body source types are supported:
1821
+ *
1822
+ * * `null` — The writable side is closed immediately (FIN sent with no data).
1823
+ * * `string` — UTF-8 encoded and sent as a single chunk.
1824
+ * * `ArrayBuffer`, `SharedArrayBuffer`, `ArrayBufferView` — Sent as a single
1825
+ * chunk. The bytes are copied into an internal buffer, so the caller's
1826
+ * source buffer is unchanged and may be reused or mutated immediately
1827
+ * after the call returns. Callers wanting to ensure their source cannot
1828
+ * be mutated after handing it off can call
1829
+ * `ArrayBuffer.prototype.transfer()` themselves before passing the buffer.
1830
+ * * `Blob` — Sent from the Blob's underlying data queue.
1831
+ * * {FileHandle} — The file contents are read asynchronously via an
1832
+ * fd-backed data source. The `FileHandle` must be opened for reading
1833
+ * (e.g. via [`fs.promises.open(path, 'r')`][]). Once passed as a body, the
1834
+ * `FileHandle` is locked and cannot be used as a body for another stream.
1835
+ * The `FileHandle` is automatically closed when the stream finishes.
1836
+ * * `AsyncIterable`, `Iterable` — Each yielded chunk (string or
1837
+ * `Uint8Array`) is written incrementally in streaming mode.
1838
+ * * `Promise` — Awaited; the resolved value is used as the body (subject
1839
+ * to the same type rules).
1840
+ *
1841
+ * Throws `ERR_INVALID_STATE` if the outbound is already configured or if
1842
+ * the writer has been accessed.
1843
+ * @since v26.2.0
1844
+ */
1845
+ setBody(body: StreamBody): void;
1846
+ /**
1847
+ * The session that created this stream, or `null` if the stream has been
1848
+ * destroyed. Read only.
904
1849
  * @since v23.8.0
905
1850
  */
906
- readonly session: QuicSession;
1851
+ readonly session: QuicSession | null;
907
1852
  /**
908
1853
  * The current statistics for the stream. Read only.
909
1854
  * @since v23.8.0
@@ -966,13 +1911,33 @@ declare module "node:quic" {
966
1911
  readonly receivedAt: bigint;
967
1912
  }
968
1913
  }
1914
+ /**
1915
+ * An object containing commonly used constants for QUIC configuration.
1916
+ * @since v26.2.0
1917
+ */
969
1918
  namespace constants {
1919
+ /**
1920
+ * Congestion control algorithm identifiers, for use with the
1921
+ * `sessionOptions.cc` option:
1922
+ *
1923
+ * * `quic.constants.cc.RENO` — Reno congestion control.
1924
+ * * `quic.constants.cc.CUBIC` — CUBIC congestion control.
1925
+ * * `quic.constants.cc.BBR` — BBR congestion control.
1926
+ */
970
1927
  enum cc {
971
1928
  RENO = "reno",
972
1929
  CUBIC = "cubic",
973
1930
  BBR = "bbr",
974
1931
  }
1932
+ /**
1933
+ * The default TLS 1.3 cipher suite list used when `sessionOptions.ciphers`
1934
+ * is not specified.
1935
+ */
975
1936
  const DEFAULT_CIPHERS: string;
1937
+ /**
1938
+ * The default TLS 1.3 key-exchange group list used when
1939
+ * `sessionOptions.groups` is not specified.
1940
+ */
976
1941
  const DEFAULT_GROUPS: string;
977
1942
  }
978
1943
  }