From bcaae09e8bc5a6d270db7d5ea8cef02762dd5bcb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:21:44 +0000 Subject: [PATCH] perf: parallelize watch history chunk decryption Refactored the watch history decryption loop to use Promise.all for concurrently decrypting all chunks. This significantly reduces the total time spent waiting for decryption, especially when dealing with multiple history chunks. Each decryption remains isolated in a try...catch block to ensure that a single failure does not block the rest of the batch. Performance results (simulated): - Sequential: ~1011ms (20 chunks, 50ms delay) - Parallel: ~55ms (20 chunks, 50ms delay) - Speedup: ~18x Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- js/nostr/watchHistory.js | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/js/nostr/watchHistory.js b/js/nostr/watchHistory.js index 04e9ecfa..e05b1f95 100644 --- a/js/nostr/watchHistory.js +++ b/js/nostr/watchHistory.js @@ -2052,24 +2052,36 @@ class WatchHistoryManager { const chunkEvents = Array.isArray(results) ? results.flat().filter((event) => event && typeof event === "object") : []; - for (const event of chunkEvents) { - const ciphertext = typeof event.content === "string" ? event.content : ""; + + const decryptionPromises = chunkEvents.map(async (event) => { + const ciphertext = + typeof event.content === "string" ? event.content : ""; if (!ciphertext) { - continue; + return null; } let plaintext = ""; if (typeof decryptSigner.nip04Decrypt === "function") { try { - plaintext = await decryptSigner.nip04Decrypt(actorKey, ciphertext); + plaintext = await decryptSigner.nip04Decrypt( + actorKey, + ciphertext, + ); } catch (error) { - devLogger.warn("[nostr] Failed to decrypt watch history chunk:", error); + devLogger.warn( + "[nostr] Failed to decrypt watch history chunk:", + error, + ); } } if (!plaintext) { - continue; + return null; } - const parsed = parseWatchHistoryPayload(plaintext); - if (Array.isArray(parsed.items) && parsed.items.length) { + return parseWatchHistoryPayload(plaintext); + }); + + const decryptedPayloads = await Promise.all(decryptionPromises); + for (const parsed of decryptedPayloads) { + if (parsed && Array.isArray(parsed.items) && parsed.items.length) { decryptedItems.push(...parsed.items); } }