quico 0.1.1 → 0.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.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  <h1 align="center">QUICO</h1>
6
6
  <p align="center">
7
- <em>🚀 JavaScript implementation of QUIC, HTTP/3, QPACK & WebTransport for Node.js</em>
7
+ <em>Pure JavaScript implementation of QUIC, HTTP/3, QPACK &amp; WebTransport for Node.js</em>
8
8
  </p>
9
9
 
10
10
  <p align="center">
@@ -17,112 +17,350 @@
17
17
 
18
18
  ---
19
19
 
20
- > **⚠️ Project status: _Active development_.**
21
- > APIs may change without notice until we reach v1.0.
22
- > Use at your own risk and please report issues!
20
+ > **⚠️ Project status: Active development.**
21
+ > APIs may change before v1.0. Use at your own risk and please report issues!
23
22
 
24
- ## ✨ Features
25
- - **Pure JS QUIC**: Initial & 1-RTT packets, connection ID management, ACK & flow-control.
26
- - **TLS 1.3 handshake** in JavaScript (no OpenSSL binding).
27
- - **HTTP/3** control stream, request/response, server push, GOAWAY.
28
- - **WebTransport** streams & datagrams (RFC 9298) — tested with Chrome Canary.
29
- - **QPACK** encoder/decoder with custom Huffman table support.
30
- - Fully self-contained—no native addons, no external OpenSSL.
23
+ ---
24
+
25
+
26
+ ## Table of Contents
27
+ 1. [What is QUIC / HTTP/3?](#-what-is-quic--http3)
28
+ 2. [Why QUICO?](#-why-quico)
29
+ 3. [Quick Start](#-quick-start)
30
+ 4. [Features](#-features)
31
+ 5. [Node.js API Compatibility](#-nodejs-api-compatibility)
32
+ 6. [WebTransport](#-webtransport)
33
+ 7. [Testing](#-testing)
34
+ 8. [Project Structure](#-project-structure)
35
+ 9. [Roadmap](#-roadmap)
36
+ 10. [Sponsors](#-sponsors)
37
+ 11. [Contact](#-contact)
38
+ 12. [License](#-license)
39
+
40
+
41
+ ## ⚡ What is QUIC / HTTP/3?
42
+
43
+ **QUIC** is the future of Internet transport protocols. Created at Google and standardized by the IETF, QUIC powers **HTTP/3** and is already deployed at scale by the world’s largest platforms. It was specifically designed to overcome the limitations of TCP and deliver a faster, smoother, and more resilient web.
44
+
45
+ Key advantages of QUIC include:
46
+
47
+ - **Eliminating bottlenecks**: With TCP, data must arrive strictly in order. If a single packet is lost or delayed, all subsequent packets are blocked until it arrives — a phenomenon called **head-of-line blocking**. QUIC removes this bottleneck by running over UDP, so each package arrives on its own and avoids dependence on delayed pieces of data.
48
+
49
+ - **UDP efficiency**: By running over UDP, QUIC bypasses decades of kernel-level constraints, enabling lightning-fast performance even on constrained devices such as smartphones, IoT hardware, or edge gateways.
50
+
51
+ - **Security by default**: TLS 1.3 is built directly into the protocol. Every connection is encrypted — no exceptions, no downgrade paths.
52
+
53
+ - **Seamless mobility**: Connections remain stable as devices move across networks (e.g., Wi-Fi → 4G/5G) or switch IP addresses, without breaking the session.
54
+
55
+ - **Lower latency**: QUIC merges the transport and TLS handshake into fewer round-trips, significantly reducing connection setup time.
56
+
57
+ - **Smarter congestion control**: Advanced congestion control algorithms (such as BBR) continuously measure bandwidth, round-trip time, and loss in real time. They dynamically adjust to real-world network conditions.
31
58
 
32
- ## 📦 Installation
59
+
60
+ QUIC combines **UDP speed, TCP reliability, mandatory TLS security, and adaptive multiplexing** into one powerful transport layer.
61
+
62
+ **HTTP/3** (h3 in short) is the layer on top of QUIC. This is the evolution of the web’s application layer. Instead of riding over TCP, HTTP/3 maps HTTP requests and responses directly onto QUIC streams.
63
+ HTTP/3 is also himself dramatically reduces overhead and improves efficiency - thats bring faster page loads and real-time applications that scale across the modern web.
64
+
65
+
66
+
67
+ ## 🧠 Why QUICO?
68
+
69
+ Node.js is the backbone of countless modern web applications, but it currently lacks a native QUIC implementation. Supporting QUIC inside Node.js requires **deep access to TLS internals** that Node's existing TLS APIs don't expose. Beyond that, QUIC demands a **highly complex architecture** — intricate state machines, packet schedulers, and congestion control mechanisms.
70
+
71
+ **QUICO** brings this missing capability directly into the **Node.js ecosystem**. It is a from-scratch JavaScript implementation of QUIC, HTTP/3 and WebTransport, built without relying on OpenSSL or native code. At its core, it uses [LemonTLS](https://github.com/colocohen/lemon-tls) — a pure JavaScript TLS 1.3 library built by the same author — to provide the cryptographic layer that QUIC requires. Together, QUICO and LemonTLS form a complete, fully auditable JavaScript networking stack from UDP to HTTP/3.
72
+
73
+ **What this means for you:**
74
+
75
+ - **`npm install` and go** — no build tools, no platform-specific binaries, no gyp
76
+ - **Works everywhere Node.js runs** — Linux, macOS, Windows, ARM, Docker, edge
77
+ - **Debuggable top to bottom** — every packet, every frame, every byte is JavaScript you can step through
78
+
79
+
80
+ ## 📦 Quick Start
33
81
 
34
82
  ```bash
35
83
  npm install quico
36
84
  ```
37
85
 
38
- ## 🏃 Quick start
86
+ ### Server
87
+
88
+ ```js
89
+ import quico from 'quico';
90
+ import fs from 'node:fs';
91
+
92
+ const server = quico.createServer({
93
+ key: fs.readFileSync('server.key'),
94
+ cert: fs.readFileSync('server.crt')
95
+ }, (req, res) => {
96
+ res.writeHead(200, { 'content-type': 'text/plain' });
97
+ res.end('Hello from HTTP/3!');
98
+ });
99
+
100
+ server.listen(4433, () => {
101
+ console.log('HTTP/3 server on https://localhost:4433');
102
+ });
103
+ ```
104
+
105
+ ### Client
106
+
107
+ ```js
108
+ import quico from 'quico';
39
109
 
40
- ### Step 1: Generate a self-signed certificate
110
+ quico.request('https://www.google.com/', (res) => {
111
+ console.log('Status:', res.statusCode); // 200
112
+ console.log('Protocol:', res.httpVersion); // "3.0"
113
+ res.on('data', (chunk) => process.stdout.write(chunk));
114
+ });
115
+ ```
41
116
 
42
- To test QUICO locally, you’ll need a TLS certificate.
43
- Generate one using OpenSSL:
117
+ > 📂 For more examples, see [`examples/`](./examples)
44
118
 
45
- ```bash
46
- mkdir certs
47
- openssl req -x509 -newkey rsa:2048 -nodes -keyout certs/localhost.key -out certs/localhost.crt -days 365
119
+
120
+ ## ✨ Features
121
+
122
+ ### HTTP/3 Server & Client
123
+ - Full request/response cycle over QUIC
124
+ - QPACK header compression with static and dynamic tables
125
+ - Standard Node.js API: `req.headers`, `res.writeHead()`, `res.end()`
126
+ - Multiple requests per connection (stream multiplexing)
127
+ - Automatic `Alt-Svc` header for HTTP/3 protocol discovery
128
+ - H3 → H2 → H1 fallback when QUIC isn't available
129
+ - Tested against Google, Cloudflare, Facebook, Microsoft and nginx QUIC servers
130
+
131
+ ### WebTransport
132
+ - Client and server implementation
133
+ - Bidirectional and unidirectional streams (Node.js Duplex + WHATWG Streams API)
134
+ - Unreliable datagrams (RFC 9297)
135
+ - Natural API: `req.on('stream')`, `res.sendDatagram()`, `res.writeHead(200)` to accept
136
+
137
+ ### QUIC Transport
138
+ - Full TLS 1.3 handshake via LemonTLS (no OpenSSL)
139
+ - Initial, Handshake, and 1-RTT packet handling
140
+ - Connection ID management
141
+ - ACK processing and flow control
142
+ - Key updates (key phase bit rotation)
143
+ - HelloRetryRequest support (P-256, P-384, X25519)
144
+ - AES-128-GCM and AES-256-GCM cipher suites
145
+ - Handshake timeout
146
+
147
+
148
+ ## 🔗 Node.js API Compatibility
149
+
150
+ One of the core design goals of QUICO is to provide a **familiar API**. If you already know `node:https`, working with QUICO should feel natural — `createServer`, `request`, `req`, `res` all work the same way.
151
+
152
+ This means existing frameworks work out of the box:
153
+
154
+ ```js
155
+ import express from 'express';
156
+ import quico from 'quico';
157
+
158
+ const app = express();
159
+ app.get('/', (req, res) => res.json({ protocol: req.httpVersion }));
160
+
161
+ quico.createServer({ key: KEY, cert: CERT }, app).listen(4433);
162
+ // → { "protocol": "3.0" }
48
163
  ```
49
164
 
50
- ### Step 2: Create a basic HTTP/3 server
165
+ For multi-domain setups, QUICO supports `SNICallback` just like `node:https`:
51
166
 
52
167
  ```js
53
- const fs = require('fs');
54
- const quico = require('quico');
168
+ import quico from 'quico';
169
+ import tls from 'lemon-tls';
55
170
 
56
171
  const server = quico.createServer({
57
172
  SNICallback: function (servername, cb) {
58
- cb(null, {
59
- key: fs.readFileSync('certs/localhost.key'),
60
- cert: fs.readFileSync('certs/localhost.crt')
61
- });
173
+ cb(null, tls.createSecureContext({
174
+ key: fs.readFileSync('certs/' + servername + '.key'),
175
+ cert: fs.readFileSync('certs/' + servername + '.crt')
176
+ }));
62
177
  }
63
- }, function (req, res) {
64
- const data = new TextEncoder().encode('Hello World from HTTP/3 on Node.js!');
65
- res.writeHead(200, {
66
- 'Content-Type': 'text/html; charset=utf-8',
67
- 'Content-Length': data.byteLength
68
- });
69
- res.end(data);
178
+ }, (req, res) => {
179
+ res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
180
+ res.end('Hello World from HTTP/3 on Node.js!');
70
181
  });
71
182
 
72
- server.listen(4433, function () {
183
+ server.listen(4433, () => {
73
184
  console.log('🚀 QUIC server running on https://localhost:4433');
74
185
  });
75
186
  ```
76
187
 
77
- > ✅ You must launch Chrome with `--enable-quic` and `--origin-to-force-quic-on=localhost:4433`
78
- > 📂 For more examples, see [`examples/`](./examples)
79
188
 
80
- ## 🛣 Roadmap
189
+ ## 🚀 WebTransport
81
190
 
82
- The following roadmap reflects the current and planned status of the QUICO project.
83
- ✅ = Completed 🔄 = In progress ⏳ = Planned ❌ = Not planned
191
+ ### Server
84
192
 
85
- ### ✅ Completed
86
- | Status | Item |
87
- |:------:|------|
88
- | ✅ | QUIC: Initial / Handshake / 1-RTT |
89
- | ✅ | TLS 1.3 handshake & key schedule |
90
- | ✅ | HTTP/3: control streams & basic requests |
91
- | ✅ | QPACK: static & dynamic table |
193
+ ```js
194
+ import quico from 'quico';
195
+
196
+ quico.createServer({ key: KEY, cert: CERT }, (req, res) => {
197
+ if (req.headers[':protocol'] === 'webtransport') {
198
+ // Accept the WebTransport session
199
+ res.writeHead(200);
200
+
201
+ // Bidirectional streams from the client
202
+ req.on('stream', (stream) => {
203
+ stream.on('data', (chunk) => {
204
+ stream.write(chunk); // echo back
205
+ });
206
+ stream.on('end', () => stream.end());
207
+ });
208
+
209
+ // Unreliable datagrams
210
+ req.on('datagram', (data) => {
211
+ res.sendDatagram(data); // echo back
212
+ });
213
+
214
+ // Server can also create streams
215
+ const push = res.createBidirectionalStream();
216
+ push.write('server says hello');
217
+ push.end();
218
+ } else {
219
+ // Regular HTTP/3 request
220
+ res.end('Hello HTTP/3!');
221
+ }
222
+ }).listen(4433);
223
+ ```
224
+
225
+ ### Client (Node.js)
226
+
227
+ ```js
228
+ import { WebTransport } from 'quico';
229
+
230
+ const wt = new WebTransport('https://localhost:4433/echo');
231
+ await wt.ready;
232
+
233
+ // Bidirectional stream
234
+ const stream = await wt.createBidirectionalStream();
235
+ stream.write('hello');
236
+ stream.on('data', (chunk) => console.log('echo:', chunk.toString()));
237
+ stream.end();
238
+
239
+ // Unidirectional stream
240
+ const uni = await wt.createUnidirectionalStream();
241
+ uni.write('fire and forget');
242
+ uni.end();
243
+
244
+ // Datagrams (unreliable)
245
+ wt.sendDatagram(Buffer.from('ping'));
246
+ wt.on('datagram', (data) => console.log('pong:', data.toString()));
247
+
248
+ wt.close();
249
+ ```
250
+
251
+ ### Client (Browser)
252
+
253
+ ```js
254
+ const wt = new WebTransport('https://yourserver.com:4433/live');
255
+ await wt.ready;
256
+
257
+ // Send via WHATWG Streams API
258
+ const writer = wt.datagrams.writable.getWriter();
259
+ await writer.write(new TextEncoder().encode('Hello QUIC'));
260
+
261
+ // Receive
262
+ const reader = wt.datagrams.readable.getReader();
263
+ const { value } = await reader.read();
264
+ console.log('Received:', new TextDecoder().decode(value));
265
+ ```
266
+
267
+
268
+ ## 🧪 Testing
269
+
270
+ QUIC requires TLS 1.3. Self-signed RSA certificates usually fail with QUIC clients and browsers. For local development, [mkcert](https://github.com/FiloSottile/mkcert) is the easiest option — it generates locally-trusted ECDSA certificates automatically.
271
+
272
+ This project supports ALPN `"h3"` only (not draft variants like `h3-29`). You must explicitly force h3 when testing with Chrome.
273
+
274
+ **Chrome:**
275
+ ```bash
276
+ chrome --enable-quic --quic-version=h3 --ignore-certificate-errors --origin-to-force-quic-on=localhost:4433
277
+ ```
278
+
279
+ **curl:**
280
+ ```bash
281
+ curl --http3 https://localhost:4433 --insecure
282
+ ```
283
+
284
+ **Integration tests:**
285
+ ```bash
286
+ node examples/test_integration.js # HTTP/3 client + server — 19 tests
287
+ node examples/test_wt_server.js # WebTransport server echo (QUICO ↔ QUICO)
288
+ node examples/test_webtransport.js URL # WebTransport client against any server
289
+ ```
290
+
291
+
292
+ ## 📁 Project Structure
293
+
294
+ ```
295
+ quico/
296
+ ├── index.js — Public API exports
297
+ └── src/
298
+ ├── server.js — Unified server (drop-in for node:https)
299
+ ├── client.js — Unified client with H3 → H2 → H1 fallback
300
+ ├── agent.js — Connection pooling and Alt-Svc protocol cache
301
+ ├── streams.js — IncomingMessage, ServerResponse, ClientRequest
302
+ ├── h3.js — HTTP/3 framing, QPACK, WebTransport detection
303
+ ├── h3_server.js — HTTP/3 + WebTransport server
304
+ ├── h3_client.js — HTTP/3 client (DNS, UDP, QUIC, H3 pipeline)
305
+ ├── quic_connection.js — QUIC state machine, burst scheduler, flow control
306
+ ├── transport.js — Packet parsing, frame encoding/decoding
307
+ ├── crypto.js — AEAD encryption, header protection, key derivation
308
+ ├── tls_bridge.js — LemonTLS integration, transport parameters
309
+ └── webtransport.js — WebTransport client + stream classes
310
+ ```
311
+
312
+
313
+ ## 🛣 Roadmap
314
+
315
+ ### ✅ Done
316
+ - QUIC v1 transport (RFC 9000) — Initial, Handshake, 1-RTT
317
+ - TLS 1.3 via LemonTLS — X25519, P-256, P-384, AES-128/256-GCM
318
+ - HTTP/3 server and client (RFC 9114)
319
+ - QPACK header compression with static and dynamic tables (RFC 9204)
320
+ - WebTransport client and server — bidi/uni streams + datagrams (RFC 9297)
321
+ - Node.js `https`-style API compatibility — `createServer`, `request`, `get`
322
+ - Express / Fastify / Koa middleware support
323
+ - Connection reuse and multiplexing
324
+ - HelloRetryRequest — client and server
325
+ - Key updates (key phase rotation)
326
+ - Interop with Google, Cloudflare, Facebook, Microsoft, nginx
327
+ - Handshake timeout
92
328
 
93
329
  ### 🔄 In Progress
94
- | Status | Item | Notes |
95
- |:------:|------|-------|
96
- | 🔄 | QPACK: Huffman encoding/decoding | Custom table support partially working |
97
- | 🔄 | WebTransport: unidirectional & bidirectional streams | Stream interface WIP |
98
- | 🔄 | HTTP/3: GOAWAY & request cancellation | Partial control flow support |
99
- | 🔄 | Integration with Node.js `https`-style API | Goal: seamless compatibility |
100
- | 🔄 | Project modularization & internal refactoring | To improve maintainability |
330
+ - Loss detection and PTO timers (RFC 9002)
331
+ - Congestion control (BBR / CUBIC)
332
+ - 0-RTT and session resumption
333
+ - Debug log cleanup (`QUICO_DEBUG` environment flag)
101
334
 
102
335
  ### ⏳ Planned
103
- | Status | Item | Notes |
104
- |:------:|------|-------|
105
- | ⏳ | QUIC: 0-RTT support | Will follow key update & early data support |
106
- | ⏳ | WebTransport: datagram support | Based on RFC 9298 |
107
- | ⏳ | QUIC: proper connection teardown | CLOSE frame, idle timeout |
108
- | ⏳ | QUIC: keep-alive & PING frames | For long-lived connections |
109
- | ⏳ | QUIC: flow control & congestion (BBR / CUBIC) | Needs metrics and simulation |
110
- | ⏳ | QUIC: session resumption & connection migration | For mobile/roaming support |
111
- | ⏳ | End-to-end test suite against Chromium | Automate using testh3 and Puppeteer |
112
- | ⏳ | Benchmarks, performance analysis & tuning | Resource usage, latency, throughput |
113
- | ⏳ | Fuzz testing and protocol robustness checks | To improve security and reliability |
114
- | ⏳ | Developer documentation & API reference | For better onboarding |
115
- | ⏳ | TypeScript typings | Type safety for IDE support |
116
-
117
- _Note: QUICO is a work-in-progress project aiming to provide a full JavaScript implementation of QUIC + HTTP/3. Community contributions are welcome!_
118
-
119
- _Please ⭐ star the repo to follow progress!_
336
+ - Connection migration (PATH_CHALLENGE / PATH_RESPONSE)
337
+ - ChaCha20-Poly1305 cipher suite (0x1303)
338
+ - GOAWAY and graceful shutdown
339
+ - Stream priority (RFC 9218)
340
+ - TypeScript type definitions
341
+ - Performance benchmarks
342
+ - Fuzz testing
343
+
344
+ _Community contributions are welcome! Please ⭐ star the repo to follow progress._
345
+
120
346
 
121
347
  ## 🙏 Sponsors
122
348
 
123
349
  QUICO is an evenings-and-weekends project.
124
350
  Support development via **GitHub Sponsors** or simply share the project.
125
351
 
352
+
353
+
354
+ ## 💬 Contact
355
+
356
+ For feedback, ideas, or contributions,
357
+ contact directly at:
358
+ 📧 **support@quicojs.dev**
359
+
360
+ For security-related issues, please see [SECURITY.md](./SECURITY.md).
361
+
362
+
363
+
126
364
  ## 📜 License
127
365
 
128
366
  **Apache License 2.0**
package/index.cjs ADDED
@@ -0,0 +1,45 @@
1
+ /*
2
+ * quico — CommonJS entry point
3
+ *
4
+ * Since quico is ESM-only internally, CommonJS users
5
+ * must await .ready before calling any API:
6
+ *
7
+ * const quico = require('quico');
8
+ * await quico.ready;
9
+ * const server = quico.createServer({ ... }, handler);
10
+ *
11
+ * Or in one step:
12
+ *
13
+ * const quico = await require('quico').ready;
14
+ * const server = quico.createServer({ ... }, handler);
15
+ */
16
+
17
+ let _mod;
18
+
19
+ const proxy = new Proxy({}, {
20
+ get(target, key) {
21
+ // .ready must be accessible before module loads
22
+ if (key === 'ready') return target.ready;
23
+ // Prevent Promise auto-unwrapping when proxy is returned from async
24
+ if (key === 'then') return undefined;
25
+ if (!_mod) throw new Error(
26
+ 'quico: module not loaded yet. Use "const quico = await require(\'quico\').ready" first.'
27
+ );
28
+ return _mod[key];
29
+ }
30
+ });
31
+
32
+ // Kick off async ESM import — sets .ready on proxy target
33
+ proxy.ready = import('./index.js').then(function (m) {
34
+ // Merge default export (createServer, request, etc.)
35
+ // with named exports (WebTransport, etc.)
36
+ _mod = Object.assign({}, m.default);
37
+ for (var key in m) {
38
+ if (key !== 'default' && key !== '__esModule') {
39
+ _mod[key] = m[key];
40
+ }
41
+ }
42
+ return proxy;
43
+ });
44
+
45
+ module.exports = proxy;
package/index.d.ts ADDED
@@ -0,0 +1,158 @@
1
+ /*
2
+ * quico — TypeScript declarations
3
+ * Pure JavaScript QUIC, HTTP/3, QPACK & WebTransport for Node.js
4
+ */
5
+
6
+ /// <reference types="node" />
7
+
8
+ import { IncomingMessage, ServerResponse } from 'node:http';
9
+ import { Duplex, Readable, Writable } from 'node:stream';
10
+ import { EventEmitter } from 'node:events';
11
+
12
+ // ============================================================
13
+ // Server
14
+ // ============================================================
15
+
16
+ type RequestHandler = (req: QuicoIncomingMessage, res: QuicoServerResponse) => void;
17
+
18
+ interface ServerOptions {
19
+ key?: string | Buffer;
20
+ cert?: string | Buffer;
21
+ ca?: string | Buffer;
22
+ SNICallback?: (servername: string, cb: (err: Error | null, ctx: any) => void) => void;
23
+ maxConnections?: number;
24
+ }
25
+
26
+ interface QuicoServer extends EventEmitter {
27
+ listen(port: number, callback?: () => void): this;
28
+ listen(port: number, host: string, callback?: () => void): this;
29
+ close(callback?: () => void): void;
30
+ on(event: 'request', listener: RequestHandler): this;
31
+ on(event: 'listening', listener: () => void): this;
32
+ on(event: 'error', listener: (err: Error) => void): this;
33
+ on(event: string, listener: (...args: any[]) => void): this;
34
+ }
35
+
36
+ interface QuicoIncomingMessage extends IncomingMessage {
37
+ /** QUIC stream ID */
38
+ streamId?: number;
39
+
40
+ // WebTransport events (available after res.writeHead(200) on WT sessions)
41
+ on(event: 'stream', listener: (stream: Duplex) => void): this;
42
+ on(event: 'unidirectionalStream', listener: (stream: Readable) => void): this;
43
+ on(event: 'datagram', listener: (data: Buffer) => void): this;
44
+ on(event: string, listener: (...args: any[]) => void): this;
45
+ }
46
+
47
+ interface QuicoServerResponse extends ServerResponse {
48
+ // WebTransport methods (available after res.writeHead(200) on WT sessions)
49
+ sendDatagram?(data: Buffer | Uint8Array | string): void;
50
+ createBidirectionalStream?(): Duplex;
51
+ createUnidirectionalStream?(): Writable;
52
+ }
53
+
54
+
55
+ // ============================================================
56
+ // Client
57
+ // ============================================================
58
+
59
+ interface RequestOptions {
60
+ hostname?: string;
61
+ host?: string;
62
+ port?: number;
63
+ path?: string;
64
+ method?: string;
65
+ headers?: Record<string, string | string[]>;
66
+ agent?: QuicoAgent;
67
+ rejectUnauthorized?: boolean;
68
+ timeout?: number;
69
+ }
70
+
71
+ interface QuicoClientRequest extends Writable {
72
+ on(event: 'response', listener: (res: QuicoIncomingMessage) => void): this;
73
+ on(event: 'error', listener: (err: Error) => void): this;
74
+ on(event: 'timeout', listener: () => void): this;
75
+ on(event: string, listener: (...args: any[]) => void): this;
76
+ end(data?: string | Buffer): this;
77
+ abort(): void;
78
+ setTimeout(ms: number, callback?: () => void): this;
79
+ }
80
+
81
+
82
+ // ============================================================
83
+ // Agent
84
+ // ============================================================
85
+
86
+ interface QuicoAgent {
87
+ destroy(): void;
88
+ }
89
+
90
+
91
+ // ============================================================
92
+ // WebTransport
93
+ // ============================================================
94
+
95
+ interface WebTransportOptions {
96
+ /** Skip certificate verification (default: true for self-signed) */
97
+ rejectUnauthorized?: boolean;
98
+ }
99
+
100
+ declare class WebTransport extends EventEmitter {
101
+ constructor(url: string, options?: WebTransportOptions);
102
+
103
+ /** Resolves when the WebTransport session is established */
104
+ readonly ready: Promise<void>;
105
+ /** Current state: 'connecting' | 'connected' | 'closed' */
106
+ readonly state: string;
107
+ /** The URL of the WebTransport session */
108
+ readonly url: string;
109
+
110
+ /** WHATWG-style datagram interface */
111
+ readonly datagrams: {
112
+ readonly readable: ReadableStream<Uint8Array>;
113
+ readonly writable: WritableStream<Uint8Array>;
114
+ };
115
+
116
+ /** Create a bidirectional stream (Node.js Duplex + WHATWG .readable/.writable) */
117
+ createBidirectionalStream(): Promise<Duplex & {
118
+ readonly readable: ReadableStream<Uint8Array>;
119
+ readonly writable: WritableStream<Uint8Array>;
120
+ }>;
121
+
122
+ /** Create a unidirectional stream for writing */
123
+ createUnidirectionalStream(): Promise<Writable>;
124
+
125
+ /** Send an unreliable datagram */
126
+ sendDatagram(data: Buffer | Uint8Array): void;
127
+
128
+ /** Close the WebTransport session */
129
+ close(info?: { closeCode?: number; reason?: string }): void;
130
+
131
+ on(event: 'datagram', listener: (data: Buffer) => void): this;
132
+ on(event: 'close', listener: () => void): this;
133
+ on(event: string, listener: (...args: any[]) => void): this;
134
+ }
135
+
136
+
137
+ // ============================================================
138
+ // Main module
139
+ // ============================================================
140
+
141
+ declare const quico: {
142
+ createServer(options: ServerOptions, handler?: RequestHandler): QuicoServer;
143
+
144
+ request(url: string | URL, callback?: (res: QuicoIncomingMessage) => void): QuicoClientRequest;
145
+ request(url: string | URL, options: RequestOptions, callback?: (res: QuicoIncomingMessage) => void): QuicoClientRequest;
146
+ request(options: RequestOptions, callback?: (res: QuicoIncomingMessage) => void): QuicoClientRequest;
147
+
148
+ get(url: string | URL, callback?: (res: QuicoIncomingMessage) => void): QuicoClientRequest;
149
+ get(url: string | URL, options: RequestOptions, callback?: (res: QuicoIncomingMessage) => void): QuicoClientRequest;
150
+ get(options: RequestOptions, callback?: (res: QuicoIncomingMessage) => void): QuicoClientRequest;
151
+
152
+ globalAgent: QuicoAgent;
153
+ };
154
+
155
+ export default quico;
156
+ export { WebTransport };
157
+ export { QuicoServer, QuicoIncomingMessage, QuicoServerResponse, QuicoClientRequest, QuicoAgent };
158
+ export { ServerOptions, RequestOptions, RequestHandler, WebTransportOptions };