mirror of
https://github.com/dergigi/boris.git
synced 2025-12-19 07:34:28 +01:00
refactor: use applesauce EventStore for offline event management
Major improvements: - Store highlights in EventStore immediately when created - Query EventStore instead of local relays for offline sync - Pass eventStore to highlight creation service and hooks - Simplified offline sync: no more relay queries, just EventStore lookups - More efficient and reliable offline event tracking - Better integration with applesauce architecture Benefits: - Faster sync (no relay queries needed) - More reliable (events always in EventStore) - Cleaner code (leveraging applesauce patterns) - Better separation of concerns
This commit is contained in:
@@ -59,6 +59,7 @@ const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
|
||||
useOfflineSync({
|
||||
relayPool,
|
||||
account: activeAccount,
|
||||
eventStore,
|
||||
relayStatuses,
|
||||
enabled: true
|
||||
})
|
||||
@@ -129,6 +130,7 @@ const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
|
||||
} = useHighlightCreation({
|
||||
activeAccount,
|
||||
relayPool,
|
||||
eventStore,
|
||||
currentArticle,
|
||||
selectedUrl,
|
||||
readerContent,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCallback, useRef } from 'react'
|
||||
import { RelayPool } from 'applesauce-relay'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { IEventStore } from 'applesauce-core'
|
||||
import { Highlight } from '../types/highlights'
|
||||
import { ReadableContent } from '../services/readerService'
|
||||
import { createHighlight } from '../services/highlightCreationService'
|
||||
@@ -11,6 +12,7 @@ interface UseHighlightCreationParams {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
activeAccount: any
|
||||
relayPool: RelayPool | null
|
||||
eventStore: IEventStore | null
|
||||
currentArticle: NostrEvent | undefined
|
||||
selectedUrl: string | undefined
|
||||
readerContent: ReadableContent | undefined
|
||||
@@ -21,6 +23,7 @@ interface UseHighlightCreationParams {
|
||||
export const useHighlightCreation = ({
|
||||
activeAccount,
|
||||
relayPool,
|
||||
eventStore,
|
||||
currentArticle,
|
||||
selectedUrl,
|
||||
readerContent,
|
||||
@@ -38,7 +41,7 @@ export const useHighlightCreation = ({
|
||||
}, [])
|
||||
|
||||
const handleCreateHighlight = useCallback(async (text: string) => {
|
||||
if (!activeAccount || !relayPool) {
|
||||
if (!activeAccount || !relayPool || !eventStore) {
|
||||
console.error('Missing requirements for highlight creation')
|
||||
return
|
||||
}
|
||||
@@ -61,6 +64,7 @@ export const useHighlightCreation = ({
|
||||
source,
|
||||
activeAccount,
|
||||
relayPool,
|
||||
eventStore,
|
||||
contentForContext,
|
||||
undefined,
|
||||
settings
|
||||
@@ -79,7 +83,7 @@ export const useHighlightCreation = ({
|
||||
// Re-throw to allow parent to handle
|
||||
throw error
|
||||
}
|
||||
}, [activeAccount, relayPool, currentArticle, selectedUrl, readerContent, onHighlightCreated, settings])
|
||||
}, [activeAccount, relayPool, eventStore, currentArticle, selectedUrl, readerContent, onHighlightCreated, settings])
|
||||
|
||||
return {
|
||||
highlightButtonRef,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { RelayPool } from 'applesauce-relay'
|
||||
import { IAccount } from 'applesauce-core/helpers'
|
||||
import { IAccount, IEventStore } from 'applesauce-core'
|
||||
import { syncLocalEventsToRemote } from '../services/offlineSyncService'
|
||||
import { isLocalRelay } from '../utils/helpers'
|
||||
import { RelayStatus } from '../services/relayStatusService'
|
||||
@@ -8,6 +8,7 @@ import { RelayStatus } from '../services/relayStatusService'
|
||||
interface UseOfflineSyncParams {
|
||||
relayPool: RelayPool | null
|
||||
account: IAccount | null
|
||||
eventStore: IEventStore | null
|
||||
relayStatuses: RelayStatus[]
|
||||
enabled?: boolean
|
||||
}
|
||||
@@ -15,6 +16,7 @@ interface UseOfflineSyncParams {
|
||||
export function useOfflineSync({
|
||||
relayPool,
|
||||
account,
|
||||
eventStore,
|
||||
relayStatuses,
|
||||
enabled = true
|
||||
}: UseOfflineSyncParams) {
|
||||
@@ -27,7 +29,7 @@ export function useOfflineSync({
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || !relayPool || !account) return
|
||||
if (!enabled || !relayPool || !account || !eventStore) return
|
||||
|
||||
const connectedRelays = relayStatuses.filter(r => r.isInPool)
|
||||
const hasRemoteRelays = connectedRelays.some(r => !isLocalRelay(r.url))
|
||||
@@ -57,11 +59,11 @@ export function useOfflineSync({
|
||||
// Wait a moment for relays to fully establish connections
|
||||
setTimeout(() => {
|
||||
console.log('🚀 Starting sync after delay...')
|
||||
syncLocalEventsToRemote(relayPool, account)
|
||||
syncLocalEventsToRemote(relayPool, account, eventStore)
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
previousStateRef.current.hasRemoteRelays = hasRemoteRelays
|
||||
}, [relayPool, account, relayStatuses, enabled])
|
||||
}, [relayPool, account, eventStore, relayStatuses, enabled])
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { RelayPool } from 'applesauce-relay'
|
||||
import { IAccount } from 'applesauce-accounts'
|
||||
import { AddressPointer } from 'nostr-tools/nip19'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { Helpers } from 'applesauce-core'
|
||||
import { Helpers, IEventStore } from 'applesauce-core'
|
||||
import { RELAYS } from '../config/relays'
|
||||
import { Highlight } from '../types/highlights'
|
||||
import { UserSettings } from './settingsService'
|
||||
@@ -35,6 +35,7 @@ export async function createHighlight(
|
||||
source: NostrEvent | string,
|
||||
account: IAccount,
|
||||
relayPool: RelayPool,
|
||||
eventStore: IEventStore,
|
||||
contentForContext?: string,
|
||||
comment?: string,
|
||||
settings?: UserSettings
|
||||
@@ -143,6 +144,10 @@ export async function createHighlight(
|
||||
eventId: signedEvent.id
|
||||
})
|
||||
|
||||
// Store the event in the local EventStore immediately
|
||||
eventStore.add(signedEvent)
|
||||
console.log('💾 Stored highlight in EventStore:', signedEvent.id.slice(0, 8))
|
||||
|
||||
// If we're in local-only mode, mark this event for later sync
|
||||
if (isLocalOnly) {
|
||||
markEventAsOfflineCreated(signedEvent.id)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RelayPool } from 'applesauce-relay'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { IAccount } from 'applesauce-core/helpers'
|
||||
import { IAccount, IEventStore } from 'applesauce-core'
|
||||
import { RELAYS } from '../config/relays'
|
||||
import { isLocalRelay } from '../utils/helpers'
|
||||
|
||||
@@ -19,10 +19,12 @@ export function markEventAsOfflineCreated(eventId: string): void {
|
||||
|
||||
/**
|
||||
* Syncs local-only events to remote relays when coming back online
|
||||
* Now uses applesauce EventStore instead of querying relays
|
||||
*/
|
||||
export async function syncLocalEventsToRemote(
|
||||
relayPool: RelayPool,
|
||||
account: IAccount
|
||||
account: IAccount,
|
||||
eventStore: IEventStore
|
||||
): Promise<void> {
|
||||
if (isSyncing) {
|
||||
console.log('⏳ Sync already in progress, skipping...')
|
||||
@@ -34,16 +36,9 @@ export async function syncLocalEventsToRemote(
|
||||
isSyncing = true
|
||||
|
||||
try {
|
||||
const localRelays = RELAYS.filter(isLocalRelay)
|
||||
const remoteRelays = RELAYS.filter(url => !isLocalRelay(url))
|
||||
|
||||
console.log(`📡 Local relays: ${localRelays.length}, Remote relays: ${remoteRelays.length}`)
|
||||
|
||||
if (localRelays.length === 0) {
|
||||
console.log('⚠️ No local relays available for sync')
|
||||
isSyncing = false
|
||||
return
|
||||
}
|
||||
console.log(`📡 Remote relays: ${remoteRelays.length}`)
|
||||
|
||||
if (remoteRelays.length === 0) {
|
||||
console.log('⚠️ No remote relays available for sync')
|
||||
@@ -51,49 +46,30 @@ export async function syncLocalEventsToRemote(
|
||||
return
|
||||
}
|
||||
|
||||
// Get events from local relays that were created in the last 24 hours
|
||||
const since = Math.floor(Date.now() / 1000) - (24 * 60 * 60)
|
||||
if (offlineCreatedEvents.size === 0) {
|
||||
console.log('✅ No offline events to sync')
|
||||
isSyncing = false
|
||||
return
|
||||
}
|
||||
|
||||
// Get events from EventStore using the tracked IDs
|
||||
const eventsToSync: NostrEvent[] = []
|
||||
console.log(`🔍 Querying EventStore for ${offlineCreatedEvents.size} offline events...`)
|
||||
|
||||
console.log(`🔍 Querying local relays for events since ${new Date(since * 1000).toISOString()}...`)
|
||||
|
||||
// Query for user's events from local relays
|
||||
const filters = [
|
||||
{ kinds: [9802], authors: [account.pubkey], since }, // Highlights
|
||||
{ kinds: [10003, 30003], authors: [account.pubkey], since }, // Bookmarks
|
||||
]
|
||||
|
||||
for (const filter of filters) {
|
||||
console.log(`🔎 Querying with filter:`, filter)
|
||||
const events = await new Promise<NostrEvent[]>((resolve) => {
|
||||
const collected: NostrEvent[] = []
|
||||
const sub = relayPool.req(localRelays, filter, {
|
||||
onevent: (event: NostrEvent) => {
|
||||
console.log(`📥 Received event ${event.id.slice(0, 8)} (kind ${event.kind}) from local relay`)
|
||||
collected.push(event)
|
||||
},
|
||||
oneose: () => {
|
||||
console.log(`✅ EOSE received, collected ${collected.length} events`)
|
||||
sub.close()
|
||||
resolve(collected)
|
||||
for (const eventId of offlineCreatedEvents) {
|
||||
const event = eventStore.getEvent(eventId)
|
||||
if (event) {
|
||||
console.log(`📥 Found event ${eventId.slice(0, 8)} (kind ${event.kind}) in EventStore`)
|
||||
eventsToSync.push(event)
|
||||
} else {
|
||||
console.warn(`⚠️ Event ${eventId.slice(0, 8)} not found in EventStore`)
|
||||
}
|
||||
})
|
||||
|
||||
// Timeout after 10 seconds (increased from 5)
|
||||
setTimeout(() => {
|
||||
console.log(`⏱️ Query timeout, collected ${collected.length} events`)
|
||||
sub.close()
|
||||
resolve(collected)
|
||||
}, 10000)
|
||||
})
|
||||
|
||||
eventsToSync.push(...events)
|
||||
}
|
||||
|
||||
console.log(`📊 Total events collected: ${eventsToSync.length}`)
|
||||
console.log(`📊 Total events to sync: ${eventsToSync.length}`)
|
||||
|
||||
if (eventsToSync.length === 0) {
|
||||
console.log('✅ No local events to sync')
|
||||
console.log('✅ No events found in EventStore to sync')
|
||||
isSyncing = false
|
||||
offlineCreatedEvents.clear()
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user