diff options
| author | Adam Soltys <[email protected]> | 2026-09-13 14:55:18 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-13 14:55:18 -0700 |
| commit | b11ae2e1811bd5dc6965d127414d8f4f03f248cd (patch) | |
| tree | 989d8b9a08b9400d929a5e56e0265ac21d73a978 /tools/profile-batch-test.js | |
| parent | fda681331ae3de5abee04042caed994954e1b705 (diff) | |
| download | coinosv3-b11ae2e1811bd5dc6965d127414d8f4f03f248cd.tar.gz coinosv3-b11ae2e1811bd5dc6965d127414d8f4f03f248cd.zip | |
The feed keeps up, and stops moving the page while you read.
A phone freezes a backgrounded tab: timers stop and the relay sockets are
cut, so the feed came back holding whatever it had when you left and only
caught up if you pulled it down by hand. Features now hear about the
return — app.js calls f.resumed(awayMs) on focus — and the feed answers
it by forcing a pass past the thirty-second throttle and rebuilding its
subscriptions, which were talking to sockets that no longer exist. A
blink between apps (under five seconds) is left alone.
That catch-up raises the second problem rather than solving it: dropping
eight posts in at the top moves the words under the thumb of whoever was
reading. So posts that arrive on their own — live, or as a catch-up —
wait when you're scrolled away from the top. A floating pill says how
many, and the tap that lets them in also takes you up to them. Scrolling
back to the top by yourself lets them in too, since up there they cost
nothing. Anything you actually asked for still goes straight in.
Also, on profiles that still show an npub: the batch now falls back to
the relays whose whole job is indexing kind 0 (purplepag.es and friends),
which we never read notes from and so never asked. profile-batch-test's
"handful of asks" bound was a fraction of the row count, which that
fallback broke; the property it means to assert is that the number does
NOT grow with the rows, so it is a constant now.
tools/feed-live-test.js drives a real signed event down a real open
subscription — an unsigned fake is dropped by the signature gate and
would prove nothing — and checks the page does not move, the pill says
"1 new post", tapping it scrolls to the top, and coming back from hidden
re-asks the relays on its own.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
Diffstat (limited to 'tools/profile-batch-test.js')
| -rw-r--r-- | tools/profile-batch-test.js | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/tools/profile-batch-test.js b/tools/profile-batch-test.js index bf8dcf4..8f8250c 100644 --- a/tools/profile-batch-test.js +++ b/tools/profile-batch-test.js @@ -89,13 +89,17 @@ try { const reqs = await page.evaluate(() => window.__k0); const rowCount = await page.evaluate(() => document.querySelectorAll('.notes-feed > .row').length); - // A screenful of faces must cost a handful of asks, not one per row. (A few - // singles are expected and fine: our own profile, which onboarding reads - // before it writes a name, and the outbox fallback chasing one straggler to - // the relay only they publish to.) + // A screenful of faces must cost a fixed handful of asks — the number must + // not grow with the rows, which is the bug this whole thing is about (one + // REQ per row, eighty at once, most refused). The bound is a constant, not + // a fraction of the rows, because that is the actual property: a couple of + // debounced batches, each of which may also ask the profile-index relays + // and then chase stragglers to their own relays. Singles are expected among + // them — our own profile, and one straggler on a relay only they use. + const ASK_CEILING = 12; const asks = await page.evaluate(() => [...(window.__k0asks || [])].length); - check('a screenful of faces costs a handful of asks, not one per row', - reqs.length > 0 && asks <= Math.max(4, rowCount / 4), + check('a screenful of faces costs a fixed handful of asks, however many rows', + reqs.length > 0 && asks <= ASK_CEILING, `${asks} asks for ${rowCount} rows, batches of ${[...new Set(reqs)].filter((n) => n > 1).join(',')}`); check('...one request covers the screen', Math.max(0, ...reqs) >= 8, 'biggest carried ' + Math.max(0, ...reqs) + ' pubkeys'); |
