- Log when kind:1 events are fetched by EventLoader
- Log when kind:1 events are hydrated with content
- Helps diagnose why text content isn't displaying for bookmarked notes
- Remove all console.log statements with [bookmark] prefix from App.tsx
- Remove all console.log statements with [bookmark] prefix from bookmarkController.ts
- Replace verbose error logging with simple error messages
- Keep code clean and reduce console clutter
The loaders were initialized without extraRelays, so they had no relays
to fetch from. Added RELAYS config as extraRelays option for both loaders.
This ensures the loaders know where to query for events when hydrating
bookmarks in the background.
Removed excessive per-event logging from EventLoader and AddressLoader
subscriptions. Keep only essential logs:
- Initial hydration count
- Error logging
This reduces console noise while maintaining visibility into hydration
progress and errors.
Added extensive logging to track queryEvents lifecycle:
- Log when queryEvents is called
- Log each event as it's received via onEvent callback
- Log when batch completes with event count
- Log errors if batch fails
This will help identify where the hydration is hanging - whether:
- queryEvents never returns
- No events are received
- Some batches fail silently
No functional changes, only diagnostic logging.
Problem: With 400+ bookmarked events, trying to fetch all referenced events at once caused queryEvents to hang/timeout, making bookmarks appear to not load even though they were emitted.
Solution:
- Added MAX_IDS_TO_FETCH limit (100 IDs)
- Added MAX_COORDS_TO_FETCH limit (100 coordinates)
- If counts exceed limits, skip fetching and show bookmarks with IDs only
- Bookmarks still appear immediately with placeholder data (IDs)
- For smaller collections, metadata still loads in background
This fixes the hanging issue for users with large bookmark collections - all 532 bookmarks will now appear instantly in the sidebar (showing IDs), without waiting for potentially slow/hanging queryEvents calls.
Root cause: When decryption completed, we were only storing counts, not the actual decrypted bookmark items. When buildAndEmitBookmarks ran, it would try to decrypt again or skip encrypted events entirely.
Changes:
- Renamed decryptedEvents to decryptedResults and changed type to store actual IndividualBookmark arrays
- Store full decrypted results (publicItems, privateItems, metadata) when decryption completes
- In buildAndEmitBookmarks, separate unencrypted and decrypted events
- Process only unencrypted events with collectBookmarksFromEvents
- Merge in stored decrypted results for encrypted events
- Updated filter to check decryptedResults map for encrypted events
This fixes the missing Amethyst bookmarks issue - all 416 private items should now appear in the sidebar after decryption completes.
Changes:
- Emit bookmarks IMMEDIATELY with placeholders (IDs only)
- Fetch referenced events in background (non-blocking)
- Re-emit progressively as events load:
1. First emit: IDs only (instant)
2. Second emit: after fetching events by ID
3. Third emit: after fetching addressable events
This solves the hanging issue by:
- Never blocking the initial display
- Making all event fetching happen in background Promises
- Updating the UI progressively as metadata loads
Sidebar will show bookmarks instantly with IDs, then titles/content will populate as events arrive.
Root cause: queryEvents() hangs when fetching referenced events by ID
Temporary fix: Skip event fetching entirely, show bookmark items without full metadata
The logs showed:
- [bookmark] 🔧 Fetching events by ID...
- (never completes, hangs indefinitely)
This blocked buildAndEmitBookmarks from completing and emitting to the sidebar.
TODO: Investigate why queryEvents with { ids: [...] } doesn't complete/timeout
Added logging at every step of buildAndEmitBookmarks:
- After collectBookmarksFromEvents returns
- Before/after fetching events by ID
- Before/after fetching addressable events
- Before/after hydration and dedup
- Before/after enrichment and sorting
- Before creating final Bookmark object
This will show exactly where the process is hanging.
Changed all console logs to use [bookmark] prefix:
- Controller: all logs now use [bookmark] instead of [controller]
- App: all bookmark-related logs use [bookmark] instead of [app]
This allows filtering console with 'bookmark' to see only relevant logs for bookmark loading/debugging.
Added logging at each step:
- Before calling collectBookmarksFromEvents
- After collectBookmarksFromEvents returns
- Detailed error info if it fails (message + stack)
This will show us exactly where the silent failure is happening.
Simplified to only show unencrypted bookmarks:
- Skip encrypted events entirely (no decrypt for now)
- This eliminates all parse errors
Added comprehensive logging:
- Controller: log when building, how many items, how many listeners, when emitting
- App: log when subscribing, when receiving bookmarks, when loading state changes
This will help identify where the disconnect is between controller and sidebar.
Filter events in buildAndEmitBookmarks to avoid parse errors:
- Unencrypted events: always included
- Encrypted events: only included if already decrypted
Progressive flow:
- Unencrypted event arrives → build bookmarks immediately
- Encrypted event arrives → wait for decrypt → then build bookmarks
- Each build only processes ready events (no parse errors)
Sidebar now populates with unencrypted bookmarks immediately, encrypted ones appear after decrypt.
Changed bookmark controller to emit updates progressively:
- Unencrypted events: immediate buildAndEmitBookmarks call
- Encrypted events: buildAndEmitBookmarks after decrypt completes
- Each update emits new bookmark list to subscribers
Removed coalescing/scheduling logic (scheduleBookmarkUpdate):
- Direct callback pattern is simpler and more predictable
- Updates happen exactly when events are ready
Progressive sidebar population now works correctly without parse errors.
Changed onEvent callback from async to synchronous:
- Removed await inside onEvent that was blocking observable
- Decryption now fires in background using .then()/.catch()
- Allows queryEvents to complete (EOSE) and trigger final bookmark build
This matches the working Debug pattern and allows bookmarks to appear in sidebar.