@moq/web-transport
v0.1.1
Published
WebTransport polyfill for Node.js via QUIC/HTTP3
Maintainers
Readme
@moq/web-transport
WebTransport for Node.js, powered by native QUIC/HTTP3 via NAPI-RS.
Provides a custom client and server API for setup, then exposes the standard W3C WebTransport API for streams, datagrams, and session lifecycle.
Installation
bun add @moq/web-transportClient
Connect to a WebTransport server using the Session class, which implements the W3C WebTransport interface:
import Session from "@moq/web-transport";
const session = new Session("https://example.com:4443/path");
await session.ready;
// Use the standard W3C WebTransport API from here onCertificate options
// Skip certificate verification (testing only!)
const session = new Session("https://localhost:4443", {
serverCertificateDisableVerify: true,
});
// Pin to specific certificate hashes
const session = new Session("https://localhost:4443", {
serverCertificateHashes: [
{ algorithm: "sha-256", value: certHash },
],
});Polyfill
Install Session as the global WebTransport for libraries that expect the browser API:
import { install } from "@moq/web-transport";
install(); // globalThis.WebTransport = Session (no-op if already defined)Server
Use Server to accept incoming connections. Each Request can be accepted (returning a W3C Session) or rejected:
import { Server } from "@moq/web-transport";
import fs from "node:fs";
const cert = fs.readFileSync("cert.pem");
const key = fs.readFileSync("key.pem");
const server = Server.bind("[::]:4443", cert, key);
while (true) {
const request = await server.accept();
if (!request) break;
const url = await request.url;
console.log("incoming session:", url);
const session = await request.ok(); // or request.reject(404)
// Use the standard W3C WebTransport API from here on
handleSession(session);
}
// Stop accepting new connections
server.close();W3C WebTransport API
Once you have a Session (client or server-side), the API follows the W3C WebTransport spec:
Bidirectional streams
// Open a bidirectional stream
const stream = await session.createBidirectionalStream();
const writer = stream.writable.getWriter();
await writer.write(new Uint8Array([1, 2, 3]));
await writer.close();
// Accept incoming bidirectional streams
const reader = session.incomingBidirectionalStreams.getReader();
const { value: incoming } = await reader.read();
const data = await new Response(incoming.readable).arrayBuffer();Unidirectional streams
// Open a unidirectional stream
const writable = await session.createUnidirectionalStream();
const writer = writable.getWriter();
await writer.write(new TextEncoder().encode("hello"));
await writer.close();
// Accept incoming unidirectional streams
const reader = session.incomingUnidirectionalStreams.getReader();
const { value: readable } = await reader.read();
const text = await new Response(readable).text();Datagrams
// Send datagrams
const writer = session.datagrams.writable.getWriter();
await writer.write(new Uint8Array([0x01, 0x02]));
// Receive datagrams
const reader = session.datagrams.readable.getReader();
const { value: datagram } = await reader.read();Closing
// Close gracefully
session.close({ closeCode: 0, reason: "done" });
// Wait for the session to close
const info = await session.closed;
console.log(info.closeCode, info.reason);License
MIT OR Apache-2.0
