Ship Web refresh cache/lock, mobile demand gate, matches 职业/国服 filter, and related site updates through 0.5.84. Co-authored-by: Cursor <cursoragent@cursor.com>
71 lines
1.9 KiB
JavaScript
71 lines
1.9 KiB
JavaScript
/**
|
|
* 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);
|
|
}
|
|
}
|