sortsafe tracks used, open-box and Warehouse pricing on the parts people actually hunt for — GPUs, RAM, NVMe drives, CPUs — and it does it without a server holding the catalog. Every "Refresh from Amazon" runs inside the visitor's own browser: it pulls Amazon search and product HTML through a small Cloudflare Worker, parses it with DOMParser right there on the page, and writes offers into a per-category IndexedDB store. The scraping fan-out — and the bot-detection surface with it — is spread across the audience instead of concentrated on one server IP that Amazon eventually walls off.
The Worker is 97 lines and does two things nobody expects. It is allowlisted to amazon.com so it can't be turned into an open relay, and it decides whether a fetch actually succeeded by measuring the response: a real product page is tens of kilobytes, Amazon's robot-check interstitial is a few, so anything under 50 KB triggers a retry with backoff on the theory that Cloudflare will egress from a different IP next time. It then returns HTTP 200 to the browser no matter what happened upstream, stashing the real status in a header, so the client-side parser can inspect a blocked page instead of dying on a failed fetch. Cross-tab, a navigator.locks mutex guarantees exactly one refresh per category no matter how many tabs are open, and four staggered workers crawl the queue at a deliberately unhurried pace.
Behind the live scrape sits a Keepa-driven seeder scheduling itself against a token bucket that refills at one per minute: enriching a known ASIN costs one token, discovering new ones costs fifty, so the cron reserves budget for discovery, stops enriching early rather than starve it, and rotates discovery to whichever model has the thinnest coverage. Records it merges are gated on what Keepa responded about rather than what produced a price — the difference between a sold-out listing disappearing and it haunting the deal list forever. Seeded records carry a provenance flag so a new seed can evict the whole previous one without touching offers you pulled yourself. And the entire system — SvelteKit build, static site, Cloudflare Worker — ships from an Android phone under Termux, which meant symlinking esbuild's Linux binaries over the missing Android ones, swapping rollup for its WASM build, running Vite through bun because Termux's node reports the wrong platform, and hand-writing an 87-line deployer against Cloudflare's REST API because wrangler has no android-arm64 build at all.
// Technical highlights
- Zero-backend architecture: the visitor's browser scrapes Amazon and stores 4 category catalogs in IndexedDB — the "server" is a 97-line Cloudflare Worker with an
amazon.com-only allowlist. - Bot-wall detection by payload size, not status code: under 50 KB means robot check, so retry up to 4× with 400/800/1200 ms backoff for a fresh Cloudflare egress IP.
- The proxy always answers HTTP 200 and reports the true upstream status in
x-proxy-status, so the client-side parser can read blocked bodies instead of throwing. - Keepa seeder schedules against a 1-token/minute bucket: ~1 token per ASIN vs ~50 per search, an explicit 55-token discovery reserve, and rotation to the thinnest-covered model each 30-minute cron run.
- Merge logic gates carry-forward on ASINs Keepa answered about, not ASINs that produced a price — so sold-out listings actually disappear instead of freezing at their last price.
navigator.locksenforces one refresh per category across every open tab; 4 staggered workers crawl 10 variants at 500 ms apart, 1.5 s between search pages.- Built and deployed entirely from an Android phone: esbuild symlink, rollup-WASM swap, Vite-under-bun shim, and an 87-line REST deployer because wrangler has no android-arm64 build.