@@ -6205,14 +6205,15 @@ async function handlePublish(requestId, event, port) {
if ( NDKRelaySet ? . fromRelayUrls ) {
targetRelaySet = NDKRelaySet . fromRelayUrls ( allUrls , ndk ) ;
// Set the connection timeout on all relays in the set to match
// the per-relay publish timeout (5s) . NDK's default
// connectionTimeout is 4400ms — we set it t o 5000ms so th e
// connection attempt and publish share the same 5s budget.
// the per-relay publish timeout. NDK's default
// connectionTimeout is 4400ms — we increa se it s o relays hav e
// 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 = 5 000;
relay . connectionTimeout = 60 000;
}
} catch ( _ ) { /* relay may be read-only */ }
}
@@ -6295,12 +6296,13 @@ async function handlePublish(requestId, event, port) {
}
// Publish to relays (with broadcast relay set if broadcasting, else default outbox).
// Per-relay timeout for broadcasts: 5 seconds. This covers both the WebSocket
// connection attempt and the publish OK response for each relay. NDK runs all
// relay publishes in parallel via Promise.all, so with 600 relays th e ov erall
// time is ~5s (the slowest relay), not 600× 5s.
// 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 som e op erations. 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 = 5 000;
const BROADCAST _PER _RELAY _TIMEOUT _MS = 60 000;
const publishTimeoutMs = isBroadcast ? BROADCAST _PER _RELAY _TIMEOUT _MS : undefined ;
const publishRequiredCount = isBroadcast ? 1 : undefined ;
@@ -6309,9 +6311,9 @@ async function handlePublish(requestId, event, port) {
// 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 — in practice all relays run in parallel so the publ ish
// should complete in ~perRelayTimeout, but the deadline ensures we never
// hang indefinit ely if something goes wrong .
// 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-r ela y 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 ) => {