/** * Pages Function: GET|POST /api/mobile-demand * * Best-effort edge counter for "please add mobile support" demand. * Stored via the Cache API (no KV / wrangler binding), same pattern as * live-status. Counts may undercount under concurrent colo races and can * reset if the edge entry is evicted; good enough as a demand signal. * * GET -> { count } * POST -> increment once, return { count, voted: true } */ const CACHE_KEY = "https://mobile-demand.internal/v1"; // Long store TTL so eviction is rare; freshness is not time-gated. const CACHE_STORE_MAX_AGE_S = 365 * 24 * 60 * 60; function jsonResponse(body, status = 200) { return new Response(JSON.stringify(body), { status, headers: { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-store", }, }); } async function readCount() { try { const cached = await caches.default.match(CACHE_KEY); if (!cached) return 0; const data = await cached.json(); const n = Number(data && data.count); return Number.isFinite(n) && n >= 0 ? Math.floor(n) : 0; } catch { return 0; } } async function writeCount(count) { const body = { count, updated_at: new Date().toISOString(), }; const cached = new Response(JSON.stringify(body), { headers: { "Content-Type": "application/json; charset=utf-8", "Cache-Control": `max-age=${CACHE_STORE_MAX_AGE_S}`, }, }); await caches.default.put(CACHE_KEY, cached); } export async function onRequestGet() { try { const count = await readCount(); return jsonResponse({ count }); } catch { return jsonResponse({ count: 0 }); } } export async function onRequestPost() { try { const next = (await readCount()) + 1; await writeCount(next); return jsonResponse({ count: next, voted: true }); } catch { return jsonResponse({ error: "increment_failed" }, 503); } }