Examples
This page gives the recommended learning path for the Softadastra JavaScript SDK examples.
The examples are designed to be read in order. Each one introduces one new SDK capability while keeping the previous model stable.
The core learning path is:
local store
persistent store
remove value
sync
transport
discovery
metadataExample list
01-local-store.js02-persistent-store.js03-remove-value.js04-basic-sync.js05-tcp-peer-sync.js06-discovery.js07-node-metadata.js
Before running examples
cd ~/softadastra/sdk-js
npm install
mkdir -p dataPackage scripts
The repository should expose scripts in package.json:
{
"scripts": {
"test": "node --test",
"examples:local-store": "node examples/01-local-store.js",
"examples:persistent-store": "node examples/02-persistent-store.js",
"examples:remove-value": "node examples/03-remove-value.js",
"examples:basic-sync": "node examples/04-basic-sync.js",
"examples:tcp-peer-sync": "node examples/05-tcp-peer-sync.js",
"examples:discovery": "node examples/06-discovery.js",
"examples:node-metadata": "node examples/07-node-metadata.js"
}
}Full recommended run order
cd ~/softadastra/sdk-js
npm install
mkdir -p data
npm run examples:local-store
npm run examples:persistent-store
npm run examples:remove-value
npm run examples:basic-sync
npm run examples:tcp-peer-sync
npm run examples:discovery
npm run examples:node-metadata1. Local Store
File: examples/01-local-store.js
npm run examples:local-storeThis example shows the simplest local-only SDK usage. It teaches ClientOptions.local, Client, open, put, get, size, and close.
Expected output style:
key : app/name
value : Softadastra SDK
size : 1This proves the most important Softadastra rule: local work does not require the network.
Code shape:
import { Client, ClientOptions } from "../src/index.js";
const client = new Client(ClientOptions.local("node-local"));
await client.open();
await client.put("app/name", "Softadastra SDK");
const valueResult = await client.get("app/name");
if (valueResult.isOk()) {
console.log("key : app/name");
console.log(`value : ${valueResult.value().toString()}`);
console.log(`size : ${client.size()}`);
}
await client.close();2. Persistent Store
File: examples/02-persistent-store.js
npm run examples:persistent-storeThis example shows WAL-backed local persistence. It teaches ClientOptions.persistent, enableWal, walPath, autoFlush, and sync state after write.
Expected output style:
key : settings/theme
value : dark
wal path : data/sdk-persistent-store.wal
store size : 1
outbox size : 1Code shape:
const options = ClientOptions.persistent(
"node-persistent",
"data/sdk-persistent-store.wal",
);
options.autoFlush = true;Before running: mkdir -p data.
3. Remove Value
File: examples/03-remove-value.js
npm run examples:remove-valueThis example shows how to remove a local value. It teaches put, contains, remove, get for a missing key, and the not_found error.
Expected output style:
before remove
contains : yes
after remove
contains : no
read result: not_foundCode shape:
await client.put("cache/session", "temporary-data");
console.log(`before remove: ${client.contains("cache/session") ? "yes" : "no"}`);
await client.remove("cache/session");
console.log(`after remove: ${client.contains("cache/session") ? "yes" : "no"}`);
const valueResult = await client.get("cache/session");
if (valueResult.isErr()) {
console.log(`read result: ${valueResult.error().codeString()}`);
}4. Basic Sync
File: examples/04-basic-sync.js
npm run examples:basic-syncThis example shows manual sync state and sync ticks. It teaches syncStateInfo, outboxSize, queuedCount, failedCount, tick, retriedCount, prunedCount, and batchSize.
Expected output style:
before tick
outbox : 1
queued : 1
failed : 0
tick result
retried : 0
pruned : 0
batch : 1Code shape:
await client.put("profile/name", "Softadastra");
const before = await client.syncStateInfo();
if (before.isOk()) {
console.log("before tick");
console.log(` outbox : ${before.value().outboxSize}`);
console.log(` queued : ${before.value().queuedCount}`);
console.log(` failed : ${before.value().failedCount}`);
}
const tickResult = await client.tick();
if (tickResult.isOk()) {
console.log("\ntick result");
console.log(` retried : ${tickResult.value().retriedCount}`);
console.log(` pruned : ${tickResult.value().prunedCount}`);
console.log(` batch : ${tickResult.value().batchSize}`);
}5. TCP Peer Sync
File: examples/05-tcp-peer-sync.js
npm run examples:tcp-peer-syncThis example enables transport and tries to connect to a peer. It teaches enableTransport, transportHost, transportPort, startTransport, Peer, connect, and transportRunning.
Expected output style when no peer is running:
peer connection failed
peer : node-tcp-b
address : 127.0.0.1:4042
error : ...
sync tick
retried : 0
pruned : 0
batch : 1
transport
running : yesThis proves that transport failure should not break local-first behavior.
Code shape:
import { Client, ClientOptions, Peer } from "../src/index.js";
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;
const client = new Client(options);
await client.open();
await client.startTransport();
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}`);
}
await client.put("sync/message", "hello from node-tcp-a");
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();6. Discovery
File: examples/06-discovery.js
npm run examples:discoveryThis example enables discovery and lists known peers. It teaches enableDiscovery, discoveryHost, discoveryPort, discoveryBroadcastHost, discoveryBroadcastPort, startDiscovery, discoveryRunning, and peers.
Expected output style:
discovery
running : yes
bind : 127.0.0.1:5051
target : 127.0.0.1:5052
peers
no peer discovered yetCode shape:
const options = ClientOptions.local("node-discovery-a");
options.enableTransport = true;
options.transportHost = "127.0.0.1";
options.transportPort = 4051;
options.enableDiscovery = true;
options.discoveryHost = "127.0.0.1";
options.discoveryPort = 5051;
options.discoveryBroadcastHost = "127.0.0.1";
options.discoveryBroadcastPort = 5052;
const client = new Client(options);
await client.open();
await client.startDiscovery();
const peersResult = await client.peers();
console.log("discovery");
console.log(` running : ${client.discoveryRunning() ? "yes" : "no"}`);
console.log(` bind : ${options.discoveryHost}:${options.discoveryPort}`);
console.log(` target : ${options.discoveryBroadcastHost}:${options.discoveryBroadcastPort}`);
console.log("\npeers");
if (peersResult.isOk() && peersResult.value().length === 0) {
console.log(" no peer discovered yet");
}
await client.close();7. Node Metadata
File: examples/07-node-metadata.js
npm run examples:node-metadataThis example reads local node metadata. It teaches displayName, version, refreshNodeInfo, NodeInfo, nodeId, hostname, osName, uptime_ms, and capabilities.
Expected output style:
node metadata
node id : node-metadata
display name : Softadastra SDK Node
hostname : ...
os : ...
version : 0.1.0
uptime ms : ...
capabilities : ...Code shape:
const options = ClientOptions.local("node-metadata");
options.displayName = "Softadastra SDK Node";
options.version = "0.1.0";
options.enableWal = false;
options.enableTransport = false;
options.enableDiscovery = false;
const client = new Client(options);
await client.open();
const nodeResult = await client.refreshNodeInfo();
if (nodeResult.isOk()) {
const node = nodeResult.value();
console.log("node metadata");
console.log(` node id : ${node.nodeId}`);
console.log(` display name : ${node.displayName}`);
console.log(` hostname : ${node.hostname}`);
console.log(` os : ${node.osName}`);
console.log(` version : ${node.version}`);
console.log(` uptime ms : ${node.uptime_ms()}`);
}
await client.close();What each example adds
| Example | New idea |
|---|---|
01-local-store.js | Local memory store |
02-persistent-store.js | WAL-backed local persistence |
03-remove-value.js | Remove and missing-key behavior |
04-basic-sync.js | Sync state and manual tick |
05-tcp-peer-sync.js | Transport and peer connection |
06-discovery.js | Peer discovery and peer list |
07-node-metadata.js | Local node metadata |
Learning path
- Can I write locally?
- Can I persist locally?
- Can I remove locally?
- Can I observe sync work?
- Can I start transport?
- Can I discover peers?
- Can I inspect node metadata?
Expected normal failures
Peer connection failure
05-tcp-peer-sync.js may print peer connection failed. This is normal if no peer is running on the target port. The example should still show that local writes and sync ticks continue.
No discovered peers
06-discovery.js may print no peer discovered yet. This is normal if only one node is running.
Missing key after remove
03-remove-value.js should show not_found. This is expected after removing a key.
Troubleshooting
ESM import error
npm pkg set type=moduleWAL path failed
mkdir -p dataTransport port already in use
ss -ltnp | grep 4041Discovery port already in use
ss -lunp | grep 5051How examples map to documentation
| Example | Documentation |
|---|---|
01-local-store.js | Local Store |
02-persistent-store.js | Persistent Store |
03-remove-value.js | Local Store |
04-basic-sync.js | Sync |
05-tcp-peer-sync.js | Transport |
06-discovery.js | Discovery |
07-node-metadata.js | Metadata |
Minimal example template
import { Client, ClientOptions } from "../src/index.js";
const options = ClientOptions.local("node-example");
const client = new Client(options);
const opened = await client.open();
if (opened.isErr()) {
console.error(opened.error().message);
process.exit(1);
}
// example logic here
await client.close();For published package examples:
import { Client, ClientOptions } from "@softadastra/sdk";Summary
The JavaScript SDK examples are the fastest way to understand Softadastra from an application developer point of view.
Read them in this order: Local Store, Persistent Store, Remove Value, Basic Sync, TCP Peer Sync, Discovery, Node Metadata.
The key idea is: start local, add durability, observe sync, then add peers.
Next step
Continue with the engine documentation: