Compare commits

...
3 Commits
3 changed files with 23 additions and 27 deletions
+3 -3
View File
@@ -1,5 +1,5 @@
{
"VERSION": "v0.7.73",
"VERSION_NUMBER": "0.7.73",
"BUILD_DATE": "2026-06-30T14:02:00.201Z"
"VERSION": "v0.7.76",
"VERSION_NUMBER": "0.7.76",
"BUILD_DATE": "2026-06-30T14:13:46.694Z"
}
+19 -19
View File
@@ -6204,17 +6204,16 @@ async function handlePublish(requestId, event, port) {
const allUrls = [...new Set([...outboxWriteUrls, ...activeBroadcastUrls])];
if (NDKRelaySet?.fromRelayUrls) {
targetRelaySet = NDKRelaySet.fromRelayUrls(allUrls, ndk);
// Increase the connection timeout on all relays in the set.
// NDK's default connectionTimeout is 4400ms, which is too short
// for hundreds of temporary broadcast relays that need to
// establish WebSocket connections. Give them 15s to connect.
// The publish timeout (30s below) covers the full connect+publish
// cycle per relay.
// Set the connection timeout on all relays in the set to match
// the per-relay publish timeout. NDK's default
// connectionTimeout is 4400ms — we increase it so relays have
// time to connect even when hundreds are competing for browser
// connection slots.
if (targetRelaySet?.relays) {
for (const relay of targetRelaySet.relays) {
try {
if (relay.connectionTimeout !== undefined) {
relay.connectionTimeout = 15000;
relay.connectionTimeout = 60000;
}
} catch (_) { /* relay may be read-only */ }
}
@@ -6297,24 +6296,25 @@ async function handlePublish(requestId, event, port) {
}
// Publish to relays (with broadcast relay set if broadcasting, else default outbox).
// When broadcasting to many relays (potentially hundreds), use a much longer
// per-relay timeout than NDK's default 4400ms — temporary relays need time to
// establish WebSocket connections. Use 30s per relay for broadcasts.
// Per-relay timeout for broadcasts: 60 seconds. NDK may not be able to handle
// hundreds of simultaneous WebSocket connections in true parallel — the browser
// has connection limits and NDK's pool may serialize some operations. A 60s
// per-relay timeout gives each relay ample time to connect and publish even when
// queued behind hundreds of others.
// requiredRelayCount=1 so NDK doesn't throw if only 1 of 600 relays succeeds.
const BROADCAST_PER_RELAY_TIMEOUT_MS = 30000;
const BROADCAST_PER_RELAY_TIMEOUT_MS = 60000;
const publishTimeoutMs = isBroadcast ? BROADCAST_PER_RELAY_TIMEOUT_MS : undefined;
const publishRequiredCount = isBroadcast ? 1 : undefined;
let relaySet;
if (isBroadcast) {
// For broadcasts, don't await the full Promise.all — NDK's publish()
// waits for ALL relays to resolve, so one slow relay blocks the entire
// operation. Instead, race the publish against an overall deadline.
// The live progress listeners (relay:published / relay:publish:failed)
// already track per-relay results in real time, so we can resolve early
// once the deadline hits. Relays that haven't responded by the deadline
// are simply not counted — they may still complete in the background.
const BROADCAST_OVERALL_DEADLINE_MS = 45000; // 45s overall cap
// For broadcasts, race the publish against an overall deadline.
// NDK's publish() uses Promise.all internally, so it waits for ALL
// relays to resolve. The overall deadline is totalRelays × perRelayTimeout
// as a safety cap. With 600 relays × 60s = 36000s (10 hours) — this is
// effectively "wait until all relays finish" since the deadline will never
// fire before the per-relay timeouts resolve all promises.
const BROADCAST_OVERALL_DEADLINE_MS = Math.max(30000, totalTarget * BROADCAST_PER_RELAY_TIMEOUT_MS);
const publishPromise = ndkEvent.publish(targetRelaySet, publishTimeoutMs, publishRequiredCount)
.catch((err) => {
// NDKPublishError is expected when not all relays succeed —
+1 -5
View File
@@ -833,12 +833,8 @@ import { initPostCards } from './js/post-interactions2.mjs';
: '';
spanBroadcastStatus.textContent = `📡 ${d.successful}/${d.total} relays · ${shortRelay}`;
} else if (d.phase === 'done') {
// Keep the result displayed until the next publish overwrites it.
spanBroadcastStatus.textContent = `${d.successful}/${d.total} relays` + (d.failed > 0 ? ` (${d.failed} failed)` : '');
setTimeout(() => {
if (spanBroadcastStatus.textContent.startsWith('✅')) {
spanBroadcastStatus.textContent = '';
}
}, 10000);
}
});