Skip to content

refactor(network): look up LISH search detail row by id via $derived#23

Merged
libersoft-org merged 2 commits intofix/gossipsub-score-for-fresh-peersfrom
refactor/lish-search-row-lookup-by-id
May 3, 2026
Merged

refactor(network): look up LISH search detail row by id via $derived#23
libersoft-org merged 2 commits intofix/gossipsub-score-for-fresh-peersfrom
refactor/lish-search-row-lookup-by-id

Conversation

@lukyrys
Copy link
Copy Markdown
Collaborator

@lukyrys lukyrys commented May 3, 2026

Summary

Followup refactor to PR #22. Replaces the in-place row mutation in lishSearch.handleUpdate with a clean replace-by-id pattern, and moves the LISH peer-list detail page from holding a snapshot reference to looking up the row reactively by id.

Why

PR #22's frontend change kept the LishSearchResult row identity stable across updates because Network.svelte held a direct reference to the row object (lishPeerListRow = row). That worked but introduced two cognitive-load issues flagged in code review:

  1. Mixed reactivity model — new LISH = new reference, update of existing = in-place mutation. Future contributors have to remember which path applies when.
  2. Snapshot reference is fragile — any future change to the search reducer that replaces row objects would silently break the open detail page again.

What this PR does

Network.svelte — hold the LISH id, derive the row:

let lishPeerListRowID = $state<string | null>(null);
let lishPeerListRow = $derived<LishSearchResult | null>(
    lishPeerListRowID === null ? null : search.results.find(r => r.id === lishPeerListRowID) ?? null
);

lishSearch.svelte.ts handleUpdate — simplified back to replace-by-id:

const byID = new Map(results.map(r => [r.id, r] as const));
for (const row of d.lishs) byID.set(row.id, row);
results = [...byID.values()];

The search reducer is no longer responsible for preserving object identity — consumers that need cross-update tracking look up by id.

Edge case

When search.clear() runs (or the row disappears from results), $derived returns null and the {:else if ... && lishPeerListRow} guard unmounts the detail page. This matches the search session lifecycle (max network.searchTimeout, default 30 s) — showing a stale frozen snapshot of a finished search would arguably be the worse UX.

Dependency

Stacks on top of PR #22 (4 commits behind in this branch). Merge order: #22 first, then this. If #22 is rebased / amended, this branch needs to follow.

Test plan

  • bun run check (frontend) — 0 errors, 0 warnings
  • Manual: open search, click LISH detail, verify peer count updates as new responders arrive
  • Manual: close search while detail is open — detail unmounts cleanly

@lukyrys lukyrys changed the base branch from main to fix/gossipsub-score-for-fresh-peers May 3, 2026 14:09
@lukyrys lukyrys force-pushed the fix/gossipsub-score-for-fresh-peers branch from c04ddc8 to 7c43887 Compare May 3, 2026 14:41
@lukyrys lukyrys force-pushed the refactor/lish-search-row-lookup-by-id branch from e218f52 to ec99fc8 Compare May 3, 2026 14:41
@libersoft-org libersoft-org merged commit a014465 into fix/gossipsub-score-for-fresh-peers May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants