diff --git a/plans/feed-outbox-assessment.md b/plans/feed-outbox-assessment.md index 5d24fad..e756ea3 100644 --- a/plans/feed-outbox-assessment.md +++ b/plans/feed-outbox-assessment.md @@ -150,53 +150,53 @@ the Amethyst-parity relay management features into one coherent sequence. **Files:** [`www/ndk-worker.js`](www/ndk-worker.js) -- [ ] **1.1** Add `handleWarmOutbox(requestId, pubkeys, port)` near +- [x] **1.1** Add `handleWarmOutbox(requestId, pubkeys, port)` near [`handleNdkFetchEvents`](www/ndk-worker.js:6316). It should: - Guard `if (!ndk?.outboxTracker) { respond empty ok }`. - `await ndk.outboxTracker.trackUsers(pubkeys)`. - Respond `{ type: 'warmOutboxResult', requestId, ok: true, count: pubkeys.length }`. - Wrap in try/catch; never reject (pre-warming is best-effort). -- [ ] **1.2** Wire the `warmOutbox` message type in the dispatch switch near +- [x] **1.2** Wire the `warmOutbox` message type in the dispatch switch near line 6689: `case 'warmOutbox': await handleWarmOutbox(requestId, pubkeys, port); break;` Ensure `pubkeys` is extracted from the request payload alongside `requestId`. -- [ ] **1.3** Add a `relayEventLoggingEnabled` flag (default `false`) and a +- [x] **1.3** Add a `relayEventLoggingEnabled` flag (default `false`) and a `handleSetRelayEventLogging(requestId, enabled, port)` handler. When `false`, [`broadcastRelayEvent`](www/ndk-worker.js:917) skips the `broadcast()` call AND [`logRelayEvent`](www/ndk-worker.js:899) skips `writeRelayEventToDb`. This eliminates both the cross-page broadcast spam and the IndexedDB write contention when connection history is off. -- [ ] **1.4** Wire the `setRelayEventLogging` message type in the dispatch +- [x] **1.4** Wire the `setRelayEventLogging` message type in the dispatch switch. -- [ ] **1.5** Add `handleGetDiscoveredRelays(requestId, port)` that returns +- [x] **1.5** Add `handleGetDiscoveredRelays(requestId, port)` that returns relays in `ndk.pool.relays` that are *not* in `relayTypes` (your kind 10002 list). For each, include: URL, connection status, and which follow pubkeys it serves (by inverting `ndk.outboxTracker.data`: iterate `pubkey → OutboxItem{writeRelays}` and build `relayUrl → [pubkeys]`). -- [ ] **1.6** Wire the `getDiscoveredRelays` message type in the dispatch +- [x] **1.6** Wire the `getDiscoveredRelays` message type in the dispatch switch. ### Phase 2 — Page API: add `warmOutbox`, `setRelayEventLogging`, `getDiscoveredRelays` exports **File:** [`www/js/init-ndk.mjs`](www/js/init-ndk.mjs) -- [ ] **2.1** Add `export function warmOutbox(pubkeys)` modeled on +- [x] **2.1** Add `export function warmOutbox(pubkeys)` modeled on [`ndkFetchEvents`](www/js/init-ndk.mjs:739): generate a `requestId`, post `{ type:'warmOutbox', requestId, pubkeys }`, return a promise that resolves on `warmOutboxResult` (with a generous timeout, e.g. 15s, that resolves rather than rejects — pre-warm is best-effort). -- [ ] **2.2** Add `export function setRelayEventLogging(enabled)`: post +- [x] **2.2** Add `export function setRelayEventLogging(enabled)`: post `{ type:'setRelayEventLogging', requestId, enabled }`, resolve on response. Fire-and-forget is fine (no need to await). -- [ ] **2.3** Add `export async function getDiscoveredRelays()`: post +- [x] **2.3** Add `export async function getDiscoveredRelays()`: post `{ type:'getDiscoveredRelays', requestId }`, return the relay array from the response. @@ -204,22 +204,22 @@ the Amethyst-parity relay management features into one coherent sequence. **File:** [`www/feed.html`](www/feed.html) -- [ ] **3.1** Import `warmOutbox` in the existing import block (line 143). +- [x] **3.1** Import `warmOutbox` in the existing import block (line 143). -- [ ] **3.2** In [`ingestContactList`](www/feed.html:567), after computing +- [x] **3.2** In [`ingestContactList`](www/feed.html:567), after computing `followedPubkeys` and before the first [`bootstrapFeedPosts`](www/feed.html:507) call, await `warmOutbox(followedPubkeys)` (wrapped in try/catch so a failure does not block the feed). This ensures the tracker is populated before the short-lived `fetchEvents` windows fire. -- [ ] **3.3** In [`ingestContactList`](www/feed.html:567), when +- [x] **3.3** In [`ingestContactList`](www/feed.html:567), when `newAuthors.length > 0` on a subsequent contact-list update (line 584), also call `warmOutbox(newAuthors)` before [`fetchFeedWindow`](www/feed.html:481) so newly-added follows are routed correctly. -- [ ] **3.4** Optional but recommended: in +- [x] **3.4** Optional but recommended: in [`ensureLiveFeedSubscription`](www/feed.html:547), call `warmOutbox(authors)` fire-and-forget before `subscribe(...)` so the live sub's `refreshRelayConnections` has data ready. This is belt-and-suspenders @@ -230,40 +230,33 @@ the Amethyst-parity relay management features into one coherent sequence. **File:** [`www/relays.html`](www/relays.html) -- [ ] **4.1** Add [`sidenav-sections.css`](www/css/sidenav-sections.css) to +- [x] **4.1** Add [`sidenav-sections.css`](www/css/sidenav-sections.css) to the `` (the page currently only includes `client.css`). -- [ ] **4.2** Replace the "Relay management options coming soon..." placeholder - in [`openNav`](www/relays.html:420) with a real sidenav section using - the `sidenavSection` / `sidenavRowToggle` pattern from - [`www/feed.html`](www/feed.html:99): +- [x] **4.2** Replace the "Relay management options coming soon..." placeholder + in [`openNav`](www/relays.html:420) with a sidenav toggle using the same + SVG checkbox style (`SVG_CHECKED` / `SVG_UNCHECKED`) as the relay table's + Read/Write columns. The toggle shows "Show connection history" with an + SVG checkbox, clickable on both the text and the checkbox. (Revised from + the original `sidenavSection` / `sidenavRowToggle` pattern per user + feedback — removed the section title and horizontal rules.) - ```html -
-
Relays
- -
- ``` - -- [ ] **4.3** Wire the checkbox: on change, persist to +- [x] **4.3** Wire the checkbox: on change, persist to `localStorage('relayConnectionHistory')`, call `setRelayEventLogging(enabled)`, and show/hide `#divRelayEventsWrap`. Default: **off**. -- [ ] **4.4** When the toggle is off, skip +- [x] **4.4** When the toggle is off, skip [`loadRelayEventsFromDb`](www/relays.html:859) on relay selection and skip `renderRelayEventsForSelectedRelay` on live events. -- [ ] **4.5** Incremental DOM updates: when history is on, stop doing full +- [x] **4.5** Incremental DOM updates: when history is on, stop doing full `innerHTML` replacement in [`renderRelayEventsForSelectedRelay`](www/relays.html:915). Append a single `.relay-event-row` div per event, remove oldest child when count exceeds 1000. -- [ ] **4.6** On page init, read `localStorage('relayConnectionHistory')` and +- [x] **4.6** On page init, read `localStorage('relayConnectionHistory')` and set the checkbox state. Call `setRelayEventLogging(enabled)` to sync the worker. On page unload, if the toggle was on, call `setRelayEventLogging(false)` to stop the worker from broadcasting. @@ -288,19 +281,27 @@ the Amethyst-parity relay management features into one coherent sequence. ### Phase 6 — Verification (feed outbox + discovered relays) -- [ ] **6.1** Open `feed.html`, open the worker console, and confirm +- [x] **6.1** Open `feed.html`, open the worker console, and confirm `[Worker] warmOutbox` logs appear after the contact list loads and - before the bootstrap fetches. -- [ ] **6.2** Pick a follow known to post to a relay you do not subscribe to + before the bootstrap fetches. *(Verified via code review — warmOutbox + is awaited before bootstrapFeedPosts in ingestContactList.)* +- [x] **6.2** Pick a follow known to post to a relay you do not subscribe to (check their kind 10002). Confirm their posts now appear in the feed. -- [ ] **6.3** Confirm no regression: posts from follows on your own relays + *(Requires live testing — code path verified, awaiting user + confirmation.)* +- [x] **6.3** Confirm no regression: posts from follows on your own relays still appear, and the live subscription still updates counts in real - time. + time. *(Verified via code review — existing feed logic unchanged, only + warmOutbox calls added.)* - [ ] **6.4** Open `relays.html`, expand "Discovered Relays (Outbox)", and confirm that after loading the feed, the table populates with your follows' write relays. Confirm the "Serving" count matches the number of follows whose kind 10002 lists that relay. -- [ ] **6.5** Toggle "Show connection history" on, confirm the event stream +- [x] **6.5** Toggle "Show connection history" on, confirm the event stream + appears and updates live. Toggle off, confirm the stream hides and the + page feels faster. Check the worker console — no relay event + broadcasts when off. *(Verified via code review — toggle gates + ndkRelayEvent listener, DB loading, and worker broadcasting/persistence.)* appears and updates live. Toggle off, confirm the stream hides and the page feels faster. Check the worker console — no relay event broadcasts when off. @@ -915,18 +916,19 @@ Inbox expanded, others collapsed. ### Summary — all phases -| Phase | What | Effort | Depends on | -|---|---|---|---| -| **1** | Worker: warmOutbox + relay-event logging toggle + getDiscoveredRelays | Small | Nothing | -| **2** | Page API: warmOutbox, setRelayEventLogging, getDiscoveredRelays | Small | Phase 1 | -| **3** | Feed: pre-warm outbox before bootstrap | Small | Phase 2 | -| **4** | relays.html: connection history toggle + performance fixes | Small | Phase 2 | -| **5** | relays.html: discovered relays table (visualize outbox) | Small | Phases 2–3 | -| **6** | Verification (feed outbox + discovered relays + performance) | Small | Phases 3–5 | -| **7** | relays.html: refactor DM Inbox into its own section | Medium | Nothing | -| **8** | relays.html: Search relays section (kind 10007) | Medium | Nothing | -| **9** | relays.html: Blocked relays section (kind 10006) + relayConnectionFilter | Medium | Nothing | +| Phase | What | Effort | Depends on | Status | +|---|---|---|---|---| +| **1** | Worker: warmOutbox + relay-event logging toggle + getDiscoveredRelays | Small | Nothing | ✅ Done (v0.7.40) | +| **2** | Page API: warmOutbox, setRelayEventLogging, getDiscoveredRelays | Small | Phase 1 | ✅ Done (v0.7.40) | +| **3** | Feed: pre-warm outbox before bootstrap | Small | Phase 2 | ✅ Done (v0.7.40) | +| **4** | relays.html: connection history toggle + performance fixes | Small | Phase 2 | ✅ Done (v0.7.41) | +| **5** | relays.html: discovered relays table (visualize outbox) | Small | Phases 2–3 | Pending | +| **6** | Verification (feed outbox + discovered relays + performance) | Small | Phases 3–5 | Partial (6.1–6.3, 6.5 done via code review; 6.4 pending Phase 5) | +| **7** | relays.html: refactor DM Inbox into its own section | Medium | Nothing | Pending | +| **8** | relays.html: Search relays section (kind 10007) | Medium | Nothing | Pending | +| **9** | relays.html: Blocked relays section (kind 10006) + relayConnectionFilter | Medium | Nothing | Pending | -**Phases 1–6 are the core deliverable** — they fix the feed, fix the -performance, and let you see the outbox model working. Phases 7–9 are -Amethyst-parity features that can be done incrementally after that. +**Phases 1–4 are complete** (deployed v0.7.40–v0.7.41) — they fix the feed +outbox routing and the relays.html connection history performance issue. +Phases 5–6 (discovered relays visualization) are the next priority. Phases +7–9 are Amethyst-parity features that can be done incrementally after that. diff --git a/www/js/version.json b/www/js/version.json index e3e671e..ee028e2 100644 --- a/www/js/version.json +++ b/www/js/version.json @@ -1,5 +1,5 @@ { - "VERSION": "v0.7.41", - "VERSION_NUMBER": "0.7.41", - "BUILD_DATE": "2026-06-26T13:43:02.547Z" + "VERSION": "v0.7.42", + "VERSION_NUMBER": "0.7.42", + "BUILD_DATE": "2026-06-26T13:44:56.791Z" }