POST /_fill (cache id in the body; target private|public; action
start|stop) starts or stops a background walk of every diigo page into
the cache. DO alarms advance it pagesPerStep pages per step (default
20), a second apart; progress (FillStatus) is stored in the DO after
each page, so it survives eviction. Cached pages are skipped; starting
while running rejoins the job; a stop mid-step wins; a failure is
recorded with its reason and logged once. The created page gets fill
buttons; the public page shows "filling: n of m pages".
Fill state is new, additive DO storage (fill, fillStep): no existing
state changes meaning.
The 13 fill specs are unskipped and green, plus one: a fill makes one
diigo call per page fetched.
Generated-by: Claude Opus 5.5
Two bugs in page()'s miss path, found while building the fill job:
- the webapp stubs (app, pathjoin, query) were never disposed, which
kept the DO from being evicted (evictDurableObject hung after a single
miss); they are now disposed once the page is in hand
- a miss on page n > 1 also fetched page 1 and threw it away, doubling
diigo calls; every page carries `total`, so only page n is fetched
Regression test: a miss, then eviction, then a cache hit. tsconfig adds
the ESNext.Disposable lib for Symbol.dispose.
Generated-by: Claude Opus 5.5
A button that grabs every page into a cache: owner-only POST /_fill
(cache id in the body; target private|public; action start|stop),
advanced by DO alarms a few pages per step, progress stored in the DO
(new, additive state) so it survives eviction, cached pages skipped,
a rerun rejoins the running job, failures recorded and logged once.
The created page gets the button; the public page shows progress.
startFill/fillStatus/stopFill on PagedCache are JSDoc'd stubs; 13
specs are describe.skip until it lands (alarms driven by
runDurableObjectAlarm, eviction by evictDurableObject).
Generated-by: Claude Opus 5.5
The public page's filters, toward the weekly PESOS roundup (#23):
?days=N (7/30/90/365 presets), gmail-style after/before (UTC days,
half-open: after inclusive, before exclusive; yyyy/mm/dd accepted), and
q (words, "phrases", #tags exact against diigo's comma-separated tags,
- negation); q alone searches the last 365 days and says so; malformed
filters are a 400. Filtering walks diigo's updated-desc pages from 1 and
stops at the window, so ?days=7 costs one page.
src/query.ts is the typed, JSDoc'd API (stubs that throw); 22 specs are
describe.skip until it lands. The fake webapp gains a dated account.
Generated-by: Claude Opus 5.5
The list is in diigo's updated order; each item now leads with its
updated_at as Date#toISOString() (diigo sends epoch seconds; updatedISO
converts, tested), or "(no date)".
Generated-by: Claude Opus 5.5
A hit must replay diigo's order as fetched (page_members.pos), not a
column sort. The fake webapp's link_id and updated_at are scrambled so
neither column sorts back into diigo's order; ordering the replay by
updated or item_id fails the new test.
Generated-by: Claude Opus 5.5
vitest, @cloudflare/vitest-plugin, and typescript are devDependencies
here instead of being borrowed from diigo-bookmarks through hand-made
node_modules symlinks and a deep-path import.
- lint: wrangler types, then tsc over src/ and tests/ (Cloudflare's
documented typecheck shape: regenerate types, then tsc)
- test: vitest run
- tests/tsconfig.json per the vitest-plugin docs; the dangling
typecheck script (tsconfig.check.json never existed) is gone
Generated-by: Claude Opus 5.5
The dump worker becomes a page cache: a hit is served from DO SQLite
storage with no diigo call; a miss asks the webapp instance in the
cache's wiring and etches the page.
- two independent caches, one behavior (PagedCache): DiigoCache keeps
every item; PublicCache keeps shared items only, dropping private
rows before they are stored; served at /public/<username> (HTML page
form, or JSON)
- create flow on one port: /_connect relays webapp's mint form, /_mint
proxies the mint, /_wire wires a private or public cache; /_publish
adds a public cache later
- ids are webkeys: kept out of URLs (POST bodies), shown and logged
only as a hash fingerprint; saved to the password manager under the
holder's petname (never sent to the server)
- items keyed on diigo's link_id; username from u_name; unkeyable
items and every failure path are logged; each page read logs hit/miss
- tests run the real worker + DOs in the vitest pool against a fake
webapp (tests/fake-webapp.js)
Generated-by: opencode (GLM)
Generated-by: Claude Opus 5.5