diigo-cache: diigo counts pages from 0; migrate stored pages (schema v2)
Comparing a cache with diigo's RSS export: the size-100 walk had missed
exactly the 100 newest bookmarks (everything updated since 2026-09-16).
diigo's page_num is 0-based, and we sent our 1-based page number
unchanged, so "page 1" was really page 2 and the newest page was never
fetched. diigo's total (16744) was right; the "total-overstated"
reading was a misdiagnosis.
- page() asks for page_num = n - 1
- BREAKING for stored state, agreed beforehand, migrated in place:
schema v2 renumbers every stored page +1 (pages and page_members, via
negation so no number collides), once, recorded as kv "schema" = 2;
nothing is refetched, page 1 just becomes a miss
- fill jobs record their numbering; a job saved without it fails ("page
numbering changed …; start the fill again") instead of resuming
- the fake pages from 0 like diigo (7 tests failed until the fix);
tests feed v1-shaped storage and a v1-numbered job to the new code
- the next-page peek guard stays; its comments no longer claim diigo
overstates its total
- the fixed test clock moves to 2099: pinned to "today" its alarms came
due in real time and fired on their own
Generated-by: Claude Opus 5.5
This commit is contained in:
1 parent
e6deb9fda0
commit
cffb1fa9b2
5 files changed
+116
-17
No files matched your search
@@ -131,7 +131,7 @@ describe("fill job (goal 1e)", () => {
|
||||
expect(status?.error).toMatch(/page size not honored/);
|
||||
});
|
||||
|
||||
it("fills to the real end when diigo's total overstates its items", async () => {
|
||||
it("fills to the real end if a total overstates the items", async () => {
|
||||
const stub = await wired("fake-overstated-webapp");
|
||||
await stub.startFill();
|
||||
await drain(stub);
|
||||
@@ -143,6 +143,18 @@ describe("fill job (goal 1e)", () => {
|
||||
expect((await stub.page(3, PAGE_SIZE)).items).toHaveLength(50);
|
||||
});
|
||||
|
||||
it("a job saved under the old page numbering fails instead of resuming", async () => {
|
||||
const stub = await wired();
|
||||
await runInDurableObject(stub, async (_obj, state) => {
|
||||
const at = new Date().toISOString();
|
||||
await state.storage.put("fill", { state: "running", nextPage: 40, pages: 168, fetched: 39, pageSize: 100, startedAt: at, updatedAt: at });
|
||||
await state.storage.setAlarm(Date.now() + 60_000);
|
||||
});
|
||||
await drain(stub);
|
||||
expect((await stub.fillStatus())?.error).toMatch(/page numbering changed/);
|
||||
expect(await stub.startFill()).toMatchObject({ state: "running", nextPage: 1, numbering: 2 });
|
||||
});
|
||||
|
||||
it("a job saved under another page size fails instead of resuming; a new start replaces it", async () => {
|
||||
const stub = await wired();
|
||||
// the shape a 24-per-page job left in storage (no pageSize field)
|
||||
|
||||
Reference in new issue
Block a user