Transport
The transport layer handles how messages are sent and received between clients and servers. Teleportal’s transport system is built on the Web Streams API, making it composable and allowing multiple transports to be chained together.
Overview
Section titled “Overview”A Transport is a combination of a Source (for reading messages) and a Sink (for writing messages). The server’s perspective is:
{ readable: messagesFromClient, writable: messagesToClient}The client’s perspective is:
{ readable: messagesFromServer, writable: messagesToServer}Architecture
Section titled “Architecture”The transport system follows a composable architecture:
- Base transports handle the actual communication (HTTP, SSE, WebSocket, PubSub)
- Middleware transports wrap other transports to add functionality (encryption, rate limiting, logging, validation)
- Utility functions help compose, pipe, and transform transports
Rate Limiting
Section titled “Rate Limiting”Throttles messages using a token bucket algorithm:
import { withRateLimit } from "teleportal/transports/rate-limiter";
const rateLimitedTransport = withRateLimit(transport, { maxMessages: 100, windowMs: 1000, trackBy: "user",});Message Encryption
Section titled “Message Encryption”Wraps a transport with end-to-end encryption:
import { getEncryptedTransport } from "teleportal/transports/encrypted";
const encryptedTransport = getEncryptedTransport(handler);Message Validation
Section titled “Message Validation”Adds authorization checks to message reading and writing:
import { withMessageValidator } from "teleportal/transports/message-validator";
const validatedTransport = withMessageValidator(transport, { isAuthorized: async (message, type) => { // Your authorization logic return true; },});Logging
Section titled “Logging”Logs all messages for debugging:
import { withLogger } from "teleportal/transports/logger";
const loggedTransport = withLogger(transport);ACK Support
Section titled “ACK Support”Adds acknowledgment message support for reliable message delivery:
import { withAckSink, withAckTrackingSink } from "teleportal/transports/ack";
// Server: Send ACKs automaticallyconst ackSink = withAckSink(sink, { pubSub, ackTopic: "acks", sourceId: "server-1",});
// Client: Track ACKsconst trackingSink = withAckTrackingSink(sink, { pubSub, ackTopic: "acks", sourceId: "client-1", ackTimeout: 10000,});Transport Composition
Section titled “Transport Composition”Transports can be composed in layers:
// Base transportlet transport = getBaseTransport();
// Add encryptiontransport = getEncryptedTransport(handler);
// Add rate limitingtransport = withRateLimit(transport, options);
// Add loggingtransport = withLogger(transport);
// Add message validationtransport = withMessageValidator(transport, { isAuthorized: async (message, type) => { // Authorization logic return true; },});Y.js Document Transport
Section titled “Y.js Document Transport”The YDoc transport integrates Y.js documents with the Teleportal transport system:
import { getYTransportFromYDoc } from "teleportal/transports/ydoc";
const transport = getYTransportFromYDoc({ ydoc, awareness, document: "my-document", context: { clientId: "client-1" },});
// Start synchronizationawait transport.handler.start();Utility Functions
Section titled “Utility Functions”Compose
Section titled “Compose”Combines a Source and Sink into a Transport:
import { compose } from "teleportal/transports";
const transport = compose(source, sink);Pipes messages from a Source to a Sink:
import { pipe } from "teleportal/transports";
await pipe(source, sink);Bidirectionally syncs two transports:
import { sync } from "teleportal/transports";
await sync(transportA, transportB);Best Practices
Section titled “Best Practices”- Compose from bottom up: Start with base transports, then add middleware
- Handle errors: Transports can error, ensure proper error handling
- Clean up resources: Call
close()orunsubscribe()when done - Use appropriate transports: Choose transports based on your use case
- Rate limit client transports: Always rate limit client-side transports to prevent abuse
- Validate messages: Use message validators for authorization checks
- Monitor with logging: Use logger transport during development
Next Steps
Section titled “Next Steps”- Server - Learn how the server uses transports
- Provider - See how clients use transports
- Advanced: Custom Transport - Implement your own transport