mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-29 08:52:25 +00:00
Merge pull request #1755 from PR0M3TH3AN/fix-nip07-login-and-list-sync-2738736650874322508
Fix NIP-07 Login Slowness and Prevent List Data Loss on Network Failure
This commit is contained in:
5 files changed
+57
-35
No files matched your search
+16
-23
@@ -548,29 +548,22 @@ async function fetchLatestListEvent(filter, contextLabel = "admin-list") {
|
||||
}
|
||||
|
||||
let events = [];
|
||||
try {
|
||||
if (pubkey) {
|
||||
events = await nostrClient.fetchListIncrementally({
|
||||
kind,
|
||||
pubkey,
|
||||
dTag,
|
||||
relayUrls: relays
|
||||
});
|
||||
} else {
|
||||
// Fallback for non-specific queries
|
||||
const normalizedFilter = {
|
||||
kinds: [kind],
|
||||
limit: 50
|
||||
};
|
||||
if (dTag) normalizedFilter["#d"] = [dTag];
|
||||
if (filter.authors) normalizedFilter.authors = filter.authors;
|
||||
events = await nostrClient.pool.list(relays, [normalizedFilter]);
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn(
|
||||
`[adminListStore] Fetch failed for ${contextLabel}:`,
|
||||
error,
|
||||
);
|
||||
if (pubkey) {
|
||||
events = await nostrClient.fetchListIncrementally({
|
||||
kind,
|
||||
pubkey,
|
||||
dTag,
|
||||
relayUrls: relays
|
||||
});
|
||||
} else {
|
||||
// Fallback for non-specific queries
|
||||
const normalizedFilter = {
|
||||
kinds: [kind],
|
||||
limit: 50
|
||||
};
|
||||
if (dTag) normalizedFilter["#d"] = [dTag];
|
||||
if (filter.authors) normalizedFilter.authors = filter.authors;
|
||||
events = await nostrClient.pool.list(relays, [normalizedFilter]);
|
||||
}
|
||||
|
||||
if (!events || !events.length) {
|
||||
|
||||
+21
-6
@@ -3520,6 +3520,9 @@ export class NostrClient {
|
||||
chunks.push(normalizedRelays.slice(i, i + concurrencyLimit));
|
||||
}
|
||||
|
||||
let anySuccess = false;
|
||||
const failures = [];
|
||||
|
||||
for (const chunk of chunks) {
|
||||
const promises = chunk.map(async (relayUrl) => {
|
||||
let lastSeen = this.getSyncLastSeen(
|
||||
@@ -3587,7 +3590,7 @@ export class NostrClient {
|
||||
this.updateSyncLastSeen(kind, normalizedPubkey, dTag, relayUrl, maxCreated);
|
||||
}
|
||||
|
||||
return events;
|
||||
return { events, ok: true };
|
||||
} catch (error) {
|
||||
// Fallback to full fetch if incremental failed or if relay error
|
||||
if (!doFullFetch) {
|
||||
@@ -3606,26 +3609,38 @@ export class NostrClient {
|
||||
if (maxCreated > 0) {
|
||||
this.updateSyncLastSeen(kind, normalizedPubkey, dTag, relayUrl, maxCreated);
|
||||
}
|
||||
return events || [];
|
||||
return { events: events || [], ok: true };
|
||||
} catch (fallbackError) {
|
||||
devLogger.warn(`[fetchListIncrementally] Full fetch fallback failed for ${relayUrl}`, fallbackError);
|
||||
return [];
|
||||
return { error: fallbackError, ok: false };
|
||||
}
|
||||
} else {
|
||||
devLogger.warn(`[fetchListIncrementally] Fetch failed for ${relayUrl}`, error);
|
||||
return [];
|
||||
return { error, ok: false };
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const chunkResults = await Promise.all(promises);
|
||||
for (const res of chunkResults) {
|
||||
if (Array.isArray(res)) {
|
||||
results.push(...res);
|
||||
if (res.ok) {
|
||||
anySuccess = true;
|
||||
if (Array.isArray(res.events)) {
|
||||
results.push(...res.events);
|
||||
}
|
||||
} else {
|
||||
failures.push(res.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!anySuccess && normalizedRelays.length > 0) {
|
||||
const error = new Error("All relays failed to fetch list.");
|
||||
error.code = "fetch-failed";
|
||||
error.failures = failures;
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Deduplicate by ID
|
||||
const uniqueEvents = new Map();
|
||||
for (const ev of results) {
|
||||
|
||||
@@ -270,12 +270,21 @@ export async function requestEnablePermissions(
|
||||
|
||||
let lastError = null;
|
||||
for (const options of permissionVariants) {
|
||||
// If specific permissions are requested (variants 1 & 2), fail fast (3s)
|
||||
// to avoid hanging if the extension doesn't support the structured format.
|
||||
// If we fall back to standard enable() (null), allow the full user interaction time.
|
||||
const variantTimeoutOverrides = options
|
||||
? {
|
||||
timeoutMs: Math.min(NIP07_LOGIN_TIMEOUT_MS, getEnableVariantTimeoutMs()),
|
||||
timeoutMs: 3000,
|
||||
retryMultiplier: 1,
|
||||
}
|
||||
: { retryMultiplier: 1 };
|
||||
: {
|
||||
timeoutMs: Math.min(
|
||||
NIP07_LOGIN_TIMEOUT_MS,
|
||||
getEnableVariantTimeoutMs(),
|
||||
),
|
||||
retryMultiplier: 1,
|
||||
};
|
||||
|
||||
try {
|
||||
await runNip07WithRetry(
|
||||
|
||||
@@ -505,6 +505,14 @@ class HashtagPreferencesService {
|
||||
}
|
||||
|
||||
if (!events.length) {
|
||||
if (fetchError) {
|
||||
userLogger.warn(
|
||||
`${LOG_PREFIX} Failed to load hashtag preferences (keeping local state if any).`,
|
||||
fetchError,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we failed to fetch (network error) but already have data for this user,
|
||||
// preserve the existing state instead of wiping it.
|
||||
// If fetchListIncrementally returns empty, it means no new updates or full fetch yielded nothing.
|
||||
|
||||
+1
-4
@@ -1096,10 +1096,7 @@ class UserBlockListManager {
|
||||
|
||||
|
||||
} catch (error) {
|
||||
userLogger.error("[UserBlockList] loadBlocks failed:", error);
|
||||
applyBlockedPubkeys([], { source: "fast", reason: "load-error", error });
|
||||
this.blockEventId = null;
|
||||
this.blockEventCreatedAt = null;
|
||||
userLogger.error("[UserBlockList] loadBlocks failed (keeping local state):", error);
|
||||
emitStatus({ status: "error", error });
|
||||
} finally {
|
||||
this.loaded = true;
|
||||
|
||||
Reference in new issue
Block a user