diff --git a/lib/articlePublisher.ts b/lib/articlePublisher.ts index 45a6f77..45c8c73 100644 --- a/lib/articlePublisher.ts +++ b/lib/articlePublisher.ts @@ -1,7 +1,7 @@ import { nostrService } from './nostr' import type { AlbyInvoice } from '@/types/alby' import { getStoredPrivateContent, getStoredInvoice, removeStoredPrivateContent } from './articleStorage' -import { buildPresentationEvent, fetchAuthorPresentationFromPool, sendEncryptedContent } from './articlePublisherHelpers' +import { buildPresentationEvent, sendEncryptedContent } from './articlePublisherHelpers' import type { ArticleDraft, AuthorPresentationDraft, PublishedArticle } from './articlePublisherTypes' import { prepareAuthorKeys, isValidCategory, type PublishValidationResult } from './articlePublisherValidation' import { buildFailure, encryptAndPublish } from './articlePublisherPublish' @@ -209,11 +209,18 @@ export class ArticlePublisher { async getAuthorPresentation(pubkey: string): Promise { try { - const pool = nostrService.getPool() - if (!pool) { - return null + // Read only from IndexedDB cache + const { objectCache } = await import('./objectCache') + const cached = await objectCache.getAuthorByPubkey(pubkey) + if (cached) { + const presentation = cached + // Calculate totalSponsoring from cache + const { getAuthorSponsoring } = await import('./sponsoring') + presentation.totalSponsoring = await getAuthorSponsoring(presentation.pubkey) + return presentation } - return fetchAuthorPresentationFromPool(pool, pubkey) + // Not found in cache - return null (no network request) + return null } catch (error) { console.error('Error getting author presentation:', error) return null diff --git a/lib/authorQueries.ts b/lib/authorQueries.ts index a28d2f8..a4e09f3 100644 --- a/lib/authorQueries.ts +++ b/lib/authorQueries.ts @@ -21,7 +21,7 @@ export async function fetchAuthorByHashId( // Read only from IndexedDB cache const cached = await objectCache.getAuthorByPubkey(hashIdOrPubkey) if (cached) { - const presentation = cached as import('@/types/nostr').AuthorPresentationArticle + const presentation = cached // Calculate totalSponsoring from cache const { getAuthorSponsoring } = await import('./sponsoring') presentation.totalSponsoring = await getAuthorSponsoring(presentation.pubkey) diff --git a/lib/notificationDetector.ts b/lib/notificationDetector.ts index 08808f6..bcce03f 100644 --- a/lib/notificationDetector.ts +++ b/lib/notificationDetector.ts @@ -121,7 +121,7 @@ class NotificationDetector { // Create notifications for objects created after last scan for (const obj of userObjects) { - const cachedObj = obj as CachedObject + const cachedObj = obj if (cachedObj.createdAt * 1000 > this.lastScanTime) { const eventId = cachedObj.id.split(':')[1] ?? cachedObj.id await notificationService.createNotification({ @@ -172,7 +172,7 @@ class NotificationDetector { // We can't track old/new state easily, so we'll create notification // if object was published recently (created in last hour and published) const oneHourAgo = Date.now() - 60 * 60 * 1000 - const cachedObj = obj as CachedObject + const cachedObj = obj if (cachedObj.createdAt * 1000 > oneHourAgo) { const relays = cachedObj.published as string[] await notificationService.createNotification({ @@ -276,7 +276,7 @@ class NotificationDetector { case 'payment_note': return `Une note de paiement a été ajoutée` case 'published': - const cachedObj = _obj as CachedObject + const cachedObj = _obj const relays = Array.isArray(cachedObj.published) ? cachedObj.published : [] return `Votre contenu a été publié sur ${relays.length} relais` default: diff --git a/lib/publishWorker.ts b/lib/publishWorker.ts index 904e149..b939586 100644 --- a/lib/publishWorker.ts +++ b/lib/publishWorker.ts @@ -3,7 +3,6 @@ * Continuously attempts to publish objects with published === false */ -import { nostrService } from './nostr' import { objectCache, type ObjectType } from './objectCache' import { relaySessionManager } from './relaySessionManager' import { publishLog } from './publishLog' diff --git a/lib/swSyncHandler.ts b/lib/swSyncHandler.ts index 99a889a..c0cce01 100644 --- a/lib/swSyncHandler.ts +++ b/lib/swSyncHandler.ts @@ -118,7 +118,6 @@ class ServiceWorkerSyncHandler { try { console.warn('[SWSyncHandler] Executing notification detection request for:', userPubkey) const { notificationDetector } = await import('./notificationDetector') - const { writeService } = await import('./writeService') // Scanner IndexedDB pour détecter les nouveaux événements await notificationDetector.scan() @@ -132,36 +131,31 @@ class ServiceWorkerSyncHandler { /** * Handle publish request from Service Worker + * Uses websocketService to route events to Service Worker */ private async handlePublishRequest(event: Event, relays: string[]): Promise { try { console.warn('[SWSyncHandler] Executing publish request for event:', event.id) - const pool = nostrService.getPool() - if (!pool) { - throw new Error('Pool not initialized') - } - - // Publish to specified relays - const pubs = pool.publish(relays, event) - const results = await Promise.allSettled(pubs) - + const { websocketService } = await import('./websocketService') const { publishLog } = await import('./publishLog') + + // Publish to specified relays via websocketService (routes to Service Worker) + const statuses = await websocketService.publishEvent(event, relays) const successfulRelays: string[] = [] - results.forEach((result, index) => { + statuses.forEach((status, index) => { const relayUrl = relays[index] if (!relayUrl) { return } - if (result.status === 'fulfilled') { + if (status.success) { successfulRelays.push(relayUrl) // Log successful publication void publishLog.logPublication(event.id, relayUrl, true, undefined) } else { - const error = result.reason - const errorMessage = error instanceof Error ? error.message : String(error) - console.error(`[SWSyncHandler] Relay ${relayUrl} failed:`, error) + const errorMessage = status.error ?? 'Unknown error' + console.error(`[SWSyncHandler] Relay ${relayUrl} failed:`, errorMessage) // Log failed publication void publishLog.logPublication(event.id, relayUrl, false, errorMessage) } diff --git a/pages/_app.tsx b/pages/_app.tsx index 28bdf40..61fc2a0 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -2,10 +2,7 @@ import '@/styles/globals.css' import type { AppProps } from 'next/app' import { useI18n } from '@/hooks/useI18n' import React from 'react' -import { platformSyncService } from '@/lib/platformSync' import { nostrAuthService } from '@/lib/nostrAuth' -import { syncUserContentToCache } from '@/lib/userContentSync' -import { syncProgressManager } from '@/lib/syncProgressManager' import { relaySessionManager } from '@/lib/relaySessionManager' import { publishWorker } from '@/lib/publishWorker' import { swSyncHandler } from '@/lib/swSyncHandler' @@ -69,74 +66,51 @@ export default function App({ Component, pageProps }: AppProps): React.ReactElem } }, []) - // Start platform sync on app mount and resume on each page navigation + // Start platform sync on app mount via Service Worker only React.useEffect(() => { - // Start continuous sync (runs periodically in background, uses Service Worker if available) - void platformSyncService.startContinuousSync() - - // Also trigger a sync on each page navigation - const handleRouteChange = (): void => { - if (!platformSyncService.isSyncing()) { - void platformSyncService.startSync() + const startPlatformSync = async (): Promise => { + try { + const isReady = await swClient.isReady() + if (isReady) { + await swClient.startPlatformSync() + } + } catch (error) { + console.warn('[App] Service Worker not available for platform sync:', error) } } + void startPlatformSync() + + // Trigger sync on each page navigation + const handleRouteChange = (): void => { + void startPlatformSync() + } + // Listen to route changes const router = require('next/router').default router.events?.on('routeChangeComplete', handleRouteChange) return () => { router.events?.off('routeChangeComplete', handleRouteChange) - void platformSyncService.stopSync() + void swClient.stopPlatformSync() } }, []) - // Start user content sync on app mount and on each page navigation if connected + // Start user content sync on app mount via Service Worker only React.useEffect(() => { - let syncInProgress = false - const startUserSync = async (): Promise => { - if (syncInProgress) { - console.warn('[App] Sync already in progress, skipping') - return - } - const state = nostrAuthService.getState() - console.warn('[App] Checking connection state:', { connected: state.connected, hasPubkey: Boolean(state.pubkey) }) if (!state.connected || !state.pubkey) { - console.warn('[App] Not connected or no pubkey, skipping sync') return } - syncInProgress = true - console.warn('[App] Starting user content sync...') - - // Try to use Service Worker for background sync try { const isReady = await swClient.isReady() if (isReady) { - console.warn('[App] Using Service Worker for user content sync') await swClient.startUserSync(state.pubkey) - // Still sync immediately in main thread for UI feedback } } catch (error) { - console.warn('[App] Service Worker not available, using direct sync:', error) - } - - try { - await syncUserContentToCache(state.pubkey, (progress) => { - syncProgressManager.setProgress(progress) - if (progress.completed) { - syncProgressManager.setProgress(null) - } - }) - console.warn('[App] User content sync completed') - syncProgressManager.setProgress(null) - } catch (error) { - console.error('[App] Error during user content sync:', error) - syncProgressManager.setProgress(null) - } finally { - syncInProgress = false + console.warn('[App] Service Worker not available for user content sync:', error) } } @@ -146,15 +120,13 @@ export default function App({ Component, pageProps }: AppProps): React.ReactElem // Also listen to connection changes and route changes to sync when user connects or navigates const router = require('next/router').default const handleRouteChange = (): void => { - if (!syncInProgress) { - void startUserSync() - } + void startUserSync() } router.events?.on('routeChangeComplete', handleRouteChange) const unsubscribe = nostrAuthService.subscribe((state) => { - if (state.connected && state.pubkey && !syncInProgress) { + if (state.connected && state.pubkey) { void startUserSync() } }) @@ -171,3 +143,4 @@ export default function App({ Component, pageProps }: AppProps): React.ReactElem ) } +