Vix.cpp docs moved to vixcpp.com
Skip to content

Transport

Transport is the part of the Softadastra JavaScript SDK that allows a local node to connect to peers.

The core rule is:

Sync decides what should be sent. Transport sends it.

Transport is optional. A Softadastra client can still write, read, persist, and track sync work without transport.

Why transport exists

A local write can happen without any peer:

js
await client.put("message/1", "hello");

But when a peer is available, the node may need to send sync work to that peer. Transport exists for that delivery step.

txt
local write

store

sync outbox

sync batch

transport

peer

Transport is optional

js
options.enableTransport = false;

The client can still open, put, get, remove, syncStateInfo, tick, refreshNodeInfo, and close.

Basic transport example

js
import { Client, ClientOptions, Peer } from "@softadastra/sdk";

const options = ClientOptions.local("node-tcp-a");

options.enableWal = true;
options.walPath = "data/sdk-tcp-peer-sync.wal";
options.autoFlush = true;

options.enableTransport = true;
options.transportHost = "127.0.0.1";
options.transportPort = 4041;

options.enableDiscovery = false;

const client = new Client(options);

const openResult = await client.open();

if (openResult.isErr()) {
  console.error(`failed to open client: ${openResult.error().message}`);
  process.exit(1);
}

const transportResult = await client.startTransport();

if (transportResult.isErr()) {
  console.error(`failed to start transport: ${transportResult.error().message}`);
  await client.close();
  process.exit(1);
}

const peer = new Peer("node-tcp-b", "127.0.0.1", 4042);

const connectResult = await client.connect(peer);

if (connectResult.isErr()) {
  console.log("peer connection failed");
  console.log(`  peer    : ${peer.nodeId}`);
  console.log(`  address : ${peer.host}:${peer.port}`);
  console.log(`  error   : ${connectResult.error().message}`);
} else {
  console.log("connected to peer");
}

const putResult = await client.put("sync/message", "hello from node-tcp-a");

if (putResult.isErr()) {
  console.error(`failed to submit sync value: ${putResult.error().message}`);
  await client.close();
  process.exit(1);
}

const tickResult = await client.tick();

if (tickResult.isOk()) {
  console.log("\nsync tick");
  console.log(`  retried : ${tickResult.value().retriedCount}`);
  console.log(`  pruned  : ${tickResult.value().prunedCount}`);
  console.log(`  batch   : ${tickResult.value().batchSize}`);
}

console.log("\ntransport");
console.log(`  running : ${client.transportRunning() ? "yes" : "no"}`);

await client.close();

If no peer is running on 127.0.0.1:4042, the connection can fail cleanly. Local writes and sync ticks continue regardless.

Start transport

js
const result = await client.startTransport();

if (result.isErr()) {
  console.error(`failed to start transport: ${result.error().message}`);
  await client.close();
  process.exit(1);
}

Snake_case alias, if exposed: await client.start_transport().

Check transport status

js
if (client.transportRunning()) {
  console.log("transport is running");
}

Stop transport

If exposed:

js
await client.stopTransport();

Peer

js
const peer = new Peer("node-tcp-b", "127.0.0.1", 4042);

Connect to a peer

js
const result = await client.connect(peer);

if (result.isErr()) {
  console.log("peer connection failed");
  console.log(`  peer    : ${peer.nodeId}`);
  console.log(`  address : ${peer.host}:${peer.port}`);
  console.log(`  error   : ${result.error().message}`);
}

A failed connection should not make the local store unusable:

js
await client.put("draft/1", "still local");

Transport and local writes

Transport is not required for local writes. Even if client.connect(peer) fails, client.put() should still work.

Transport port configuration

Each local node needs a different transport port:

js
// Node A
options.transportPort = 4041;

// Node B
options.transportPort = 4042;

Transport API reference

MethodPurpose
startTransport()Start the local transport layer
start_transport()Snake_case alias, if exposed
stopTransport()Stop transport, if exposed
stop_transport()Snake_case alias, if exposed
transportRunning()Check whether transport is running
transport_running()Snake_case alias, if exposed
connect(peer)Connect to a peer

Transport option reference

OptionPurpose
enableTransportEnable transport support
transportHostLocal bind host
transportPortLocal bind port

Peer reference

FieldPurpose
nodeIdRemote node id
hostRemote host
portRemote transport port

Common issues

Port already in use

sh
ss -ltnp | grep 4041

Use another port: options.transportPort = 4043.

Transport disabled

If you call startTransport() but enableTransport = false, the SDK should return a clear error.

Common mistakes

Expecting transport to be required for local writes

Transport is optional. Local writes work without it.

Confusing transport with sync

Transport sends messages. Sync tracks operations.

Confusing transport with discovery

Discovery finds peers. Transport connects to peers.

Reusing the same port

Use unique ports for each local node.

Run the SDK example

sh
cd ~/softadastra/sdk-js
npm install
mkdir -p data
npm run examples:tcp-peer-sync

Summary

Transport is the peer communication layer of the JavaScript SDK.

It gives you startTransport, transportRunning, connect(peer), and optional stopTransport.

The key idea is: transport sends messages, sync decides what messages mean, and store remains local-first.

A transport failure should delay synchronization, not destroy local work.

Next step

Continue with discovery:

Go to Discovery

Released under the Apache License 2.0.