nip71: make ingest observable + throttle its feed refreshes

Two stabilization fixes after live testing showed ingest was invisible
and could amplify feed load:

1. Diagnostics were using devLogger.log, which is gated by IS_DEV_MODE
   (false in all current builds) — so the [nip71Ingest] subscribe/flush
   lines never printed and the feature was impossible to observe. Switched
   the subscribe + per-flush lines to userLogger.info so we can confirm in
   the console whether it subscribed (author count) and whether events are
   arriving/injecting. (Temporary while stabilizing.)

2. Coalesce ingest-driven "videos:updated" signals behind an 8s throttle.
   A burst of incoming events previously emitted a refresh per flush; each
   refresh re-runs the feed and re-subscribes moderation/social context for
   every video, which can contribute to a REQ storm. Injected videos are
   already in the active store, so throttling only delays the visual
   refresh, not the data.

Tests: throttle coalescing test (one immediate refresh per window, both
videos still stored); mutation-verified. 1234/1235 unit (known flake).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-22 16:05:01 -04:00
1 parent dcce28cc97
commit c4df08d5a1
2 files changed
+76 -22

No files matched your search

+19
View File
@@ -102,6 +102,8 @@ function makeService(harness, extra = {}) {
// Disable the hydration retry by default so each test is deterministic and
// leaves no dangling timers; the retry behavior is covered explicitly below.
maxOpenAttempts: 0,
// Emit refreshes synchronously (no throttle timer) for deterministic tests.
refreshThrottleMs: 0,
...extra,
});
}
@@ -216,6 +218,23 @@ test("re-subscribes when the whitelist changes", () => {
assert.deepEqual(h.capturedFilters[0].authors, ["aa", "cc"], "subscription re-scoped after change");
});
test("coalesces refresh signals so an event burst can't storm the feed", () => {
const h = makeHarness();
const svc = makeService(h, { refreshThrottleMs: 10000 });
svc.start();
h.fireEvent(foreignEvent({ id: "a", kind: 34235, tags: [["d", "ra"], ["title", "A"], ["imeta", "url https://e/a.mp4", "m video/mp4"]] }));
svc.flush();
h.fireEvent(foreignEvent({ id: "b", kind: 34235, tags: [["d", "rb"], ["title", "B"], ["imeta", "url https://e/b.mp4", "m video/mp4"]] }));
svc.flush();
const refreshes = h.emitted.filter((e) => e.name === "videos:updated");
assert.equal(refreshes.length, 1, "only one immediate refresh within the throttle window");
// Both videos still landed in the store regardless of the throttled signal.
assert.ok(h.activeMap.has("ROOT:ra") && h.activeMap.has("ROOT:rb"));
svc.stop();
});
test("FEATURE_NIP71_INGEST off makes the service completely inert", () => {
const h = makeHarness();
const svc = createNip71IngestService({