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.
44 lines
1.6 KiB
44 lines
1.6 KiB
import { 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. */ |
|
export 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://') |
|
} |
|
|
|
/** |
|
* Merge each author's outboxes (capped per author) with {@link READ_ONLY_RELAY_URLS}: |
|
* normalized, blocked-stripped, deduped (first occurrence wins). |
|
*/ |
|
export function buildFollowOutboxAggregateReadUrls( |
|
relayLists: readonly TRelayList[], |
|
blockedRelays: 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) |
|
} |
|
} |
|
|
|
for (const u of READ_ONLY_RELAY_URLS) { |
|
const n = normalizeUrl(u) || u |
|
if (!n || isNonPublicWsRelayUrl(n) || blocked.has(n) || seen.has(n)) continue |
|
seen.add(n) |
|
out.push(n) |
|
} |
|
|
|
return out |
|
}
|
|
|