Normalize relay URLs to prevent duplicate WebSocket connections
The deduplication was comparing raw URL strings, so 'wss://relay.ditto.pub' and 'wss://relay.ditto.pub/' were treated as different relays, each getting their own WebSocket connection. - Normalize URLs (lowercase, strip trailing slashes) before comparing - Strip trailing slashes from NIP-65 relay URLs when syncing - Deduplicate user-only relay lists too, not just merged lists Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
@@ -33,7 +33,7 @@ export function NostrSync() {
|
||||
const fetchedRelays = event.tags
|
||||
.filter(([name]) => name === 'r')
|
||||
.map(([_, url, marker]) => ({
|
||||
url,
|
||||
url: url.replace(/\/+$/, ''),
|
||||
read: !marker || marker === 'read',
|
||||
write: !marker || marker === 'write',
|
||||
}));
|
||||
|
||||
+33
-7
@@ -1,5 +1,10 @@
|
||||
import type { RelayMetadata } from '@/contexts/AppContext';
|
||||
|
||||
/** Normalize a relay URL for deduplication (lowercase, strip trailing slash). */
|
||||
function normalizeUrl(url: string): string {
|
||||
return url.toLowerCase().replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* App default relays that are used as a fallback when the user has no NIP-65 relay list,
|
||||
* and can be optionally combined with user relays.
|
||||
@@ -24,18 +29,39 @@ export function getEffectiveRelays(
|
||||
useAppRelays: boolean
|
||||
): RelayMetadata {
|
||||
if (!useAppRelays) {
|
||||
return userRelays;
|
||||
return deduplicateRelays(userRelays);
|
||||
}
|
||||
|
||||
// Merge app relays with user relays, avoiding duplicates
|
||||
const appRelayUrls = new Set(APP_RELAYS.relays.map(r => r.url));
|
||||
const mergedRelays = [
|
||||
...APP_RELAYS.relays,
|
||||
...userRelays.relays.filter(r => !appRelayUrls.has(r.url)),
|
||||
];
|
||||
// Merge app relays with user relays, avoiding duplicates by normalized URL
|
||||
const seen = new Set<string>();
|
||||
const mergedRelays = [];
|
||||
|
||||
for (const relay of [...APP_RELAYS.relays, ...userRelays.relays]) {
|
||||
const normalized = normalizeUrl(relay.url);
|
||||
if (!seen.has(normalized)) {
|
||||
seen.add(normalized);
|
||||
mergedRelays.push(relay);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
relays: mergedRelays,
|
||||
updatedAt: userRelays.updatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
/** Deduplicate relays within a single list by normalized URL. */
|
||||
function deduplicateRelays(metadata: RelayMetadata): RelayMetadata {
|
||||
const seen = new Set<string>();
|
||||
const relays = [];
|
||||
|
||||
for (const relay of metadata.relays) {
|
||||
const normalized = normalizeUrl(relay.url);
|
||||
if (!seen.has(normalized)) {
|
||||
seen.add(normalized);
|
||||
relays.push(relay);
|
||||
}
|
||||
}
|
||||
|
||||
return { relays, updatedAt: metadata.updatedAt };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user