You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
2.0 KiB
61 lines
2.0 KiB
import { |
|
DEFAULT_FAVORITE_RELAYS, |
|
FAST_READ_RELAY_URLS, |
|
READ_ONLY_RELAY_URLS |
|
} from '@/constants' |
|
import { normalizeUrl } from '@/lib/url' |
|
import { relayUrlsLocalsFirst } from '@/lib/relay-url-priority' |
|
import type { TRelayList } from '@/types' |
|
|
|
/** First N NIP-65 `write` (outbox) URLs per followed pubkey, follow-list order; locals first per author. */ |
|
const FOLLOW_OUTBOX_AGGREGATE_PER_AUTHOR = 2 |
|
|
|
/** Plain `ws://` relays are almost always someone else's LAN; the client cannot use them for third-party reads. */ |
|
function isNonPublicWsRelayUrl(normalizedUrl: string): boolean { |
|
return normalizedUrl.toLowerCase().startsWith('ws://') |
|
} |
|
|
|
function addLayer( |
|
out: string[], |
|
seen: Set<string>, |
|
blocked: Set<string>, |
|
urls: readonly string[] |
|
): void { |
|
for (const u of urls) { |
|
const n = normalizeUrl(u) || u |
|
if (!n || isNonPublicWsRelayUrl(n) || blocked.has(n) || seen.has(n)) continue |
|
seen.add(n) |
|
out.push(n) |
|
} |
|
} |
|
|
|
/** |
|
* Merge each author's outboxes (capped per author) with {@link READ_ONLY_RELAY_URLS}, |
|
* {@link FAST_READ_RELAY_URLS}, and user favorites: normalized, blocked-stripped, |
|
* deduped (first occurrence wins). |
|
*/ |
|
export function buildFollowOutboxAggregateReadUrls( |
|
relayLists: readonly TRelayList[], |
|
blockedRelays: readonly string[], |
|
favoriteRelays: readonly string[] = [] |
|
): string[] { |
|
const blocked = new Set(blockedRelays.map((b) => normalizeUrl(b) || b).filter(Boolean)) |
|
const seen = new Set<string>() |
|
const out: string[] = [] |
|
|
|
for (const rl of relayLists) { |
|
const writes = relayUrlsLocalsFirst(rl.write ?? []) |
|
for (const u of writes.slice(0, FOLLOW_OUTBOX_AGGREGATE_PER_AUTHOR)) { |
|
const n = normalizeUrl(u) || u |
|
if (!n || isNonPublicWsRelayUrl(n) || blocked.has(n) || seen.has(n)) continue |
|
seen.add(n) |
|
out.push(n) |
|
} |
|
} |
|
|
|
addLayer(out, seen, blocked, READ_ONLY_RELAY_URLS) |
|
addLayer(out, seen, blocked, FAST_READ_RELAY_URLS) |
|
addLayer(out, seen, blocked, favoriteRelays.length > 0 ? favoriteRelays : DEFAULT_FAVORITE_RELAYS) |
|
|
|
return out |
|
}
|
|
|