Files
BridgeSwarm/examples/sync-demo/app.js
T
Raven Scott f71b01bdb2
CI / Build & Test (push) Successful in 8m7s
Update examples
2026-07-27 02:28:23 -04:00

172 lines
5.6 KiB
JavaScript

(function () {
var statusEl = document.getElementById('status');
var logEl = document.getElementById('log');
var swarm = null;
var peerCount = 0;
var pollTimer = null;
var session = BridgeSwarmExamples.sessionStore('sync');
function setStatus(msg, isError) {
statusEl.textContent = msg;
statusEl.className = 'bs-status' + (isError ? ' error' : '');
}
function log(msg, type) {
BridgeSwarmExamples.logLine(logEl, msg, type);
}
function request(type, payload) {
return window.BridgeSwarm.request(type, payload || {}).then(function (r) {
if (!r.ok) throw new Error(r.error || 'Request failed');
return r;
});
}
async function refreshCore() {
try {
var r = await request('coreInfo');
document.getElementById('coreMeta').textContent =
'Core key=' + (r.key || '').slice(0, 16) + '… length=' + r.length + ' writable=' + r.writable;
return r;
} catch (e) {
log(e.message, 'err');
}
}
function setJoinedUi(joined) {
document.getElementById('btnJoin').disabled = joined;
document.getElementById('btnLeave').disabled = !joined;
document.getElementById('btnAutoOn').disabled = !joined;
document.getElementById('btnAutoOff').disabled = !joined;
document.getElementById('appendVal').disabled = !joined;
document.getElementById('btnAppend').disabled = !joined;
document.getElementById('btnInfo').disabled = !joined;
}
async function joinTopic(topic, opts) {
if (swarm) return;
opts = opts || {};
swarm = new window.BridgeSwarm(session.swarmOptions('bridge-swarm-sync', topic, opts));
swarm.on('connection', function (conn, peerInfo, payload) {
peerCount++;
document.getElementById('peers').textContent = 'Peers: ' + peerCount;
var auto = (payload && payload.autoReplicated) || (peerInfo && peerInfo.autoReplicated);
log(
'Peer ' + (peerInfo.publicKey || '').slice(0, 16) + '…' +
(auto ? ' (auto-replicated)' : ''),
'peer'
);
conn.on('end', function () {
peerCount = Math.max(0, peerCount - 1);
document.getElementById('peers').textContent = 'Peers: ' + peerCount;
log('Peer left', 'sys');
});
});
await swarm.join(topic);
await session.resumeConnections(swarm);
session.markJoined(swarm, topic);
var pk = await swarm.getPublicKey();
document.getElementById('publicKey').textContent = 'Your public key: ' + pk;
setStatus('Joined "' + topic + '"');
setJoinedUi(true);
log('Joined ' + topic, 'sys');
await refreshCore();
}
BridgeSwarmExamples.waitForBridgeSwarm().then(async function () {
await refreshCore();
var sess = session.load();
if (sess && sess.active && sess.topic) {
document.getElementById('topic').value = sess.topic;
setStatus('Restoring session…');
try {
await joinTopic(sess.topic, { swarmId: sess.swarmId });
} catch (e) {
session.clear();
setStatus(e.message || 'Could not restore session', true);
log(e.message, 'err');
}
return;
}
setStatus('Join a topic. Enable auto-replicate, then append on one tab and poll on the other.');
}).catch(function (e) {
setStatus(e.message, true);
});
document.getElementById('btnJoin').onclick = async function () {
if (swarm) return;
try {
var topic = document.getElementById('topic').value.trim() || 'bridge-swarm-sync';
await joinTopic(topic);
} catch (e) {
setStatus(e.message, true);
log(e.message, 'err');
}
};
document.getElementById('btnLeave').onclick = async function () {
if (pollTimer) clearInterval(pollTimer);
pollTimer = null;
if (swarm) {
try { await swarm.destroy(); } catch (_) {}
}
swarm = null;
peerCount = 0;
session.clear();
document.getElementById('peers').textContent = 'Peers: 0';
setJoinedUi(false);
document.getElementById('autoState').textContent = 'auto: off';
setStatus('Left.');
log('Left', 'sys');
};
document.getElementById('btnAutoOn').onclick = async function () {
if (!swarm) return;
try {
var info = await refreshCore();
await swarm.setAutoReplicate({
enabled: true,
coreKeyHex: info && info.key,
});
document.getElementById('autoState').textContent = 'auto: on';
document.getElementById('autoState').className = 'bs-pill bs-pill--live';
log('Auto-replicate enabled for default core', 'val');
if (pollTimer) clearInterval(pollTimer);
pollTimer = setInterval(refreshCore, 2000);
} catch (e) {
log(e.message, 'err');
}
};
document.getElementById('btnAutoOff').onclick = async function () {
if (!swarm) return;
try {
await swarm.setAutoReplicate({ enabled: false });
document.getElementById('autoState').textContent = 'auto: off';
document.getElementById('autoState').className = 'bs-pill';
if (pollTimer) clearInterval(pollTimer);
pollTimer = null;
log('Auto-replicate disabled', 'sys');
} catch (e) {
log(e.message, 'err');
}
};
document.getElementById('btnAppend').onclick = async function () {
var text = document.getElementById('appendVal').value;
if (!text) return;
try {
var base64 = btoa(unescape(encodeURIComponent(text)));
await request('coreAppend', { base64: base64 });
log('Appended: ' + text, 'val');
document.getElementById('appendVal').value = '';
await refreshCore();
} catch (e) {
log(e.message, 'err');
}
};
document.getElementById('btnInfo').onclick = function () {
refreshCore().then(function (r) {
if (r) log('length=' + r.length, 'val');
});
};
})();