The transport connects adapters to the Saikuro runtime. All transports carry the same MessagePack-encoded envelopes; only the underlying mechanism differs.

Address Format

All adapters use a unified address string to select and configure transports:

Format Transport Platform
memory:// (or memory://name) InMemory All (testing)
unix:///path/to/socket Unix socket Linux, macOS
tcp://host:port TCP All native
ws://host/path WebSocket All
wss://host/path WebSocket TLS All
wasm-host://channel (or wasm-host) BroadcastChannel WASM (browser)

The factory functions (makeTransport / make_transport) parse these addresses automatically:

// TypeScript - factory picks the right transport
import { makeTransport } from "@nisoku/saikuro";

const transport = makeTransport("unix:///tmp/saikuro.sock");
# Python
from saikuro import make_transport

transport = make_transport("unix:///tmp/saikuro.sock")
// C# - TransportFactory parses address strings
var transport = TransportFactory.Create("unix:///tmp/saikuro.sock");

InMemory Transport

For same-process usage: testing, embedded runtimes, and WASM environments.

Both sides of the transport are created as a pair:

import { InMemoryTransport } from "@nisoku/saikuro";

const [providerTransport, clientTransport] = InMemoryTransport.pair();

const provider = new SaikuroProvider("math");
// provider.serveOn(providerTransport); ...

const client = await SaikuroClient.openOn(clientTransport);
from saikuro import InMemoryTransport

provider_transport, client_transport = InMemoryTransport.pair()

InMemory transport is the default for tests. It gives you full Saikuro behavior with zero network overhead.

Unix Socket

For same-machine cross-process communication.

const client = await SaikuroClient.connect("unix:///tmp/saikuro.sock");
async with SaikuroClient.connect("unix:///tmp/saikuro.sock") as client:
    ...
let client = Client::connect("unix:///tmp/saikuro.sock").await?;

TCP Transport

For cross-machine communication.

const client = await SaikuroClient.connect("tcp://10.0.0.5:7700");
async with SaikuroClient.connect("tcp://10.0.0.5:7700") as client:
    ...

WebSocket Transport

For browser clients or when you need HTTP compatibility.

// Browser or Node.js
const client = await SaikuroClient.connect("ws://localhost:7700");
async with SaikuroClient.connect("ws://localhost:7700") as client:
    ...

TLS is supported via the wss:// scheme:

const client = await SaikuroClient.connect("wss://example.com/saikuro");

WasmHost Transport

For same-origin browser WASM communication using the BroadcastChannel API. Both the runtime and adapters run in the browser, and the transport bridges them via message passing.

// Browser WASM context
import { WasmHostTransport } from "@nisoku/saikuro";

const transport = new WasmHostTransport("saikuro");

The address string form is wasm-host://channel-name:

const client = await SaikuroClient.connect("wasm-host://saikuro");

See the WASM Guide for full details on WASM integration.

In C and C++

Transport configuration is passed via the runtime handle at initialization:

SaikuroRuntimeConfig config = {
    .address = "unix:///tmp/saikuro.sock",
    .transport_kind = SAIKURO_TRANSPORT_UNIX
};
SaikuroHandle* handle = saikuro_init(&config);

Transport Requirements

All transports must provide:

  • Ordered delivery: messages arrive in the order sent
  • Backpressure: senders slow down when the receiver falls behind
  • Binary-safe: raw bytes without modification

InMemory, Unix, TCP, and WebSocket all satisfy these by default.

Testing with InMemory Transport

import { describe, it, expect } from "vitest";
import { SaikuroProvider, SaikuroClient, InMemoryTransport } from "@nisoku/saikuro";

describe("math provider", () => {
  it("adds two numbers", async () => {
    const [pt, ct] = InMemoryTransport.pair();

    const provider = new SaikuroProvider("math");
    provider.register("add", (a: number, b: number) => a + b);
    await provider.serveOn(pt);

    const client = await SaikuroClient.openOn(ct);
    expect(await client.call("math.add", [1, 2])).toBe(3);
  });
});
import pytest
from saikuro import SaikuroProvider, SaikuroClient, InMemoryTransport

@pytest.mark.asyncio
async def test_add():
    pt, ct = InMemoryTransport.pair()
    provider = SaikuroProvider("math")

    @provider.register("add")
    def add(a: int, b: int) -> int:
        return a + b

    await provider.serve_on(pt)
    async with SaikuroClient.open_on(ct) as client:
        assert await client.call("math.add", [1, 2]) == 3

Next Steps