mirror of
https://github.com/dergigi/boris.git
synced 2026-01-31 20:54:41 +01:00
feat(write): add unified publishEvent service and refactor highlight and settings to use it
This commit is contained in:
@@ -7,8 +7,8 @@ import { Helpers, IEventStore } from 'applesauce-core'
|
||||
import { RELAYS } from '../config/relays'
|
||||
import { Highlight } from '../types/highlights'
|
||||
import { UserSettings } from './settingsService'
|
||||
import { areAllRelaysLocal } from '../utils/helpers'
|
||||
import { markEventAsOfflineCreated } from './offlineSyncService'
|
||||
import { isLocalRelay, areAllRelaysLocal } from '../utils/helpers'
|
||||
import { publishEvent } from './writeService'
|
||||
|
||||
// Boris pubkey for zap splits
|
||||
// npub19802see0gnk3vjlus0dnmfdagusqrtmsxpl5yfmkwn9uvnfnqylqduhr0x
|
||||
@@ -118,59 +118,26 @@ export async function createHighlight(
|
||||
// Sign the event
|
||||
const signedEvent = await factory.sign(highlightEvent)
|
||||
|
||||
// Publish to all configured relays - let the relay pool handle connection state
|
||||
const targetRelays = RELAYS
|
||||
|
||||
// Store the event in the local EventStore FIRST for immediate UI display
|
||||
eventStore.add(signedEvent)
|
||||
console.log('💾 Stored highlight in EventStore:', signedEvent.id.slice(0, 8))
|
||||
|
||||
// Check current connection status - are we online or in flight mode?
|
||||
// Use unified write service to store and publish
|
||||
await publishEvent(relayPool, eventStore, signedEvent, settings)
|
||||
|
||||
// Check current connection status for UI feedback
|
||||
const connectedRelays = Array.from(relayPool.relays.values())
|
||||
.filter(relay => relay.connected)
|
||||
.map(relay => relay.url)
|
||||
|
||||
const hasRemoteConnection = connectedRelays.some(url =>
|
||||
!url.includes('localhost') && !url.includes('127.0.0.1')
|
||||
)
|
||||
|
||||
// Determine which relays we expect to succeed
|
||||
const expectedSuccessRelays = hasRemoteConnection
|
||||
? RELAYS
|
||||
: RELAYS.filter(r => r.includes('localhost') || r.includes('127.0.0.1'))
|
||||
|
||||
|
||||
const hasRemoteConnection = connectedRelays.some(url => !isLocalRelay(url))
|
||||
const expectedSuccessRelays = hasRemoteConnection
|
||||
? RELAYS
|
||||
: RELAYS.filter(isLocalRelay)
|
||||
const isLocalOnly = areAllRelaysLocal(expectedSuccessRelays)
|
||||
|
||||
console.log('📍 Highlight relay status:', {
|
||||
targetRelays: targetRelays.length,
|
||||
expectedSuccessRelays,
|
||||
isLocalOnly,
|
||||
hasRemoteConnection,
|
||||
eventId: signedEvent.id
|
||||
})
|
||||
|
||||
// If we're in local-only mode, mark this event for later sync
|
||||
if (isLocalOnly) {
|
||||
markEventAsOfflineCreated(signedEvent.id)
|
||||
}
|
||||
|
||||
|
||||
// Convert to Highlight with relay tracking info and return IMMEDIATELY
|
||||
const highlight = eventToHighlight(signedEvent)
|
||||
highlight.publishedRelays = expectedSuccessRelays // Show only relays we expect to succeed
|
||||
highlight.publishedRelays = expectedSuccessRelays
|
||||
highlight.isLocalOnly = isLocalOnly
|
||||
highlight.isOfflineCreated = isLocalOnly // Mark as created offline if local-only
|
||||
|
||||
// Publish to relays in the background (non-blocking)
|
||||
// This allows instant UI updates while publishing happens asynchronously
|
||||
relayPool.publish(targetRelays, signedEvent)
|
||||
.then(() => {
|
||||
console.log('✅ Highlight published to', targetRelays.length, 'relay(s):', targetRelays)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('⚠️ Failed to publish highlight to relays (event still saved locally):', error)
|
||||
})
|
||||
|
||||
// Return the highlight immediately for instant UI updates
|
||||
highlight.isOfflineCreated = isLocalOnly
|
||||
|
||||
return highlight
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { EventFactory } from 'applesauce-factory'
|
||||
import { RelayPool, onlyEvents } from 'applesauce-relay'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { firstValueFrom } from 'rxjs'
|
||||
import { publishEvent } from './writeService'
|
||||
|
||||
const SETTINGS_IDENTIFIER = 'com.dergigi.boris.user-settings'
|
||||
const APP_DATA_KIND = 30078 // NIP-78 Application Data
|
||||
@@ -148,10 +149,10 @@ export async function saveSettings(
|
||||
eventStore: IEventStore,
|
||||
factory: EventFactory,
|
||||
settings: UserSettings,
|
||||
relays: string[]
|
||||
_relays: string[]
|
||||
): Promise<void> {
|
||||
console.log('💾 Saving settings to nostr:', settings)
|
||||
|
||||
|
||||
// Create NIP-78 application data event manually
|
||||
// Note: AppDataBlueprint is not available in the npm package
|
||||
const draft = await factory.create(async () => ({
|
||||
@@ -160,14 +161,12 @@ export async function saveSettings(
|
||||
tags: [['d', SETTINGS_IDENTIFIER]],
|
||||
created_at: Math.floor(Date.now() / 1000)
|
||||
}))
|
||||
|
||||
|
||||
const signed = await factory.sign(draft)
|
||||
|
||||
console.log('📤 Publishing settings event:', signed.id, 'to', relays.length, 'relays')
|
||||
|
||||
eventStore.add(signed)
|
||||
await relayPool.publish(relays, signed)
|
||||
|
||||
|
||||
// Use unified write service
|
||||
await publishEvent(relayPool, eventStore, signed, settings)
|
||||
|
||||
console.log('✅ Settings published successfully')
|
||||
}
|
||||
|
||||
|
||||
59
src/services/writeService.ts
Normal file
59
src/services/writeService.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { RelayPool } from 'applesauce-relay'
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { IEventStore } from 'applesauce-core'
|
||||
import { UserSettings } from './settingsService'
|
||||
import { RELAYS } from '../config/relays'
|
||||
import { isLocalRelay, areAllRelaysLocal } from '../utils/helpers'
|
||||
import { markEventAsOfflineCreated } from './offlineSyncService'
|
||||
|
||||
/**
|
||||
* Unified write helper: add event to EventStore, detect connectivity,
|
||||
* mark for offline sync if needed, and publish in background.
|
||||
*/
|
||||
export async function publishEvent(
|
||||
relayPool: RelayPool,
|
||||
eventStore: IEventStore,
|
||||
event: NostrEvent,
|
||||
settings?: UserSettings
|
||||
): Promise<void> {
|
||||
// Store the event in the local EventStore FIRST for immediate UI display
|
||||
eventStore.add(event)
|
||||
console.log('💾 Stored event in EventStore:', event.id.slice(0, 8), `(kind ${event.kind})`)
|
||||
|
||||
// Check current connection status - are we online or in flight mode?
|
||||
const connectedRelays = Array.from(relayPool.relays.values())
|
||||
.filter(relay => relay.connected)
|
||||
.map(relay => relay.url)
|
||||
|
||||
const hasRemoteConnection = connectedRelays.some(url => !isLocalRelay(url))
|
||||
|
||||
// Determine which relays we expect to succeed
|
||||
const expectedSuccessRelays = hasRemoteConnection
|
||||
? RELAYS
|
||||
: RELAYS.filter(isLocalRelay)
|
||||
|
||||
const isLocalOnly = areAllRelaysLocal(expectedSuccessRelays)
|
||||
|
||||
console.log('📍 Event relay status:', {
|
||||
targetRelays: RELAYS.length,
|
||||
expectedSuccessRelays: expectedSuccessRelays.length,
|
||||
isLocalOnly,
|
||||
hasRemoteConnection,
|
||||
eventId: event.id.slice(0, 8)
|
||||
})
|
||||
|
||||
// If we're in local-only mode, mark this event for later sync
|
||||
if (isLocalOnly) {
|
||||
markEventAsOfflineCreated(event.id)
|
||||
}
|
||||
|
||||
// Publish to all configured relays in the background (non-blocking)
|
||||
relayPool.publish(RELAYS, event)
|
||||
.then(() => {
|
||||
console.log('✅ Event published to', RELAYS.length, 'relay(s):', event.id.slice(0, 8))
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('⚠️ Failed to publish event to relays (event still saved locally):', error)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user