Co-Authored-By: gpt-5.6-sol <noreply@openai.com>
@webnet/transport
Transport abstractions and implementations for webnet.
The package defines RawTransport, RawDialer, and RawListener, the byte-stream interfaces every protocol package (http, ssh, ftp, webdav, smb2, ...) is built on: connect, accept, read a chunk, write a chunk, close, and optionally upgrade in place to TLS via upgradeTls. Reader and Writer are the read-only and write-only projections of RawTransport. Concrete implementations live in subpath exports: an in-memory loopback pair for tests, a Node net/tls socket wrapper, and a WebRTC data channel transport. ReadBuffer and WriteBuffer in the root export provide line- and size-based buffering on top of any Reader/Writer.
Entry points
| Entry point | Description |
|---|---|
@webnet/transport |
Transport interfaces and operation options. |
@webnet/transport/node |
NodeTransport-backed nodeDialer, NodeListener, nodeListen for TCP/TLS sockets. |
@webnet/transport/loopback |
loopbackTransportPair, loopbackListener for in-process, dependency-free transports. |
@webnet/transport/webrtc |
DataChannelTransport, openDataChannel, acceptDataChannel for WebRTC data channels. |
@webnet/transport/buffer |
ReadBuffer, WriteBuffer, and prependTransport for bounded reads, buffering, and CRLF line reads. |
@webnet/transport/operation |
abortable and writeAll helpers for cancellable operations and complete writes. |
@webnet/transport/stream |
Web Stream adapters and stream-to-writer pumping with backpressure. |
_internals entry points are unstable and are not part of the public API.
Usage
import { loopbackListener } from "@webnet/transport/loopback"
import type { RawTransport } from "@webnet/transport"
const [listener, dialer] = loopbackListener()
const acceptPromise = listener.accept()
const client: RawTransport = await dialer.dial("localhost", 0)
const server = await acceptPromise
await client.write(new TextEncoder().encode("hello"))
const chunk = await server.read()
if (chunk === null) {
// The peer cleanly ended its byte stream. Later reads also return null.
} else {
console.log(new TextDecoder().decode(chunk))
}
RawTransport.read() resolves to null for clean end-of-stream and keeps returning null on
later reads. Connection failures reject the promise, so callers can distinguish an orderly peer
close from a broken transport without inspecting error messages.
Pass an AbortSignal through the operation options to cancel read(), write(), or
upgradeTls(). An already-aborted signal rejects with signal.reason without touching the
transport. If the signal aborts after I/O starts, the operation rejects with the same reason and
closes the transport. Closing is required because a read may have consumed bytes and a write may
have sent some bytes.
See also
@webnet/http— HTTP client/server built onRawTransport.@webnet/ssh— SSH transport layer built onRawDialer/RawListener.@webnet/tsconnect— dials Tailscale connections through this package's transport interfaces.