From 88bc7f690ed1c3008e64940bf41bde0f6cae6172 Mon Sep 17 00:00:00 2001 From: Gigi Date: Fri, 17 Oct 2025 23:19:32 +0200 Subject: [PATCH] feat: add progressive bookmark updates via callback pattern 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. --- src/services/bookmarkController.ts | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/services/bookmarkController.ts b/src/services/bookmarkController.ts index 7fbc451a..9407d70f 100644 --- a/src/services/bookmarkController.ts +++ b/src/services/bookmarkController.ts @@ -53,7 +53,6 @@ class BookmarkController { private currentEvents: Map = new Map() private decryptedEvents: Map = new Map() private isLoading = false - private updateScheduled = false onRawEvent(cb: RawEventCallback): () => void { this.rawEventListeners.push(cb) @@ -87,7 +86,6 @@ class BookmarkController { this.currentEvents.clear() this.decryptedEvents.clear() this.setLoading(false) - this.updateScheduled = false } private setLoading(loading: boolean): void { @@ -101,20 +99,6 @@ class BookmarkController { this.rawEventListeners.forEach(cb => cb(evt)) } - private scheduleBookmarkUpdate( - relayPool: RelayPool, - activeAccount: AccountWithExtension, - signerCandidate: unknown - ): void { - if (this.updateScheduled) return - - this.updateScheduled = true - setTimeout(async () => { - this.updateScheduled = false - await this.buildAndEmitBookmarks(relayPool, activeAccount, signerCandidate) - }, 0) - } - private async buildAndEmitBookmarks( relayPool: RelayPool, activeAccount: AccountWithExtension, @@ -292,9 +276,6 @@ class BookmarkController { // Emit raw event for Debug UI this.emitRawEvent(evt) - // Schedule bookmark update (non-blocking, coalesced) - this.scheduleBookmarkUpdate(relayPool, maybeAccount, signerCandidate) - // Auto-decrypt if event has encrypted content (fire-and-forget, non-blocking) if (hasEncryptedContent(evt)) { console.log('[controller] 🔓 Auto-decrypting event', evt.id.slice(0, 8)) @@ -315,12 +296,17 @@ class BookmarkController { cb(evt.id, publicItemsAll.length, privateItemsAll.length) ) - // Schedule another update after decrypt - this.scheduleBookmarkUpdate(relayPool, maybeAccount, signerCandidate) + // Rebuild bookmarks with newly decrypted content (progressive update) + this.buildAndEmitBookmarks(relayPool, maybeAccount, signerCandidate) + .catch(err => console.error('[controller] ❌ Failed to update after decrypt:', err)) }) .catch((error) => { console.error('[controller] ❌ Auto-decrypt failed:', evt.id.slice(0, 8), error) }) + } else { + // For unencrypted events, build bookmarks immediately (progressive update) + this.buildAndEmitBookmarks(relayPool, maybeAccount, signerCandidate) + .catch(err => console.error('[controller] ❌ Failed to update after event:', err)) } } }