Custom Transport
You can implement custom transport layers for Teleportal by implementing the Transport interface. This guide shows you how.
Transport Interface
Section titled “Transport Interface”A transport is a combination of a Source (for reading messages) and a Sink (for writing messages):
interface Transport<Context, Properties = {}> { readable: ReadableStream<Message<Context>>; writable: WritableStream<Message<Context>>; // Optional additional properties [key: string]: any;}Example: Custom Transport
Section titled “Example: Custom Transport”import { compose } from "teleportal/transports";import type { Transport, Source, Sink } from "teleportal/transports";
// Create a source that reads from your transportfunction getMyTransportSource(): Source<Context> { return { readable: new ReadableStream({ async start(controller) { // Set up your transport's read mechanism myTransport.on("message", (data) => { // Decode message const message = decodeMessage(data); controller.enqueue(message); });
myTransport.on("close", () => { controller.close(); });
myTransport.on("error", (error) => { controller.error(error); }); }, }), };}
// Create a sink that writes to your transportfunction getMyTransportSink(): Sink<Context> { return { writable: new WritableStream({ async write(message) { // Encode message const encoded = encodeMessage(message); // Send via your transport await myTransport.send(encoded); }, async close() { await myTransport.close(); }, }), };}
// Compose into a transportconst transport: Transport<Context> = compose( getMyTransportSource(), getMyTransportSink());Binary Transport
Section titled “Binary Transport”If your transport works with raw binary data, you can use binary transport utilities:
import { toBinaryTransport, fromBinaryTransport } from "teleportal/transports";
// Convert to binary transportconst binaryTransport = toBinaryTransport(transport, context);
// Convert from binary transportconst messageTransport = fromBinaryTransport(binaryTransport, context);Composing with Middleware
Section titled “Composing with Middleware”You can compose your custom transport with middleware:
import { withLogger, withRateLimit } from "teleportal/transports";
// Add logginglet transport = withLogger(myTransport);
// Add rate limitingtransport = withRateLimit(transport, { maxMessages: 100, windowMs: 1000,});Best Practices
Section titled “Best Practices”- Handle Errors: Implement proper error handling for connection failures
- Support Cleanup: Implement cleanup logic for closing connections
- Message Encoding: Use Teleportal’s encoding/decoding utilities
- Stream API: Follow the Web Streams API patterns
- Context Injection: Ensure context is properly injected into messages