nip71: defer ingest until feed renders; diagnose display path

Live logs proved ingest works (subscribed to 17 whitelisted authors,
received 61 events, injected 39) — but injecting foreign authors during
cold-start triggers the moderation/WoT stage to hydrate their social graph
(kind 30000), which competes with the initial feed load and stalls it
("Fetching recent videos…" hanging, needs a refresh).

- startWhenFeedReady(): defer the first ingest subscription until the
  native feed's first videos:updated (with a 12s fallback for empty
  feeds), keeping ingest off the cold-start critical path. Wired in
  applicationBootstrap (kept thin so the size cap holds).
- emitRefresh now logs how many ingested videos survive the feed filter
  ("N ingested of M in filtered feed") so we can tell whether foreign
  videos are filtered out vs. injected-but-not-rendered.

Tests: defer-until-feed-ready + fallback-timer; mutation-verified.
1236/1237 unit (known UploadModal flake).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-22 16:23:45 -04:00
1 parent c4df08d5a1
commit d1246dc113
3 files changed
+98 -5

No files matched your search

+7 -5
View File
@@ -858,6 +858,12 @@ export default class ApplicationBootstrap {
// Inbound NIP-71 ingest: pull video events published by other Nostr apps
// (scoped to whitelisted authors while whitelist mode is on) and surface
// them in the feed. Gated by FEATURE_NIP71_INGEST. Best-effort.
//
// Deferred until the native feed has rendered once: injecting foreign
// authors triggers the moderation/WoT stage to hydrate their social graph
// (kind 30000), which during cold-start competes with the initial feed load
// and can stall it. Starting after the first videos:updated keeps ingest off
// the critical path; a fallback timer covers the empty-feed case.
const nip71IngestService = createNip71IngestService({
nostrClient,
nostrService: app.nostrService,
@@ -865,11 +871,7 @@ export default class ApplicationBootstrap {
});
app.nip71IngestService = nip71IngestService;
if (nip71IngestService.isAvailable()) {
try {
nip71IngestService.start();
} catch (error) {
devLogger.warn("[applicationBootstrap] NIP-71 ingest start failed", error);
}
nip71IngestService.startWhenFeedReady();
nostrUnsubscribes.push(() => nip71IngestService.stop());
}
nostrUnsubscribes.push(