aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/transport.js
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-24 23:47:01 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-24 23:47:01 +0200
commita41be5c5d6212f4eadc54bc17354311b0655a5a4 (patch)
tree85a46658b9cacf5752c3bfdc0ee513aa303a13d5 /packages/meshbay-hub/src/meshbay_hub/static/transport.js
parent926ebce735afd01800a669a266b90fc98f673a6b (diff)
downloadmeshbay-a41be5c5d6212f4eadc54bc17354311b0655a5a4.tar.gz
fix(hub): keep an unmatched admin_challenge visible, add trace logging
A real report showed audio_root timing out with *nothing* logged in between the connection handshake and the timeout — no admin_challenge, no error, nothing. The previous fix made an unmatched admin_challenge return silently (correctly, to stop it stealing an unrelated pending request — see the earlier commit), but that silence is indistinguishable from "the request never reached the node at all", which is exactly the ambiguity blocking this investigation. An unmatched admin_challenge is now logged (op, op_id, and the full set of currently-pending keys) instead of dropped quietly, and setAudioRoot/_authorizeAdminOp trace both hops of the round trip explicitly. Node-side, _do_audio_root gets a debug log at entry — cheap, and the only way to know from server logs alone whether the request was ever received if the client-side trail comes up empty. Diagnostic only: no routing behavior changed from the previous fix, verified against the same reproduction script.
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/transport.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport.js18
1 files changed, 17 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
index 8d8027e..7528a92 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
@@ -634,7 +634,9 @@ class MeshBayTransport {
*/
async setAudioRoot(path, signFn) {
const clean = (path || '').replace(/^\/+|\/+$/g, '');
+ console.log('[MeshBay] setAudioRoot: sending request, path=', JSON.stringify(clean));
const msg = await this._sendAndWait({ type: 'audio_root', v: '0.10', path: clean });
+ console.log('[MeshBay] setAudioRoot: first reply =', msg);
if (msg.type === 'error') throw new Error(msg.detail);
if (msg.type === 'admin_challenge') {
return this._authorizeAdminOp(msg, 'audio_root', clean, signFn);
@@ -800,6 +802,8 @@ class MeshBayTransport {
challenge.subject, challenge.nonce, challenge.ts);
const signature = await signFn(transcript);
+ console.log('[MeshBay] _authorizeAdminOp: signed', challenge.op, 'op_id=', challenge.op_id,
+ '— sending admin_response');
const ack = await this._sendAndWait({
type: 'admin_response',
v: '0.1',
@@ -813,6 +817,7 @@ class MeshBayTransport {
// pending) are matched by nothing more than arrival order.
op: challenge.op,
});
+ console.log('[MeshBay] _authorizeAdminOp:', challenge.op, 'admin_response reply =', ack);
if (ack.type === 'error') throw new Error(ack.detail);
return ack;
}
@@ -1522,8 +1527,19 @@ class MeshBayTransport {
// "oldest pending" here can only ever be wrong, never a fallback
// that happens to be right.
const key = `admin:${msg.op}`;
+ let matched = false;
for (const [, handler] of this._pending) {
- if (handler._key === key) { handler.resolve(msg); break; }
+ if (handler._key === key) { handler.resolve(msg); matched = true; break; }
+ }
+ if (!matched) {
+ // Should not happen — every caller that can receive this type keys
+ // its own request the same way. Logged rather than silently
+ // dropped (the old fallback below at least warned, however wrongly
+ // it guessed) so a real mismatch is still visible instead of
+ // looking exactly like the request never left the browser at all.
+ console.warn('[MeshBay] admin_challenge for op=', msg.op, 'op_id=', msg.op_id,
+ 'matched no pending request (pending keys:',
+ [...this._pending.values()].map(h => h._key), ')');
}
return;
} else if (typeof msg.type === 'string' && msg.type.endsWith('_ack')) {