├── .envrc ├── dev ├── .gitignore ├── localhost.conf └── setup ├── web-demo ├── .gitignore ├── package.json ├── client.html └── client.js ├── .gitignore ├── .release-plz.toml ├── web-transport-ws ├── .gitignore ├── src │ ├── lib.rs │ ├── index.ts │ ├── stream.ts │ ├── stream.rs │ ├── error.rs │ ├── varint.ts │ ├── frame.ts │ └── frame.rs ├── tsconfig.json ├── scripts │ ├── release.ts │ └── package.ts ├── Cargo.toml ├── package.json ├── examples │ ├── client.rs │ ├── server.rs │ └── client.ts ├── CHANGELOG.md ├── package-lock.json └── README.md ├── .cargo └── config.toml ├── package.json ├── web-transport-proto ├── src │ ├── lib.rs │ ├── error.rs │ ├── stream.rs │ └── frame.rs ├── README.md ├── Cargo.toml └── CHANGELOG.md ├── web-transport-quiche ├── src │ ├── h3 │ │ ├── mod.rs │ │ ├── request.rs │ │ ├── settings.rs │ │ └── connect.rs │ ├── ez │ │ ├── mod.rs │ │ ├── lock.rs │ │ ├── stream.rs │ │ ├── client.rs │ │ └── server.rs │ ├── lib.rs │ ├── client.rs │ ├── error.rs │ ├── recv.rs │ ├── send.rs │ └── server.rs ├── CHANGELOG.md ├── examples │ ├── README.md │ ├── echo-client.rs │ └── echo-server.rs ├── Cargo.toml └── README.md ├── .editorconfig ├── web-transport-wasm ├── README.md ├── src │ ├── lib.rs │ ├── error.rs │ ├── send.rs │ ├── client.rs │ ├── recv.rs │ └── session.rs ├── Cargo.toml └── CHANGELOG.md ├── Cargo.toml ├── web-transport-trait ├── Cargo.toml ├── CHANGELOG.md ├── src │ └── util.rs └── README.md ├── .github └── workflows │ ├── pr.yml │ └── release.yml ├── web-transport ├── src │ ├── lib.rs │ └── wasm.rs ├── Cargo.toml ├── README.md └── CHANGELOG.md ├── web-transport-quinn ├── examples │ ├── README.md │ ├── echo-client-advanced.rs │ ├── echo-client.rs │ ├── echo-server.rs │ └── echo-server-advanced.rs ├── Cargo.toml ├── src │ ├── settings.rs │ ├── crypto.rs │ ├── lib.rs │ ├── connect.rs │ ├── recv.rs │ ├── server.rs │ └── send.rs ├── README.md └── CHANGELOG.md ├── biome.jsonc ├── LICENSE-MIT ├── flake.nix ├── flake.lock ├── README.md └── justfile /.envrc: -------------------------------------------------------------------------------- 1 | use flake -------------------------------------------------------------------------------- /dev/.gitignore: -------------------------------------------------------------------------------- 1 | *.crt 2 | *.hex 3 | *.key 4 | -------------------------------------------------------------------------------- /web-demo/.gitignore: -------------------------------------------------------------------------------- 1 | .parcel-cache 2 | dist 3 | node_modules 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | .direnv/ 4 | node_modules 5 | -------------------------------------------------------------------------------- /.release-plz.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | dependencies_update = true 3 | -------------------------------------------------------------------------------- /web-transport-ws/.gitignore: -------------------------------------------------------------------------------- 1 | # Rust 2 | /target 3 | Cargo.lock 4 | 5 | # Node/TypeScript 6 | node_modules/ 7 | dist/ 8 | *.log 9 | .DS_Store -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.'cfg(all())'] 2 | rustflags = ["--cfg=web_sys_unstable_apis"] 3 | 4 | [target.wasm32-unknown-unknown] 5 | runner = "wasm-bindgen-test-runner" 6 | -------------------------------------------------------------------------------- /web-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-demo", 3 | "private": true, 4 | "devDependencies": { 5 | "@parcel/transformer-inline-string": "^2.10.3", 6 | "parcel": "^2.10.3" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-transport-workspace", 3 | "private": true, 4 | "type": "module", 5 | "workspaces": [ 6 | "web-demo", 7 | "web-transport-ws" 8 | ], 9 | "scripts": { 10 | "check": "biome check", 11 | "fix": "biome check --fix" 12 | }, 13 | "devDependencies": { 14 | "@biomejs/biome": "^2.2.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /web-demo/client.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebTransport Client 6 | 7 | 8 |

WebTransport Client

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web-transport-proto/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod capsule; 2 | mod connect; 3 | mod error; 4 | mod frame; 5 | mod settings; 6 | mod stream; 7 | mod varint; 8 | 9 | pub use capsule::*; 10 | pub use connect::*; 11 | pub use error::*; 12 | pub use frame::*; 13 | pub use settings::*; 14 | pub use stream::*; 15 | pub use varint::*; 16 | 17 | mod huffman; 18 | mod qpack; 19 | -------------------------------------------------------------------------------- /web-transport-quiche/src/h3/mod.rs: -------------------------------------------------------------------------------- 1 | //! HTTP/3 handshake helpers for WebTransport. 2 | //! 3 | //! This module handles the HTTP/3 SETTINGS and CONNECT handshake required 4 | //! to establish a WebTransport session over QUIC. 5 | 6 | mod connect; 7 | mod request; 8 | mod settings; 9 | 10 | pub use connect::*; 11 | pub use request::*; 12 | pub use settings::*; 13 | -------------------------------------------------------------------------------- /dev/localhost.conf: -------------------------------------------------------------------------------- 1 | [req] 2 | distinguished_name = req_distinguished_name 3 | req_extensions = req_ext 4 | x509_extensions = v3_req 5 | prompt = no 6 | 7 | [req_distinguished_name] 8 | CN = Localhost 9 | 10 | [req_ext] 11 | subjectAltName = @alt_names 12 | 13 | [v3_req] 14 | subjectAltName = @alt_names 15 | 16 | [alt_names] 17 | DNS.1 = localhost 18 | IP.1 = 127.0.0.1 19 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | indent_style = space 9 | indent_size = 4 10 | max_line_length = 100 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.yml] 16 | indent_style = space 17 | indent_size = 2 18 | 19 | [COMMIT_EDITMSG] 20 | max_line_length = 72 21 | -------------------------------------------------------------------------------- /web-transport-wasm/README.md: -------------------------------------------------------------------------------- 1 | [![crates.io](https://img.shields.io/crates/v/web-transport-wasm)](https://crates.io/crates/web-transport-wasm) 2 | [![docs.rs](https://img.shields.io/docsrs/web-transport-wasm)](https://docs.rs/web-transport-wasm) 3 | [![discord](https://img.shields.io/discord/1124083992740761730)](https://discord.gg/FCYF3p99mr) 4 | 5 | # web-transport-wasm 6 | A wrapper around the WebTransport browser API. 7 | -------------------------------------------------------------------------------- /web-transport-ws/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod error; 2 | mod frame; 3 | mod session; 4 | mod stream; 5 | 6 | pub(crate) use error::*; 7 | pub(crate) use frame::*; 8 | pub(crate) use stream::*; 9 | 10 | pub use session::*; 11 | pub use tokio_tungstenite; 12 | pub use tokio_tungstenite::tungstenite; 13 | 14 | // We use this ALPN to identify our WebTransport compatibility layer. 15 | pub const ALPN: &str = "webtransport"; 16 | -------------------------------------------------------------------------------- /web-transport-ws/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["esnext", "dom", "dom.iterable"], 4 | "target": "esnext", 5 | "module": "esnext", 6 | "moduleResolution": "bundler", 7 | "outDir": "./dist", 8 | "declaration": true, 9 | "isolatedModules": true, 10 | "strict": true, 11 | "skipLibCheck": true, 12 | "rewriteRelativeImportExtensions": true 13 | }, 14 | "include": ["src/**/*"] 15 | } 16 | -------------------------------------------------------------------------------- /web-transport-ws/src/index.ts: -------------------------------------------------------------------------------- 1 | import WebTransportWs from "./session.ts"; 2 | 3 | // Install polyfill if WebTransport is not available, returning true if installed 4 | export function install(): boolean { 5 | if ("WebTransport" in globalThis) return false; 6 | // biome-ignore lint/suspicious/noExplicitAny: polyfill 7 | (globalThis as any).WebTransport = WebTransportWs; 8 | return true; 9 | } 10 | 11 | export default WebTransportWs; 12 | -------------------------------------------------------------------------------- /web-transport-wasm/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! WebTransport wrapper for WebAssembly. 2 | //! 3 | //! This crate wraps the WebTransport API and provides ergonomic Rust bindings. 4 | //! Some liberties have been taken to make the API more Rust-like and closer to native. 5 | 6 | mod client; 7 | mod error; 8 | mod recv; 9 | mod send; 10 | mod session; 11 | 12 | pub use client::*; 13 | pub use error::*; 14 | pub use recv::*; 15 | pub use send::*; 16 | pub use session::*; 17 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "web-transport", 4 | "web-transport-proto", 5 | "web-transport-quiche", 6 | "web-transport-quinn", 7 | "web-transport-trait", 8 | "web-transport-wasm", 9 | "web-transport-ws", 10 | ] 11 | resolver = "2" 12 | 13 | [workspace.dependencies] 14 | web-transport-proto = { path = "web-transport-proto", version = "0.3" } 15 | web-transport-trait = { path = "web-transport-trait", version = "0.3" } 16 | -------------------------------------------------------------------------------- /web-transport-proto/README.md: -------------------------------------------------------------------------------- 1 | [![crates.io](https://img.shields.io/crates/v/web-transport-proto)](https://crates.io/crates/web-transport-proto) 2 | [![discord](https://img.shields.io/discord/1124083992740761730)](https://discord.gg/FCYF3p99mr) 3 | 4 | # web-transport-proto 5 | The gritty WebTransport protocol implementation. 6 | Not meant to be used directly, but as a dependency for [web-transport-quinn](../web-transport-quinn) and [web-transport-wasm](../web-transport-wasm). 7 | -------------------------------------------------------------------------------- /web-transport-trait/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "web-transport-trait" 3 | description = "An async WebTransport trait." 4 | authors = ["Luke Curley"] 5 | repository = "https://github.com/moq-dev/web-transport" 6 | license = "MIT OR Apache-2.0" 7 | 8 | version = "0.3.0" 9 | edition = "2021" 10 | 11 | keywords = ["quic", "http3", "webtransport"] 12 | categories = ["network-programming", "web-programming"] 13 | 14 | # async traits 15 | rust-version = "1.75" 16 | 17 | [dependencies] 18 | bytes = "1" 19 | -------------------------------------------------------------------------------- /web-transport-ws/scripts/release.ts: -------------------------------------------------------------------------------- 1 | // ChatGPT made a script that rewrites package.json file to use the correct paths. 2 | // The problem is that I want paths to reference `src` during development, but `dist` during release. 3 | // It's not pretty but nothing in NPM is. 4 | 5 | import { execSync } from "node:child_process"; 6 | 7 | console.log("📦 Building package..."); 8 | execSync("pnpm build", { stdio: "inherit" }); 9 | 10 | console.log("🚀 Publishing..."); 11 | execSync("pnpm publish --access=public", { 12 | stdio: "inherit", 13 | cwd: "dist", 14 | }); 15 | -------------------------------------------------------------------------------- /web-transport-proto/src/error.rs: -------------------------------------------------------------------------------- 1 | // WebTransport shares with HTTP/3, so we can't start at 0 or use the full VarInt. 2 | const ERROR_FIRST: u64 = 0x52e4a40fa8db; 3 | const ERROR_LAST: u64 = 0x52e5ac983162; 4 | 5 | pub const fn error_from_http3(code: u64) -> Option { 6 | if code < ERROR_FIRST || code > ERROR_LAST { 7 | return None; 8 | } 9 | 10 | let code = code - ERROR_FIRST; 11 | let code = code - code / 0x1f; 12 | 13 | Some(code as u32) 14 | } 15 | 16 | pub const fn error_to_http3(code: u32) -> u64 { 17 | ERROR_FIRST + code as u64 + code as u64 / 0x1e 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | permissions: 3 | contents: read 4 | 5 | on: 6 | pull_request: 7 | branches: ["main"] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | # Install Nix 20 | - uses: cachix/install-nix-action@v27 21 | with: 22 | github_access_token: ${{ secrets.GITHUB_TOKEN }} 23 | 24 | # Set RUSTFLAGS 25 | - run: echo "RUSTFLAGS=--cfg=web_sys_unstable_apis" >> $GITHUB_ENV 26 | 27 | # Make sure u guys don't write bad code 28 | - run: nix develop --command just check 29 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | permissions: 4 | pull-requests: write 5 | contents: write 6 | 7 | on: 8 | push: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | release: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | - name: Install Rust toolchain 21 | uses: dtolnay/rust-toolchain@stable 22 | - name: Run release-plz 23 | uses: MarcoIeni/release-plz-action@v0.5 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 27 | -------------------------------------------------------------------------------- /web-transport/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A generic WebTransport interface. 2 | //! 3 | //! The underlying implementation switches based on the platform: 4 | //! - native: [web-transport-quinn](https://docs.rs/web-transport-quinn/latest) 5 | //! - web: [web-transport-wasm](https://docs.rs/web-transport-wasm/latest) 6 | //! 7 | //! WASM lacks server support, so for native you first establish a [web_transport_quinn::Session] and then use [Session::from()] to cast to this generic interface. 8 | 9 | #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] 10 | #[path = "quinn.rs"] 11 | mod quic; 12 | 13 | #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] 14 | #[path = "wasm.rs"] 15 | mod quic; 16 | 17 | pub use quic::*; 18 | -------------------------------------------------------------------------------- /dev/setup: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | set -euo pipefail 3 | cd "$(dirname "${BASH_SOURCE[0]}")" 4 | 5 | # Generate a self-signed certificate for localhost. 6 | # This is only valid for 10 days so we can use serverCertificateHashes to avoid a CA (bugged). 7 | # https://developer.mozilla.org/en-US/docs/Web/API/WebTransport/WebTransport#servercertificatehashes 8 | openssl ecparam -genkey -name prime256v1 -out localhost.key 9 | openssl req -x509 -sha256 -nodes -days 10 -key localhost.key -out localhost.crt -config localhost.conf -extensions 'v3_req' 10 | 11 | # Generate a hex-encoded (easy to parse) SHA-256 hash of the certificate. 12 | openssl x509 -in localhost.crt -outform der | openssl dgst -sha256 -binary | xxd -p -c 256 > localhost.hex 13 | -------------------------------------------------------------------------------- /web-transport-proto/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "web-transport-proto" 3 | description = "WebTransport core protocol" 4 | authors = ["Luke Curley"] 5 | repository = "https://github.com/moq-dev/web-transport" 6 | license = "MIT OR Apache-2.0" 7 | 8 | version = "0.3.0" 9 | edition = "2021" 10 | 11 | keywords = ["quic", "http3", "webtransport"] 12 | categories = ["network-programming", "web-programming"] 13 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 14 | 15 | [dependencies] 16 | bytes = "1" 17 | http = "1" 18 | thiserror = "2" 19 | 20 | # Just for AsyncRead and AsyncWrite traits 21 | tokio = { version = "1", default-features = false, features = ["io-util"] } 22 | url = "2" 23 | -------------------------------------------------------------------------------- /web-transport-quiche/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [0.0.1](https://github.com/moq-dev/web-transport/releases/tag/web-transport-quiche-v0.0.1) - 2025-11-14 11 | 12 | ### Other 13 | 14 | - Avoid some spurious semver changes and bump the rest ([#121](https://github.com/moq-dev/web-transport/pull/121)) 15 | - Fix a rare race when accepting a stream. ([#120](https://github.com/moq-dev/web-transport/pull/120)) 16 | - Initial web-transport-quiche support ([#118](https://github.com/moq-dev/web-transport/pull/118)) 17 | -------------------------------------------------------------------------------- /web-transport-quiche/examples/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | A simple [server](echo-server.rs) and [client](echo-client.rs). 4 | 5 | QUIC requires TLS, which makes the initial setup a bit more involved. 6 | However, quiche doesn't support client certificates, so we have to disable verification anyway. 7 | 8 | # Commands 9 | - cd `web-transport-quiche` 10 | - Generate a certificate: `../dev/setup` 11 | - Run the Rust server: `cargo run --example echo-server -- --tls-cert ../dev/localhost.crt --tls-key ../dev/localhost.key` 12 | - Run the Rust client: `cargo run --example echo-client -- --tls-disable-verify` 13 | - Run a Web client: `cd ../web-demo; npm install; npx parcel serve client.html --open` 14 | 15 | If you get a certificate error with the web client, try deleting `.parcel-cache`. 16 | -------------------------------------------------------------------------------- /web-transport-quinn/examples/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | A simple [server](echo-server.rs) and [client](echo-client.rs). 4 | 5 | There's also advanced examples [server](echo-server-advanced.rs) and [client](echo-client-advanced.rs) that construct the QUIC connection manually. 6 | 7 | QUIC requires TLS, which makes the initial setup a bit more involved. 8 | 9 | - Generate a certificate: `../dev/setup` 10 | - Run the Rust server: `cargo run --example echo-server -- --tls-cert ../dev/localhost.crt --tls-key ../dev/localhost.key` 11 | - Run the Rust client: `cargo run --example echo-client -- --tls-cert ../dev/localhost.crt` 12 | - Run a Web client: `cd ../web-demo; npm install; npx parcel serve client.html --open` 13 | 14 | If you get a certificate error with the web client, try deleting `.parcel-cache`. 15 | -------------------------------------------------------------------------------- /web-transport-ws/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "web-transport-ws" 3 | description = "WebTransport polyfill using WebSockets" 4 | authors = ["Luke Curley"] 5 | repository = "https://github.com/moq-dev/web-transport" 6 | license = "MIT OR Apache-2.0" 7 | 8 | version = "0.2.0" 9 | edition = "2021" 10 | 11 | keywords = ["quic", "http3", "webtransport", "websocket", "polyfill"] 12 | categories = ["network-programming", "web-programming"] 13 | 14 | [dependencies] 15 | bytes = "1" 16 | futures = "0.3" 17 | thiserror = "2" 18 | tokio = { version = "1", features = ["sync", "time", "macros", "rt"] } 19 | tokio-tungstenite = "0.24" 20 | web-transport-proto = { workspace = true } 21 | web-transport-trait = { workspace = true } 22 | 23 | [dev-dependencies] 24 | anyhow = "1" 25 | tokio = { version = "1", features = ["full"] } 26 | -------------------------------------------------------------------------------- /web-transport-quiche/src/ez/mod.rs: -------------------------------------------------------------------------------- 1 | //! Easy-to-use QUIC connection and stream management. 2 | //! 3 | //! This module provides a simplified interface for working with raw QUIC connections 4 | //! using the quiche implementation. It handles the low-level details of connection 5 | //! management, stream creation, and I/O operations. 6 | 7 | mod client; 8 | mod connection; 9 | mod driver; 10 | mod lock; 11 | mod recv; 12 | mod send; 13 | mod server; 14 | mod stream; 15 | 16 | pub use client::*; 17 | pub use connection::*; 18 | pub use recv::*; 19 | pub use send::*; 20 | pub use server::*; 21 | pub use stream::*; 22 | 23 | use driver::*; 24 | use lock::*; 25 | 26 | pub use tokio_quiche::metrics::{DefaultMetrics, Metrics}; 27 | pub use tokio_quiche::settings::{ 28 | CertificateKind, QuicSettings as Settings, TlsCertificatePaths as CertificatePath, 29 | }; 30 | -------------------------------------------------------------------------------- /web-transport/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "web-transport" 3 | description = "Generic WebTransport API with native (web-transport-quinn) and WASM (web-transport-wasm) support." 4 | authors = ["Luke Curley"] 5 | repository = "https://github.com/moq-dev/web-transport" 6 | license = "MIT OR Apache-2.0" 7 | 8 | version = "0.10.0" 9 | edition = "2021" 10 | 11 | keywords = ["quic", "http3", "webtransport"] 12 | categories = ["network-programming", "web-programming"] 13 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 14 | 15 | [dependencies] 16 | bytes = "1" 17 | thiserror = "2" 18 | url = "2" 19 | 20 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 21 | web-transport-quinn = { version = "0.10.0", path = "../web-transport-quinn" } 22 | 23 | [target.'cfg(target_arch = "wasm32")'.dependencies] 24 | web-transport-wasm = { version = "0.5.3", path = "../web-transport-wasm" } 25 | -------------------------------------------------------------------------------- /web-transport-ws/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@moq/web-transport-ws", 3 | "author": "Luke Curley ", 4 | "version": "0.1.2", 5 | "description": "WebTransport polyfill using WebSockets", 6 | "type": "module", 7 | "license": "(MIT OR Apache-2.0)", 8 | "repository": "github:moq-dev/web-transport", 9 | "exports": { 10 | ".": "./src/index.ts" 11 | }, 12 | "types": "./src/index.ts", 13 | "files": [ 14 | "./src" 15 | ], 16 | "scripts": { 17 | "build": "rimraf dist && tsc && tsx scripts/package.ts", 18 | "dev": "tsc --watch", 19 | "check": "tsc --noEmit", 20 | "example": "tsx examples/client.ts", 21 | "release": "tsx scripts/release.ts" 22 | }, 23 | "devDependencies": { 24 | "typescript": "^5.9.2", 25 | "rimraf": "^6.0.1", 26 | "@types/node": "^24.3.0", 27 | "tsx": "^4.20.5" 28 | }, 29 | "keywords": [ 30 | "webtransport", 31 | "websocket", 32 | "polyfill", 33 | "quic", 34 | "streams" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /biome.jsonc: -------------------------------------------------------------------------------- 1 | // This has to be in the root otherwise the VSCode plugin will not work out of the box. 2 | { 3 | "$schema": "https://biomejs.dev/schemas/2.3.6/schema.json", 4 | "vcs": { 5 | "enabled": true, 6 | "clientKind": "git", 7 | "useIgnoreFile": true 8 | }, 9 | "formatter": { 10 | // We repeat the editorconfig settings here because biome has spotty mono-repo support. 11 | // "useEditorconfig": true, 12 | "lineWidth": 120, 13 | "indentStyle": "tab", 14 | "indentWidth": 4, 15 | "lineEnding": "lf" 16 | }, 17 | "linter": { 18 | "rules": { 19 | "a11y": { 20 | // We mostly make headless