zebra-spaces: never truncate in log lines — strip every shortHex() out of logLine()

Per fox. shortHex() rendered things like 'joined as host — uuid
8255…6dd6' / 'sfu: subscribed as bfd2…17c8' — useless for diagnosing
defects because the truncated hex doesn't match what's in the SFU
log or the WS server log.

Stripped shortHex from every logLine() callsite (17 lines):
- 'logged out — fresh identity <full pubHex>'
- 'sfu: receiving <full uuid>' (mic attach)
- 'sfu: publishing as <full peerID>' (mic publish)
- 'sfu: sharing screen as <full peerID>'
- 'sfu: sharing gameplay as <full peerID>'
- 'sfu: camera on as <full peerID>'
- 'sfu ontrack: kind=X pub=<full pubHex>'
- 'sfu: unknown kind X from <full pubHex>'
- 'sfu: subscribed as <full peerID>'
- 'meter for <full uuid>: <err>'
- 'joined as <role> — uuid <full uuid>'
- 'sdp from <full uuid> failed: <err>'

UI sites (badges, pub-short label, member-row chips, invite-from
banner) still call shortHex — those are display, not diagnostic.
This commit is contained in:
Russell Ballestrini 2026-06-02 13:13:41 -04:00
parent 0dcc99599e
commit 3526596936
No known key found for this signature in database

View file

@ -1335,7 +1335,7 @@ $('btn-logout').addEventListener('click', async () => {
myHandle = ''; $('handle').value = '';
myKeys = await generateIdentity();
renderIdentity();
logLine('', 'logged out — fresh identity '+shortHex(myKeys.pubHex));
logLine('', 'logged out — fresh identity '+myKeys.pubHex);
});
$('btn-vault-backup').addEventListener('click', async () => {
const pw = $('vault-pass').value;
@ -1455,7 +1455,7 @@ function attachSfuTrack(uuid, stream){
* swap — caller already had a user gesture (entered the space) */
try { const p = a.play(); if (p && p.catch) p.catch(()=>{}); } catch(_){}
stopMeter(uuid); startMeter(uuid, stream);
logLine('', 'sfu: receiving '+((members.get(uuid)||{}).handle || shortHex(uuid)));
logLine('', 'sfu: receiving '+((members.get(uuid)||{}).handle || uuid));
}
/* If we already have a cached SFU stream for this member's pubkey (from a
* prior subscribe-side ontrack), attach it. Used on peer-joined / host
@ -1907,7 +1907,7 @@ async function sfuPublish(){
const ans = await res.json();
await pc.setRemoteDescription({ type:'answer', sdp: ans.sdp });
sfuPubPC = pc; sfuPubPeerID = ans.peer_id;
logLine('', 'sfu: publishing as '+shortHex(sfuPubPeerID));
logLine('', 'sfu: publishing as '+sfuPubPeerID);
}
/* ----- screen share ----- */
@ -1975,7 +1975,7 @@ async function sfuPublishScreen(){
if (s.track.kind === 'video') setSenderMaxBitrate(s, 6000000);
if (s.track.kind === 'audio') setSenderMaxBitrate(s, 256000);
}
logLine('', 'sfu: sharing screen as '+shortHex(sfuScreenPeerID));
logLine('', 'sfu: sharing screen as '+sfuScreenPeerID);
/* render a muted local preview so the publisher sees what they're
* sharing — SFU does not echo the publisher's own stream back */
renderScreenTile(myKeys.pubHex, stream, { local: true });
@ -2054,7 +2054,7 @@ async function sfuPublishGame(iframe){
if (s.track.kind === 'video') setSenderMaxBitrate(s, 4000000);
if (s.track.kind === 'audio') setSenderMaxBitrate(s, 256000);
}
logLine('', 'sfu: sharing gameplay as '+shortHex(sfuGamePeerID));
logLine('', 'sfu: sharing gameplay as '+sfuGamePeerID);
}
async function sfuUnpublishGame(){
if (!sfuGamePC && !sfuGameStream) return;
@ -2104,7 +2104,7 @@ async function sfuPublishCamera(){
for (const s of pc.getSenders()){
if (s.track && s.track.kind === 'video') setSenderMaxBitrate(s, 1500000);
}
logLine('', 'sfu: camera on as '+shortHex(sfuCameraPeerID));
logLine('', 'sfu: camera on as '+sfuCameraPeerID);
renderCameraTile(myKeys.pubHex, stream, { local: true });
$('btn-camera-share').classList.add('hidden');
$('btn-camera-stop').classList.remove('hidden');
@ -2168,7 +2168,7 @@ async function sfuSubscribe(){
} catch(_){}
}
if (kind === 'screen' || kind === 'camera' || kind === 'game'){
logLine('', 'sfu ontrack: kind=' + kind + ' pub=' + shortHex(pubHex) +
logLine('', 'sfu ontrack: kind=' + kind + ' pub=' + pubHex +
' track=' + ev.track.kind + ' mute=' + ev.track.muted + ' state=' + ev.track.readyState);
}
if (kind === 'screen'){
@ -2193,7 +2193,7 @@ async function sfuSubscribe(){
return;
}
if (kind !== 'mic'){
logLine('', 'sfu: unknown kind '+kind+' from '+shortHex(pubHex));
logLine('', 'sfu: unknown kind '+kind+' from '+pubHex);
return;
}
/* mic audio — 400ms jitter-buffer target absorbs Wi-Fi peak jitter */
@ -2291,7 +2291,7 @@ async function sfuSubscribe(){
});
};
sfuSubEvents.onerror = () => { /* EventSource auto-reconnects */ };
logLine('', 'sfu: subscribed as '+shortHex(sfuSubPeerID));
logLine('', 'sfu: subscribed as '+sfuSubPeerID);
}
async function sfuUnsubscribe(){
@ -2517,7 +2517,7 @@ function startMeter(uuid, stream){
if (!audioCtx) audioCtx = new (window.AudioContext||window.webkitAudioContext)();
let src;
try { src = audioCtx.createMediaStreamSource(stream); }
catch(e){ logLine('err','meter for '+shortHex(uuid)+': '+e.message); return; }
catch(e){ logLine('err','meter for '+uuid+': '+e.message); return; }
const an = audioCtx.createAnalyser(); an.fftSize = 512;
src.connect(an);
const buf = new Uint8Array(an.fftSize);
@ -2661,7 +2661,7 @@ async function handleSignal(raw){
spotlights.set(myUUID, spotlightKey());
broadcastSpotlight();
reorderTiles();
logLine('', 'joined as '+myRole+' — uuid '+shortHex(myUUID));
logLine('', 'joined as '+myRole+' — uuid '+myUUID);
setStatus('connected as '+myRole, 'ok');
$('dot-call').className='dot ok';
$('btn-leave').disabled = false;
@ -2733,7 +2733,7 @@ async function handleSignal(raw){
break;
case 'sdp-from':
try { await onSDP(m.from, m.kind, await aesDecrypt(sigKey, unb64(m.data))); }
catch(e){ logLine('err','sdp from '+shortHex(m.from)+' failed: '+e.message); }
catch(e){ logLine('err','sdp from '+m.from+' failed: '+e.message); }
break;
case 'mic-state':
try { const s = JSON.parse(await aesDecrypt(sigKey, unb64(m.data)));
@ -2762,7 +2762,7 @@ async function handleSignal(raw){
const from = members.get(m.from);
$('invite-from').textContent = 'from '+(from?from.handle:shortHex(m.from));
$('sec-invite').classList.remove('hidden');
logLine('', 'you were invited to the mic by '+(from?from.handle:shortHex(m.from)));
logLine('', 'you were invited to the mic by '+(from?from.handle:m.from));
} else {
const from = members.get(m.from), to = members.get(m.to);
if (from && to) logLine('', from.handle+' invited '+to.handle+' to the mic');
@ -2771,7 +2771,7 @@ async function handleSignal(raw){
case 'mic-invite-declined':
if (m.from === myUUID){
const to = members.get(m.to);
logLine('', (to?to.handle:shortHex(m.to))+' declined the mic');
logLine('', (to?to.handle:m.to)+' declined the mic');
}
break;
case 'role-change':
@ -2847,7 +2847,7 @@ async function handleSignal(raw){
if (mm){ mm.role = 'host';
if (m.new_host_uuid === myUUID){ myRole = 'host'; setStatus('connected as host','ok'); onRoleChanged('cohost','host'); }
else { setStatus('connected as '+myRole, 'ok'); } /* clears the space-closing warning */
logLine('', (mm.handle||shortHex(m.new_host_uuid))+' is now host'); }
logLine('', (mm.handle||m.new_host_uuid)+' is now host'); }
flushSfuStreams();
renderRoom();
reorderTiles();
@ -2956,7 +2956,7 @@ function updateRoleUI(){
* ================================================================== */
async function connectToPeer(uuid, weOffer){
if (peers.has(uuid)) return;
if (!micStream){ try { await getMic(); } catch(e){ logLine('err','mic for '+shortHex(uuid)+': '+e.message); return; } }
if (!micStream){ try { await getMic(); } catch(e){ logLine('err','mic for '+uuid+': '+e.message); return; } }
const pc = new RTCPeerConnection(rtcConfig);
peers.set(uuid, pc);
for (const tr of micStream.getTracks()){ tagTrack(tr); pc.addTrack(tr, micStream); }
@ -2973,7 +2973,7 @@ async function connectToPeer(uuid, weOffer){
pc.onicecandidate = (ev) => { /* using waitForIceGathering pattern, candidates ignored */ };
pc.onconnectionstatechange = () => {
if (pc.connectionState === 'failed' && peers.get(uuid) === pc){
logLine('', 'peer '+shortHex(uuid)+' failed — reconnecting');
logLine('', 'peer '+uuid+' failed — reconnecting');
tearPeer(uuid);
/* let the offerer drive recovery */
setTimeout(()=>{ if (members.has(uuid) && canSpeak(members.get(uuid).role) && canSpeak(myRole))
@ -3526,8 +3526,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-02</span><br>
md5 <span class="stamp-md5">6943dfacd39a9bdfd65afc8ff520a202</span><br>
sha256 <span class="stamp-sha">2586303203b2c3703e7f211d7350b160c7e9638c482531fa472f128248ad72b2</span><br>
md5 <span class="stamp-md5">db7864ab02b2dfe8c011bbce6b12cdd9</span><br>
sha256 <span class="stamp-sha">cf6dea71571ba9dba2c5c68b71660332186c77383056c5ee2e7a928b93fd822d</span><br>
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
</footer>