From 6099e3c6a41bd5f911bf1bc752ef9c5f4c1e072d Mon Sep 17 00:00:00 2001 From: Gigi Date: Sat, 18 Oct 2025 22:08:22 +0200 Subject: [PATCH] feat: store nostrverse content in centralized event store - Add eventStore parameter to fetchNostrverseBlogPosts - Add eventStore parameter to fetchNostrverseHighlights - Pass eventStore from Explore component to nostrverse fetchers - Store all nostrverse blog posts and highlights in event store - Enables offline access to nostrverse content --- src/components/Explore.tsx | 4 ++-- src/services/nostrverseService.ts | 33 +++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index bf12f64e..e43874f4 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -184,8 +184,8 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti const [friendsPosts, friendsHighlights, nostrversePosts, nostriverseHighlights] = await Promise.all([ fetchBlogPostsFromAuthors(relayPool, contactsArray, relayUrls), fetchHighlightsFromAuthors(relayPool, contactsArray), - fetchNostrverseBlogPosts(relayPool, relayUrls, 50), - fetchNostrverseHighlights(relayPool, 100) + fetchNostrverseBlogPosts(relayPool, relayUrls, 50, eventStore || undefined), + fetchNostrverseHighlights(relayPool, 100, eventStore || undefined) ]) // Merge and deduplicate all posts diff --git a/src/services/nostrverseService.ts b/src/services/nostrverseService.ts index 586136b5..44933452 100644 --- a/src/services/nostrverseService.ts +++ b/src/services/nostrverseService.ts @@ -1,6 +1,6 @@ import { RelayPool } from 'applesauce-relay' import { NostrEvent } from 'nostr-tools' -import { Helpers } from 'applesauce-core' +import { Helpers, IEventStore } from 'applesauce-core' import { BlogPostPreview } from './exploreService' import { Highlight } from '../types/highlights' import { eventToHighlight, dedupeHighlights, sortHighlights } from './highlightEventProcessor' @@ -13,12 +13,14 @@ const { getArticleTitle, getArticleImage, getArticlePublished, getArticleSummary * @param relayPool - The relay pool to query * @param relayUrls - Array of relay URLs to query * @param limit - Maximum number of posts to fetch (default: 50) + * @param eventStore - Optional event store to persist fetched events * @returns Array of blog post previews */ export const fetchNostrverseBlogPosts = async ( relayPool: RelayPool, relayUrls: string[], - limit = 50 + limit = 50, + eventStore?: IEventStore ): Promise => { try { console.log('📚 Fetching nostrverse blog posts (kind 30023), limit:', limit) @@ -32,6 +34,11 @@ export const fetchNostrverseBlogPosts = async ( { relayUrls, onEvent: (event: NostrEvent) => { + // Store in event store if provided + if (eventStore) { + eventStore.add(event) + } + const dTag = event.tags.find(t => t[0] === 'd')?.[1] || '' const key = `${event.pubkey}:${dTag}` const existing = uniqueEvents.get(key) @@ -73,21 +80,39 @@ export const fetchNostrverseBlogPosts = async ( * Fetches public highlights (kind:9802) from the nostrverse (not filtered by author) * @param relayPool - The relay pool to query * @param limit - Maximum number of highlights to fetch (default: 100) + * @param eventStore - Optional event store to persist fetched events * @returns Array of highlights */ export const fetchNostrverseHighlights = async ( relayPool: RelayPool, - limit = 100 + limit = 100, + eventStore?: IEventStore ): Promise => { try { console.log('💡 Fetching nostrverse highlights (kind 9802), limit:', limit) + const seenIds = new Set() const rawEvents = await queryEvents( relayPool, { kinds: [9802], limit }, - {} + { + onEvent: (event: NostrEvent) => { + if (seenIds.has(event.id)) return + seenIds.add(event.id) + + // Store in event store if provided + if (eventStore) { + eventStore.add(event) + } + } + } ) + // Store all events in event store if provided (in case some were missed in streaming) + if (eventStore) { + rawEvents.forEach(evt => eventStore.add(evt)) + } + const uniqueEvents = dedupeHighlights(rawEvents) const highlights = uniqueEvents.map(eventToHighlight)