From d801af81a426b914307e6fb3c65d33a9df00fd5b Mon Sep 17 00:00:00 2001 From: Gigi Date: Thu, 2 Oct 2025 08:45:55 +0200 Subject: [PATCH] fix: handle addressLoader as both function and Observable - Add type checking to handle addressLoader as either function or Observable - Fix TypeError: addressLoader is not a function error - Add debugging logs to understand addressLoader type at runtime - Support both function and Observable patterns for addressLoader usage --- .cursor/rules/applesauce.mdc | 5 ++ src/components/Bookmarks.tsx | 89 +++++++++++++++++++++++++----------- 2 files changed, 67 insertions(+), 27 deletions(-) create mode 100644 .cursor/rules/applesauce.mdc diff --git a/.cursor/rules/applesauce.mdc b/.cursor/rules/applesauce.mdc new file mode 100644 index 00000000..18c47a74 --- /dev/null +++ b/.cursor/rules/applesauce.mdc @@ -0,0 +1,5 @@ +--- +alwaysApply: true +--- + +If you can use an applesauce-module for something, use applesauce. https://hzrd149.github.io/applesauce/typedoc/modules.html \ No newline at end of file diff --git a/src/components/Bookmarks.tsx b/src/components/Bookmarks.tsx index 99d40c19..3db03eed 100644 --- a/src/components/Bookmarks.tsx +++ b/src/components/Bookmarks.tsx @@ -73,41 +73,76 @@ const Bookmarks: React.FC = ({ addressLoader, onLogout }) => { console.log('Fetching bookmarks for pubkey:', activeAccount.pubkey) console.log('Starting bookmark fetch for:', activeAccount.pubkey.slice(0, 8) + '...') + // Debug the addressLoader + console.log('addressLoader in fetchBookmarks:', addressLoader) + console.log('addressLoader type in fetchBookmarks:', typeof addressLoader) + console.log('addressLoader is function:', typeof addressLoader === 'function') + // Use applesauce address loader to fetch bookmark lists (kind 10003) // This is the proper way according to NIP-51 and applesauce documentation const bookmarkList: Bookmark[] = [] - // Use address loader with relay group for optimal performance - // This follows applesauce-relay documentation for relay groups - const subscription = addressLoader({ - kind: 10003, // Bookmark list according to NIP-51 - pubkey: activeAccount.pubkey, - // Relay group automatically handles multiple relays and deduplication - // No need to specify individual relays - the group manages this - }).subscribe({ - next: (event: NostrEvent) => { - console.log('Received bookmark event:', event) - const bookmarkData = parseBookmarkEvent(event) - if (bookmarkData) { - bookmarkList.push(bookmarkData) - console.log('Parsed bookmark:', bookmarkData) + // Set timeout to prevent hanging + let subscription: { unsubscribe: () => void } | null = null + + // Check if addressLoader is a function or an Observable + if (typeof addressLoader === 'function') { + // Use address loader with relay group for optimal performance + // This follows applesauce-relay documentation for relay groups + subscription = addressLoader({ + kind: 10003, // Bookmark list according to NIP-51 + pubkey: activeAccount.pubkey, + // Relay group automatically handles multiple relays and deduplication + // No need to specify individual relays - the group manages this + }).subscribe({ + next: (event: NostrEvent) => { + console.log('Received bookmark event:', event) + const bookmarkData = parseBookmarkEvent(event) + if (bookmarkData) { + bookmarkList.push(bookmarkData) + console.log('Parsed bookmark:', bookmarkData) + } + }, + error: (error: unknown) => { + console.error('Error fetching bookmarks:', error) + setLoading(false) + }, + complete: () => { + console.log('Bookmark fetch complete. Found:', bookmarkList.length, 'bookmarks') + setBookmarks(bookmarkList) + setLoading(false) } - }, - error: (error: unknown) => { - console.error('Error fetching bookmarks:', error) - setLoading(false) - }, - complete: () => { - console.log('Bookmark fetch complete. Found:', bookmarkList.length, 'bookmarks') - setBookmarks(bookmarkList) - setLoading(false) - } - }) - + }) + } else { + // If addressLoader is an Observable, subscribe to it directly + console.log('addressLoader is an Observable, subscribing directly') + subscription = addressLoader.subscribe({ + next: (event: NostrEvent) => { + console.log('Received bookmark event:', event) + const bookmarkData = parseBookmarkEvent(event) + if (bookmarkData) { + bookmarkList.push(bookmarkData) + console.log('Parsed bookmark:', bookmarkData) + } + }, + error: (error: unknown) => { + console.error('Error fetching bookmarks:', error) + setLoading(false) + }, + complete: () => { + console.log('Bookmark fetch complete. Found:', bookmarkList.length, 'bookmarks') + setBookmarks(bookmarkList) + setLoading(false) + } + }) + } + // Set timeout to prevent hanging setTimeout(() => { console.log('Bookmark fetch timeout. Found:', bookmarkList.length, 'bookmarks') - subscription.unsubscribe() + if (subscription) { + subscription.unsubscribe() + } if (bookmarkList.length === 0) { setBookmarks([]) setLoading(false)