(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'); }); }; })();