Revert "perf(profile): implement stale-while-revalidate for lists and messages"

This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-01-26 13:18:51 -05:00
1 parent b570350412
commit 27b71ba9bb
4 files changed
+106 -163

No files matched your search

-64
View File
@@ -215,50 +215,6 @@ const listVideoViewEventsApi = (pointer, options) =>
const subscribeVideoViewEventsApi = (pointer, options) =>
subscribeVideoViewEvents(nostrClient, pointer, options);
class TinyEventEmitter {
constructor() {
this.listeners = new Map();
}
on(eventName, handler) {
if (typeof eventName !== "string" || typeof handler !== "function") {
return () => {};
}
if (!this.listeners.has(eventName)) {
this.listeners.set(eventName, new Set());
}
const handlers = this.listeners.get(eventName);
handlers.add(handler);
return () => {
handlers.delete(handler);
if (!handlers.size) {
this.listeners.delete(eventName);
}
};
}
emit(eventName, detail) {
const handlers = this.listeners.get(eventName);
if (!handlers || !handlers.size) {
return;
}
for (const handler of Array.from(handlers)) {
try {
handler(detail);
} catch (error) {
userLogger.warn(
`[SubscriptionsManager] listener for "${eventName}" threw an error`,
error,
);
}
}
}
}
/**
* Manages the user's subscription list (kind=30000 follow set) *privately*,
* using encrypted NIP-51 tag arrays (NIP-04/NIP-44) for the content field.
@@ -281,7 +237,6 @@ class SubscriptionsManager {
this.scheduledRefreshDetail = null;
this.isRunningFeed = false;
this.hasRenderedOnce = false;
this.emitter = new TinyEventEmitter();
this.ensureNostrServiceListener();
profileCache.subscribe((event, detail) => {
@@ -333,10 +288,6 @@ class SubscriptionsManager {
profileCache.set("subscriptions", Array.from(this.subscribedPubkeys));
}
on(eventName, handler) {
return this.emitter.on(eventName, handler);
}
async updateFromRelays(userPubkey) {
if (!userPubkey) return;
@@ -507,10 +458,6 @@ class SubscriptionsManager {
}
if (changed) {
this.emitter.emit("change", {
action: "sync",
subscribedPubkeys: Array.from(this.subscribedPubkeys),
});
devLogger.log("[SubscriptionsManager] Subscription list updated from relays, refreshing feed.");
this.refreshActiveFeed({ reason: "subscription-update-background" }).catch((error) => {
userLogger.warn(
@@ -533,7 +480,6 @@ class SubscriptionsManager {
this.lastRunOptions = null;
this.lastResult = null;
this.hasRenderedOnce = false;
this.emitter.emit("change", { action: "reset", subscribedPubkeys: [] });
}
async ensureLoaded(actorHex) {
@@ -698,11 +644,6 @@ class SubscriptionsManager {
}
this.subscribedPubkeys.add(normalizedChannel);
this.saveToCache(userPubkey);
this.emitter.emit("change", {
action: "add",
channel: normalizedChannel,
subscribedPubkeys: Array.from(this.subscribedPubkeys),
});
await this.publishSubscriptionList(userPubkey);
this.refreshActiveFeed({ reason: "subscription-update" }).catch((error) => {
userLogger.warn(
@@ -728,11 +669,6 @@ class SubscriptionsManager {
}
this.subscribedPubkeys.delete(normalizedChannel);
this.saveToCache(userPubkey);
this.emitter.emit("change", {
action: "remove",
channel: normalizedChannel,
subscribedPubkeys: Array.from(this.subscribedPubkeys),
});
await this.publishSubscriptionList(userPubkey);
this.refreshActiveFeed({ reason: "subscription-update" }).catch((error) => {
userLogger.warn(
+18 -45
View File
@@ -1407,24 +1407,6 @@ export class ProfileModalController {
this.addAccountButtonState = null;
this.adminEmptyMessages = new Map();
this.hashtagPreferencesUnsubscribe = null;
if (
this.subscriptionsService &&
typeof this.subscriptionsService.on === "function"
) {
this.subscriptionsService.on("change", () => {
void this.populateSubscriptionsList();
});
}
if (
this.services.userBlocks &&
typeof this.services.userBlocks.on === "function"
) {
this.services.userBlocks.on("change", () => {
this.populateBlockedList();
});
}
}
async load() {
@@ -6783,16 +6765,11 @@ export class ProfileModalController {
const shouldStayInMenu = keepMenuView && isMobile;
this.setMobileView(shouldStayInMenu ? "menu" : "pane");
const activeHex = this.normalizeHexPubkey(this.getActivePubkey());
if (target === "history") {
void this.populateProfileWatchHistory();
} else if (target === "relays") {
this.populateProfileRelays();
void this.refreshRelayHealthPanel({
forceRefresh: true,
reason: "pane-select",
});
void this.refreshRelayHealthPanel({ forceRefresh: true, reason: "pane-select" });
} else if (target === "messages") {
this.resumeProfileMessages();
void this.populateProfileMessages({ reason: "pane-select" });
@@ -6804,14 +6781,8 @@ export class ProfileModalController {
} else if (target === "hashtags") {
this.populateHashtagPreferences();
} else if (target === "subscriptions") {
if (activeHex && this.subscriptionsService) {
this.subscriptionsService.loadSubscriptions(activeHex).catch(noop);
}
void this.populateSubscriptionsList();
} else if (target === "blocked") {
if (activeHex && this.services.userBlocks) {
this.services.userBlocks.loadBlocks(activeHex).catch(noop);
}
this.populateBlockedList();
} else if (target === "safety") {
this.refreshModerationSettingsUi();
@@ -8037,6 +8008,17 @@ export class ProfileModalController {
if (Array.isArray(subscriptions) && subscriptions.length) {
sourceEntries = subscriptions;
} else {
if (typeof service.ensureLoaded === "function") {
try {
await service.ensureLoaded(activeHex);
} catch (error) {
devLogger.warn(
"[profileModal] Failed to ensure subscriptions before populating subscriptions list:",
error,
);
}
}
if (typeof service.getSubscribedAuthors === "function") {
try {
sourceEntries = service.getSubscribedAuthors() || [];
@@ -12717,21 +12699,14 @@ export class ProfileModalController {
this.setActivePubkey(activePubkey);
}
const walletPromise = this.hydrateActiveWalletSettings(activePubkey);
const adminPromise = this.refreshAdminPaneState().catch((error) => {
userLogger.warn("Failed to refresh admin pane after login:", error);
});
await this.hydrateActiveWalletSettings(activePubkey);
this.renderSavedProfiles();
// Trigger aggressive parallel fetches
if (activePubkey) {
if (this.services.userBlocks) {
this.services.userBlocks.loadBlocks(activePubkey).catch(noop);
}
if (this.subscriptionsService) {
this.subscriptionsService.loadSubscriptions(activePubkey).catch(noop);
}
try {
await this.refreshAdminPaneState();
} catch (error) {
userLogger.warn("Failed to refresh admin pane after login:", error);
}
this.populateBlockedList();
@@ -12743,10 +12718,8 @@ export class ProfileModalController {
this.handleActiveDmIdentityChanged(activePubkey);
void this.refreshDmRelayPreferences({ force: true });
// Ensure critical state is settled if possible, but don't block initial rendering
Promise.all([walletPromise, adminPromise, postLoginPromise])
postLoginPromise
.then(() => {
// Re-run population to ensure any late-arriving data is reflected
this.populateBlockedList();
void this.populateSubscriptionsList();
void this.populateFriendsList();
+2
View File
@@ -737,6 +737,8 @@ class UserBlockListManager {
blockedPubkeys: Array.from(this.blockedPubkeys),
source: "local",
});
emitStatus({ status: "settled" });
return;
}
const applyBlockedPubkeys = (nextValues, meta = {}) => {
+86 -54
View File
@@ -4,13 +4,12 @@ import assert from "node:assert/strict";
import { JSDOM } from "jsdom";
import { nostrClient } from "../js/nostrClientFacade.js";
import { getActiveSigner, setActiveSigner, clearActiveSigner } from "../js/nostr/client.js";
import { getActiveSigner, setActiveSigner } from "../js/nostr/client.js";
import { subscriptions } from "../js/subscriptions.js";
import { setApplication } from "../js/applicationContext.js";
import nostrService from "../js/services/nostrService.js";
import moderationService from "../js/services/moderationService.js";
import { getNostrEventSchema, NOTE_TYPES } from "../js/nostrEventSchemas.js";
import { profileCache } from "../js/state/profileCache.js";
test("loadSubscriptions aggregates relay results when one rejects", async () => {
const SubscriptionsManager = subscriptions.constructor;
@@ -72,8 +71,6 @@ test("loadSubscriptions aggregates relay results when one rejects", async () =>
const decryptCalls = [];
globalThis.window.nostr = {
getPublicKey: async () => "0000000000000000000000000000000000000000000000000000000000000123",
signEvent: async () => ({}),
nip04: {
async decrypt(_pubkey, ciphertext) {
decryptCalls.push(ciphertext);
@@ -86,7 +83,7 @@ test("loadSubscriptions aggregates relay results when one rejects", async () =>
};
try {
await manager.loadSubscriptions("0000000000000000000000000000000000000000000000000000000000000123");
await manager.loadSubscriptions("user-pubkey-123");
assert.deepEqual(
Array.from(manager.subscribedPubkeys),
@@ -133,9 +130,6 @@ test("loadSubscriptions aggregates relay results when one rejects", async () =>
delete globalThis.window;
}
localStorage.clear();
profileCache.memoryCache.clear();
profileCache.activePubkey = null;
clearActiveSigner();
}
});
@@ -176,7 +170,7 @@ test("loadSubscriptions queries the correct subscription list kind", async () =>
nostrClient.ensureExtensionPermissions = async () => ({ ok: true });
try {
await manager.loadSubscriptions("0000000000000000000000000000000000000000000000000000000000000002");
await manager.loadSubscriptions("user-pubkey-legacy");
assert.ok(
capturedFilters.length > 0,
@@ -216,9 +210,6 @@ test("loadSubscriptions queries the correct subscription list kind", async () =>
delete globalThis.window;
}
localStorage.clear();
profileCache.memoryCache.clear();
profileCache.activePubkey = null;
clearActiveSigner();
}
});
@@ -235,6 +226,12 @@ test("loadSubscriptions falls back to nip44 when hinted", async () => {
const originalPool = nostrClient.pool;
const originalEnsurePermissions = nostrClient.ensureExtensionPermissions;
const hadWindow = typeof globalThis.window !== "undefined";
if (!hadWindow) {
globalThis.window = {};
}
const originalWindowNostr = globalThis.window.nostr;
const relayUrls = ["wss://relay-nip44.example"];
nostrClient.relays = relayUrls;
nostrClient.writeRelays = relayUrls;
@@ -255,20 +252,23 @@ test("loadSubscriptions falls back to nip44 when hinted", async () => {
nostrClient.ensureExtensionPermissions = async () => ({ ok: true });
const decryptCalls = { nip04: 0, nip44: 0 };
setActiveSigner({
pubkey: "0000000000000000000000000000000000000000000000000000000000000005",
async nip04Decrypt() {
decryptCalls.nip04 += 1;
throw new Error("nip04 unavailable");
globalThis.window.nostr = {
nip04: {
async decrypt() {
decryptCalls.nip04 += 1;
throw new Error("nip04 unavailable");
},
},
async nip44Decrypt(_pubkey, ciphertext) {
decryptCalls.nip44 += 1;
return JSON.stringify([["p", "pub-nip44", ciphertext]]);
nip44: {
async decrypt(_pubkey, ciphertext) {
decryptCalls.nip44 += 1;
return JSON.stringify([["p", "pub-nip44", ciphertext]]);
},
},
});
};
try {
await manager.loadSubscriptions("0000000000000000000000000000000000000000000000000000000000000005");
await manager.loadSubscriptions("user-pubkey-123");
assert.deepEqual(
Array.from(manager.subscribedPubkeys),
@@ -292,10 +292,15 @@ test("loadSubscriptions falls back to nip44 when hinted", async () => {
nostrClient.writeRelays = originalWriteRelays;
nostrClient.pool = originalPool;
nostrClient.ensureExtensionPermissions = originalEnsurePermissions;
if (typeof originalWindowNostr === "undefined") {
delete globalThis.window.nostr;
} else {
globalThis.window.nostr = originalWindowNostr;
}
if (!hadWindow) {
delete globalThis.window;
}
localStorage.clear();
profileCache.memoryCache.clear();
profileCache.activePubkey = null;
clearActiveSigner();
}
});
@@ -312,6 +317,12 @@ test("loadSubscriptions handles nip44.v2 decryptors", async () => {
const originalPool = nostrClient.pool;
const originalEnsurePermissions = nostrClient.ensureExtensionPermissions;
const hadWindow = typeof globalThis.window !== "undefined";
if (!hadWindow) {
globalThis.window = {};
}
const originalWindowNostr = globalThis.window.nostr;
const relayUrls = ["wss://relay-nip44-v2.example"];
nostrClient.relays = relayUrls;
nostrClient.writeRelays = relayUrls;
@@ -332,16 +343,19 @@ test("loadSubscriptions handles nip44.v2 decryptors", async () => {
nostrClient.ensureExtensionPermissions = async () => ({ ok: true });
const decryptCalls = { nip04: 0, nip44: 0, nip44_v2: 0 };
setActiveSigner({
pubkey: "0000000000000000000000000000000000000000000000000000000000000006",
async nip44Decrypt(_pubkey, ciphertext) {
decryptCalls.nip44_v2 += 1;
return JSON.stringify([["p", "pub-nip44-v2"], ["t", ciphertext]]);
globalThis.window.nostr = {
nip44: {
v2: {
async decrypt(_pubkey, ciphertext) {
decryptCalls.nip44_v2 += 1;
return JSON.stringify([["p", "pub-nip44-v2"], ["t", ciphertext]]);
},
},
},
});
};
try {
await manager.loadSubscriptions("0000000000000000000000000000000000000000000000000000000000000006");
await manager.loadSubscriptions("user-pubkey-123");
assert.deepEqual(
Array.from(manager.subscribedPubkeys),
@@ -370,10 +384,15 @@ test("loadSubscriptions handles nip44.v2 decryptors", async () => {
nostrClient.writeRelays = originalWriteRelays;
nostrClient.pool = originalPool;
nostrClient.ensureExtensionPermissions = originalEnsurePermissions;
if (typeof originalWindowNostr === "undefined") {
delete globalThis.window.nostr;
} else {
globalThis.window.nostr = originalWindowNostr;
}
if (!hadWindow) {
delete globalThis.window;
}
localStorage.clear();
profileCache.memoryCache.clear();
profileCache.activePubkey = null;
clearActiveSigner();
}
});
@@ -390,6 +409,12 @@ test("loadSubscriptions prefers nip44 decryptors when both are available", async
const originalPool = nostrClient.pool;
const originalEnsurePermissions = nostrClient.ensureExtensionPermissions;
const hadWindow = typeof globalThis.window !== "undefined";
if (!hadWindow) {
globalThis.window = {};
}
const originalWindowNostr = globalThis.window.nostr;
const relayUrls = ["wss://relay-nip44-pref.example"];
nostrClient.relays = relayUrls;
nostrClient.writeRelays = relayUrls;
@@ -410,20 +435,25 @@ test("loadSubscriptions prefers nip44 decryptors when both are available", async
nostrClient.ensureExtensionPermissions = async () => ({ ok: true });
const decryptCalls = { nip04: 0, nip44: 0 };
setActiveSigner({
pubkey: "0000000000000000000000000000000000000000000000000000000000000003",
async nip04Decrypt() {
decryptCalls.nip04 += 1;
return JSON.stringify([["p", "pub-nip04"]]);
globalThis.window.nostr = {
nip04: {
async decrypt() {
decryptCalls.nip04 += 1;
return JSON.stringify([["p", "pub-nip04"]]);
},
},
async nip44Decrypt(_pubkey, ciphertext) {
decryptCalls.nip44 += 1;
return JSON.stringify([["p", "pub-nip44-pref", ciphertext]]);
nip44: {
v2: {
async decrypt(_pubkey, ciphertext) {
decryptCalls.nip44 += 1;
return JSON.stringify([["p", "pub-nip44-pref", ciphertext]]);
},
},
},
});
};
try {
await manager.loadSubscriptions("0000000000000000000000000000000000000000000000000000000000000003");
await manager.loadSubscriptions("user-pubkey-123");
assert.deepEqual(
Array.from(manager.subscribedPubkeys),
@@ -437,10 +467,15 @@ test("loadSubscriptions prefers nip44 decryptors when both are available", async
nostrClient.writeRelays = originalWriteRelays;
nostrClient.pool = originalPool;
nostrClient.ensureExtensionPermissions = originalEnsurePermissions;
if (typeof originalWindowNostr === "undefined") {
delete globalThis.window.nostr;
} else {
globalThis.window.nostr = originalWindowNostr;
}
if (!hadWindow) {
delete globalThis.window;
}
localStorage.clear();
profileCache.memoryCache.clear();
profileCache.activePubkey = null;
clearActiveSigner();
}
});
@@ -491,7 +526,7 @@ test(
const decryptCalls = [];
setActiveSigner({
pubkey: "0000000000000000000000000000000000000000000000000000000000000004",
pubkey: "user-pubkey-123",
async nip04Decrypt(pubkey, ciphertext) {
decryptCalls.push({ pubkey, ciphertext });
return JSON.stringify([["p", "pub-direct"]]);
@@ -499,13 +534,13 @@ test(
});
try {
await manager.loadSubscriptions("0000000000000000000000000000000000000000000000000000000000000004");
await manager.loadSubscriptions("user-pubkey-123");
assert.equal(permissionCalls, 0, "should not request extension permissions");
assert.equal(decryptCalls.length, 1, "signer decrypt should be invoked once");
assert.deepEqual(
decryptCalls[0],
{ pubkey: "0000000000000000000000000000000000000000000000000000000000000004", ciphertext: "cipher-direct" },
{ pubkey: "user-pubkey-123", ciphertext: "cipher-direct" },
"signer decrypt should receive the expected arguments",
);
assert.deepEqual(
@@ -528,9 +563,6 @@ test(
delete globalThis.window;
}
localStorage.clear();
profileCache.memoryCache.clear();
profileCache.activePubkey = null;
clearActiveSigner();
}
},
);