refactor(highlights): split service into smaller modules; keep files <210 lines

This commit is contained in:
Gigi
2025-10-12 22:54:11 +02:00
parent 31f7d53829
commit 484c2e0c2f
4 changed files with 267 additions and 327 deletions

View File

@@ -0,0 +1,78 @@
import { RelayPool, completeOnEose, onlyEvents } from 'applesauce-relay'
import { lastValueFrom, takeUntil, timer, tap, toArray } from 'rxjs'
import { NostrEvent } from 'nostr-tools'
import { Highlight } from '../../types/highlights'
import { prioritizeLocalRelays, partitionRelays } from '../../utils/helpers'
import { eventToHighlight, dedupeHighlights, sortHighlights } from '../highlightEventProcessor'
import { UserSettings } from '../settingsService'
import { rebroadcastEvents } from '../rebroadcastService'
export const fetchHighlights = async (
relayPool: RelayPool,
pubkey: string,
onHighlight?: (highlight: Highlight) => void,
settings?: UserSettings
): Promise<Highlight[]> => {
try {
const relayUrls = Array.from(relayPool.relays.values()).map(relay => relay.url)
const ordered = prioritizeLocalRelays(relayUrls)
const { local: localRelays, remote: remoteRelays } = partitionRelays(ordered)
const seenIds = new Set<string>()
let rawEvents: NostrEvent[] = []
if (localRelays.length > 0) {
try {
rawEvents = await lastValueFrom(
relayPool
.req(localRelays, { kinds: [9802], authors: [pubkey] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
if (!seenIds.has(event.id)) {
seenIds.add(event.id)
if (onHighlight) onHighlight(eventToHighlight(event))
}
}),
completeOnEose(),
takeUntil(timer(1200)),
toArray()
)
)
} catch {
rawEvents = []
}
}
if (remoteRelays.length > 0) {
try {
const remoteEvents = await lastValueFrom(
relayPool
.req(remoteRelays, { kinds: [9802], authors: [pubkey] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
if (!seenIds.has(event.id)) {
seenIds.add(event.id)
if (onHighlight) onHighlight(eventToHighlight(event))
}
}),
completeOnEose(),
takeUntil(timer(6000)),
toArray()
)
)
rawEvents = rawEvents.concat(remoteEvents)
} catch {
// ignore
}
}
await rebroadcastEvents(rawEvents, relayPool, settings)
const uniqueEvents = dedupeHighlights(rawEvents)
const highlights = uniqueEvents.map(eventToHighlight)
return sortHighlights(highlights)
} catch {
return []
}
}

View File

@@ -0,0 +1,119 @@
import { RelayPool, completeOnEose, onlyEvents } from 'applesauce-relay'
import { lastValueFrom, takeUntil, timer, tap, toArray } from 'rxjs'
import { NostrEvent } from 'nostr-tools'
import { Highlight } from '../../types/highlights'
import { RELAYS } from '../../config/relays'
import { prioritizeLocalRelays, partitionRelays } from '../../utils/helpers'
import { eventToHighlight, dedupeHighlights, sortHighlights } from '../highlightEventProcessor'
import { UserSettings } from '../settingsService'
import { rebroadcastEvents } from '../rebroadcastService'
export const fetchHighlightsForArticle = async (
relayPool: RelayPool,
articleCoordinate: string,
eventId?: string,
onHighlight?: (highlight: Highlight) => void,
settings?: UserSettings
): Promise<Highlight[]> => {
try {
const seenIds = new Set<string>()
const processEvent = (event: NostrEvent): Highlight | null => {
if (seenIds.has(event.id)) return null
seenIds.add(event.id)
return eventToHighlight(event)
}
const orderedRelays = prioritizeLocalRelays(RELAYS)
const { local: localRelays } = partitionRelays(orderedRelays)
let aTagEvents: NostrEvent[] = []
if (localRelays.length > 0) {
try {
aTagEvents = await lastValueFrom(
relayPool
.req(localRelays, { kinds: [9802], '#a': [articleCoordinate] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
const highlight = processEvent(event)
if (highlight && onHighlight) onHighlight(highlight)
}),
completeOnEose(),
takeUntil(timer(1200)),
toArray()
)
)
} catch {
aTagEvents = []
}
}
if (aTagEvents.length === 0) {
aTagEvents = await lastValueFrom(
relayPool
.req(orderedRelays, { kinds: [9802], '#a': [articleCoordinate] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
const highlight = processEvent(event)
if (highlight && onHighlight) onHighlight(highlight)
}),
completeOnEose(),
takeUntil(timer(6000)),
toArray()
)
)
}
let eTagEvents: NostrEvent[] = []
if (eventId) {
if (localRelays.length > 0) {
try {
eTagEvents = await lastValueFrom(
relayPool
.req(localRelays, { kinds: [9802], '#e': [eventId] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
const highlight = processEvent(event)
if (highlight && onHighlight) onHighlight(highlight)
}),
completeOnEose(),
takeUntil(timer(1200)),
toArray()
)
)
} catch {
eTagEvents = []
}
}
if (eTagEvents.length === 0) {
eTagEvents = await lastValueFrom(
relayPool
.req(orderedRelays, { kinds: [9802], '#e': [eventId] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
const highlight = processEvent(event)
if (highlight && onHighlight) onHighlight(highlight)
}),
completeOnEose(),
takeUntil(timer(6000)),
toArray()
)
)
}
}
const rawEvents = [...aTagEvents, ...eTagEvents]
await rebroadcastEvents(rawEvents, relayPool, settings)
const uniqueEvents = dedupeHighlights(rawEvents)
const highlights: Highlight[] = uniqueEvents.map(eventToHighlight)
return sortHighlights(highlights)
} catch {
return []
}
}

View File

@@ -0,0 +1,67 @@
import { RelayPool, completeOnEose, onlyEvents } from 'applesauce-relay'
import { lastValueFrom, takeUntil, timer, tap, toArray } from 'rxjs'
import { NostrEvent } from 'nostr-tools'
import { Highlight } from '../../types/highlights'
import { RELAYS } from '../../config/relays'
import { prioritizeLocalRelays, partitionRelays } from '../../utils/helpers'
import { eventToHighlight, dedupeHighlights, sortHighlights } from '../highlightEventProcessor'
import { UserSettings } from '../settingsService'
import { rebroadcastEvents } from '../rebroadcastService'
export const fetchHighlightsForUrl = async (
relayPool: RelayPool,
url: string,
onHighlight?: (highlight: Highlight) => void,
settings?: UserSettings
): Promise<Highlight[]> => {
try {
const seenIds = new Set<string>()
const orderedRelaysUrl = prioritizeLocalRelays(RELAYS)
const { local: localRelaysUrl } = partitionRelays(orderedRelaysUrl)
let rawEvents: NostrEvent[] = []
if (localRelaysUrl.length > 0) {
try {
rawEvents = await lastValueFrom(
relayPool
.req(localRelaysUrl, { kinds: [9802], '#r': [url] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
seenIds.add(event.id)
if (onHighlight) onHighlight(eventToHighlight(event))
}),
completeOnEose(),
takeUntil(timer(1200)),
toArray()
)
)
} catch {
rawEvents = []
}
}
if (rawEvents.length === 0) {
rawEvents = await lastValueFrom(
relayPool
.req(orderedRelaysUrl, { kinds: [9802], '#r': [url] })
.pipe(
onlyEvents(),
tap((event: NostrEvent) => {
seenIds.add(event.id)
if (onHighlight) onHighlight(eventToHighlight(event))
}),
completeOnEose(),
takeUntil(timer(6000)),
toArray()
)
)
}
await rebroadcastEvents(rawEvents, relayPool, settings)
const uniqueEvents = dedupeHighlights(rawEvents)
const highlights: Highlight[] = uniqueEvents.map(eventToHighlight)
return sortHighlights(highlights)
} catch {
return []
}
}