Public: anyone can read this; the crew can change it.

The feed leaves out what happened in an archived repository #3484

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/3477-the-feed-leaves-out-what-happened-in-an → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/3477-the-feed-leaves-out-what-happened-in-an was merged into main as 9990bee.

Review

Sign in to review this change.
2 files changed +30 −2
src/feed/items.ts +15 −1
@@ -304,7 +304,21 @@ export function candidatesFor(
304304 urgency: 0,
305305 });
306306 }
307 return out;
307 return awake(db, out, repos);
308 }
309
310 /**
311 * Archived things are hidden, not gone (#1838): whatever a sleeping
312 * repository did stays out of the feed until it is woken, with no other step.
313 */
314 function awake(
315 db: Database,
316 candidates: Candidate[],
317 known: ReadonlyMap<string, Repo>,
318 ): Candidate[] {
319 const unknown = candidates.map((c) => c.repoId).filter((id) => !known.has(id));
320 const all = new Map([...known, ...getReposByIds(db, unknown)]);
321 return candidates.filter((c) => all.get(c.repoId)?.archivedAt == null);

Correct and small. Later, push this into listEventsVisibleTo so archived events never take window slots. Also note in the README archive section that the feed hides them.

308322 }
309323
310324 type Partial = Omit<Candidate, "actor">;
test/feed.test.ts +15 −1
@@ -12,7 +12,7 @@ import { createRepo } from "../src/actions/repos.ts";
1212 import { createSession } from "../src/core/sessions.ts";
1313 import { createToken } from "../src/core/tokens.ts";
1414 import { recordInteraction } from "../src/core/interactions.ts";
15 import type { Repo } from "../src/core/repos.ts";
15 import { moveArchived, type Repo } from "../src/core/repos.ts";
1616 import { createUser, type User } from "../src/core/users.ts";
1717 import { serve, type Servers } from "../src/http/server.ts";
1818 import { Affinity, affinityFor } from "../src/feed/affinity.ts";
@@ -185,6 +185,20 @@ describe("the feed of a forge", () => {
185185 expect(theirs.map((i) => i.kind).sort()).toEqual(["map", "run"]);
186186 });
187187
188 test("an archived repository's news leaves the feed, and returns when woken", async () => {
189 const apps = (v: User) => new Set(readFeed(app.db, v).items.map((i) => i.app));
190 expect(apps(bob).has("alice/open")).toBe(true);
191 expect(apps(alice).has("alice/secret")).toBe(true);
192 expect(moveArchived(app.db, openRepo.id, true)).toBe(true);
193 expect(apps(bob).has("alice/open")).toBe(false);
194 expect(apps(alice).has("alice/open")).toBe(false);
195 expect(apps(alice).has("alice/secret")).toBe(true);
196 // Hidden, not gone: its page still answers.
197 expect((await api(bobToken, "/alice/open")).status).toBe(200);
198 expect(moveArchived(app.db, openRepo.id, false)).toBe(true);
199 expect(apps(bob).has("alice/open")).toBe(true);
200 });
201
188202 test("items are plain data with a reason and a link", () => {
189203 for (const i of readFeed(app.db, alice).items) {
190204 expect(i.id).toMatch(/^[a-z]+:/);

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs