diff options
| author | Adam Soltys <[email protected]> | 2026-09-30 19:27:26 +0000 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-30 19:27:26 +0000 |
| commit | be6e447c8960e0b74308137efa10b45d0763b922 (patch) | |
| tree | e6e203918e1ce10e91caa22b10794c6862f1b985 /tools/feed-cache-test.js | |
| parent | 0879e4f55dcee9bb7af86b1e4e2a62ee9d6ef3b6 (diff) | |
| download | coinosv3-be6e447c8960e0b74308137efa10b45d0763b922.tar.gz coinosv3-be6e447c8960e0b74308137efa10b45d0763b922.zip | |
Switching feeds paints posts at once instead of a spinner while the relays answer.
The disk cache held four feeds, so with more chips than that (or one never
opened here) a switch opened on nothing. Now:
- up to twelve feeds on disk: the four read last keep a page of 30, the
rest 5 seed posts (same 256 KB budget);
- once the feed on screen settles, every other feed with nothing on disk
has its first posts fetched ahead, one small request each, every 15 min;
- a feed with nothing on disk borrows matching posts (its people, its
topics) that open feeds already hold.
tools/feed-switch-seed-test.js: with 8 s relays, a fetched-ahead feed and a
never-opened topic feed both paint rows at once (fails on the old code).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WMMwWYJkPQxLgfMsY7hWcU
Diffstat (limited to 'tools/feed-cache-test.js')
| -rw-r--r-- | tools/feed-cache-test.js | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/tools/feed-cache-test.js b/tools/feed-cache-test.js index 995e01a..3df9447 100644 --- a/tools/feed-cache-test.js +++ b/tools/feed-cache-test.js @@ -12,14 +12,28 @@ storage.setItem('wallet:funds', 'untouched'); assert.equal(cache.read('following').length, 30); assert.equal(JSON.parse(storage.getItem('wallet:feedNotes')).notes.length, 30); for (let i = 0; i < 5; i++) cache.save('custom' + i, notes); -assert.equal(cache.read('following').length, 0); -assert.equal([...values.keys()].filter((k) => k.includes('feedNotes')).length, 4); -cache.read('custom1'); -cache.save('custom5', notes); -assert.equal(cache.read('custom2').length, 0); +const stored = (id) => JSON.parse(storage.getItem(id === 'following' ? 'wallet:feedNotes' : 'wallet:feedNotes:' + id) || 'null'); +assert.equal(stored('following').notes.length, 5, 'a feed past the four most recent keeps seed posts'); +assert.equal(stored('custom4').notes.length, 30); +assert.equal(cache.read('following').length, 5, 'and reads them back'); +for (let i = 5; i < 14; i++) cache.save('custom' + i, notes); +assert.equal([...values.keys()].filter((k) => k.includes('feedNotes')).length, 12); +assert.equal(stored('custom0'), null, 'the least recently read goes first'); +assert.equal(stored('custom3').notes.length, 5); +cache.read('custom3'); cache.save('custom3', notes); +assert.equal(stored('custom3').notes.length, 30, 'reopened, it gets a full page again'); +assert.equal(stored('custom10').notes.length, 5, 'and the oldest of the four drops to seed posts'); +// seeds warmed ahead never outrank or overwrite a feed that was read +cache.seed('custom13', notes.slice(0, 2)); +assert.equal(stored('custom13').notes.length, 30); +assert.equal(cache.has('warm'), false); +cache.seed('warm', notes); +assert.equal(cache.has('warm'), true); +assert.equal(stored('warm').notes.length, 5); +assert.equal(stored('custom13').notes.length, 30); cache.save('big', notes.map((e) => ({ ...e, content: 'x'.repeat(15000) }))); assert([...values].filter(([k]) => k.includes('feedNotes')).reduce((n, [, v]) => n + v.length, 0) <= 256000); time += 8 * 86400_000; assert.equal(cache.read('big').length, 0); assert.equal(storage.getItem('wallet:funds'), 'untouched'); -console.log('✓ legacy caches shrink; 30 posts/feed, four feeds, byte budget, LRU and seven-day expiry enforced'); +console.log('✓ legacy caches shrink; 30 posts for the four most recent feeds, 5 seed posts for up to 12, byte budget, LRU and seven-day expiry enforced'); |
